/******************************************************************************* * Copyright (c) 2009, 2015 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(); } }