package edu.uw.zookeeper.netty;
import static org.junit.Assert.*;
import java.util.Collections;
import java.util.Set;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.local.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import edu.uw.zookeeper.net.Connection;
import edu.uw.zookeeper.net.ConnectionTestAdapter;
import edu.uw.zookeeper.net.QueueingConnectionListener;
@RunWith(JUnit4.class)
public class ChannelConnectionTest extends ConnectionTestAdapter {
@Test(timeout=5000)
public void test() throws Exception {
final Set<QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>>> serverConnections =
Collections.synchronizedSet(Sets.<QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>>>newHashSet());
final Set<QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>>> clientConnections =
Collections.synchronizedSet(Sets.<QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>>>newHashSet());
LocalEventLoopGroup group = new LocalEventLoopGroup(1);
LocalServerChannel server = (LocalServerChannel)
new ServerBootstrap()
.group(group, group)
.channel(LocalServerChannel.class)
.localAddress(LocalAddress.ANY)
.childHandler(new ChannelInitializer<LocalChannel>() {
@Override
protected void initChannel(LocalChannel channel)
throws Exception {
serverConnections.add(newConnection(channel));
}
})
.bind().sync().channel();
Bootstrap clients = new Bootstrap()
.group(group)
.channel(LocalChannel.class)
.handler(new ChannelInitializer<LocalChannel>() {
@Override
protected void initChannel(LocalChannel channel)
throws Exception {
clientConnections.add(newConnection(channel));
}
});
clients.connect(server.localAddress()).sync();
QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>> clientConnection = Iterables.getOnlyElement(clientConnections);
QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>> serverConnection = Iterables.getOnlyElement(serverConnections);
pingPong(clientConnection, serverConnection);
assertEquals(clientConnection.listener().states().take().to(), Connection.State.CONNECTION_OPENED);
assertEquals(serverConnection.listener().states().take().to(), Connection.State.CONNECTION_OPENED);
server.close().await();
synchronized (serverConnections) {
synchronized (clientConnections) {
for (QueuedConnection<?,?,?> c: Sets.union(serverConnections, clientConnections)) {
c.connection().close().get();
}
}
}
group.shutdownGracefully();
synchronized (serverConnections) {
synchronized (clientConnections) {
for (QueuedConnection<?,?,?> c: Sets.union(serverConnections, clientConnections)) {
assertEquals(c.listener().states().take().to(), Connection.State.CONNECTION_CLOSING);
assertEquals(c.listener().states().take().to(), Connection.State.CONNECTION_CLOSED);
assertTrue(c.listener().states().isEmpty());
assertTrue(c.listener().reads().isEmpty());
}
}
}
}
protected QueuedConnection<String,String,? extends AbstractChannelConnection<String,String,?>> newConnection(Channel channel) {
QueueingConnectionListener<String> listener = QueueingConnectionListener.linkedQueues();
ChannelConnection<String,String> connection =
ChannelConnection.withListeners(
String.class, channel, ImmutableList.of(listener));
return QueuedConnection.create(connection, listener);
}
}