/* * JBoss, Home of Professional Open Source. * Copyright 2013 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * Licensed 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 org.xnio.nio.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.SocketAddress; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.xnio.ChannelListener; import org.xnio.FutureResult; import org.xnio.IoFuture; import org.xnio.LocalSocketAddress; import org.xnio.Option; import org.xnio.OptionMap; import org.xnio.Options; import org.xnio.StreamConnection; import org.xnio.XnioWorker; import org.xnio.channels.AcceptingChannel; import org.xnio.channels.StreamSinkChannel; import org.xnio.channels.StreamSourceChannel; /** * Tests a pair of connected TCP connections (client/server). * * @author <a href="mailto:frainone@redhat.com">Flavia Rainone</a> */ public class TcpConnectionTestCase extends AbstractStreamSinkSourceChannelTest<StreamSinkChannel, StreamSourceChannel> { protected SocketAddress bindAddress; protected StreamConnection connection = null; protected StreamConnection serverConnection = null; protected AcceptingChannel<? extends StreamConnection> server; @Before public void createServer() throws IOException { bindAddress = new InetSocketAddress(Inet4Address.getByAddress(new byte[] { 127, 0, 0, 1 }), 12345); final ChannelListener<AcceptingChannel<StreamConnection>> acceptingChannelListener = new TestChannelListener<AcceptingChannel<StreamConnection>>();; server = worker.createStreamConnectionServer( bindAddress, acceptingChannelListener, OptionMap.EMPTY); assertNotNull(server); } @After public void closeServer() throws IOException { if (server != null) { server.close(); } } @Override protected synchronized void initChannels(XnioWorker xnioWorker, OptionMap optionMap, TestChannelListener<StreamSinkChannel> channelListener, TestChannelListener<StreamSourceChannel> serverChannelListener) throws IOException { if (connection != null) { connection.close(); serverConnection.close(); } final IoFuture<StreamConnection> openedConnection = xnioWorker.openStreamConnection(bindAddress, null, optionMap); final FutureResult<StreamConnection> accepted = new FutureResult<StreamConnection>(xnioWorker); server.getAcceptSetter().set(new ChannelListener<AcceptingChannel<? extends StreamConnection>>() { public void handleEvent(final AcceptingChannel<? extends StreamConnection> channel) { try { accepted.setResult(server.accept()); } catch (IOException e) { accepted.setException(e); } } }); server.resumeAccepts(); serverConnection = accepted.getIoFuture().get(); connection = openedConnection.get(); assertNotNull(serverConnection); assertNotNull(connection); channelListener.handleEvent(connection.getSinkChannel()); serverChannelListener.handleEvent(serverConnection.getSourceChannel()); } @Test @Ignore("unreliable") public void optionSetup() throws IOException { initChannels(); final Option<?>[] unsupportedOptions = OptionHelper.getNotSupportedOptions(Options.CLOSE_ABORT, Options.IP_TRAFFIC_CLASS, Options.KEEP_ALIVE, Options.READ_TIMEOUT, Options.RECEIVE_BUFFER, Options.RECEIVE_BUFFER, Options.SEND_BUFFER, Options.TCP_NODELAY, Options.TCP_OOB_INLINE, Options.WRITE_TIMEOUT); for (Option<?> option: unsupportedOptions) { assertFalse("Channel supports " + option, connection.supportsOption(option)); assertNull("Expected null value for option " + option + " but got " + connection.getOption(option) + " instead", connection.getOption(option)); } assertTrue(connection.supportsOption(Options.CLOSE_ABORT)); assertFalse(connection.getOption(Options.CLOSE_ABORT)); assertTrue(connection.supportsOption(Options.IP_TRAFFIC_CLASS)); assertEquals(0, (int) connection.getOption(Options.IP_TRAFFIC_CLASS)); assertTrue(connection.supportsOption(Options.KEEP_ALIVE)); assertFalse(connection.getOption(Options.KEEP_ALIVE)); assertTrue(connection.supportsOption(Options.READ_TIMEOUT)); assertEquals(0, (int) connection.getOption(Options.READ_TIMEOUT)); assertTrue(connection.supportsOption(Options.RECEIVE_BUFFER)); assertTrue(connection.getOption(Options.RECEIVE_BUFFER) > 0); assertTrue(connection.supportsOption(Options.SEND_BUFFER)); assertTrue(connection.getOption(Options.SEND_BUFFER) > 0); assertTrue(connection.supportsOption(Options.TCP_NODELAY)); assertNotNull(connection.getOption(Options.TCP_NODELAY)); assertTrue(connection.supportsOption(Options.TCP_OOB_INLINE)); assertFalse(connection.getOption(Options.TCP_OOB_INLINE)); assertTrue(connection.supportsOption(Options.WRITE_TIMEOUT)); assertEquals(0, (int) connection.getOption(Options.WRITE_TIMEOUT)); connection.setOption(Options.CLOSE_ABORT, true); connection.setOption(Options.IP_TRAFFIC_CLASS, 5); connection.setOption(Options.KEEP_ALIVE, true); connection.setOption(Options.READ_TIMEOUT, 234095747); connection.setOption(Options.RECEIVE_BUFFER, 5000); connection.setOption(Options.SEND_BUFFER, 3000); connection.setOption(Options.TCP_NODELAY, true); connection.setOption(Options.TCP_OOB_INLINE, true); connection.setOption(Options.WRITE_TIMEOUT, 1301093); assertNull("Unexpected option value: " + connection.getOption(Options.MAX_INBOUND_MESSAGE_SIZE), connection.setOption(Options.MAX_INBOUND_MESSAGE_SIZE, 50000));// unsupported assertTrue(connection.getOption(Options.CLOSE_ABORT)); assertTrue(connection.getOption(Options.IP_TRAFFIC_CLASS) >= 0);// it is okay that 5 is not returned // 5 value will only be set if the channels' family equals StandardProtocolFamily.INET assertTrue(connection.getOption(Options.KEEP_ALIVE)); assertEquals(234095747, (int) connection.getOption(Options.READ_TIMEOUT)); assertTrue(connection.getOption(Options.RECEIVE_BUFFER) > 0); assertTrue(connection.getOption(Options.SEND_BUFFER) >= 3000); assertTrue(connection.getOption(Options.TCP_NODELAY)); assertTrue(connection.getOption(Options.TCP_OOB_INLINE)); assertEquals(1301093, (int) connection.getOption(Options.WRITE_TIMEOUT)); assertTrue(connection.getOption(Options.CLOSE_ABORT)); assertNull(connection.getOption(Options.MAX_INBOUND_MESSAGE_SIZE));// unsupported assertTrue(connection.setOption(Options.CLOSE_ABORT, false)); assertTrue(connection.setOption(Options.IP_TRAFFIC_CLASS, 30) >= 0); assertTrue(connection.setOption(Options.KEEP_ALIVE, false)); assertEquals(234095747, (int) connection.setOption(Options.READ_TIMEOUT, 1290455)); assertTrue(connection.setOption(Options.RECEIVE_BUFFER, 3000) >= 5000); assertTrue(connection.setOption(Options.SEND_BUFFER, 5000) >= 3000); assertTrue(connection.setOption(Options.TCP_NODELAY, false)); assertTrue(connection.setOption(Options.TCP_OOB_INLINE, false)); assertEquals(1301093, (int) connection.setOption(Options.WRITE_TIMEOUT, 293265)); assertFalse(connection.getOption(Options.CLOSE_ABORT)); assertTrue(connection.getOption(Options.IP_TRAFFIC_CLASS) >= 0); assertFalse(connection.getOption(Options.KEEP_ALIVE)); assertEquals(1290455, (int) connection.getOption(Options.READ_TIMEOUT)); assertTrue(connection.getOption(Options.RECEIVE_BUFFER) > 0); assertEquals(5000, (int) connection.getOption(Options.SEND_BUFFER)); assertFalse(connection.getOption(Options.TCP_NODELAY)); assertFalse(connection.getOption(Options.TCP_OOB_INLINE)); assertEquals(293265, (int) connection.getOption(Options.WRITE_TIMEOUT)); assertFalse(connection.setOption(Options.CLOSE_ABORT, null)); assertFalse(connection.setOption(Options.KEEP_ALIVE, null)); assertEquals(1290455, (int) connection.setOption(Options.READ_TIMEOUT, null)); assertFalse(connection.setOption(Options.TCP_NODELAY, null)); assertFalse(connection.setOption(Options.TCP_OOB_INLINE, null)); assertEquals(293265, (int) connection.setOption(Options.WRITE_TIMEOUT, null)); assertFalse(connection.getOption(Options.CLOSE_ABORT)); assertTrue((int) connection.getOption(Options.IP_TRAFFIC_CLASS) >= 0); assertFalse(connection.getOption(Options.KEEP_ALIVE)); assertEquals(0, (int) connection.getOption(Options.READ_TIMEOUT)); assertTrue(connection.getOption(Options.RECEIVE_BUFFER) > 0); assertTrue(connection.getOption(Options.SEND_BUFFER) > 0); assertNotNull(connection.getOption(Options.TCP_NODELAY)); assertFalse(connection.getOption(Options.TCP_OOB_INLINE)); assertEquals(0, (int) connection.getOption(Options.WRITE_TIMEOUT)); } @Test public void channelAddress() throws IOException { initChannels(); assertEquals(bindAddress, connection.getPeerAddress()); assertEquals(bindAddress, connection.getPeerAddress(InetSocketAddress.class)); assertNull(connection.getPeerAddress(LocalSocketAddress.class)); final SocketAddress clientAddress = connection.getLocalAddress(); assertNotNull(clientAddress); assertEquals(clientAddress, connection.getLocalAddress((InetSocketAddress.class))); assertNull(connection.getLocalAddress((LocalSocketAddress.class))); assertNotNull(connection.toString()); } }