package hudson.node_monitors;

import static org.awaitility.Awaitility.await;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import hudson.model.Computer;
import hudson.model.ComputerSet;
import hudson.model.Node;
import hudson.model.User;
import hudson.slaves.DumbSlave;
import hudson.slaves.JNLPLauncher;
import hudson.slaves.OfflineCause;
import hudson.slaves.RetentionStrategy;
import hudson.slaves.SlaveComputer;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;

/**
 * @author Andrew Bayer
 */
public class ResponseTimeMonitorTest {

    @Rule
    public JenkinsRule j = new JenkinsRule();

    /**
     * Makes sure that it doesn't try to monitor an already-offline agent.
     */
    @Test
    @Issue("JENKINS-20272")
    public void skipOfflineAgent() throws Exception {
        DumbSlave s = j.createSlave();
        SlaveComputer c = s.getComputer();
        c.connect(false).get(); // wait until it's connected

        // Try as temporarily offline first.
        c.setTemporarilyOffline(true, new OfflineCause.UserCause(User.getUnknown(), "Temporarily offline"));
        assertNotNull(ResponseTimeMonitor.DESCRIPTOR.monitor(c));

        // Now try as actually disconnected.
        c.setTemporarilyOffline(false, null);
        j.disconnectSlave(s);
        assertNull(ResponseTimeMonitor.DESCRIPTOR.monitor(c));

        // Now reconnect and make sure we get a non-null response.
        c.connect(false).get(); // wait until it's connected

        assertNotNull(ResponseTimeMonitor.DESCRIPTOR.monitor(c));
    }

    @Test
    public void doNotDisconnectBeforeLaunched() throws Exception {
        DumbSlave slave = new DumbSlave("dummy", "dummy", j.createTmpDir().getPath(), "1", Node.Mode.NORMAL, "", new JNLPLauncher(), RetentionStrategy.NOOP, Collections.EMPTY_LIST);
        j.jenkins.addNode(slave);
        Computer c = slave.toComputer();
        assertNotNull(c);
        await().pollInterval(250, TimeUnit.MILLISECONDS)
                .atMost(10, TimeUnit.SECONDS)
                .until(() -> c.getOfflineCause(), notNullValue());
        OfflineCause originalOfflineCause = c.getOfflineCause();
        assertNotNull(originalOfflineCause);

        ResponseTimeMonitor rtm = ComputerSet.getMonitors().get(ResponseTimeMonitor.class);
        for (int i = 0; i < 10; i++) {
            rtm.triggerUpdate().join();
            System.out.println(rtm.getDescriptor().get(c));
            assertEquals(originalOfflineCause, c.getOfflineCause());
        }
    }
}

@@ -28,109 +28,8 @@
 s;%0A%0A
-import static org.awaitility.Awaitility.await;%0Aimport static org.hamcrest.CoreMatchers.notNullValue;%0A
 impo
@@ -242,19 +242,20 @@
 n.model.
-Nod
+Slav
 e;%0Aimpor
@@ -332,199 +332,79 @@
 ves.
-JNLPLauncher;%0Aimport hudson.slaves.OfflineCause;%0Aimport hudson.slaves.RetentionStrategy;%0Aimport hudson.slaves.SlaveComputer;%0Aimport java.util.Collections;%0Aimport java.util.concurrent.TimeUnit
+OfflineCause;%0Aimport hudson.slaves.SlaveComputer;%0Aimport org.junit.Rule
 ;%0Aim
@@ -410,36 +410,36 @@
 mport org.junit.
-Rule
+Test
 ;%0Aimport org.jun
@@ -432,33 +432,57 @@
 import org.j
-unit.Test
+vnet.hudson.test.InboundAgentRule
 ;%0Aimport org
@@ -675,24 +675,103 @@
 insRule();%0A%0A
+    @Rule%0A    public InboundAgentRule inboundAgents = new InboundAgentRule();%0A%0A
     /**%0A    
@@ -1774,28 +1774,24 @@
 n %7B%0A        
-Dumb
 Slave slave 
@@ -1796,432 +1796,161 @@
 e = 
-new DumbSlave(%22dummy%22, %22dummy%22, j.createTmpDir().getPath(), %221%22, Node.Mode.NORMAL, %22%22, new JNLPLauncher(), RetentionStrategy.NOOP, Collections.EMPTY_LIST);%0A        j.jenkins.addNode(slave);%0A        Computer c = slave.toComputer();%0A        assertNotNull(c);%0A        await().pollInterval(250, TimeUnit.MILLISECONDS)%0A                .atMost(10, TimeUnit.SECONDS)%0A                .until(() -%3E c.getOfflineCause(), notNullValue()
+inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().skipStart().build());%0A        Computer c = slave.toComputer();%0A        assertNotNull(c
 );%0A 

Use `InboundAgentRule` in `ResponseTimeMonitorTest#doNotDisconnectBeforeLaunched` (#7252)