From 82608019c1e03552fc80df7f70e7f7c5270a0637 Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" Date: Wed, 9 Jan 2013 21:46:39 +0100 Subject: Cleanup output classes. --- .../org/jacoco/agent/rt/internal/AgentTest.java | 26 +- .../rt/internal/controller/ExecutorTestBase.java | 59 ---- .../internal/controller/LocalControllerTest.java | 74 ----- .../rt/internal/controller/MockServerSocket.java | 188 ------------ .../internal/controller/MockServerSocketTest.java | 150 --------- .../internal/controller/MockSocketConnection.java | 339 --------------------- .../controller/MockSocketConnectionTest.java | 188 ------------ .../controller/TcpClientControllerTest.java | 116 ------- .../rt/internal/controller/TcpConnectionTest.java | 274 ----------------- .../controller/TcpServerControllerTest.java | 145 --------- .../agent/rt/internal/output/ExecutorTestBase.java | 59 ++++ .../agent/rt/internal/output/FileOutputTest.java | 75 +++++ .../agent/rt/internal/output/MockServerSocket.java | 188 ++++++++++++ .../rt/internal/output/MockServerSocketTest.java | 150 +++++++++ .../rt/internal/output/MockSocketConnection.java | 339 +++++++++++++++++++++ .../internal/output/MockSocketConnectionTest.java | 188 ++++++++++++ .../rt/internal/output/TcpClientOutputTest.java | 118 +++++++ .../rt/internal/output/TcpConnectionTest.java | 275 +++++++++++++++++ .../rt/internal/output/TcpServerOutputTest.java | 146 +++++++++ 19 files changed, 1551 insertions(+), 1546 deletions(-) delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/ExecutorTestBase.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/LocalControllerTest.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocket.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocketTest.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnection.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnectionTest.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpClientControllerTest.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpConnectionTest.java delete mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpServerControllerTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/ExecutorTestBase.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocket.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocketTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnectionTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java create mode 100644 org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpServerOutputTest.java (limited to 'org.jacoco.agent.rt.test/src/org/jacoco/agent') diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java index 5482cca5..010cdd2c 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/AgentTest.java @@ -27,11 +27,11 @@ import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; import javax.management.ObjectName; -import org.jacoco.agent.rt.internal.controller.IAgentController; -import org.jacoco.agent.rt.internal.controller.LocalController; -import org.jacoco.agent.rt.internal.controller.NoneController; -import org.jacoco.agent.rt.internal.controller.TcpClientController; -import org.jacoco.agent.rt.internal.controller.TcpServerController; +import org.jacoco.agent.rt.internal.output.IAgentOutput; +import org.jacoco.agent.rt.internal.output.FileOutput; +import org.jacoco.agent.rt.internal.output.NoneOutput; +import org.jacoco.agent.rt.internal.output.TcpClientOutput; +import org.jacoco.agent.rt.internal.output.TcpServerOutput; import org.jacoco.core.JaCoCo; import org.jacoco.core.data.ExecutionDataReader; import org.jacoco.core.data.ExecutionDataStore; @@ -70,19 +70,19 @@ public class AgentTest implements IExceptionLogger { Agent agent = new Agent(options, this); options.setOutput(OutputMode.file); - assertEquals(LocalController.class, agent.createAgentController() + assertEquals(FileOutput.class, agent.createAgentOutput() .getClass()); options.setOutput(OutputMode.tcpserver); - assertEquals(TcpServerController.class, agent.createAgentController() + assertEquals(TcpServerOutput.class, agent.createAgentOutput() .getClass()); options.setOutput(OutputMode.tcpclient); - assertEquals(TcpClientController.class, agent.createAgentController() + assertEquals(TcpClientOutput.class, agent.createAgentOutput() .getClass()); options.setOutput(OutputMode.none); - assertEquals(NoneController.class, agent.createAgentController() + assertEquals(NoneOutput.class, agent.createAgentOutput() .getClass()); } @@ -106,8 +106,8 @@ public class AgentTest implements IExceptionLogger { final Exception expected = new Exception(); Agent agent = new Agent(options, this) { @Override - IAgentController createAgentController() { - return new IAgentController() { + IAgentOutput createAgentOutput() { + return new IAgentOutput() { public void startup(AgentOptions options, RuntimeData data) { } @@ -231,8 +231,8 @@ public class AgentTest implements IExceptionLogger { final boolean[] called = new boolean[1]; Agent agent = new Agent(options, this) { @Override - IAgentController createAgentController() { - return new IAgentController() { + IAgentOutput createAgentOutput() { + return new IAgentOutput() { public void startup(AgentOptions options, RuntimeData data) { } diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/ExecutorTestBase.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/ExecutorTestBase.java deleted file mode 100644 index a2ec01d4..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/ExecutorTestBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.fail; - -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.junit.After; -import org.junit.Before; - -/** - * Unit tests base for tests that need an {@link Executor} for multithreaded - * test scenarios. - */ -public abstract class ExecutorTestBase { - - protected ExecutorService executor; - - @Before - public void setup() throws Exception { - executor = Executors.newSingleThreadExecutor(); - } - - @After - public void teardown() throws Exception { - executor.shutdown(); - } - - /** - * Asserts that the given future blocks. - * - * @param future - * future to test - * @throws Exception - */ - protected void assertBlocks(final Future future) throws Exception { - try { - future.get(10, TimeUnit.MILLISECONDS); - fail("Operation should block"); - } catch (TimeoutException e) { - } - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/LocalControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/LocalControllerTest.java deleted file mode 100644 index 3038eb81..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/LocalControllerTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Brock Janiczak - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.jacoco.core.runtime.AgentOptions; -import org.jacoco.core.runtime.RuntimeData; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -/** - * Unit tests for {@link LocalController}. - */ -public class LocalControllerTest { - - @Rule - public TemporaryFolder folder = new TemporaryFolder(); - - @Test - public void testCreateDestFileOnStartup() throws Exception { - File destFile = folder.newFile("jacoco.exec"); - AgentOptions options = new AgentOptions(); - options.setDestfile(destFile.getAbsolutePath()); - - LocalController controller = new LocalController(); - controller.startup(options, new RuntimeData()); - - assertTrue("Execution data file should be created", destFile.exists()); - assertEquals("Execution data file should be empty", 0, - destFile.length()); - } - - @Test - public void testWriteData() throws Exception { - File destFile = folder.newFile("jacoco.exec"); - AgentOptions options = new AgentOptions(); - options.setDestfile(destFile.getAbsolutePath()); - - LocalController controller = new LocalController(); - controller.startup(options, new RuntimeData()); - controller.writeExecutionData(false); - controller.shutdown(); - - assertTrue("Execution data file should be created", destFile.exists()); - assertTrue("Execution data file should have contents", - destFile.length() > 0); - } - - @Test(expected = IOException.class) - public void testInvalidDestFile() throws Exception { - AgentOptions options = new AgentOptions(); - options.setDestfile(folder.newFolder("folder").getAbsolutePath()); - LocalController controller = new LocalController(); - - // Startup should fail as the file can not be created: - controller.startup(options, new RuntimeData()); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocket.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocket.java deleted file mode 100644 index a9a55ec1..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocket.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.nio.channels.ServerSocketChannel; - -/** - * Emulation of a {@link ServerSocket} for testing purposes without any physical - * tcp/ip connections. - */ -public class MockServerSocket extends ServerSocket { - - private final Object lock = new Object(); - - private boolean closed; - - private Socket connection; - - private boolean inAccept; - - public MockServerSocket() throws IOException { - super(); - closed = false; - inAccept = false; - } - - /** - * Establishes a new mock connection. This method blocks until the other end - * of the connection has been accepted. - * - * @return remote end of the mock connection - */ - public Socket connect() throws Exception { - synchronized (lock) { - final MockSocketConnection c = new MockSocketConnection(); - connection = c.getSocketA(); - lock.notifyAll(); - while (connection != null) { - lock.wait(); - } - return c.getSocketB(); - } - } - - /** - * Blocks until another thread calls the {@link #accept()} method. - */ - public void waitForAccept() throws Exception { - synchronized (lock) { - while (!inAccept) { - lock.wait(); - } - } - - } - - @Override - public void close() throws IOException { - synchronized (lock) { - closed = true; - lock.notifyAll(); - } - } - - @Override - public boolean isClosed() { - return closed; - } - - @Override - public Socket accept() throws IOException { - synchronized (lock) { - inAccept = true; - lock.notifyAll(); - try { - while (connection == null) { - if (closed) { - throw new SocketException("socket closed"); - } - lock.wait(); - } - return connection; - } catch (InterruptedException e) { - throw new InterruptedIOException(); - } finally { - connection = null; - inAccept = false; - lock.notifyAll(); - } - } - } - - // unsupported server socket methods: - - @Override - public void bind(SocketAddress endpoint, int backlog) throws IOException { - throw new AssertionError(); - } - - @Override - public void bind(SocketAddress endpoint) throws IOException { - throw new AssertionError(); - } - - @Override - public ServerSocketChannel getChannel() { - throw new AssertionError(); - } - - @Override - public InetAddress getInetAddress() { - throw new AssertionError(); - } - - @Override - public int getLocalPort() { - throw new AssertionError(); - } - - @Override - public SocketAddress getLocalSocketAddress() { - throw new AssertionError(); - } - - @Override - public synchronized int getReceiveBufferSize() throws SocketException { - throw new AssertionError(); - } - - @Override - public boolean getReuseAddress() throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized int getSoTimeout() throws IOException { - throw new AssertionError(); - } - - @Override - public boolean isBound() { - throw new AssertionError(); - } - - @Override - public void setPerformancePreferences(int connectionTime, int latency, - int bandwidth) { - throw new AssertionError(); - } - - @Override - public synchronized void setReceiveBufferSize(int size) - throws SocketException { - throw new AssertionError(); - } - - @Override - public void setReuseAddress(boolean on) throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized void setSoTimeout(int timeout) throws SocketException { - throw new AssertionError(); - } - - @Override - public String toString() { - throw new AssertionError(); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocketTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocketTest.java deleted file mode 100644 index b98258dd..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockServerSocketTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link MockServerSocket}. - */ -public class MockServerSocketTest extends ExecutorTestBase { - - private ServerSocket serverSocket; - - /** - * To verify that the tests reflect the behavior of real TCP sockets this - * flag can be set to true. - */ - private static final boolean REAL_SOCKETS = Boolean - .getBoolean("MockServerSocketTest.realSockets"); - - @Before - @Override - public void setup() throws Exception { - super.setup(); - if (REAL_SOCKETS) { - System.err.println("Using Real Sockets!"); - final InetAddress addr = InetAddress.getByName("localhost"); - serverSocket = new ServerSocket(16300, 1, addr); - } else { - serverSocket = new MockServerSocket(); - } - } - - @After - @Override - public void teardown() throws Exception { - serverSocket.close(); - super.teardown(); - } - - private Socket connect() throws Exception { - if (REAL_SOCKETS) { - final InetAddress addr = InetAddress.getByName("localhost"); - return new Socket(addr, 16300); - } else { - return ((MockServerSocket) serverSocket).connect(); - } - - } - - @Test - public void testClose() throws Exception { - assertFalse(serverSocket.isClosed()); - serverSocket.close(); - assertTrue(serverSocket.isClosed()); - } - - @Test(expected = SocketException.class) - public void testCloseWhileAccept() throws Throwable { - final Future f = executor.submit(new Callable() { - public Socket call() throws Exception { - return serverSocket.accept(); - } - }); - assertBlocks(f); - serverSocket.close(); - try { - f.get(); - } catch (ExecutionException e) { - throw e.getCause(); - } - } - - @Test - public void testAccept() throws Exception { - final Future f = executor.submit(new Callable() { - public Socket call() throws Exception { - return serverSocket.accept(); - } - }); - assertBlocks(f); - connect().getOutputStream().write(123); - final Socket socket = f.get(); - assertNotNull(socket); - assertEquals(123, socket.getInputStream().read()); - } - - @Test(expected = SocketException.class) - public void testAcceptOnClosedServerSocket() throws Exception { - serverSocket.close(); - serverSocket.accept(); - } - - @Test - public void testConnect() throws Exception { - if (!REAL_SOCKETS) { - final Future f = executor.submit(new Callable() { - public Socket call() throws Exception { - return ((MockServerSocket) serverSocket).connect(); - } - }); - assertBlocks(f); - serverSocket.accept().getOutputStream().write(42); - final Socket socket = f.get(); - assertNotNull(socket); - assertEquals(42, socket.getInputStream().read()); - } - } - - @Test - public void testWaitForAccept() throws Exception { - if (!REAL_SOCKETS) { - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - ((MockServerSocket) serverSocket).waitForAccept(); - connect(); - return null; - } - }); - assertBlocks(f); - serverSocket.accept(); - f.get(); - } - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnection.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnection.java deleted file mode 100644 index 2118fe8d..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnection.java +++ /dev/null @@ -1,339 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.net.SocketImpl; -import java.nio.channels.SocketChannel; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * Simulates the two connected {@link Socket} objects. No physical connection is - * established for this. The the behavior including the (inconsistent) exception - * messages have been derived from Sun JDK 1.5.0_18-b02. - */ -public class MockSocketConnection { - - private final MockSocket socketA; - - private final MockSocket socketB; - - public MockSocketConnection() throws SocketException { - socketA = new MockSocket(); - socketB = new MockSocket(); - socketA.connect(socketB); - } - - public Socket getSocketA() { - return socketA; - } - - public Socket getSocketB() { - return socketB; - } - - private class MockSocket extends Socket { - - private MockSocket other; - - private boolean closed; - - private final Queue buffer = new ConcurrentLinkedQueue(); - - private final OutputStream out = new OutputStream() { - - @Override - public void write(int b) throws IOException { - if (closed) { - throw new SocketException("Socket closed"); - } - synchronized (other.buffer) { - other.buffer.add(Byte.valueOf((byte) b)); - other.buffer.notifyAll(); - } - } - }; - - private final InputStream in = new InputStream() { - - @Override - public int read() throws IOException { - synchronized (buffer) { - try { - while (true) { - if (closed) { - throw new SocketException("socket closed"); - } - if (other.closed) { - return -1; - } - final Byte b = buffer.poll(); - if (b != null) { - return 0xff & b.intValue(); - } - buffer.wait(); - } - } catch (InterruptedException e) { - throw new InterruptedIOException(); - } - } - } - - @Override - public int available() throws IOException { - return buffer.size(); - } - - }; - - public MockSocket() throws SocketException { - super((SocketImpl) null); - closed = false; - } - - void connect(MockSocket other) { - this.other = other; - other.other = this; - } - - // socket methods with mocking behavior: - - @Override - public OutputStream getOutputStream() throws IOException { - if (closed) { - throw new SocketException("Socket is closed"); - } - return out; - } - - @Override - public InputStream getInputStream() throws IOException { - if (closed) { - throw new SocketException("Socket is closed"); - } - return in; - } - - @Override - public void close() throws IOException { - closed = true; - synchronized (buffer) { - buffer.notifyAll(); - } - synchronized (other.buffer) { - other.buffer.notifyAll(); - } - } - - @Override - public boolean isClosed() { - return closed; - } - - // unsupported socket methods: - - @Override - public void bind(SocketAddress bindpoint) throws IOException { - throw new AssertionError(); - } - - @Override - public void connect(SocketAddress endpoint, int timeout) - throws IOException { - throw new AssertionError(); - } - - @Override - public void connect(SocketAddress endpoint) throws IOException { - throw new AssertionError(); - } - - @Override - public SocketChannel getChannel() { - throw new AssertionError(); - } - - @Override - public InetAddress getInetAddress() { - throw new AssertionError(); - } - - @Override - public boolean getKeepAlive() throws SocketException { - throw new AssertionError(); - } - - @Override - public InetAddress getLocalAddress() { - throw new AssertionError(); - } - - @Override - public int getLocalPort() { - throw new AssertionError(); - } - - @Override - public SocketAddress getLocalSocketAddress() { - throw new AssertionError(); - } - - @Override - public boolean getOOBInline() throws SocketException { - throw new AssertionError(); - } - - @Override - public int getPort() { - throw new AssertionError(); - } - - @Override - public synchronized int getReceiveBufferSize() throws SocketException { - throw new AssertionError(); - } - - @Override - public SocketAddress getRemoteSocketAddress() { - throw new AssertionError(); - } - - @Override - public boolean getReuseAddress() throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized int getSendBufferSize() throws SocketException { - throw new AssertionError(); - } - - @Override - public int getSoLinger() throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized int getSoTimeout() throws SocketException { - throw new AssertionError(); - } - - @Override - public boolean getTcpNoDelay() throws SocketException { - throw new AssertionError(); - } - - @Override - public int getTrafficClass() throws SocketException { - throw new AssertionError(); - } - - @Override - public boolean isBound() { - throw new AssertionError(); - } - - @Override - public boolean isConnected() { - throw new AssertionError(); - } - - @Override - public boolean isInputShutdown() { - throw new AssertionError(); - } - - @Override - public boolean isOutputShutdown() { - throw new AssertionError(); - } - - @Override - public void sendUrgentData(int data) throws IOException { - throw new AssertionError(); - } - - @Override - public void setKeepAlive(boolean on) throws SocketException { - throw new AssertionError(); - } - - @Override - public void setOOBInline(boolean on) throws SocketException { - throw new AssertionError(); - } - - @Override - public void setPerformancePreferences(int connectionTime, int latency, - int bandwidth) { - throw new AssertionError(); - } - - @Override - public synchronized void setReceiveBufferSize(int size) - throws SocketException { - throw new AssertionError(); - } - - @Override - public void setReuseAddress(boolean on) throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized void setSendBufferSize(int size) - throws SocketException { - throw new AssertionError(); - } - - @Override - public void setSoLinger(boolean on, int linger) throws SocketException { - throw new AssertionError(); - } - - @Override - public synchronized void setSoTimeout(int timeout) - throws SocketException { - throw new AssertionError(); - } - - @Override - public void setTcpNoDelay(boolean on) throws SocketException { - throw new AssertionError(); - } - - @Override - public void setTrafficClass(int tc) throws SocketException { - throw new AssertionError(); - } - - @Override - public void shutdownInput() throws IOException { - throw new AssertionError(); - } - - @Override - public void shutdownOutput() throws IOException { - throw new AssertionError(); - } - - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnectionTest.java deleted file mode 100644 index fd373bf2..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/MockSocketConnectionTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link MockSocketConnection}. - */ -public class MockSocketConnectionTest extends ExecutorTestBase { - - /** - * To verify that the tests reflect the behavior of real TCP sockets this - * flag can be set to true. - */ - private static final boolean REAL_SOCKETS = Boolean - .getBoolean("MockSocketConnectionTest.realSockets"); - - private Socket a; - - private Socket b; - - @Before - @Override - public void setup() throws Exception { - super.setup(); - if (REAL_SOCKETS) { - createRealSockets(); - } else { - createMockSockets(); - } - } - - private void createMockSockets() throws Exception { - final MockSocketConnection con = new MockSocketConnection(); - a = con.getSocketA(); - b = con.getSocketB(); - } - - private void createRealSockets() throws Exception { - System.err.println("Using Real Sockets!"); - final InetAddress addr = InetAddress.getByName("localhost"); - ServerSocket ssocket = new ServerSocket(16300, 1, addr); - a = new Socket(addr, 16300); - b = ssocket.accept(); - ssocket.close(); - } - - @Test - public void testIsClosed() throws Exception { - assertFalse(a.isClosed()); - a.close(); - assertTrue(a.isClosed()); - } - - @Test(expected = SocketException.class) - public void testGetInputStreamOnClosedSocket() throws Exception { - a.close(); - a.getInputStream(); - } - - @Test(expected = SocketException.class) - public void testReadOnClosedSocket() throws Exception { - final InputStream in = a.getInputStream(); - a.close(); - in.read(); - } - - @Test(expected = SocketException.class) - public void testReadOnClosedSocketAsync() throws Throwable { - final InputStream in = a.getInputStream(); - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - in.read(); - return null; - } - }); - - assertBlocks(f); - - a.close(); - try { - f.get(); - } catch (ExecutionException e) { - throw e.getCause(); - } - } - - @Test(expected = SocketException.class) - public void testGetOutputStreamOnClosedSocket() throws Exception { - a.close(); - a.getOutputStream(); - } - - @Test(expected = SocketException.class) - public void testWriteOnClosedSocket() throws Exception { - final OutputStream out = a.getOutputStream(); - a.close(); - out.write(123); - } - - @Test - public void testContents() throws Exception { - final InputStream in = a.getInputStream(); - final OutputStream out = b.getOutputStream(); - - assertEquals(0, in.available()); - - out.write(0); - out.write(1); - out.write(2); - out.write(255); - - if (!REAL_SOCKETS) { - // Real sockets will have a delay - assertEquals(4, in.available()); - } - - assertEquals(0, in.read()); - assertEquals(1, in.read()); - assertEquals(2, in.read()); - assertEquals(255, in.read()); - } - - @Test - public void testWaitForContents() throws Exception { - final InputStream in = a.getInputStream(); - final OutputStream out = b.getOutputStream(); - - final Future f = executor.submit(new Callable() { - public Byte call() throws Exception { - return Byte.valueOf((byte) in.read()); - } - }); - - assertBlocks(f); - out.write(123); - assertEquals(123, f.get().byteValue()); - } - - @Test - public void testCloseOtherSocket() throws Exception { - b.close(); - final InputStream in = a.getInputStream(); - assertEquals(-1, in.read()); - } - - @Test - public void testCloseOtherSocketAsync() throws Exception { - final InputStream in = a.getInputStream(); - - final Future f = executor.submit(new Callable() { - public Byte call() throws Exception { - return Byte.valueOf((byte) in.read()); - } - }); - - assertBlocks(f); - b.close(); - - assertEquals(-1, f.get().byteValue()); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpClientControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpClientControllerTest.java deleted file mode 100644 index 4548d404..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpClientControllerTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Brock Janiczak - initial API and implementation - * Marc R. Hoffmann - migration to mock socket - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.io.IOException; -import java.net.Socket; -import java.util.List; - -import org.jacoco.agent.rt.internal.ExceptionRecorder; -import org.jacoco.core.data.ExecutionDataStore; -import org.jacoco.core.data.SessionInfo; -import org.jacoco.core.data.SessionInfoStore; -import org.jacoco.core.runtime.AgentOptions; -import org.jacoco.core.runtime.RemoteControlReader; -import org.jacoco.core.runtime.RemoteControlWriter; -import org.jacoco.core.runtime.RuntimeData; -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link TcpClientController}. - */ -public class TcpClientControllerTest { - - private ExceptionRecorder logger; - - private IAgentController controller; - - private Socket remoteSocket; - - private RemoteControlWriter remoteWriter; - - private RemoteControlReader remoteReader; - - private RuntimeData data; - - @Before - public void setup() throws Exception { - logger = new ExceptionRecorder(); - final MockSocketConnection con = new MockSocketConnection(); - remoteSocket = con.getSocketB(); - remoteWriter = new RemoteControlWriter(remoteSocket.getOutputStream()); - controller = new TcpClientController(logger) { - @Override - protected Socket createSocket(AgentOptions options) - throws IOException { - return con.getSocketA(); - } - }; - data = new RuntimeData(); - controller.startup(new AgentOptions(), data); - remoteReader = new RemoteControlReader(remoteSocket.getInputStream()); - } - - @Test - public void testShutdown() throws Exception { - controller.shutdown(); - assertFalse(remoteReader.read()); - logger.assertNoException(); - } - - @Test - public void testRemoteClose() throws Exception { - remoteSocket.close(); - controller.shutdown(); - logger.assertNoException(); - } - - @Test - public void testInvalidCommand() throws Exception { - remoteWriter.visitSessionInfo(new SessionInfo("info", 1, 2)); - while (remoteReader.read()) { - } - controller.shutdown(); - logger.assertException(IOException.class, "No session info visitor."); - } - - @Test - public void testWriteExecutionData() throws Exception { - data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); - data.setSessionId("stubid"); - - controller.writeExecutionData(false); - - final ExecutionDataStore execStore = new ExecutionDataStore(); - remoteReader.setExecutionDataVisitor(execStore); - final SessionInfoStore infoStore = new SessionInfoStore(); - remoteReader.setSessionInfoVisitor(infoStore); - - remoteReader.read(); - - assertEquals("Foo", execStore.get(0x12345678).getName()); - - final List infos = infoStore.getInfos(); - assertEquals(1, infos.size()); - assertEquals("stubid", infos.get(0).getId()); - - logger.assertNoException(); - controller.shutdown(); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpConnectionTest.java deleted file mode 100644 index ead889a5..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpConnectionTest.java +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Marc R. Hoffmann - initial API and implementation - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; - -import org.jacoco.core.data.ExecutionDataStore; -import org.jacoco.core.data.ExecutionDataWriter; -import org.jacoco.core.data.SessionInfo; -import org.jacoco.core.data.SessionInfoStore; -import org.jacoco.core.runtime.RemoteControlReader; -import org.jacoco.core.runtime.RemoteControlWriter; -import org.jacoco.core.runtime.RuntimeData; -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link TcpConnection}. - */ -public class TcpConnectionTest extends ExecutorTestBase { - - private MockSocketConnection mockConnection; - - private RuntimeData data; - - @Before - @Override - public void setup() throws Exception { - super.setup(); - mockConnection = new MockSocketConnection(); - data = new RuntimeData(); - } - - @Test(expected = IOException.class) - public void testInvalidHeader() throws Exception { - final OutputStream remoteOut = mockConnection.getSocketB() - .getOutputStream(); - remoteOut.write(0x01); - remoteOut.write(0xC0); - remoteOut.write(0xCA); - final TcpConnection connection = new TcpConnection( - mockConnection.getSocketA(), data); - connection.init(); - connection.run(); - } - - @Test(expected = IOException.class) - public void testInvalidContent() throws Exception { - final OutputStream remoteOut = mockConnection.getSocketB() - .getOutputStream(); - new ExecutionDataWriter(remoteOut); - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - remoteOut.write(123); - con.run(); - } - - /** - * Remote endpoint is closed after a valid header has been send. - */ - @Test - public void testRemoteClose() throws Exception { - final OutputStream remoteOut = mockConnection.getSocketB() - .getOutputStream(); - new ExecutionDataWriter(remoteOut); - - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.run(); - return null; - } - }); - - assertBlocks(f); - - mockConnection.getSocketB().close(); - f.get(); - } - - /** - * Remote endpoint is closed before even a valid header was send. - */ - public void testRemoteCloseWithoutHeader() throws Throwable { - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.init(); - return null; - } - }); - - assertBlocks(f); - - mockConnection.getSocketB().close(); - f.get(); - } - - /** - * Local socket is closed while waiting for commands. - * - * @throws Exception - */ - @Test - public void testLocalClose() throws Exception { - final OutputStream remoteOut = mockConnection.getSocketB() - .getOutputStream(); - new ExecutionDataWriter(remoteOut); - - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.run(); - return null; - } - }); - - assertBlocks(f); - - con.close(); - f.get(); - } - - @Test - public void testRemoteDump() throws Exception { - data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); - data.setSessionId("stubid"); - - final RemoteControlWriter remoteWriter = new RemoteControlWriter( - mockConnection.getSocketB().getOutputStream()); - - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.run(); - return null; - } - }); - - assertBlocks(f); - - remoteWriter.visitDumpCommand(true, false); - readAndAssertData(); - - con.close(); - f.get(); - } - - @Test - public void testLocalDump() throws Exception { - data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); - data.setSessionId("stubid"); - - new RemoteControlWriter(mockConnection.getSocketB().getOutputStream()); - - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.run(); - return null; - } - }); - - assertBlocks(f); - - con.writeExecutionData(false); - readAndAssertData(); - - con.close(); - f.get(); - } - - @Test - public void testLocalDumpWithoutInit() throws Exception { - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - // Must not write any data as we're not initialized: - con.writeExecutionData(false); - - assertEquals(0, mockConnection.getSocketB().getInputStream() - .available()); - } - - private void readAndAssertData() throws IOException { - final RemoteControlReader remoteReader = new RemoteControlReader( - mockConnection.getSocketB().getInputStream()); - - final ExecutionDataStore execStore = new ExecutionDataStore(); - remoteReader.setExecutionDataVisitor(execStore); - final SessionInfoStore infoStore = new SessionInfoStore(); - remoteReader.setSessionInfoVisitor(infoStore); - - assertTrue(remoteReader.read()); - - final List infos = infoStore.getInfos(); - assertEquals(1, infos.size()); - assertEquals("stubid", infos.get(0).getId()); - - assertEquals("Foo", execStore.get(0x12345678).getName()); - } - - @Test - public void testRemoteReset() throws Exception { - data.getExecutionData(Long.valueOf(123), "Foo", 1).getProbes()[0] = true; - - final RemoteControlWriter remoteWriter = new RemoteControlWriter( - mockConnection.getSocketB().getOutputStream()); - - final TcpConnection con = new TcpConnection( - mockConnection.getSocketA(), data); - con.init(); - - final Future f = executor.submit(new Callable() { - public Void call() throws Exception { - con.run(); - return null; - } - }); - - assertBlocks(f); - - remoteWriter.visitDumpCommand(false, true); - - final RemoteControlReader remoteReader = new RemoteControlReader( - mockConnection.getSocketB().getInputStream()); - - final ExecutionDataStore execStore = new ExecutionDataStore(); - remoteReader.setExecutionDataVisitor(execStore); - final SessionInfoStore infoStore = new SessionInfoStore(); - remoteReader.setSessionInfoVisitor(infoStore); - - assertTrue(remoteReader.read()); - assertTrue(infoStore.getInfos().isEmpty()); - assertTrue(execStore.getContents().isEmpty()); - assertFalse(data.getExecutionData(Long.valueOf(123), "Foo", 1) - .getProbes()[0]); - - con.close(); - f.get(); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpServerControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpServerControllerTest.java deleted file mode 100644 index b70d70be..00000000 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/controller/TcpServerControllerTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Brock Janiczak - initial API and implementation - * Marc R. Hoffmann - migration to mock socket - * - *******************************************************************************/ -package org.jacoco.agent.rt.internal.controller; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.List; - -import org.jacoco.agent.rt.internal.ExceptionRecorder; -import org.jacoco.core.data.ExecutionDataStore; -import org.jacoco.core.data.ExecutionDataWriter; -import org.jacoco.core.data.SessionInfo; -import org.jacoco.core.data.SessionInfoStore; -import org.jacoco.core.runtime.AgentOptions; -import org.jacoco.core.runtime.RemoteControlReader; -import org.jacoco.core.runtime.RemoteControlWriter; -import org.jacoco.core.runtime.RuntimeData; -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link TcpServerController}. - */ -public class TcpServerControllerTest { - - private ExceptionRecorder logger; - - private AgentOptions options; - - private MockServerSocket serverSocket; - - private TcpServerController controller; - - private RuntimeData data; - - @Before - public void setup() throws Exception { - options = new AgentOptions(); - logger = new ExceptionRecorder(); - serverSocket = new MockServerSocket(); - controller = new TcpServerController(logger) { - @Override - protected ServerSocket createServerSocket(AgentOptions options) - throws IOException { - return serverSocket; - } - }; - data = new RuntimeData(); - controller.startup(options, data); - } - - @Test - public void testShutdownWithoutConnection() throws Exception { - serverSocket.waitForAccept(); - controller.shutdown(); - logger.assertNoException(); - } - - @Test - public void testShutdownWithConnection() throws Exception { - serverSocket.waitForAccept(); - new ExecutionDataWriter(serverSocket.connect().getOutputStream()); - controller.shutdown(); - logger.assertNoException(); - } - - @Test - public void testWriteExecutionData() throws Exception { - data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); - data.setSessionId("stubid"); - - final Socket socket = serverSocket.connect(); - final RemoteControlWriter remoteWriter = new RemoteControlWriter( - socket.getOutputStream()); - final RemoteControlReader remoteReader = new RemoteControlReader( - socket.getInputStream()); - - // First process a NOP command to ensure the connection is initialized: - remoteWriter.visitDumpCommand(false, false); - remoteReader.read(); - - // Now the actual test starts: - controller.writeExecutionData(false); - - final ExecutionDataStore execStore = new ExecutionDataStore(); - remoteReader.setExecutionDataVisitor(execStore); - final SessionInfoStore infoStore = new SessionInfoStore(); - remoteReader.setSessionInfoVisitor(infoStore); - remoteReader.read(); - - assertEquals("Foo", execStore.get(0x12345678).getName()); - - final List infos = infoStore.getInfos(); - assertEquals(1, infos.size()); - assertEquals("stubid", infos.get(0).getId()); - - logger.assertNoException(); - controller.shutdown(); - } - - @Test - public void testInvalidHeader() throws Exception { - final Socket socket = serverSocket.connect(); - final OutputStream out = socket.getOutputStream(); - out.write(0xca); - out.write(0xfe); - out.write(0xba); - out.write(0xbe); - serverSocket.waitForAccept(); - logger.assertException(IOException.class, - "Invalid execution data file."); - controller.shutdown(); - } - - @Test - public void testGetInetAddressLoopback() throws UnknownHostException { - final InetAddress addr = controller.getInetAddress(null); - assertTrue(addr.isLoopbackAddress()); - } - - @Test - public void testGetInetAddressAny() throws UnknownHostException { - final InetAddress addr = controller.getInetAddress("*"); - assertNull(addr); - } - -} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/ExecutorTestBase.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/ExecutorTestBase.java new file mode 100644 index 00000000..96b8972f --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/ExecutorTestBase.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.fail; + +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.junit.After; +import org.junit.Before; + +/** + * Unit tests base for tests that need an {@link Executor} for multithreaded + * test scenarios. + */ +public abstract class ExecutorTestBase { + + protected ExecutorService executor; + + @Before + public void setup() throws Exception { + executor = Executors.newSingleThreadExecutor(); + } + + @After + public void teardown() throws Exception { + executor.shutdown(); + } + + /** + * Asserts that the given future blocks. + * + * @param future + * future to test + * @throws Exception + */ + protected void assertBlocks(final Future future) throws Exception { + try { + future.get(10, TimeUnit.MILLISECONDS); + fail("Operation should block"); + } catch (TimeoutException e) { + } + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java new file mode 100644 index 00000000..120dbe77 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.jacoco.agent.rt.internal.output.FileOutput; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RuntimeData; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * Unit tests for {@link FileOutput}. + */ +public class FileOutputTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testCreateDestFileOnStartup() throws Exception { + File destFile = folder.newFile("jacoco.exec"); + AgentOptions options = new AgentOptions(); + options.setDestfile(destFile.getAbsolutePath()); + + FileOutput controller = new FileOutput(); + controller.startup(options, new RuntimeData()); + + assertTrue("Execution data file should be created", destFile.exists()); + assertEquals("Execution data file should be empty", 0, + destFile.length()); + } + + @Test + public void testWriteData() throws Exception { + File destFile = folder.newFile("jacoco.exec"); + AgentOptions options = new AgentOptions(); + options.setDestfile(destFile.getAbsolutePath()); + + FileOutput controller = new FileOutput(); + controller.startup(options, new RuntimeData()); + controller.writeExecutionData(false); + controller.shutdown(); + + assertTrue("Execution data file should be created", destFile.exists()); + assertTrue("Execution data file should have contents", + destFile.length() > 0); + } + + @Test(expected = IOException.class) + public void testInvalidDestFile() throws Exception { + AgentOptions options = new AgentOptions(); + options.setDestfile(folder.newFolder("folder").getAbsolutePath()); + FileOutput controller = new FileOutput(); + + // Startup should fail as the file can not be created: + controller.startup(options, new RuntimeData()); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocket.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocket.java new file mode 100644 index 00000000..02e6a41f --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocket.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.ServerSocketChannel; + +/** + * Emulation of a {@link ServerSocket} for testing purposes without any physical + * tcp/ip connections. + */ +public class MockServerSocket extends ServerSocket { + + private final Object lock = new Object(); + + private boolean closed; + + private Socket connection; + + private boolean inAccept; + + public MockServerSocket() throws IOException { + super(); + closed = false; + inAccept = false; + } + + /** + * Establishes a new mock connection. This method blocks until the other end + * of the connection has been accepted. + * + * @return remote end of the mock connection + */ + public Socket connect() throws Exception { + synchronized (lock) { + final MockSocketConnection c = new MockSocketConnection(); + connection = c.getSocketA(); + lock.notifyAll(); + while (connection != null) { + lock.wait(); + } + return c.getSocketB(); + } + } + + /** + * Blocks until another thread calls the {@link #accept()} method. + */ + public void waitForAccept() throws Exception { + synchronized (lock) { + while (!inAccept) { + lock.wait(); + } + } + + } + + @Override + public void close() throws IOException { + synchronized (lock) { + closed = true; + lock.notifyAll(); + } + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public Socket accept() throws IOException { + synchronized (lock) { + inAccept = true; + lock.notifyAll(); + try { + while (connection == null) { + if (closed) { + throw new SocketException("socket closed"); + } + lock.wait(); + } + return connection; + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } finally { + connection = null; + inAccept = false; + lock.notifyAll(); + } + } + } + + // unsupported server socket methods: + + @Override + public void bind(SocketAddress endpoint, int backlog) throws IOException { + throw new AssertionError(); + } + + @Override + public void bind(SocketAddress endpoint) throws IOException { + throw new AssertionError(); + } + + @Override + public ServerSocketChannel getChannel() { + throw new AssertionError(); + } + + @Override + public InetAddress getInetAddress() { + throw new AssertionError(); + } + + @Override + public int getLocalPort() { + throw new AssertionError(); + } + + @Override + public SocketAddress getLocalSocketAddress() { + throw new AssertionError(); + } + + @Override + public synchronized int getReceiveBufferSize() throws SocketException { + throw new AssertionError(); + } + + @Override + public boolean getReuseAddress() throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized int getSoTimeout() throws IOException { + throw new AssertionError(); + } + + @Override + public boolean isBound() { + throw new AssertionError(); + } + + @Override + public void setPerformancePreferences(int connectionTime, int latency, + int bandwidth) { + throw new AssertionError(); + } + + @Override + public synchronized void setReceiveBufferSize(int size) + throws SocketException { + throw new AssertionError(); + } + + @Override + public void setReuseAddress(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized void setSoTimeout(int timeout) throws SocketException { + throw new AssertionError(); + } + + @Override + public String toString() { + throw new AssertionError(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocketTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocketTest.java new file mode 100644 index 00000000..ba8d9283 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockServerSocketTest.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link MockServerSocket}. + */ +public class MockServerSocketTest extends ExecutorTestBase { + + private ServerSocket serverSocket; + + /** + * To verify that the tests reflect the behavior of real TCP sockets this + * flag can be set to true. + */ + private static final boolean REAL_SOCKETS = Boolean + .getBoolean("MockServerSocketTest.realSockets"); + + @Before + @Override + public void setup() throws Exception { + super.setup(); + if (REAL_SOCKETS) { + System.err.println("Using Real Sockets!"); + final InetAddress addr = InetAddress.getByName("localhost"); + serverSocket = new ServerSocket(16300, 1, addr); + } else { + serverSocket = new MockServerSocket(); + } + } + + @After + @Override + public void teardown() throws Exception { + serverSocket.close(); + super.teardown(); + } + + private Socket connect() throws Exception { + if (REAL_SOCKETS) { + final InetAddress addr = InetAddress.getByName("localhost"); + return new Socket(addr, 16300); + } else { + return ((MockServerSocket) serverSocket).connect(); + } + + } + + @Test + public void testClose() throws Exception { + assertFalse(serverSocket.isClosed()); + serverSocket.close(); + assertTrue(serverSocket.isClosed()); + } + + @Test(expected = SocketException.class) + public void testCloseWhileAccept() throws Throwable { + final Future f = executor.submit(new Callable() { + public Socket call() throws Exception { + return serverSocket.accept(); + } + }); + assertBlocks(f); + serverSocket.close(); + try { + f.get(); + } catch (ExecutionException e) { + throw e.getCause(); + } + } + + @Test + public void testAccept() throws Exception { + final Future f = executor.submit(new Callable() { + public Socket call() throws Exception { + return serverSocket.accept(); + } + }); + assertBlocks(f); + connect().getOutputStream().write(123); + final Socket socket = f.get(); + assertNotNull(socket); + assertEquals(123, socket.getInputStream().read()); + } + + @Test(expected = SocketException.class) + public void testAcceptOnClosedServerSocket() throws Exception { + serverSocket.close(); + serverSocket.accept(); + } + + @Test + public void testConnect() throws Exception { + if (!REAL_SOCKETS) { + final Future f = executor.submit(new Callable() { + public Socket call() throws Exception { + return ((MockServerSocket) serverSocket).connect(); + } + }); + assertBlocks(f); + serverSocket.accept().getOutputStream().write(42); + final Socket socket = f.get(); + assertNotNull(socket); + assertEquals(42, socket.getInputStream().read()); + } + } + + @Test + public void testWaitForAccept() throws Exception { + if (!REAL_SOCKETS) { + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + ((MockServerSocket) serverSocket).waitForAccept(); + connect(); + return null; + } + }); + assertBlocks(f); + serverSocket.accept(); + f.get(); + } + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java new file mode 100644 index 00000000..df3b1532 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnection.java @@ -0,0 +1,339 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImpl; +import java.nio.channels.SocketChannel; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * Simulates two connected {@link Socket} objects. No physical connection is + * established for this. The behavior includes the (inconsistent) exception + * messages have been derived from Sun JDK 1.5.0_18-b02. + */ +public class MockSocketConnection { + + private final MockSocket socketA; + + private final MockSocket socketB; + + public MockSocketConnection() throws SocketException { + socketA = new MockSocket(); + socketB = new MockSocket(); + socketA.connect(socketB); + } + + public Socket getSocketA() { + return socketA; + } + + public Socket getSocketB() { + return socketB; + } + + private class MockSocket extends Socket { + + private MockSocket other; + + private boolean closed; + + private final Queue buffer = new ConcurrentLinkedQueue(); + + private final OutputStream out = new OutputStream() { + + @Override + public void write(int b) throws IOException { + if (closed) { + throw new SocketException("Socket closed"); + } + synchronized (other.buffer) { + other.buffer.add(Byte.valueOf((byte) b)); + other.buffer.notifyAll(); + } + } + }; + + private final InputStream in = new InputStream() { + + @Override + public int read() throws IOException { + synchronized (buffer) { + try { + while (true) { + if (closed) { + throw new SocketException("socket closed"); + } + if (other.closed) { + return -1; + } + final Byte b = buffer.poll(); + if (b != null) { + return 0xff & b.intValue(); + } + buffer.wait(); + } + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } + } + } + + @Override + public int available() throws IOException { + return buffer.size(); + } + + }; + + public MockSocket() throws SocketException { + super((SocketImpl) null); + closed = false; + } + + void connect(MockSocket other) { + this.other = other; + other.other = this; + } + + // socket methods with mocking behavior: + + @Override + public OutputStream getOutputStream() throws IOException { + if (closed) { + throw new SocketException("Socket is closed"); + } + return out; + } + + @Override + public InputStream getInputStream() throws IOException { + if (closed) { + throw new SocketException("Socket is closed"); + } + return in; + } + + @Override + public void close() throws IOException { + closed = true; + synchronized (buffer) { + buffer.notifyAll(); + } + synchronized (other.buffer) { + other.buffer.notifyAll(); + } + } + + @Override + public boolean isClosed() { + return closed; + } + + // unsupported socket methods: + + @Override + public void bind(SocketAddress bindpoint) throws IOException { + throw new AssertionError(); + } + + @Override + public void connect(SocketAddress endpoint, int timeout) + throws IOException { + throw new AssertionError(); + } + + @Override + public void connect(SocketAddress endpoint) throws IOException { + throw new AssertionError(); + } + + @Override + public SocketChannel getChannel() { + throw new AssertionError(); + } + + @Override + public InetAddress getInetAddress() { + throw new AssertionError(); + } + + @Override + public boolean getKeepAlive() throws SocketException { + throw new AssertionError(); + } + + @Override + public InetAddress getLocalAddress() { + throw new AssertionError(); + } + + @Override + public int getLocalPort() { + throw new AssertionError(); + } + + @Override + public SocketAddress getLocalSocketAddress() { + throw new AssertionError(); + } + + @Override + public boolean getOOBInline() throws SocketException { + throw new AssertionError(); + } + + @Override + public int getPort() { + throw new AssertionError(); + } + + @Override + public synchronized int getReceiveBufferSize() throws SocketException { + throw new AssertionError(); + } + + @Override + public SocketAddress getRemoteSocketAddress() { + throw new AssertionError(); + } + + @Override + public boolean getReuseAddress() throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized int getSendBufferSize() throws SocketException { + throw new AssertionError(); + } + + @Override + public int getSoLinger() throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized int getSoTimeout() throws SocketException { + throw new AssertionError(); + } + + @Override + public boolean getTcpNoDelay() throws SocketException { + throw new AssertionError(); + } + + @Override + public int getTrafficClass() throws SocketException { + throw new AssertionError(); + } + + @Override + public boolean isBound() { + throw new AssertionError(); + } + + @Override + public boolean isConnected() { + throw new AssertionError(); + } + + @Override + public boolean isInputShutdown() { + throw new AssertionError(); + } + + @Override + public boolean isOutputShutdown() { + throw new AssertionError(); + } + + @Override + public void sendUrgentData(int data) throws IOException { + throw new AssertionError(); + } + + @Override + public void setKeepAlive(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public void setOOBInline(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public void setPerformancePreferences(int connectionTime, int latency, + int bandwidth) { + throw new AssertionError(); + } + + @Override + public synchronized void setReceiveBufferSize(int size) + throws SocketException { + throw new AssertionError(); + } + + @Override + public void setReuseAddress(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized void setSendBufferSize(int size) + throws SocketException { + throw new AssertionError(); + } + + @Override + public void setSoLinger(boolean on, int linger) throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized void setSoTimeout(int timeout) + throws SocketException { + throw new AssertionError(); + } + + @Override + public void setTcpNoDelay(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public void setTrafficClass(int tc) throws SocketException { + throw new AssertionError(); + } + + @Override + public void shutdownInput() throws IOException { + throw new AssertionError(); + } + + @Override + public void shutdownOutput() throws IOException { + throw new AssertionError(); + } + + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnectionTest.java new file mode 100644 index 00000000..05186d73 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/MockSocketConnectionTest.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link MockSocketConnection}. + */ +public class MockSocketConnectionTest extends ExecutorTestBase { + + /** + * To verify that the tests reflect the behavior of real TCP sockets this + * flag can be set to true. + */ + private static final boolean REAL_SOCKETS = Boolean + .getBoolean("MockSocketConnectionTest.realSockets"); + + private Socket a; + + private Socket b; + + @Before + @Override + public void setup() throws Exception { + super.setup(); + if (REAL_SOCKETS) { + createRealSockets(); + } else { + createMockSockets(); + } + } + + private void createMockSockets() throws Exception { + final MockSocketConnection con = new MockSocketConnection(); + a = con.getSocketA(); + b = con.getSocketB(); + } + + private void createRealSockets() throws Exception { + System.err.println("Using Real Sockets!"); + final InetAddress addr = InetAddress.getByName("localhost"); + ServerSocket ssocket = new ServerSocket(16300, 1, addr); + a = new Socket(addr, 16300); + b = ssocket.accept(); + ssocket.close(); + } + + @Test + public void testIsClosed() throws Exception { + assertFalse(a.isClosed()); + a.close(); + assertTrue(a.isClosed()); + } + + @Test(expected = SocketException.class) + public void testGetInputStreamOnClosedSocket() throws Exception { + a.close(); + a.getInputStream(); + } + + @Test(expected = SocketException.class) + public void testReadOnClosedSocket() throws Exception { + final InputStream in = a.getInputStream(); + a.close(); + in.read(); + } + + @Test(expected = SocketException.class) + public void testReadOnClosedSocketAsync() throws Throwable { + final InputStream in = a.getInputStream(); + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + in.read(); + return null; + } + }); + + assertBlocks(f); + + a.close(); + try { + f.get(); + } catch (ExecutionException e) { + throw e.getCause(); + } + } + + @Test(expected = SocketException.class) + public void testGetOutputStreamOnClosedSocket() throws Exception { + a.close(); + a.getOutputStream(); + } + + @Test(expected = SocketException.class) + public void testWriteOnClosedSocket() throws Exception { + final OutputStream out = a.getOutputStream(); + a.close(); + out.write(123); + } + + @Test + public void testContents() throws Exception { + final InputStream in = a.getInputStream(); + final OutputStream out = b.getOutputStream(); + + assertEquals(0, in.available()); + + out.write(0); + out.write(1); + out.write(2); + out.write(255); + + if (!REAL_SOCKETS) { + // Real sockets will have a delay + assertEquals(4, in.available()); + } + + assertEquals(0, in.read()); + assertEquals(1, in.read()); + assertEquals(2, in.read()); + assertEquals(255, in.read()); + } + + @Test + public void testWaitForContents() throws Exception { + final InputStream in = a.getInputStream(); + final OutputStream out = b.getOutputStream(); + + final Future f = executor.submit(new Callable() { + public Byte call() throws Exception { + return Byte.valueOf((byte) in.read()); + } + }); + + assertBlocks(f); + out.write(123); + assertEquals(123, f.get().byteValue()); + } + + @Test + public void testCloseOtherSocket() throws Exception { + b.close(); + final InputStream in = a.getInputStream(); + assertEquals(-1, in.read()); + } + + @Test + public void testCloseOtherSocketAsync() throws Exception { + final InputStream in = a.getInputStream(); + + final Future f = executor.submit(new Callable() { + public Byte call() throws Exception { + return Byte.valueOf((byte) in.read()); + } + }); + + assertBlocks(f); + b.close(); + + assertEquals(-1, f.get().byteValue()); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java new file mode 100644 index 00000000..3283551d --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpClientOutputTest.java @@ -0,0 +1,118 @@ +/******************************************************************************* +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Brock Janiczak - initial API and implementation + * Marc R. Hoffmann - migration to mock socket + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; +import java.net.Socket; +import java.util.List; + +import org.jacoco.agent.rt.internal.ExceptionRecorder; +import org.jacoco.agent.rt.internal.output.IAgentOutput; +import org.jacoco.agent.rt.internal.output.TcpClientOutput; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.jacoco.core.runtime.RuntimeData; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpClientOutput}. + */ +public class TcpClientOutputTest { + + private ExceptionRecorder logger; + + private IAgentOutput controller; + + private Socket remoteSocket; + + private RemoteControlWriter remoteWriter; + + private RemoteControlReader remoteReader; + + private RuntimeData data; + + @Before + public void setup() throws Exception { + logger = new ExceptionRecorder(); + final MockSocketConnection con = new MockSocketConnection(); + remoteSocket = con.getSocketB(); + remoteWriter = new RemoteControlWriter(remoteSocket.getOutputStream()); + controller = new TcpClientOutput(logger) { + @Override + protected Socket createSocket(AgentOptions options) + throws IOException { + return con.getSocketA(); + } + }; + data = new RuntimeData(); + controller.startup(new AgentOptions(), data); + remoteReader = new RemoteControlReader(remoteSocket.getInputStream()); + } + + @Test + public void testShutdown() throws Exception { + controller.shutdown(); + assertFalse(remoteReader.read()); + logger.assertNoException(); + } + + @Test + public void testRemoteClose() throws Exception { + remoteSocket.close(); + controller.shutdown(); + logger.assertNoException(); + } + + @Test + public void testInvalidCommand() throws Exception { + remoteWriter.visitSessionInfo(new SessionInfo("info", 1, 2)); + while (remoteReader.read()) { + } + controller.shutdown(); + logger.assertException(IOException.class, "No session info visitor."); + } + + @Test + public void testWriteExecutionData() throws Exception { + data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); + data.setSessionId("stubid"); + + controller.writeExecutionData(false); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + remoteReader.read(); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + + final List infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + logger.assertNoException(); + controller.shutdown(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java new file mode 100644 index 00000000..0c1e44e9 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpConnectionTest.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +import org.jacoco.agent.rt.internal.output.TcpConnection; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.jacoco.core.runtime.RuntimeData; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpConnection}. + */ +public class TcpConnectionTest extends ExecutorTestBase { + + private MockSocketConnection mockConnection; + + private RuntimeData data; + + @Before + @Override + public void setup() throws Exception { + super.setup(); + mockConnection = new MockSocketConnection(); + data = new RuntimeData(); + } + + @Test(expected = IOException.class) + public void testInvalidHeader() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + remoteOut.write(0x01); + remoteOut.write(0xC0); + remoteOut.write(0xCA); + final TcpConnection connection = new TcpConnection( + mockConnection.getSocketA(), data); + connection.init(); + connection.run(); + } + + @Test(expected = IOException.class) + public void testInvalidContent() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + remoteOut.write(123); + con.run(); + } + + /** + * Remote endpoint is closed after a valid header has been send. + */ + @Test + public void testRemoteClose() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + mockConnection.getSocketB().close(); + f.get(); + } + + /** + * Remote endpoint is closed before even a valid header was send. + */ + public void testRemoteCloseWithoutHeader() throws Throwable { + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.init(); + return null; + } + }); + + assertBlocks(f); + + mockConnection.getSocketB().close(); + f.get(); + } + + /** + * Local socket is closed while waiting for commands. + * + * @throws Exception + */ + @Test + public void testLocalClose() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + con.close(); + f.get(); + } + + @Test + public void testRemoteDump() throws Exception { + data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); + data.setSessionId("stubid"); + + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + remoteWriter.visitDumpCommand(true, false); + readAndAssertData(); + + con.close(); + f.get(); + } + + @Test + public void testLocalDump() throws Exception { + data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); + data.setSessionId("stubid"); + + new RemoteControlWriter(mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + con.writeExecutionData(false); + readAndAssertData(); + + con.close(); + f.get(); + } + + @Test + public void testLocalDumpWithoutInit() throws Exception { + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + // Must not write any data as we're not initialized: + con.writeExecutionData(false); + + assertEquals(0, mockConnection.getSocketB().getInputStream() + .available()); + } + + private void readAndAssertData() throws IOException { + final RemoteControlReader remoteReader = new RemoteControlReader( + mockConnection.getSocketB().getInputStream()); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + assertTrue(remoteReader.read()); + + final List infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + } + + @Test + public void testRemoteReset() throws Exception { + data.getExecutionData(Long.valueOf(123), "Foo", 1).getProbes()[0] = true; + + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), data); + con.init(); + + final Future f = executor.submit(new Callable() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + remoteWriter.visitDumpCommand(false, true); + + final RemoteControlReader remoteReader = new RemoteControlReader( + mockConnection.getSocketB().getInputStream()); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + assertTrue(remoteReader.read()); + assertTrue(infoStore.getInfos().isEmpty()); + assertTrue(execStore.getContents().isEmpty()); + assertFalse(data.getExecutionData(Long.valueOf(123), "Foo", 1) + .getProbes()[0]); + + con.close(); + f.get(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpServerOutputTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpServerOutputTest.java new file mode 100644 index 00000000..64c677c0 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/TcpServerOutputTest.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Brock Janiczak - initial API and implementation + * Marc R. Hoffmann - migration to mock socket + * + *******************************************************************************/ +package org.jacoco.agent.rt.internal.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.List; + +import org.jacoco.agent.rt.internal.ExceptionRecorder; +import org.jacoco.agent.rt.internal.output.TcpServerOutput; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.jacoco.core.runtime.RuntimeData; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpServerOutput}. + */ +public class TcpServerOutputTest { + + private ExceptionRecorder logger; + + private AgentOptions options; + + private MockServerSocket serverSocket; + + private TcpServerOutput controller; + + private RuntimeData data; + + @Before + public void setup() throws Exception { + options = new AgentOptions(); + logger = new ExceptionRecorder(); + serverSocket = new MockServerSocket(); + controller = new TcpServerOutput(logger) { + @Override + protected ServerSocket createServerSocket(AgentOptions options) + throws IOException { + return serverSocket; + } + }; + data = new RuntimeData(); + controller.startup(options, data); + } + + @Test + public void testShutdownWithoutConnection() throws Exception { + serverSocket.waitForAccept(); + controller.shutdown(); + logger.assertNoException(); + } + + @Test + public void testShutdownWithConnection() throws Exception { + serverSocket.waitForAccept(); + new ExecutionDataWriter(serverSocket.connect().getOutputStream()); + controller.shutdown(); + logger.assertNoException(); + } + + @Test + public void testWriteExecutionData() throws Exception { + data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42); + data.setSessionId("stubid"); + + final Socket socket = serverSocket.connect(); + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + socket.getOutputStream()); + final RemoteControlReader remoteReader = new RemoteControlReader( + socket.getInputStream()); + + // First process a NOP command to ensure the connection is initialized: + remoteWriter.visitDumpCommand(false, false); + remoteReader.read(); + + // Now the actual test starts: + controller.writeExecutionData(false); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + remoteReader.read(); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + + final List infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + logger.assertNoException(); + controller.shutdown(); + } + + @Test + public void testInvalidHeader() throws Exception { + final Socket socket = serverSocket.connect(); + final OutputStream out = socket.getOutputStream(); + out.write(0xca); + out.write(0xfe); + out.write(0xba); + out.write(0xbe); + serverSocket.waitForAccept(); + logger.assertException(IOException.class, + "Invalid execution data file."); + controller.shutdown(); + } + + @Test + public void testGetInetAddressLoopback() throws UnknownHostException { + final InetAddress addr = controller.getInetAddress(null); + assertTrue(addr.isLoopbackAddress()); + } + + @Test + public void testGetInetAddressAny() throws UnknownHostException { + final InetAddress addr = controller.getInetAddress("*"); + assertNull(addr); + } + +} -- cgit v1.2.3