/* * Copyright (c) 2006-2011 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package integrationTests.multicast; import java.io.*; import java.net.*; import java.util.*; import static java.util.Arrays.asList; import org.junit.*; import mockit.*; import static org.junit.Assert.*; public final class MessageTest { static final String testContents = "hello there"; @Test public void sendMessageToSingleClient() { final Client theClient = new Client("client1"); new MockUp<Socket>() { @Mock(invocations = 1) void $init(String host, int port) { assertEquals(theClient.getAddress(), host); assertTrue(port > 0); } @Mock(invocations = 1) public OutputStream getOutputStream() { return new ByteArrayOutputStream(); } @Mock(invocations = 1) public InputStream getInputStream() { return new ByteArrayInputStream("reply1\nreply2\n".getBytes()); } @Mock(minInvocations = 1) void close() {} }; StatusListener listener = new MockUp<StatusListener>() { int eventIndex; @Mock(invocations = 1) void messageSent(Client toClient) { assertSame(theClient, toClient); assertEquals(0, eventIndex++); } @Mock(invocations = 1) void messageDisplayedByClient(Client client) { assertSame(theClient, client); assertEquals(1, eventIndex++); } @Mock(invocations = 1) void messageReadByClient(Client client) { assertSame(theClient, client); assertEquals(2, eventIndex++); } }.getMockInstance(); exerciseCodeUnderTest(listener, theClient); } private void exerciseCodeUnderTest(StatusListener listener, Client... to) { final Message message = new Message(to, testContents, listener); new TaskExecution() { public void run() { message.dispatch(); } }; } // A general-purpose utility class that waits for background task completion. abstract static class TaskExecution implements Runnable { { List<Thread> tasksBefore = getActiveTasks(); try { //noinspection OverriddenMethodCallDuringObjectConstruction run(); } finally { waitForCompletionOfNewTasks(tasksBefore); } } private List<Thread> getActiveTasks() { Thread[] tasks = new Thread[2 * Thread.activeCount()]; Thread.enumerate(tasks); return new ArrayList<Thread>(asList(tasks)); } private void waitForCompletionOfNewTasks(List<Thread> tasksBefore) { List<Thread> tasksAfter = getActiveTasks(); tasksAfter.removeAll(tasksBefore); for (Thread task : tasksAfter) { try { task.join(); } catch (InterruptedException ignore) {} } } } @Test public void sendMessageToTwoClients() { new MockUp<Socket>() { @Mock(invocations = 2) void $init(String host, int port) { assertTrue(host.startsWith("client")); assertTrue(port > 0); } @Mock(invocations = 2) public OutputStream getOutputStream() { return new ByteArrayOutputStream(); } @Mock(invocations = 2) public InputStream getInputStream() { return new ByteArrayInputStream("reply1\nreply2\n".getBytes()); } @Mock(minInvocations = 2) void close() {} }; StatusListener listener = new MockUp<StatusListener>() { @Mock(invocations = 2) void messageSent(Client toClient) { assertNotNull(toClient); } @Mock(invocations = 2) void messageDisplayedByClient(Client client) { assertNotNull(client); } @Mock(invocations = 2) void messageReadByClient(Client client) { assertNotNull(client); } }.getMockInstance(); exerciseCodeUnderTest(listener, new Client("client1"), new Client("client2")); } @Test public void sendMessageToMultipleClients(final StatusListener listener) throws Exception { final Client[] testClients = {new Client("client1"), new Client("client2"), new Client("client3")}; new NonStrictExpectations(testClients.length) { final Socket con = new Socket(withPrefix("client"), anyInt); { con.getOutputStream(); result = new ByteArrayOutputStream(); con.getInputStream(); result = new ByteArrayInputStream("reply1\nreply2\n".getBytes()); con.close(); } }; exerciseCodeUnderTest(listener, testClients); for (final Client client : testClients) { new VerificationsInOrder() { { // TODO: try creating a "setMaxDelay(msBeforeTimeout)" method that allows a given // max time for the verification block to be fully satisfied. listener.messageSent(client); listener.messageDisplayedByClient(client); listener.messageReadByClient(client); } }; } } @Test public void sendMessageToMultipleClients_minimal(final StatusListener listener) throws Exception { final Client[] testClients = {new Client("client1"), new Client("client2")}; new NonStrictExpectations(testClients.length) { Socket con; { con.getOutputStream(); result = new ByteArrayOutputStream(); con.getInputStream(); result = new ByteArrayInputStream("reply1\n reply2\n".getBytes()); } }; exerciseCodeUnderTest(listener, testClients); for (final Client client : testClients) { new VerificationsInOrder() { { listener.messageSent(client); listener.messageDisplayedByClient(client); listener.messageReadByClient(client); } }; } } }