package jenkins.slaves;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import hudson.TcpSlaveAgentListener.ConnectionFromCurrentPeer;
import hudson.remoting.Channel;
import hudson.slaves.SlaveComputer;
import jenkins.model.Jenkins;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Jenkins.class)
public class DefaultJnlpSlaveReceiverTest {
@Mock private Jenkins mockJenkins;
@Mock private SlaveComputer mockComputer;
@Mock private Channel mockChannel;
@Mock private JnlpSlaveAgentProtocol2.Handler mockHandshake;
@Mock private Future mockFuture;
private DefaultJnlpSlaveReceiver receiver;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mockStatic(Jenkins.class);
when(Jenkins.getInstance()).thenReturn(mockJenkins);
receiver = new DefaultJnlpSlaveReceiver();
}
@Test
public void testHandle() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(null);
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
when(mockHandshake.jnlpConnect(mockComputer)).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty("Secret-Key")).thenReturn("mock-secret");
when(mockComputer.getJnlpMac()).thenReturn("mock-secret");
assertTrue(receiver.handle("node", mockHandshake));
verify(mockHandshake).success(any(Properties.class));
verify(mockChannel).setProperty(any(String.class), any(String.class));
}
@Test
public void testHandleWithInvalidNode() throws Exception {
when(mockJenkins.getComputer("bogus-node")).thenReturn(null);
assertFalse(receiver.handle("bogus-node", mockHandshake));
}
@Test
public void testHandleTakeover() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie");
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture);
when(mockHandshake.jnlpConnect(mockComputer)).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty("Secret-Key")).thenReturn("mock-secret");
when(mockComputer.getJnlpMac()).thenReturn("mock-secret");
assertTrue(receiver.handle("node", mockHandshake));
verify(mockFuture).get(15, TimeUnit.SECONDS);
verify(mockHandshake).success(any(Properties.class));
verify(mockChannel).setProperty(any(String.class), any(String.class));
}
@Test
public void testHandleTakeoverFailedDisconnect() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie");
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture);
when(mockFuture.get(15, TimeUnit.SECONDS)).thenThrow(new ExecutionException(null));
try {
receiver.handle("node", mockHandshake);
fail();
} catch (IOException e) {
// good
}
}
@Test
public void testHandleTakeoverTimedOut() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie");
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture);
when(mockFuture.get(15, TimeUnit.SECONDS)).thenThrow(new TimeoutException());
try {
receiver.handle("node", mockHandshake);
fail();
} catch (IOException e) {
// good
}
}
@Test
public void testHandleAttemptTakeoverWithNullCookie() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty(any(String.class))).thenReturn(null);
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
assertTrue(receiver.handle("node", mockHandshake));
verify(mockHandshake).error(any(String.class));
}
@Test
public void testHandleAttemptTakeoverWithInvalidCookie() throws Exception {
when(mockJenkins.getComputer("node")).thenReturn(mockComputer);
when(mockComputer.getChannel()).thenReturn(mockChannel);
when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("bogus cookie");
when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie");
assertTrue(receiver.handle("node", mockHandshake));
verify(mockHandshake).error(any(String.class));
}
}