/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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 org.apache.harmony.nio.tests.java.nio.channels; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.BindException; import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.AlreadyConnectedException; import java.nio.channels.ClosedChannelException; import java.nio.channels.ConnectionPendingException; import java.nio.channels.IllegalBlockingModeException; import java.nio.channels.NoConnectionPendingException; import java.nio.channels.NotYetConnectedException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.channels.UnresolvedAddressException; import java.nio.channels.UnsupportedAddressTypeException; import java.nio.channels.spi.SelectorProvider; import junit.framework.TestCase; import tests.support.Support_PortManager; /** * Tests for SocketChannel and its default implementation. */ public class SocketChannelTest extends TestCase { private static final int CAPACITY_NORMAL = 200; private InetSocketAddress localAddr1; private InetSocketAddress localAddr2; private SocketChannel channel1; private SocketChannel channel2; private ServerSocket server1; private ServerSocket server2; private final static int TIMEOUT = 60000; private final static int EOF = -1; protected void setUp() throws Exception { super.setUp(); this.localAddr1 = new InetSocketAddress("127.0.0.1", Support_PortManager.getNextPort()); this.localAddr2 = new InetSocketAddress("127.0.0.1", Support_PortManager.getNextPort()); this.channel1 = SocketChannel.open(); this.channel2 = SocketChannel.open(); this.server1 = new ServerSocket(localAddr1.getPort()); } protected void tearDown() throws Exception { super.tearDown(); if (null != this.channel1) { try { this.channel1.close(); } catch (Exception e) { //ignore } } if (null != this.channel2) { try { this.channel2.close(); } catch (Exception e) { //ignore } } if (null != this.server1) { try { this.server1.close(); } catch (Exception e) { //ignore } } if (null != this.server2) { try { this.server2.close(); } catch (Exception e) { //ignore } } } // ------------------------------------------------------------------- // Test for methods in abstract class. // ------------------------------------------------------------------- /* * Test method for 'java.nio.channels.SocketChannel.validOps()' */ public void testValidOps() { MockSocketChannel testMSChannel = new MockSocketChannel(null); assertEquals(13, this.channel1.validOps()); assertEquals(13, testMSChannel.validOps()); } /* * Test method for 'java.nio.channels.SocketChannel.open()' */ public void testOpen() throws IOException { java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1]; buf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL); MockSocketChannel testMSChannel = new MockSocketChannel(null); MockSocketChannel testMSChannelnotnull = new MockSocketChannel( SelectorProvider.provider()); assertNull(testMSChannel.provider()); assertNotNull(testMSChannelnotnull.provider()); assertNotNull(this.channel1); assertEquals(this.channel1.provider(), testMSChannelnotnull.provider()); try { this.channel1.write(buf); fail("Should throw NotYetConnectedException"); } catch (NotYetConnectedException e) { // correct } } /* * Test method for 'java.nio.channels.SocketChannel.open(SocketAddress)' */ public void testOpenSocketAddress_Null() throws IOException { SocketChannel channel1IP = null; try { channel1IP = SocketChannel.open(null); fail("Should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { // correct } assertNull(channel1IP); } /* * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])' */ public void testReadByteBufferArray() throws IOException { java.nio.ByteBuffer[] byteBuf = null; MockSocketChannel testMSChannelnull = new MockSocketChannel(null); MockSocketChannel testMSChannel = new MockSocketChannel( SelectorProvider.provider()); ServerSocket testServer = new ServerSocket(Support_PortManager .getNextPort()); try { try { this.channel1.read(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL]; try { this.channel1.read(byteBuf); fail("Should throw NotYetConnectedException"); } catch (NotYetConnectedException e) { // correct } long readNum = CAPACITY_NORMAL; readNum = testMSChannel.read(byteBuf); assertEquals(0, readNum); readNum = CAPACITY_NORMAL; readNum = testMSChannelnull.read(byteBuf); assertEquals(0, readNum); } finally { testServer.close(); } } /* * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])' */ public void testReadByteBufferArray_BufNull() throws IOException { java.nio.ByteBuffer[] byteBuf = null; MockSocketChannel testMSChannelnull = new MockSocketChannel(null); MockSocketChannel testMSChannel = new MockSocketChannel( SelectorProvider.provider()); try { this.channel1.read(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } try { testMSChannel.read(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } try { testMSChannelnull.read(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } } /* * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])' */ public void testWriteByteBufferArray() throws IOException { java.nio.ByteBuffer[] byteBuf = null; MockSocketChannel testMSChannelnull = new MockSocketChannel(null); MockSocketChannel testMSChannel = new MockSocketChannel( SelectorProvider.provider()); try { this.channel1.write(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL]; try { this.channel1.write(byteBuf); fail("Should throw NotYetConnectedException"); } catch (NotYetConnectedException e) { // correct } testMSChannel.write(byteBuf); testMSChannelnull.write(byteBuf); } /* * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])' */ public void testWriteByteBufferArray_BufNull() throws IOException { java.nio.ByteBuffer[] byteBuf = null; MockSocketChannel testMSChannelnull = new MockSocketChannel(null); MockSocketChannel testMSChannel = new MockSocketChannel( SelectorProvider.provider()); try { this.channel1.write(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } try { testMSChannel.write(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } try { testMSChannelnull.write(byteBuf); fail("Should throw NPE"); } catch (NullPointerException e) { // correct } } public void testSocket_BasicStatusBeforeConnect() throws IOException { assertFalse(this.channel1.isConnected());// not connected Socket s1 = this.channel1.socket(); assertSocketBeforeConnect(s1); Socket s2 = this.channel1.socket(); // same assertSame(s1, s2); } public void testSocket_Block_BasicStatusAfterConnect() throws IOException { assertFalse(this.channel1.isConnected());// not connected assertTrue(this.channel1.connect(localAddr1)); assertTrue(this.channel1.isConnected()); Socket s1 = this.channel1.socket(); assertSocketAfterConnect(s1, localAddr1); Socket s2 = this.channel1.socket(); // same assertSame(s1, s2); } public void testSocket_NonBlock_BasicStatusAfterConnect() throws Exception { assertFalse(this.channel1.isConnected());// not connected this.channel1.configureBlocking(false); boolean connected = channel1.connect(localAddr1); Socket s1 = null; Socket s2 = null; if (!connected) { assertFalse(this.channel1.isConnected()); assertTrue(this.channel1.isConnectionPending()); s1 = this.channel1.socket(); // status of not connected assertSocketBeforeConnect(s1); s2 = this.channel1.socket(); // same assertSame(s1, s2); } if (tryFinish()) { assertTrue(this.channel1.isConnected()); s1 = this.channel1.socket(); assertSocketAfterConnect(s1, localAddr1); s2 = this.channel1.socket(); // same assertSame(s1, s2); } } public void testSocket_Block_ActionsBeforeConnect() throws IOException { assertFalse(this.channel1.isConnected());// not connected Socket s = this.channel1.socket(); assertSocketAction_Block_BeforeConnect(s); } public void testSocket_Block_ActionsAfterConnect() throws IOException { assertFalse(this.channel1.isConnected());// not connected assertTrue(this.channel1.connect(localAddr1)); assertTrue(this.channel1.isConnected()); Socket s = this.channel1.socket(); assertSocketAction_Block_AfterConnect(s); } public void testSocket_NonBlock_ActionsAfterConnectBeforeFinish() throws IOException { assertFalse(this.channel1.isConnected());// not connected this.channel1.configureBlocking(false); boolean connected = channel1.connect(localAddr1); if (!connected) { assertFalse(this.channel1.isConnected()); assertTrue(this.channel1.isConnectionPending()); Socket s1 = this.channel1.socket(); // Action of not connected assertSocketAction_NonBlock_BeforeConnect(s1); Socket s2 = this.channel1.socket(); // same assertSame(s1, s2); } } public void testSocket_NonBlock_ActionsAfterConnectAfterFinish() throws Exception { assertFalse(this.channel1.isConnected());// not connected this.channel1.configureBlocking(false); channel1.connect(localAddr1); if (tryFinish()) { Socket s1 = this.channel1.socket(); assertSocketAction_NonBlock_AfterConnect(s1); Socket s2 = this.channel1.socket(); // same assertSame(s1, s2); } } public void testSocket_getInetAddress() throws Exception { Socket socket = channel1.socket(); assertNull(socket.getInetAddress()); channel1.connect(localAddr1); assertNotNull(socket.getInetAddress()); assertEquals(localAddr1.getAddress(), socket.getInetAddress()); } public void testSocket_getRemoteSocketAddress() throws Exception { Socket socket = channel1.socket(); assertNull(socket.getRemoteSocketAddress()); channel1.connect(localAddr1); assertNotNull(socket.getRemoteSocketAddress()); assertEquals(localAddr1, socket.getRemoteSocketAddress()); } public void testSocket_getPort() throws Exception { Socket socket = channel1.socket(); assertEquals(0, socket.getPort()); channel1.connect(localAddr1); assertEquals(localAddr1.getPort(), socket.getPort()); } public void testSocket_getLocalAddress() throws Exception { Socket socket = channel1.socket(); assertNotNull(socket.getLocalAddress()); channel1.connect(localAddr1); assertNotNull(socket.getLocalAddress()); } public void testSocket_getLocalSocketAddress() throws Exception { Socket socket = channel1.socket(); assertNull(socket.getLocalSocketAddress()); channel1.connect(localAddr1); assertNotNull(socket.getLocalSocketAddress()); } public void testSocket_getLocalPort() throws Exception { Socket socket = channel1.socket(); assertEquals(-1, socket.getLocalPort()); channel1.connect(localAddr1); assertTrue(-1 != socket.getLocalPort()); assertTrue(0 != socket.getLocalPort()); } public void testSocket_bind() throws Exception { Socket socket = channel1.socket(); socket.bind(new InetSocketAddress("127.0.0.1", 0)); assertEquals("127.0.0.1", socket.getLocalAddress().getHostAddress()); assertTrue(socket.getLocalPort() != -1); } private void assertSocketBeforeConnect(Socket s) throws IOException { assertFalse(s.isBound()); assertFalse(s.isClosed()); assertFalse(s.isConnected()); assertFalse(s.getKeepAlive()); try { s.getInputStream(); fail("Should throw SocketException."); } catch (SocketException e) { // OK. } assertFalse(s.getOOBInline()); try { s.getOutputStream(); fail("Should throw SocketException."); } catch (SocketException e) { // OK. } assertEquals(-1, s.getSoLinger()); assertFalse(s.getTcpNoDelay()); assertFalse(s.isInputShutdown()); assertFalse(s.isOutputShutdown()); assertNull(s.getInetAddress()); assertEquals(s.getLocalAddress().getHostAddress(), "0.0.0.0"); // RI fails here. RI returns 0 while spec says unbound socket should // return -1. assertEquals(-1, s.getLocalPort()); assertFalse(s.getReuseAddress()); assertNull(s.getLocalSocketAddress()); // not connected assertEquals(0, s.getPort()); assertTrue(s.getReceiveBufferSize() >= 8192); assertNull(s.getRemoteSocketAddress()); assertTrue(s.getSendBufferSize() >= 8192); assertEquals(0, s.getSoTimeout()); assertEquals(0, s.getTrafficClass()); } private void assertSocketAfterConnect(Socket s, InetSocketAddress address) throws IOException { assertTrue(s.isBound()); assertFalse(s.isClosed()); assertTrue(s.isConnected()); assertFalse(s.getKeepAlive()); assertNotNull(s.getInputStream()); assertNotNull(s.getOutputStream()); assertFalse(s.getOOBInline()); assertEquals(-1, s.getSoLinger()); assertFalse(s.getTcpNoDelay()); assertFalse(s.isInputShutdown()); assertFalse(s.isOutputShutdown()); assertSame(s.getInetAddress(), address.getAddress()); assertEquals(s.getLocalAddress(), this.localAddr1.getAddress()); assertEquals(s.getPort(), address.getPort()); assertNotNull(s.getLocalSocketAddress()); assertTrue(s.getReceiveBufferSize() >= 8192); assertEquals(s.getRemoteSocketAddress(), (SocketAddress) address); // assertFalse(s.getReuseAddress()); assertTrue(s.getSendBufferSize() >= 8192); assertEquals(0, s.getSoTimeout()); assertEquals(0, s.getTrafficClass()); } private void assertSocketAction_Block_BeforeConnect(Socket s) throws IOException { assertFalse(this.channel1.isConnected()); this.server2 = new ServerSocket(localAddr2.getPort()); s.connect(localAddr2); assertTrue(this.channel1.isConnected()); assertTrue(s.isConnected()); assertSocketAfterConnect(s, localAddr2); try { s.bind(localAddr2); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // OK. } s.close(); assertTrue(s.isClosed()); assertFalse(this.channel1.isOpen()); } private void assertSocketAction_NonBlock_BeforeConnect(Socket s) throws IOException { assertFalse(this.channel1.isConnected()); this.server2 = new ServerSocket(localAddr2.getPort()); try { s.connect(localAddr2); fail("Should throw IllegalBlockingModeException"); } catch (IllegalBlockingModeException e1) { // OK. } if (this.channel1.isConnectionPending()) { try { s.bind(localAddr2); fail("Should throw ConnectionPendingException"); } catch (ConnectionPendingException e1) { // OK. } } else { try { s.bind(localAddr2); fail("Should throw BindException"); } catch (BindException e1) { // OK. } } assertFalse(this.channel1.isConnected()); assertFalse(s.isConnected()); s.close(); assertTrue(s.isClosed()); assertFalse(this.channel1.isOpen()); } private void assertSocketAction_Block_AfterConnect(Socket s) throws IOException { assertEquals(s.getPort(), localAddr1.getPort()); assertTrue(this.channel1.isConnected()); assertTrue(s.isConnected()); try { s.connect(localAddr2); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // OK. } try { s.bind(localAddr2); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // OK. } s.close(); assertTrue(s.isClosed()); assertFalse(this.channel1.isOpen()); } private void assertSocketAction_NonBlock_AfterConnect(Socket s) throws IOException { assertEquals(s.getPort(), localAddr1.getPort()); assertTrue(this.channel1.isConnected()); assertTrue(s.isConnected()); if (this.channel1.isConnectionPending()) { try { s.connect(localAddr2); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // OK. } } else { try { s.connect(localAddr2); fail("Should throw IllegalBlockingModeException"); } catch (IllegalBlockingModeException e) { // OK. } } try { s.bind(localAddr2); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // OK. } s.close(); assertTrue(s.isClosed()); assertFalse(this.channel1.isOpen()); } // ------------------------------------------------------------------- // Tests for connect(), finishConnect(),isConnected(),isConnectionPending() // These methods are very close, so we test them together, call them "CFII". // ------------------------------------------------------------------- /** * connect-->finish-->close */ public void testCFII_Norml_NoServer_Block() throws Exception { // ensure ensureServerClosed(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect try { this.channel1.connect(localAddr1); fail("Should throw a ConnectException here."); } catch (ConnectException e) { // OK. } statusChannelClosed(); try { this.channel1.finishConnect(); fail("Should throw a ClosedChannelException here."); } catch (ClosedChannelException e) { // OK. } } /** * connect-->finish-->close */ public void testCFII_Norml_NoServer_NonBlock() throws Exception { connectNoServerNonBlock(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->close */ public void testCFII_Norml_Server_Block() throws Exception { connectServerBlock(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->close */ public void testCFII_Norml_Server_NonBlock() throws Exception { connectServerNonBlock(); this.channel1.close(); statusChannelClosed(); } /** * connect-->server closed-->finish-->close */ public void testCFII_ServerClosed_Block() throws Exception { // ensure ensureServerOpen(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect assertTrue(this.channel1.connect(localAddr1)); statusConnected_NotPending(); ensureServerClosed(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * connect-->server closed-->finish-->close */ public void testCFII_ServerClosed_NonBlock() throws Exception { // ensure ensureServerOpen(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect boolean connected = channel1.connect(localAddr1); if (!connected) { statusNotConnected_Pending(); } ensureServerClosed(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->server closed-->close */ public void testCFII_ServerClosedAfterFinish_Block() throws Exception { connectServerBlock(); ensureServerClosed(); assertTrue(this.channel1.isOpen()); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->server closed-->close */ public void testCFII_ServerClosedAfterFinish_NonBlock() throws Exception { connectServerNonBlock(); ensureServerClosed(); assertTrue(this.channel1.isOpen()); this.channel1.close(); statusChannelClosed(); } /** * no server-->connect-->server open-->finish-->close */ public void testCFII_ServerStartLater_Block() throws Exception { // ensure ensureServerClosed(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect try { this.channel1.connect(localAddr1); fail("Should throw a ConnectException here."); } catch (ConnectException e) { // OK. } statusChannelClosed(); ensureServerOpen(); try { this.channel1.finishConnect(); fail("Should throw a ClosedChannelException here."); } catch (ClosedChannelException e) { // OK. } } /** * no server-->connect-->server open-->finish-->close */ public void testCFII_ServerStartLater_NonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); ensureServerOpen(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); this.channel1.close(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } } /** * connect-->finish-->finish-->close */ public void testCFII_FinishTwice_NoServer_NonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); this.channel1.close(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } statusChannelClosed(); } /** * connect-->finish-->finish-->close */ public void testCFII_FinishTwice_Server_Block() throws Exception { connectServerBlock(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->finish-->close */ public void testCFII_FinishTwice_Server_NonBlock() throws Exception { connectServerNonBlock(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->connect-->close */ public void testCFII_ConnectAfterFinish_NoServer_Block() throws Exception { // ensure ensureServerClosed(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect try { this.channel1.connect(localAddr1); fail("Should throw a ConnectException here."); } catch (ConnectException e) { // OK. } statusChannelClosed(); try { this.channel1.finishConnect(); fail("Should throw a ClosedChannelException here."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); try { this.channel1.connect(localAddr1); fail("Should throw a ClosedChannelException here."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); } /** * connect-->finish-->connect-->close */ public void testCFII_ConnectAfterFinish_NoServer_NonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } if (this.channel1.isOpen()) { try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); this.channel1.close(); } statusChannelClosed(); } /** * connect-->finish-->connect-->close */ public void testCFII_ConnectAfterFinish_Server_Block() throws Exception { connectServerBlock(); if (!this.channel1.isConnected()) { System.err .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished."); return; } try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); this.channel1.close(); statusChannelClosed(); } /** * connect-->finish-->connect-->close */ public void testCFII_ConnectAfterFinish_Server_NonBlock() throws Exception { connectServerNonBlock(); if (!this.channel1.isConnected()) { System.err .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished."); return; } try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException or a ConnectionPendingException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); this.channel1.close(); statusChannelClosed(); } /** * connect-->connect-->finish-->close */ public void testCFII_ConnectTwice_NoServer_NonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); this.channel1.close(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } statusChannelClosed(); } /** * connect-->connect-->finish-->close */ public void testCFII_ConnectTwice_Server_Block() throws Exception { // ensure ensureServerOpen(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect assertTrue(this.channel1.connect(localAddr1)); statusConnected_NotPending(); try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw an AlreadyConnectedException here."); } catch (AlreadyConnectedException e) { // OK. } statusConnected_NotPending(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * connect-->connect-->finish-->close */ public void testCFII_ConnectTwice_Server_NonBlock() throws Exception { // ensure ensureServerOpen(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect boolean connected = channel1.connect(localAddr1); if (!connected) { statusNotConnected_Pending(); try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect another addr try { this.channel1.connect(localAddr2); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); // connect if server closed ensureServerClosed(); try { this.channel1.connect(localAddr1); fail("Should throw a ConnectionPendingException here."); } catch (ConnectionPendingException e) { // OK. } statusNotConnected_Pending(); } tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * finish-->connect-->finish-->close */ public void testCFII_FinishFirst_NoServer_Block() throws Exception { // ensure ensureServerClosed(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // finish try { this.channel1.finishConnect(); fail("Should throw NoConnectionPendingException"); } catch (NoConnectionPendingException e) { // OK. } statusNotConnected_NotPending(); // connect try { this.channel1.connect(localAddr1); fail("Should throw a ConnectException here."); } catch (ConnectException e) { // OK. } statusChannelClosed(); try { this.channel1.finishConnect(); fail("Should throw a ClosedChannelException here."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); } /** * finish-->connect-->finish-->close */ public void testCFII_FinishFirst_NoServer_NonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // finish try { this.channel1.finishConnect(); fail("Should throw NoConnectionPendingException"); } catch (NoConnectionPendingException e) { // OK. } statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); this.channel1.close(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } statusChannelClosed(); } /** * finish-->connect-->finish-->close */ public void testCFII_FinishFirst_Server_Block() throws Exception { // ensure ensureServerOpen(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // finish try { this.channel1.finishConnect(); fail("Should throw NoConnectionPendingException"); } catch (NoConnectionPendingException e) { // OK. } statusNotConnected_NotPending(); // connect assertTrue(this.channel1.connect(localAddr1)); statusConnected_NotPending(); tryFinish(); this.channel1.close(); statusChannelClosed(); } /** * finish-->connect-->finish-->close */ public void testCFII_FinishFirst_Server_NonBlock() throws Exception { // ensure ensureServerOpen(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // finish try { this.channel1.finishConnect(); fail("Should throw NoConnectionPendingException"); } catch (NoConnectionPendingException e) { // OK. } statusNotConnected_NotPending(); // connect boolean connected = channel1.connect(localAddr1); if (!connected) { statusNotConnected_Pending(); } tryFinish(); this.channel1.close(); statusChannelClosed(); } public void testCFII_Null() throws Exception { statusNotConnected_NotPending(); try { this.channel1.connect(null); fail("Should throw an IllegalArgumentException here."); } catch (IllegalArgumentException e) { // OK. } } public void testCFII_UnsupportedType() throws Exception { class SubSocketAddress extends SocketAddress { private static final long serialVersionUID = 1L; //empty public SubSocketAddress() { super(); } } statusNotConnected_NotPending(); SocketAddress newTypeAddress = new SubSocketAddress(); try { this.channel1.connect(newTypeAddress); fail("Should throw an UnsupportedAddressTypeException here."); } catch (UnsupportedAddressTypeException e) { // OK. } } public void testCFII_Unresolved() throws IOException { statusNotConnected_NotPending(); InetSocketAddress unresolved = new InetSocketAddress( "unresolved address", 1080); try { this.channel1.connect(unresolved); fail("Should throw an UnresolvedAddressException here."); } catch (UnresolvedAddressException e) { // OK. } } public void testCFII_EmptyHost() throws Exception { statusNotConnected_NotPending(); ServerSocket server = new ServerSocket(0); int port = server.getLocalPort(); server.close(); try { this.channel1.connect(new InetSocketAddress("", port)); fail("Should throw ConnectException"); } catch (ConnectException e) { // correct } } public void testCFII_CloseFirst() throws Exception { this.channel1.close(); statusChannelClosed(); ensureServerOpen(); try { this.channel1.connect(localAddr1); fail("Should throw ClosedChannelException."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); try { this.channel1.finishConnect(); fail("Should throw ClosedChannelException."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); try { this.channel1.configureBlocking(false); fail("Should throw ClosedChannelException."); } catch (ClosedChannelException e) { // OK. } statusChannelClosed(); } public void testCFII_StatusAfterFinish() throws Exception { // 1. close server, finish must return false, check the status ensureServerClosed(); // 1.1 block mode assertTrue(this.channel1.isBlocking()); try { channel1.connect(localAddr1); fail("Should throw ConnectException"); } catch (ConnectException e) { // OK. } assertFalse(this.channel1.isOpen()); assertFalse(this.channel1.isOpen()); assertTrue(this.channel1.isBlocking()); assertFalse(this.channel1.isConnectionPending()); // 1.2 non block mode this.channel1 = SocketChannel.open(); this.channel1.configureBlocking(false); assertFalse(this.channel1.connect(localAddr1)); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); this.channel1.close(); } catch (ConnectException e) { System.out.println(e.getMessage()); } // 2. start server, finish usually return true, check the status ensureServerOpen(); // 2.1 block mode this.channel1 = SocketChannel.open(); assertTrue(this.channel1.isBlocking()); assertTrue(this.channel1.connect(localAddr1)); assertTrue(this.channel1.finishConnect()); statusConnected_NotPending(); this.channel1.close(); // 2.2 non block mode this.channel1 = SocketChannel.open(); this.channel1.configureBlocking(false); assertFalse(this.channel1.connect(localAddr1)); tryFinish(); this.channel1.close(); } private void ensureServerClosed() throws IOException { if (null != this.server1) { this.server1.close(); assertTrue(this.server1.isClosed()); } if (null != this.server2) { this.server2.close(); assertTrue(this.server2.isClosed()); } } private void ensureServerOpen() throws IOException { ensureServerClosed(); this.server1 = new ServerSocket(localAddr1.getPort()); this.server2 = new ServerSocket(localAddr2.getPort()); assertTrue(this.server1.isBound()); assertTrue(this.server2.isBound()); } private void connectNoServerNonBlock() throws Exception { // ensure ensureServerClosed(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect assertFalse(this.channel1.connect(localAddr1)); statusNotConnected_Pending(); try { assertFalse(this.channel1.finishConnect()); statusNotConnected_Pending(); } catch (ConnectException e) { // FIXME: assertEquals(e.getMessage(), "Connection refused"); } } private void connectServerNonBlock() throws Exception { // ensure ensureServerOpen(); this.channel1.configureBlocking(false); statusNotConnected_NotPending(); // connect boolean connected = channel1.connect(localAddr1); if (!connected) { statusNotConnected_Pending(); } tryFinish(); } private void connectServerBlock() throws Exception { // ensure ensureServerOpen(); assertTrue(this.channel1.isBlocking()); statusNotConnected_NotPending(); // connect assertTrue(this.channel1.connect(localAddr1)); statusConnected_NotPending(); tryFinish(); } private void statusChannelClosed() { assertFalse(this.channel1.isConnected()); assertFalse(this.channel1.isConnectionPending()); assertFalse(this.channel1.isOpen()); } private void statusNotConnected_NotPending() { assertFalse(this.channel1.isConnected()); assertFalse(this.channel1.isConnectionPending()); assertTrue(this.channel1.isOpen()); } private void statusNotConnected_Pending() { assertFalse(this.channel1.isConnected()); assertTrue(this.channel1.isConnectionPending()); assertTrue(this.channel1.isOpen()); } private void statusConnected_NotPending() { assertTrue(this.channel1.isConnected()); assertFalse(this.channel1.isConnectionPending()); assertTrue(this.channel1.isOpen()); } private boolean tryFinish() throws IOException { /* * the result of finish will be asserted in multi-thread tests. */ boolean connected = false; assertTrue(this.channel1.isOpen()); try { connected = this.channel1.finishConnect(); } catch (SocketException e) { // Finish connection failed, probably due to reset by peer error. } if (connected) { statusConnected_NotPending(); } return connected; } // ------------------------------------------------------------------- // Original tests. Test method for CFII with real data. // ------------------------------------------------------------------- /** * * 'SocketChannelImpl.connect(SocketAddress)' */ public void testCFII_Data_ConnectWithServer() throws Exception { ensureServerOpen(); java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer .allocate(CAPACITY_NORMAL); java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1]; writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL); assertFalse(this.channel1.isRegistered()); assertTrue(this.channel1.isBlocking()); this.channel1.connect(localAddr1); assertTrue(this.channel1.isBlocking()); assertTrue(this.channel1.isConnected()); assertFalse(this.channel1.isConnectionPending()); assertTrue(this.channel1.isOpen()); assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf)); assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1)); this.channel1.configureBlocking(false); try { this.channel1.connect(localAddr1); fail("Should throw AlreadyConnectedException"); } catch (AlreadyConnectedException e) { // correct } assertFalse(this.channel1.isRegistered()); tryFinish(); } /* * Test method for 'SocketChannelImpl.connect(SocketAddress)' */ public void testCFII_Data_ConnectWithServer_nonBlocking() throws Exception { ensureServerOpen(); java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer .allocate(CAPACITY_NORMAL); java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1]; writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL); assertFalse(this.channel1.isRegistered()); assertTrue(this.channel1.isBlocking()); this.channel1.configureBlocking(false); this.channel1.connect(localAddr1); assertFalse(this.channel1.isBlocking()); boolean connected = channel1.isConnected(); if (!connected) { assertTrue(this.channel1.isConnectionPending()); assertTrue(this.channel1.isOpen()); } if (tryFinish()) { assertEqual