diff --git a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java index 636c7ec5e7..bc7ceb245a 100644 --- a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java +++ b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java @@ -189,6 +189,10 @@ public class ClientBootstrap extends Bootstrap { */ public ChannelFuture connect(final SocketAddress remoteAddress, final SocketAddress localAddress) { + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } + final BlockingQueue futureQueue = new LinkedBlockingQueue(); diff --git a/src/main/java/org/jboss/netty/bootstrap/ServerBootstrap.java b/src/main/java/org/jboss/netty/bootstrap/ServerBootstrap.java index 72abec2ab0..f61da9c49e 100644 --- a/src/main/java/org/jboss/netty/bootstrap/ServerBootstrap.java +++ b/src/main/java/org/jboss/netty/bootstrap/ServerBootstrap.java @@ -212,6 +212,10 @@ public class ServerBootstrap extends Bootstrap { * bind it to the local address */ public Channel bind(final SocketAddress localAddress) { + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } + final BlockingQueue futureQueue = new LinkedBlockingQueue(); diff --git a/src/test/java/org/jboss/netty/bootstrap/BootstrapTest.java b/src/test/java/org/jboss/netty/bootstrap/BootstrapTest.java index 6596428de8..29dd2adc99 100644 --- a/src/test/java/org/jboss/netty/bootstrap/BootstrapTest.java +++ b/src/test/java/org/jboss/netty/bootstrap/BootstrapTest.java @@ -39,9 +39,6 @@ import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.logging.InternalLoggerFactory; -import org.jboss.netty.util.SilentLoggerFactory; -import org.junit.BeforeClass; import org.junit.Test; @@ -274,9 +271,4 @@ public class BootstrapTest { public void shouldNotAllowNullOptionMap() { new Bootstrap().setOptions(null); } - - @BeforeClass - public static void setUp() { - InternalLoggerFactory.setDefaultFactory(new SilentLoggerFactory()); - } } diff --git a/src/test/java/org/jboss/netty/bootstrap/ClientBootstrapTest.java b/src/test/java/org/jboss/netty/bootstrap/ClientBootstrapTest.java new file mode 100644 index 0000000000..221b7d4b75 --- /dev/null +++ b/src/test/java/org/jboss/netty/bootstrap/ClientBootstrapTest.java @@ -0,0 +1,178 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.bootstrap; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.channels.ServerSocketChannel; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelPipelineException; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.socket.oio.OioClientSocketChannelFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + + +/** + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * + * @version $Rev$, $Date$ + * + */ +public class ClientBootstrapTest { + + private static ExecutorService executor; + + @BeforeClass + public static void init() { + executor = Executors.newCachedThreadPool(); + } + + @AfterClass + public static void destroy() { + executor.shutdown(); + for (;;) { + try { + if (executor.awaitTermination(1, TimeUnit.SECONDS)) { + break; + } + } catch (InterruptedException e) { + // Ignore. + } + } + } + + + @Test(timeout = 10000) + public void testFailedConnectionAttempt() throws Exception { + ClientBootstrap bootstrap = new ClientBootstrap(); + bootstrap.setFactory(new OioClientSocketChannelFactory(executor)); + bootstrap.setOption("remoteAddress", new InetSocketAddress("255.255.255.255", 1)); + ChannelFuture future = bootstrap.connect(); + future.awaitUninterruptibly(); + assertFalse(future.isSuccess()); + assertTrue(future.getCause() instanceof IOException); + } + + @Test(timeout = 10000) + public void testSuccessfulConnectionAttempt() throws Exception { + ServerSocketChannel serverSocket = ServerSocketChannel.open(); + serverSocket.socket().bind(new InetSocketAddress(0)); + + try { + serverSocket.configureBlocking(false); + + ClientBootstrap bootstrap = + new ClientBootstrap(new OioClientSocketChannelFactory(executor)); + bootstrap.setOption( + "remoteAddress", + new InetSocketAddress( + InetAddress.getLoopbackAddress(), + serverSocket.socket().getLocalPort())); + + ChannelFuture future = bootstrap.connect(); + serverSocket.accept(); + future.awaitUninterruptibly(); + + assertTrue(future.isSuccess()); + future.getChannel().close().awaitUninterruptibly(); + } finally { + try { + serverSocket.close(); + } catch (IOException e) { + // Ignore. + } + } + } + + @Test(timeout = 10000) + public void testSuccessfulConnectionAttemptWithLocalAddress() throws Exception { + ServerSocketChannel serverSocket = ServerSocketChannel.open(); + serverSocket.socket().bind(new InetSocketAddress(0)); + + try { + serverSocket.configureBlocking(false); + + ClientBootstrap bootstrap = + new ClientBootstrap(new OioClientSocketChannelFactory(executor)); + bootstrap.setOption( + "remoteAddress", + new InetSocketAddress( + InetAddress.getLoopbackAddress(), + serverSocket.socket().getLocalPort())); + bootstrap.setOption("localAddress", new InetSocketAddress(0)); + + ChannelFuture future = bootstrap.connect(); + serverSocket.accept(); + future.awaitUninterruptibly(); + + assertTrue(future.isSuccess()); + future.getChannel().close().awaitUninterruptibly(); + } finally { + try { + serverSocket.close(); + } catch (IOException e) { + // Ignore. + } + } + } + + @Test(expected = ChannelPipelineException.class) + public void testFailedPipelineInitialization() throws Exception { + ClientBootstrap bootstrap = new ClientBootstrap(createMock(ChannelFactory.class)); + ChannelPipelineFactory pipelineFactory = createMock(ChannelPipelineFactory.class); + bootstrap.setPipelineFactory(pipelineFactory); + + expect(pipelineFactory.getPipeline()).andThrow(new ChannelPipelineException()); + replay(pipelineFactory); + + bootstrap.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 1)); + } + + @Test(expected = IllegalStateException.class) + public void shouldHaveRemoteAddressOption() { + new ClientBootstrap(createMock(ChannelFactory.class)).connect(); + } + + + @Test(expected = NullPointerException.class) + public void shouldDisallowNullRemoteAddressParameter1() { + new ClientBootstrap(createMock(ChannelFactory.class)).connect(null); + } + + @Test(expected = NullPointerException.class) + public void shouldDisallowNullRemoteAddressParameter2() { + new ClientBootstrap(createMock(ChannelFactory.class)).connect(null, null); + } +} diff --git a/src/test/java/org/jboss/netty/bootstrap/ServerBootstrapTest.java b/src/test/java/org/jboss/netty/bootstrap/ServerBootstrapTest.java new file mode 100644 index 0000000000..cc845ef9cb --- /dev/null +++ b/src/test/java/org/jboss/netty/bootstrap/ServerBootstrapTest.java @@ -0,0 +1,185 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.bootstrap; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelException; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipelineCoverage; +import org.jboss.netty.channel.ChannelPipelineException; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.ChildChannelStateEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.channel.socket.SocketChannelConfig; +import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + + +/** + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * + * @version $Rev$, $Date$ + * + */ +public class ServerBootstrapTest { + + private static ExecutorService executor; + + @BeforeClass + public static void init() { + executor = Executors.newCachedThreadPool(); + } + + @AfterClass + public static void destroy() { + executor.shutdown(); + for (;;) { + try { + if (executor.awaitTermination(1, TimeUnit.SECONDS)) { + break; + } + } catch (InterruptedException e) { + // Ignore. + } + } + } + + + @Test(timeout = 10000, expected = ChannelException.class) + public void testFailedBindAttempt() throws Exception { + ServerBootstrap bootstrap = new ServerBootstrap(); + bootstrap.setFactory(new OioServerSocketChannelFactory(executor, executor)); + bootstrap.setOption("localAddress", new InetSocketAddress("255.255.255.255", 0)); + bootstrap.bind(); + } + + @Test(timeout = 10000) + public void testSuccessfulBindAttempt() throws Exception { + ServerBootstrap bootstrap = new ServerBootstrap( + new OioServerSocketChannelFactory(executor, executor)); + + bootstrap.setParentHandler(new ParentChannelHandler()); + bootstrap.setOption("localAddress", new InetSocketAddress(0)); + bootstrap.setOption("child.receiveBufferSize", 9753); + bootstrap.setOption("child.sendBufferSize", 8642); + + Channel channel = bootstrap.bind(); + ParentChannelHandler pch = + channel.getPipeline().get(ParentChannelHandler.class); + + Socket socket = null; + try { + socket = new Socket( + InetAddress.getLoopbackAddress(), + ((InetSocketAddress) channel.getLocalAddress()).getPort()); + + // Wait until the connection is open in the server side. + while (pch.child == null) { + Thread.yield(); + } + + SocketChannelConfig cfg = (SocketChannelConfig) pch.child.getConfig(); + assertEquals(9753, cfg.getReceiveBufferSize()); + assertEquals(8642, cfg.getSendBufferSize()); + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + // Ignore. + } + } + channel.close().awaitUninterruptibly(); + } + + // Wait until the child connection is closed in the client side. + // We don't use Channel.close() to make sure it's closed automatically. + while ("12".equals(pch.result.toString())) { + Thread.yield(); + } + } + + @Test(expected = ChannelPipelineException.class) + public void testFailedPipelineInitialization() throws Exception { + ClientBootstrap bootstrap = new ClientBootstrap(createMock(ChannelFactory.class)); + ChannelPipelineFactory pipelineFactory = createMock(ChannelPipelineFactory.class); + bootstrap.setPipelineFactory(pipelineFactory); + + expect(pipelineFactory.getPipeline()).andThrow(new ChannelPipelineException()); + replay(pipelineFactory); + + bootstrap.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 1)); + } + + @Test(expected = IllegalStateException.class) + public void shouldHaveLocalAddressOption() { + new ServerBootstrap(createMock(ChannelFactory.class)).bind(); + } + + + @Test(expected = NullPointerException.class) + public void shouldDisallowNullLocalAddressParameter() { + new ServerBootstrap(createMock(ChannelFactory.class)).bind(null); + } + + @ChannelPipelineCoverage("all") + private static class ParentChannelHandler extends SimpleChannelHandler { + + volatile Channel child; + final StringBuffer result = new StringBuffer(); + + ParentChannelHandler() { + super(); + } + + @Override + public void childChannelClosed(ChannelHandlerContext ctx, + ChildChannelStateEvent e) throws Exception { + result.append('2'); + ctx.sendUpstream(e); + } + + @Override + public void childChannelOpen(ChannelHandlerContext ctx, + ChildChannelStateEvent e) throws Exception { + child = e.getChildChannel(); + result.append('1'); + ctx.sendUpstream(e); + } + } +} diff --git a/src/test/java/org/jboss/netty/util/MapUtilTest.java b/src/test/java/org/jboss/netty/util/MapUtilTest.java index b00c49a15f..2395103e92 100644 --- a/src/test/java/org/jboss/netty/util/MapUtilTest.java +++ b/src/test/java/org/jboss/netty/util/MapUtilTest.java @@ -30,8 +30,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import org.jboss.netty.logging.InternalLoggerFactory; -import org.junit.BeforeClass; import org.junit.Test; @@ -71,11 +69,6 @@ public class MapUtilTest { assertTrue(MapUtil.isOrderedMap(new UnknownOrderedMap())); } - @BeforeClass - public static void setUp() { - InternalLoggerFactory.setDefaultFactory(new SilentLoggerFactory()); - } - interface OrderedMap { // A tag interface } diff --git a/src/test/java/org/jboss/netty/util/SilentLoggerFactory.java b/src/test/java/org/jboss/netty/util/SilentLoggerFactory.java deleted file mode 100644 index 14b884c136..0000000000 --- a/src/test/java/org/jboss/netty/util/SilentLoggerFactory.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * - * Copyright 2008, Red Hat Middleware LLC, and individual contributors - * by the @author tags. See the COPYRIGHT.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.jboss.netty.util; - -import org.jboss.netty.logging.InternalLogger; -import org.jboss.netty.logging.InternalLoggerFactory; - - -/** - * Logger factory which suppresses all log messages. - * - * @author The Netty Project (netty-dev@lists.jboss.org) - * @author Trustin Lee (tlee@redhat.com) - * - * @version $Rev$, $Date$ - * - */ -public class SilentLoggerFactory extends InternalLoggerFactory { - - @Override - public InternalLogger newInstance(final String name) { - return new InternalLogger() { - public void debug(String msg) { - // NOOP - } - - public void debug(String msg, Throwable cause) { - // NOOP - } - - public void error(String msg) { - // NOOP - } - - public void error(String msg, Throwable cause) { - // NOOP - } - - public void info(String msg) { - // NOOP - } - - public void info(String msg, Throwable cause) { - // NOOP - } - - public boolean isDebugEnabled() { - return true; - } - - public boolean isErrorEnabled() { - return true; - } - - public boolean isInfoEnabled() { - return true; - } - - public boolean isWarnEnabled() { - return true; - } - - public void warn(String msg) { - // NOOP - } - - public void warn(String msg, Throwable cause) { - // NOOP - } - - @Override - public String toString() { - return name; - } - }; - } -}