package biz.aQute.remote;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.atomic.AtomicInteger;
import aQute.remote.util.Link;
import junit.framework.TestCase;
public class LinkTest extends TestCase {
private ServerSocket server;
private LocalImpl localImpl;
private RemoteImpl remoteImpl;
AtomicInteger localClosed = new AtomicInteger();
AtomicInteger remoteClosed = new AtomicInteger();
private Socket localSocket;
private Socket remoteSocket;
public void setUp() throws IOException {
server = new ServerSocket(4567);
remoteSocket = new Socket(InetAddress.getByName(null), server.getLocalPort());
remoteSocket.setSoTimeout(500);
localSocket = server.accept();
localSocket.setSoTimeout(500);
localImpl = new LocalImpl(Remote.class, localSocket.getInputStream(), localSocket.getOutputStream());
remoteImpl = new RemoteImpl(Local.class, remoteSocket.getInputStream(), remoteSocket.getOutputStream());
}
public void tearDown() throws IOException {
server.close();
localSocket.close();
remoteSocket.close();
}
interface Remote {
int foo();
void abort() throws IOException;
}
interface Local {
int bar();
void aborted() throws IOException;
}
public class LocalImpl implements Local, Closeable {
Link<Local,Remote> link;
public LocalImpl(Class<Remote> type, InputStream in, OutputStream out) {
link = new Link<Local,Remote>(type, this, in, out);
}
public int bar() {
System.out.println("bar");
return 42;
}
@Override
public void close() throws IOException {
System.out.println("local closed");
localClosed.incrementAndGet();
}
@Override
public void aborted() throws IOException {
System.out.println("bar");
link.close();
}
}
public class RemoteImpl implements Remote, Closeable {
Link<Remote,Local> link;
public RemoteImpl(Class<Local> type, InputStream in, OutputStream out) {
link = new Link<Remote,Local>(type, this, in, out);
}
public int foo() {
System.out.println("foo");
return -42;
}
@Override
public void close() throws IOException {
System.out.println("remote closed");
remoteClosed.incrementAndGet();
}
@Override
public void abort() throws IOException {
link.getRemote().aborted();
}
}
/**
* Test transfer
*
* @throws Exception
*/
public void testTransfer() throws Exception {
localImpl.link.open();
remoteImpl.link.open();
assertEquals(-42, localImpl.link.getRemote().foo());
localImpl.link.transfer(null);
LocalImpl newer = new LocalImpl(Remote.class, localImpl.link.getInput(), localImpl.link.getOutput());
newer.link.open();
assertEquals(-42, newer.link.getRemote().foo());
newer.link.close();
Thread.sleep(100);
assertEquals(1, remoteClosed.get());
assertEquals(1, localClosed.get());
newer.close();
}
/**
* Test simple
*
* @throws InterruptedException
*/
public void testSimple() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertEquals(-42, localImpl.link.getRemote().foo());
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
localSocket.getInputStream().close();
normalClose();
}
private void normalClose() throws InterruptedException {
Thread.sleep(100);
assertFalse(localImpl.link.isOpen());
assertFalse(remoteImpl.link.isOpen());
assertEquals(1, localClosed.get());
assertEquals(1, remoteClosed.get());
}
/**
* Only close in
*
* @throws InterruptedException
*/
public void testCloseLocalIn() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
assertEquals(-42, localImpl.link.getRemote().foo());
localSocket.getOutputStream().close();
normalClose();
}
public void testCloseremoteIn() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
assertEquals(-42, localImpl.link.getRemote().foo());
remoteSocket.getInputStream().close();
normalClose();
}
public void testCloseremoteOut() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
assertEquals(-42, localImpl.link.getRemote().foo());
remoteSocket.getOutputStream().close();
normalClose();
}
public void testCloseLocalSocket() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
assertEquals(-42, localImpl.link.getRemote().foo());
localSocket.close();
normalClose();
}
public void testCloseRemoteSocket() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertTrue(localImpl.link.isOpen());
assertTrue(remoteImpl.link.isOpen());
assertEquals(-42, localImpl.link.getRemote().foo());
remoteSocket.close();
normalClose();
}
public void testAbort() throws IOException, InterruptedException {
localImpl.link.open();
remoteImpl.link.open();
assertEquals(-42, localImpl.link.getRemote().foo());
localImpl.link.getRemote().abort();
normalClose();
}
}