1a9a57f2581773484d13e160fd3407692e825971aElliott Hughes/* 2a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Copyright (C) 2009 The Android Open Source Project 3f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 4a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * you may not use this file except in compliance with the License. 6a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * You may obtain a copy of the License at 7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 8a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 10a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Unless required by applicable law or agreed to in writing, software 11a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * See the License for the specific language governing permissions and 14a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * limitations under the License. 15a9a57f2581773484d13e160fd3407692e825971aElliott Hughes */ 16a9a57f2581773484d13e160fd3407692e825971aElliott Hughes 174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.net; 18a9a57f2581773484d13e160fd3407692e825971aElliott Hughes 190371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.IOException; 200371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.InputStream; 210371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.OutputStream; 224557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.ConnectException; 234557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.InetAddress; 244557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.InetSocketAddress; 254557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.ServerSocket; 264557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.Socket; 274557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketAddress; 284557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketException; 294557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketImpl; 308cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughesimport java.nio.channels.ServerSocketChannel; 318cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughesimport java.nio.channels.SocketChannel; 32ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilsonimport java.util.concurrent.Callable; 33ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilsonimport java.util.concurrent.ExecutorService; 34ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilsonimport java.util.concurrent.Executors; 35ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilsonimport java.util.concurrent.Future; 368cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 37a9a57f2581773484d13e160fd3407692e825971aElliott Hughespublic class SocketTest extends junit.framework.TestCase { 38c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes // See http://b/2980559. 39c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes public void test_close() throws Exception { 40c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes Socket s = new Socket(); 41c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes s.close(); 42c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes // Closing a closed socket does nothing. 43c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes s.close(); 44c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes } 45c390acc2461cce9edb3209caca28d95ed6aabd90Elliott Hughes 46a9a57f2581773484d13e160fd3407692e825971aElliott Hughes /** 47a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Our getLocalAddress and getLocalPort currently use getsockname(3). 48a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * This means they give incorrect results on closed sockets (as well 49a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * as requiring an unnecessary call into native code). 50a9a57f2581773484d13e160fd3407692e825971aElliott Hughes */ 51a9a57f2581773484d13e160fd3407692e825971aElliott Hughes public void test_getLocalAddress_after_close() throws Exception { 52a9a57f2581773484d13e160fd3407692e825971aElliott Hughes Socket s = new Socket(); 53a9a57f2581773484d13e160fd3407692e825971aElliott Hughes try { 54a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // Bind to an ephemeral local port. 55a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.bind(new InetSocketAddress("localhost", 0)); 56da15009528cc8300a6251f1d0931ac8657c9fc31Elliott Hughes assertTrue(s.getLocalAddress().toString(), s.getLocalAddress().isLoopbackAddress()); 57a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // What local port did we get? 58a9a57f2581773484d13e160fd3407692e825971aElliott Hughes int localPort = s.getLocalPort(); 59a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertTrue(localPort > 0); 60a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // Now close the socket... 61a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.close(); 62a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // The RI returns the ANY address but the original local port after close. 63a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertTrue(s.getLocalAddress().isAnyLocalAddress()); 64a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertEquals(localPort, s.getLocalPort()); 65a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } finally { 66a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.close(); 67a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } 68a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } 69ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes 70ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes // http://code.google.com/p/android/issues/detail?id=7935 71ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes public void test_newSocket_connection_refused() throws Exception { 72ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes try { 73ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes new Socket("localhost", 80); 74ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes fail("connection should have been refused"); 75ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } catch (ConnectException expected) { 76ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } 77ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } 788cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 798cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // http://code.google.com/p/android/issues/detail?id=3123 808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // http://code.google.com/p/android/issues/detail?id=1933 818cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void test_socketLocalAndRemoteAddresses() throws Exception { 828cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes checkSocketLocalAndRemoteAddresses(false); 838cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes checkSocketLocalAndRemoteAddresses(true); 848cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 858cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 868cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void checkSocketLocalAndRemoteAddresses(boolean setOptions) throws Exception { 878cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetAddress host = InetAddress.getLocalHost(); 888cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 898cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // Open a local server port. 908cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ServerSocketChannel ssc = ServerSocketChannel.open(); 918cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress listenAddr = new InetSocketAddress(host, 0); 928cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ssc.socket().bind(listenAddr, 0); 938cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ServerSocket ss = ssc.socket(); 948cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 958cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // Open a socket to the local port. 968cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes SocketChannel out = SocketChannel.open(); 978cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.configureBlocking(false); 988cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (setOptions) { 998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.socket().setTcpNoDelay(false); 1008cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 1018cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress addr = new InetSocketAddress(host, ssc.socket().getLocalPort()); 1028cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.connect(addr); 1038cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes while (!out.finishConnect()) { 1048cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes Thread.sleep(1); 1058cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 1068cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1078cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes SocketChannel in = ssc.accept(); 1088cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (setOptions) { 1098cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes in.socket().setTcpNoDelay(false); 1108cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 1118cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1128cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress outRemoteAddress = (InetSocketAddress) out.socket().getRemoteSocketAddress(); 1138cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress outLocalAddress = (InetSocketAddress) out.socket().getLocalSocketAddress(); 1148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress inLocalAddress = (InetSocketAddress) in.socket().getLocalSocketAddress(); 1158cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress inRemoteAddress = (InetSocketAddress) in.socket().getRemoteSocketAddress(); 1168cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("inLocalAddress: " + inLocalAddress); 1178cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("inRemoteAddress: " + inRemoteAddress); 1188cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("outLocalAddress: " + outLocalAddress); 1198cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("outRemoteAddress: " + outRemoteAddress); 1208cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1218cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outRemoteAddress.getPort(), ss.getLocalPort()); 1228cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inLocalAddress.getPort(), ss.getLocalPort()); 1238cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inRemoteAddress.getPort(), outLocalAddress.getPort()); 1248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1258cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inLocalAddress.getAddress(), ss.getInetAddress()); 1268cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inRemoteAddress.getAddress(), ss.getInetAddress()); 1278cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outLocalAddress.getAddress(), ss.getInetAddress()); 1288cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outRemoteAddress.getAddress(), ss.getInetAddress()); 1298cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1308cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes in.close(); 1318cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.close(); 1328cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ssc.close(); 1338cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1348cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertNull(in.socket().getRemoteSocketAddress()); 1358cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertNull(out.socket().getRemoteSocketAddress()); 1368cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1378cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(in.socket().getLocalSocketAddress(), ss.getLocalSocketAddress()); 1388cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 1390371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1400371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // SocketOptions.setOption has weird behavior for setSoLinger/SO_LINGER. 1410371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // This test ensures we do what the RI does. 1420371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void test_SocketOptions_setOption() throws Exception { 1430371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes class MySocketImpl extends SocketImpl { 1440371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public int option; 1450371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public Object value; 1460371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1470371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public boolean createCalled; 1480371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public boolean createStream; 1490371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1500371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public MySocketImpl() { super(); } 1510371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void accept(SocketImpl arg0) throws IOException { } 1520371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected int available() throws IOException { return 0; } 1530371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void bind(InetAddress arg0, int arg1) throws IOException { } 1540371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void close() throws IOException { } 1550371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(String arg0, int arg1) throws IOException { } 1560371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(InetAddress arg0, int arg1) throws IOException { } 1570371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(SocketAddress arg0, int arg1) throws IOException { } 1580371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected InputStream getInputStream() throws IOException { return null; } 1590371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected OutputStream getOutputStream() throws IOException { return null; } 1600371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void listen(int arg0) throws IOException { } 1610371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void sendUrgentData(int arg0) throws IOException { } 1620371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public Object getOption(int arg0) throws SocketException { return null; } 1630371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1640371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void create(boolean isStream) throws IOException { 1650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.createCalled = true; 1660371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.createStream = isStream; 1670371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1680371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1690371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void setOption(int option, Object value) throws SocketException { 1700371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.option = option; 1710371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.value = value; 1720371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1730371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1740371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes class MySocket extends Socket { 1760371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public MySocket(SocketImpl impl) throws SocketException { 1770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes super(impl); 1780371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1790371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1800371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1810371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes MySocketImpl impl = new MySocketImpl(); 1820371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes Socket s = new MySocket(impl); 1830371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1840371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // Check that, as per the SocketOptions.setOption documentation, we pass false rather 1850371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // than -1 to the SocketImpl when setSoLinger is called with the first argument false. 1860371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, -1); 1870371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1880371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // We also check that SocketImpl.create was called. SocketChannelImpl.SocketAdapter 1890371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // subclasses Socket, and whether or not to call SocketImpl.create is the main behavioral 1900371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // difference. 1910371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(true, impl.createCalled); 1920371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, 0); 1930371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1940371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, 1); 1950371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1960371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1970371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // Check that otherwise, we pass down an Integer. 1980371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(true, 0); 1990371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Integer.valueOf(0), (Integer) impl.value); 2000371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(true, 1); 2010371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Integer.valueOf(1), (Integer) impl.value); 2020371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 2030371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 2040371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void test_setTrafficClass() throws Exception { 2050371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes Socket s = new Socket(); 2060371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setTrafficClass(123); 2070371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(123, s.getTrafficClass()); 2080371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 209ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 210ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson public void testReadAfterClose() throws Exception { 211ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson MockServer server = new MockServer(); 212ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson server.enqueue(new byte[]{5, 3}, 0); 213ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson Socket socket = new Socket("localhost", server.port); 214ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson InputStream in = socket.getInputStream(); 215ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(5, in.read()); 216ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(3, in.read()); 217ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(-1, in.read()); 218ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(-1, in.read()); 219ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson socket.close(); 220ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson in.close(); 221ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 222ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson /* 223ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson * Rather astonishingly, read() doesn't throw even though the stream is 224ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson * closed. This is consistent with the RI's behavior. 225ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson */ 226ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(-1, in.read()); 227ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson assertEquals(-1, in.read()); 228ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 229ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson server.shutdown(); 230ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 231ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 232ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson public void testWriteAfterClose() throws Exception { 233ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson MockServer server = new MockServer(); 234ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson server.enqueue(new byte[0], 3); 235ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson Socket socket = new Socket("localhost", server.port); 236ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson OutputStream out = socket.getOutputStream(); 237ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson out.write(5); 238ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson out.write(3); 239ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson socket.close(); 240ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson out.close(); 241ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 242ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson try { 243ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson out.write(9); 244ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson fail(); 245ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } catch (IOException expected) { 246ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 247ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 248ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson server.shutdown(); 249ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 250ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 251b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson // http://b/5534202 252b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson public void testAvailable() throws Exception { 253b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson for (int i = 0; i < 100; i++) { 254b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson assertAvailableReturnsZeroAfterSocketReadsAllData(); 255b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson System.out.println("Success on rep " + i); 256b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 257b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 258b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson 259b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson private void assertAvailableReturnsZeroAfterSocketReadsAllData() throws Exception { 260b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson final byte[] data = "foo".getBytes(); 261b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson final ServerSocket serverSocket = new ServerSocket(0); 262b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson 263b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson new Thread() { 264b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson @Override public void run() { 265b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson try { 266b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson Socket socket = serverSocket.accept(); 267b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson socket.getOutputStream().write(data); 268b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson socket.close(); 269b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } catch (IOException e) { 270b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson e.printStackTrace(); 271b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 272b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 273b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson }.start(); 274b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson 275b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson Socket socket = new Socket("localhost", serverSocket.getLocalPort()); 276b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson byte[] readBuffer = new byte[128]; 277b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson InputStream in = socket.getInputStream(); 278b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson int total = 0; 279b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson // to prevent available() from cheating after EOF, stop reading before -1 is returned 280b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson while (total < data.length) { 281b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson total += in.read(readBuffer); 282b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 283b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson assertEquals(0, in.available()); 284b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson 285b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson socket.close(); 286b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson serverSocket.close(); 287b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson } 288b1c31fbbba0ff96366b35ab40fd49cce55c9f489Jesse Wilson 289ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson static class MockServer { 290ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson private ExecutorService executor; 291ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson private ServerSocket serverSocket; 292ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson private int port = -1; 293ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 294ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson MockServer() throws IOException { 295ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson executor = Executors.newCachedThreadPool(); 296ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson serverSocket = new ServerSocket(0); 297ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson serverSocket.setReuseAddress(true); 298ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson port = serverSocket.getLocalPort(); 299ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 300ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 301ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson public Future<byte[]> enqueue(final byte[] sendBytes, final int receiveByteCount) 302ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson throws IOException { 303ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson return executor.submit(new Callable<byte[]>() { 304ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson @Override public byte[] call() throws Exception { 305ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson Socket socket = serverSocket.accept(); 306ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson OutputStream out = socket.getOutputStream(); 307ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson out.write(sendBytes); 308ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 309ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson InputStream in = socket.getInputStream(); 310ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson byte[] result = new byte[receiveByteCount]; 311ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson int total = 0; 312ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson while (total < receiveByteCount) { 313ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson total += in.read(result, total, result.length - total); 314ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 315ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson socket.close(); 316ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson return result; 317ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 318ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson }); 319ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 320ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson 321ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson public void shutdown() throws IOException { 322ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson serverSocket.close(); 323ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson executor.shutdown(); 324ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 325ac41d7fe545831906171e3e86e1d18e201fd7739Jesse Wilson } 326a9a57f2581773484d13e160fd3407692e825971aElliott Hughes} 327