/* * The MIT License * * Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved. * Copyright 2012 Sony Mobile Communications AB. All rights reserved. * Copyright 2012 rinrinne All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.sonymobile.tools.gerrit.gerritevents; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.Reader; import java.io.Writer; import java.util.concurrent.CountDownLatch; import com.jcraft.jsch.ChannelExec; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.sonymobile.tools.gerrit.gerritevents.dto.attr.Provider; import com.sonymobile.tools.gerrit.gerritevents.ssh.Authentication; import com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnection; import com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory; //CS IGNORE MagicNumber FOR NEXT 200 LINES. REASON: TestData /** * Tests for {@link GerritConnection}. * * @author Robert Sandell <robert.sandell@sonyericsson.com> */ @RunWith(PowerMockRunner.class) @PrepareForTest(SshConnectionFactory.class) @PowerMockIgnore("org.slf4j.*") // Prevent warning about multiple sl4fj binding public class GerritConnectionTest { private static SshConnection sshConnectionMock; private static GerritConnection connection; private static PipedOutputStream pipedOutStream; private static Reader pipedReader; private static HandlerMock handlerMock; private static CountDownLatch establishedLatch = new CountDownLatch(1); private static CountDownLatch finishLatch = new CountDownLatch(1); private static CountDownLatch downLatch = new CountDownLatch(1); private static final String FINISH_WORD = "FINISH"; /** * Creates a SshConnection mock and starts a GerritConnection with that connection-mock. * * @throws Exception if so. */ @BeforeClass public static void setUp() throws Exception { sshConnectionMock = mock(SshConnection.class); when(sshConnectionMock.isAuthenticated()).thenReturn(true); when(sshConnectionMock.isConnected()).thenReturn(true); pipedOutStream = new PipedOutputStream(); PipedInputStream pipedInStream = new PipedInputStream(pipedOutStream); pipedReader = new InputStreamReader(pipedInStream); when(sshConnectionMock.executeCommand(eq("gerrit version"))).thenReturn("gerrit version 2.5.2"); when(sshConnectionMock.executeCommandReader(eq("gerrit stream-events"))).thenReturn(pipedReader); ChannelExec channelExecMock = mock(ChannelExec.class); when(channelExecMock.isConnected()).thenReturn(true); when(sshConnectionMock.executeCommandChannel(eq("gerrit stream-events"))).thenReturn(channelExecMock); when(sshConnectionMock.executeCommandChannel(eq("gerrit stream-events"), anyBoolean())) .thenReturn(channelExecMock); when(channelExecMock.getInputStream()).thenReturn(pipedInStream); PowerMockito.mockStatic(SshConnectionFactory.class); PowerMockito.doReturn(sshConnectionMock).when(SshConnectionFactory.class, "getConnection", isA(String.class), isA(Integer.class), isA(String.class), isA(Authentication.class), any()); connection = new GerritConnection("", "localhost", 29418, new Authentication(null, "")); handlerMock = mock(HandlerMock.class); connection.setHandler(handlerMock); connection.addListener(new ListenerMock()); connection.start(); try { establishedLatch.await(); } catch (InterruptedException e) { System.out.println("Interrupted while sleeping."); } assertTrue(connection.isConnected()); assertFalse(connection.isShutdownInProgress()); } /** * Shuts down the GerritConnection and the mocked connection. */ @AfterClass public static void shutDown() { try { finishLatch.await(); } catch (InterruptedException e) { System.out.println("Interrupted while sleeping."); } if (connection != null) { connection.shutdown(false); assertTrue(connection.isShutdownInProgress()); try { Writer writer = new OutputStreamWriter(pipedOutStream); writer.append("hello"); writer.append("\n"); writer.close(); downLatch.await(); assertFalse(connection.isConnected()); connection.join(); } catch (InterruptedException e) { System.err.println("interupted while waiting for connection to shut down."); } catch (IOException e) { System.err.println("Could not close the pipe."); } } connection = null; sshConnectionMock = null; pipedReader = null; pipedOutStream = null; } /** * Tests {@link GerritConnection#getGerritVersion()}. */ @Test public void testGetGerritVersion() { assertEquals("2.5.2", connection.getGerritVersion()); } /** * Tests {@link GerritConnection#getGerritHostName()}. */ @Test public void testGetGerritHostName() { assertEquals("localhost", connection.getGerritHostName()); } /** * Tests {@link GerritConnection#getAuthentication()}. */ @Test public void testGetAuthentication() { assertEquals(null, connection.getAuthentication().getPrivateKeyFile()); assertEquals("", connection.getAuthentication().getUsername()); assertEquals(null, connection.getAuthentication().getPrivateKeyFilePassword()); } /** * Tests {@link GerritConnection#getGerritSshPort()}. */ @Test public void testGetGerritSshPort() { assertEquals(29418, connection.getGerritSshPort()); } /** * Tests {@link GerritConnection#getGerritProxy()}. */ @Test public void testGetGerritProxy() { assertEquals("", connection.getGerritProxy()); } /** * Tests stream event receiver for {@link GerritConnection}. * * @throws Exception if so. */ @Test public void testReceiveEvent() throws Exception { doCallRealMethod().when(handlerMock).post(any(String.class), any(Provider.class)); Writer writer = new OutputStreamWriter(pipedOutStream); // String writer.append("Test\n"); writer.flush(); Thread.sleep(500); // JSON String writer.append("{\"say\":\"hello\"}\n"); writer.flush(); Thread.sleep(500); // Delayed Sending writer.append("Thank "); writer.flush(); System.out.println("Wait1: 2s..."); Thread.sleep(2 * 1000); writer.append("You!"); writer.flush(); System.out.println("Wait2: 2s..."); Thread.sleep(2 * 1000); writer.append("\n"); writer.flush(); Thread.sleep(500); writer.append("{\"say\":\"hello\"}\n{\"say\":\"hello again\"}\n"); writer.flush(); Thread.sleep(500); // Send finish writer.append(FINISH_WORD); writer.append("\n"); writer.flush(); Thread.sleep(500); verify(handlerMock, times(1)).post(eq("Test"), any(Provider.class)); verify(handlerMock, times(2)).post(eq("{\"say\":\"hello\"}"), any(Provider.class)); verify(handlerMock, times(1)).post(eq("{\"say\":\"hello again\"}"), any(Provider.class)); verify(handlerMock, times(1)).post(eq("Thank You!"), any(Provider.class)); } /** * A Handler mock */ static class HandlerMock extends GerritHandler { @Override public void post(String data) { post(data, null); } @Override public void post(String data, Provider provider) { System.out.println("INFO: Posted string: " + data); if (provider != null) { System.out.println("INFO: Posted " + provider); } if (data.equals(FINISH_WORD)) { finishLatch.countDown(); } } } /** * A Listener mock */ static class ListenerMock implements ConnectionListener { @Override public void connectionEstablished() { System.out.println("INFO: Handled connection established"); establishedLatch.countDown(); } @Override public void connectionDown() { System.out.println("INFO: Handled connection down"); downLatch.countDown(); } } }