package org.deftserver.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.deftserver.web.AsyncCallback;
import org.deftserver.web.AsyncResult;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class AsynchronousSocketTest {
public static final String HOST = "localhost";
public static final int PORT = 6228;
@Before
public void setup() throws InterruptedException {
// start the IOLoop from a new thread so we dont block this test.
new Thread(new Runnable() {
@Override public void run() { IOLoop.INSTANCE.start(); }
}).start();
Thread.sleep(300); // hack to avoid SLF4J warning
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
DataInputStream is = null;
DataOutputStream os = null;
try {
System.out.println("waiting for client...");
ServerSocket server = new ServerSocket(PORT);
latch.countDown();
Socket client = server.accept();
System.out.println("client connected..");
is = new DataInputStream(client.getInputStream());
os = new DataOutputStream(client.getOutputStream());
String recevied = is.readLine();
System.out.println("about to send: " + recevied);
os.writeBytes(recevied.toUpperCase());
System.out.println("sent data to client, shutdown server...");
server.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeQuietly(is, os);
}
}
}).start();
latch.await(5, TimeUnit.SECONDS);
}
@After
public void tearDown() throws InterruptedException {
IOLoop.INSTANCE.addCallback(new AsyncCallback() {
@Override
public void onCallback() { IOLoop.INSTANCE.stop(); }
});
Thread.sleep(300); // give the IOLoop thread some time to gracefully shutdown
}
private void closeQuietly(InputStream is, OutputStream os) {
try {
if (is != null) is.close();
if (os != null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private final AsynchronousSocket socket;
private final CountDownLatch latch = new CountDownLatch(3); // 3 op/callbacks (connect, write, read)
public AsynchronousSocketTest() throws IOException {
SelectableChannel channel = SocketChannel.open();
channel.configureBlocking(false);
socket = new AsynchronousSocket(channel);
}
@Test
public void connectWriteAndReadCallbackTest() throws InterruptedException, IOException {
AsyncResult<Boolean> ccb = new AsyncResult<Boolean>() {
public void onFailure(Throwable caught) { }
public void onSuccess(Boolean result) { onConnect(); }
};
socket.connect(HOST, PORT, ccb);
latch.await(5, TimeUnit.SECONDS);
assertEquals(0, latch.getCount());
// TODO stop ioloop
}
private void onConnect() {
latch.countDown();
AsyncCallback wcb = new AsyncCallback() { @Override public void onCallback() { onWriteComplete(); }};
socket.write("roger|\r\n", wcb);
}
private void onWriteComplete() {
latch.countDown();
AsyncResult<String> rcb = new AsyncResult<String>() {
@Override public void onFailure(Throwable caught) { assertTrue(false); }
@Override public void onSuccess(String result) { onReadComplete(result); }
};
socket.readUntil("|", rcb);
}
private void onReadComplete(String result) {
if ("ROGER".equals(result)) {
latch.countDown();
}
assertEquals("ROGER", result);
}
}