diff --git a/testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketTest.java b/testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketTest.java new file mode 100644 index 0000000000..cfabbd7784 --- /dev/null +++ b/testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.testsuite.transport.socket; + +import io.netty.bootstrap.Bootstrap; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.logging.InternalLogger; +import io.netty.logging.InternalLoggerFactory; +import io.netty.testsuite.transport.socket.SocketTestCombination.Factory; +import io.netty.testsuite.util.TestUtils; +import io.netty.util.SocketAddresses; + +import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Map.Entry; + +import org.junit.Rule; +import org.junit.rules.TestName; + +public abstract class AbstractSocketTest { + + private static final List, Factory>> COMBO = + SocketTestCombination.all(); + + @Rule + public final TestName testName = new TestName(); + + protected final InternalLogger logger = InternalLoggerFactory.getInstance(getClass()); + + protected volatile ServerBootstrap sb; + protected volatile Bootstrap cb; + protected volatile InetSocketAddress addr; + + protected void run() throws Exception { + int i = 0; + for (Entry, Factory> e: COMBO) { + sb = e.getKey().newInstance(); + cb = e.getValue().newInstance(); + addr = new InetSocketAddress( + SocketAddresses.LOCALHOST, TestUtils.getFreePort()); + sb.localAddress(addr); + cb.remoteAddress(addr); + + logger.info(String.format( + "Running: %s %d of %d", testName.getMethodName(), ++ i, COMBO.size())); + try { + Method m = getClass().getDeclaredMethod( + testName.getMethodName(), ServerBootstrap.class, Bootstrap.class); + m.invoke(this, sb, cb); + } finally { + sb.shutdown(); + cb.shutdown(); + } + } + } +} diff --git a/testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketEchoTest.java b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketEchoTest.java similarity index 55% rename from testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketEchoTest.java rename to testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketEchoTest.java index 8a9ab53b48..d82cfee602 100644 --- a/testsuite/src/test/java/io/netty/testsuite/transport/socket/AbstractSocketEchoTest.java +++ b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketEchoTest.java @@ -16,75 +16,44 @@ package io.netty.testsuite.transport.socket; import static org.junit.Assert.*; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Random; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicReference; - -import io.netty.bootstrap.ClientBootstrap; +import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ChannelBuffer; import io.netty.buffer.ChannelBuffers; import io.netty.channel.Channel; -import io.netty.channel.ChannelFactory; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelStateEvent; -import io.netty.channel.ExceptionEvent; -import io.netty.channel.MessageEvent; -import io.netty.channel.SimpleChannelUpstreamHandler; -import io.netty.util.SocketAddresses; -import io.netty.util.internal.ExecutorUtil; -import org.junit.AfterClass; -import org.junit.BeforeClass; +import io.netty.channel.ChannelInboundHandlerContext; +import io.netty.channel.ChannelInboundStreamHandlerAdapter; + +import java.io.IOException; +import java.util.Random; +import java.util.concurrent.atomic.AtomicReference; + import org.junit.Test; -public abstract class AbstractSocketEchoTest { +public class SocketEchoTest extends AbstractSocketTest { private static final Random random = new Random(); static final byte[] data = new byte[1048576]; - private static ExecutorService executor; - static { random.nextBytes(data); } - @BeforeClass - public static void init() { - executor = Executors.newCachedThreadPool(); - } - - @AfterClass - public static void destroy() { - ExecutorUtil.terminate(executor); - } - - protected abstract ChannelFactory newServerSocketChannelFactory(Executor executor); - protected abstract ChannelFactory newClientSocketChannelFactory(Executor executor); - @Test - public void testSimpleEcho() throws Throwable { - ServerBootstrap sb = new ServerBootstrap(newServerSocketChannelFactory(executor)); - ClientBootstrap cb = new ClientBootstrap(newClientSocketChannelFactory(executor)); + public void testSimpleEcho() throws Exception { + run(); + } + public void testSimpleEcho(ServerBootstrap sb, Bootstrap cb) throws Throwable { EchoHandler sh = new EchoHandler(); EchoHandler ch = new EchoHandler(); - sb.pipeline().addFirst("handler", sh); - cb.pipeline().addFirst("handler", ch); + sb.childHandler(sh); + cb.handler(ch); - Channel sc = sb.bind(new InetSocketAddress(0)); - int port = ((InetSocketAddress) sc.getLocalAddress()).getPort(); + Channel sc = sb.bind().sync().channel(); + Channel cc = cb.connect().sync().channel(); - ChannelFuture ccf = cb.connect(new InetSocketAddress(SocketAddresses.LOCALHOST, port)); - assertTrue(ccf.awaitUninterruptibly().isSuccess()); - - Channel cc = ccf.channel(); for (int i = 0; i < data.length;) { int length = Math.min(random.nextInt(1024 * 64), data.length - i); cc.write(ChannelBuffers.wrappedBuffer(data, i, length)); @@ -121,9 +90,9 @@ public abstract class AbstractSocketEchoTest { } } - sh.channel.close().awaitUninterruptibly(); - ch.channel.close().awaitUninterruptibly(); - sc.close().awaitUninterruptibly(); + sh.channel.close().sync(); + ch.channel.close().sync(); + sc.close().sync(); if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) { throw sh.exception.get(); @@ -139,7 +108,7 @@ public abstract class AbstractSocketEchoTest { } } - private static class EchoHandler extends SimpleChannelUpstreamHandler { + private static class EchoHandler extends ChannelInboundStreamHandlerAdapter { volatile Channel channel; final AtomicReference exception = new AtomicReference(); volatile int counter; @@ -148,35 +117,35 @@ public abstract class AbstractSocketEchoTest { } @Override - public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) + public void channelActive(ChannelInboundHandlerContext ctx) throws Exception { - channel = e.channel(); + channel = ctx.channel(); } @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + public void inboundBufferUpdated( + ChannelInboundHandlerContext ctx, ChannelBuffer in) throws Exception { - ChannelBuffer m = (ChannelBuffer) e.getMessage(); - byte[] actual = new byte[m.readableBytes()]; - m.getBytes(0, actual); + byte[] actual = new byte[in.readableBytes()]; + in.readBytes(actual); int lastIdx = counter; for (int i = 0; i < actual.length; i ++) { assertEquals(data[i + lastIdx], actual[i]); } - if (channel.getParent() != null) { - channel.write(m); + if (channel.parent() != null) { + channel.write(ChannelBuffers.wrappedBuffer(actual)); } counter += actual.length; } @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception { - if (exception.compareAndSet(null, e.cause())) { - e.channel().close(); + public void exceptionCaught(ChannelInboundHandlerContext ctx, + Throwable cause) throws Exception { + if (exception.compareAndSet(null, cause)) { + ctx.close(); } } } diff --git a/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketTestCombination.java b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketTestCombination.java new file mode 100644 index 0000000000..32d21f8eda --- /dev/null +++ b/testsuite/src/test/java/io/netty/testsuite/transport/socket/SocketTestCombination.java @@ -0,0 +1,90 @@ +package io.netty.testsuite.transport.socket; + +import io.netty.bootstrap.Bootstrap; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.socket.nio.NioEventLoop; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.channel.socket.oio.OioEventLoop; +import io.netty.channel.socket.oio.OioServerSocketChannel; +import io.netty.channel.socket.oio.OioSocketChannel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +final class SocketTestCombination { + + static List, Factory>> all() { + List, Factory>> list = + new ArrayList, Factory>>(); + + // Make the list of ServerBootstrap factories. + List> sbfs = + new ArrayList>(); + sbfs.add(new Factory() { + @Override + public ServerBootstrap newInstance() { + return new ServerBootstrap(). + eventLoop(new NioEventLoop(), new NioEventLoop()). + channel(new NioServerSocketChannel()); + } + }); + sbfs.add(new Factory() { + @Override + public ServerBootstrap newInstance() { + return new ServerBootstrap(). + eventLoop(new OioEventLoop(), new OioEventLoop()). + channel(new OioServerSocketChannel()); + } + }); + + // Make the list of Bootstrap factories. + List> cbfs = + new ArrayList>(); + cbfs.add(new Factory() { + @Override + public Bootstrap newInstance() { + return new Bootstrap().eventLoop(new NioEventLoop()).channel(new NioSocketChannel()); + } + }); + cbfs.add(new Factory() { + @Override + public Bootstrap newInstance() { + return new Bootstrap().eventLoop(new OioEventLoop()).channel(new OioSocketChannel()); + } + }); + + // Populate the combinations + for (Factory sbf: sbfs) { + for (Factory cbf: cbfs) { + final Factory sbf0 = sbf; + final Factory cbf0 = cbf; + list.add(new Map.Entry, SocketTestCombination.Factory>() { + @Override + public Factory getKey() { + return sbf0; + } + + @Override + public Factory getValue() { + return cbf0; + } + + @Override + public Factory setValue(Factory value) { + throw new UnsupportedOperationException(); + } + }); + } + } + + return list; + } + + private SocketTestCombination() {} + + static interface Factory { + T newInstance(); + } +} diff --git a/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java b/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java index 3f2689177b..d03dfd7308 100644 --- a/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java @@ -249,6 +249,5 @@ public class ServerBootstrap { } } } - } }