12620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes/*
22620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * Copyright (C) 2010 The Android Open Source Project
3f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
42620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * you may not use this file except in compliance with the License.
62620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * You may obtain a copy of the License at
7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
82620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
102620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * Unless required by applicable law or agreed to in writing, software
112620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * See the License for the specific language governing permissions and
142620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes * limitations under the License.
152620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes */
162620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.nio.channels;
182620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes
1947ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fullerimport java.io.IOException;
20933fbbf606268eec9fc430632b8bca7002a833b3Neil Fullerimport java.io.InputStream;
21933fbbf606268eec9fc430632b8bca7002a833b3Neil Fullerimport java.io.OutputStream;
221cb7758226b1bd3c8f39d9adb9068b02a18fcc7cKenny Rootimport java.lang.reflect.Field;
23e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.net.BindException;
24c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughesimport java.net.ConnectException;
25e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.net.Inet4Address;
26c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughesimport java.net.InetAddress;
27c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughesimport java.net.InetSocketAddress;
282620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughesimport java.net.ServerSocket;
29e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.net.Socket;
30e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.net.SocketImpl;
31dbbe65b6a81ad02bc3bd432f21dccce6c0242cdbNarayan Kamathimport java.net.StandardSocketOptions;
322620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughesimport java.nio.ByteBuffer;
33e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.nio.channels.AlreadyBoundException;
34c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughesimport java.nio.channels.ClosedChannelException;
35e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.nio.channels.NotYetConnectedException;
36c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughesimport java.nio.channels.SelectionKey;
37e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.nio.channels.Selector;
38e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmeraimport java.nio.channels.SocketChannel;
392620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes
402620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughespublic class SocketChannelTest extends junit.framework.TestCase {
4147ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller
42e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_read_intoReadOnlyByteArrays() throws Exception {
43e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ByteBuffer readOnly = ByteBuffer.allocate(1).asReadOnlyBuffer();
44e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
45e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ss.setReuseAddress(true);
46e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress());
47e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
48e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.read(readOnly);
49e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
50e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (IllegalArgumentException expected) {
51e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
52e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
53e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.read(new ByteBuffer[] { readOnly });
54e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
55e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (IllegalArgumentException expected) {
56e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
57e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
58e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.read(new ByteBuffer[] { readOnly }, 0, 1);
59e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
60e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (IllegalArgumentException expected) {
61e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
62c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughes    }
63e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
64e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    // https://code.google.com/p/android/issues/detail?id=56684
65e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_56684() throws Exception {
66e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
67e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.configureBlocking(false);
68e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
69e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Selector selector = Selector.open();
70e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SelectionKey selectionKey = sc.register(selector, SelectionKey.OP_CONNECT);
71e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
72e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
73e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            // This test originally mocked the connect syscall to return ENETUNREACH.
74e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            // This is not easily doable in openJdk libcore, but a connect to broadcast
75e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            // address (255.255.255.255) for a TCP connection produces ENETUNREACH
76e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            // Kernel code that does it is at
77e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            // http://lxr.free-electrons.com/source/net/ipv4/tcp_ipv4.c?v=3.18#L182
78e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[] {
79e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                    (byte) 255, (byte) 255, (byte) 255, (byte) 255 }), 0));
80e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
81e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (ConnectException ex) {
82e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
83e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
84e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
85e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.finishConnect();
86e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
87e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (ClosedChannelException expected) {
88e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
89c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughes    }
90c6ad01d286af243fd300dd105eb2e4437e0b6b16Elliott Hughes
91e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /** Checks that closing a Socket's output stream also closes the Socket and SocketChannel. */
92e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_channelSocketOutputStreamClosureState() throws Exception {
93e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
94e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
95e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress());
96e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.configureBlocking(true);
97e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
98e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket scSocket = sc.socket();
99e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        OutputStream os = scSocket.getOutputStream();
100e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
101e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isOpen());
102e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(scSocket.isClosed());
103e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
104e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        os.close();
105e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
106e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isOpen());
107e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(scSocket.isClosed());
108e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
109e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ss.close();
1102620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes    }
111933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
112e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /** Checks that closing a Socket's input stream also closes the Socket and SocketChannel. */
113e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_channelSocketInputStreamClosureState() throws Exception {
114e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
115933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
116e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress());
117e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.configureBlocking(true);
118933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
119e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket scSocket = sc.socket();
120e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InputStream is = scSocket.getInputStream();
121933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
122e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isOpen());
123e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(scSocket.isClosed());
124933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
125e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        is.close();
126933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
127e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isOpen());
128e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(scSocket.isClosed());
129933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
130e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ss.close();
131e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
132933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
133e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /** Checks the state of the SocketChannel and associated Socket after open() */
134e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_open_initialState() throws Exception {
135e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
136e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
137e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertNull(sc.socket().getLocalSocketAddress());
138e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
139e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            Socket socket = sc.socket();
140e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertFalse(socket.isBound());
141e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertFalse(socket.isClosed());
142e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertFalse(socket.isConnected());
143e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertEquals(-1, socket.getLocalPort());
144e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertTrue(socket.getLocalAddress().isAnyLocalAddress());
145e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertNull(socket.getLocalSocketAddress());
146e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertNull(socket.getInetAddress());
147e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertEquals(0, socket.getPort());
148e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertNull(socket.getRemoteSocketAddress());
149e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertFalse(socket.getReuseAddress());
150e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
151e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            assertSame(sc, socket.getChannel());
152e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } finally {
153e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.close();
154e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
155e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
156933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
157e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_bind_unresolvedAddress() throws IOException {
158e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
159e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
160e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
161e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
162e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (IOException expected) {
163e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
164933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
165e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNull(sc.socket().getLocalSocketAddress());
166e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isOpen());
167e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isConnected());
168e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
169e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
170e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
171933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
172e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /** Checks that the SocketChannel and associated Socket agree on the socket state. */
173e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_bind_socketStateSync() throws IOException {
174e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
175e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNull(sc.socket().getLocalSocketAddress());
176933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
177e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket socket = sc.socket();
178e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNull(socket.getLocalSocketAddress());
179e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(socket.isBound());
180933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
181e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
182e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.socket().bind(bindAddr);
183933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
184e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
185e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(actualAddr, socket.getLocalSocketAddress());
186e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
187e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(socket.isBound());
188e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(socket.isConnected());
189e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(socket.isClosed());
190933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
191e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
19247ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller
193e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isOpen());
194e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(socket.isClosed());
195e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
19647ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller
197e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /**
198e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera     * Checks that the SocketChannel and associated Socket agree on the socket state, even if
199e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera     * the Socket object is requested/created after bind().
200e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera     */
201e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_bind_socketObjectCreationAfterBind() throws IOException {
202e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
203e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNull(sc.socket().getLocalSocketAddress());
204e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
205e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
206e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.socket().bind(bindAddr);
207e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
208e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // Socket object creation after bind().
209e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket socket = sc.socket();
210e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
211e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(actualAddr, socket.getLocalSocketAddress());
212e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
213e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(socket.isBound());
214e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(socket.isConnected());
215e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(socket.isClosed());
216e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
217e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
218e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
219e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isOpen());
220e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(socket.isClosed());
22147ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller    }
222e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
223e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /**
224e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera     * Tests connect() and object state for a blocking SocketChannel. Blocking mode is the default.
225e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera     */
226e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_connect_blocking() throws Exception {
227e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
228e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
229e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
230e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isBlocking());
231e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
232e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.connect(ss.getLocalSocketAddress()));
233e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
234e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.socket().isBound());
235e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isConnected());
236e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.socket().isConnected());
237e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.socket().isClosed());
238e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isBlocking());
239e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
240e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ss.close();
241e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
242df29508a7aa622f265aaebdc472eb7d679185ebbNeil Fuller    }
243df29508a7aa622f265aaebdc472eb7d679185ebbNeil Fuller
244e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    /** Tests connect() and object state for a non-blocking SocketChannel. */
245e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_connect_nonBlocking() throws Exception {
246e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
247e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
248e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
249e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isBlocking());
250e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.configureBlocking(false);
251e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isBlocking());
252e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
253e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        if (!sc.connect(ss.getLocalSocketAddress())) {
254e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            do {
255e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                assertTrue(sc.socket().isBound());
256e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                assertFalse(sc.isConnected());
257e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                assertFalse(sc.socket().isConnected());
258e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                assertFalse(sc.socket().isClosed());
259e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            } while (!sc.finishConnect());
260e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
261933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        assertTrue(sc.socket().isBound());
262e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.isConnected());
263e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(sc.socket().isConnected());
264933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        assertFalse(sc.socket().isClosed());
265e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertFalse(sc.isBlocking());
266e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
267e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ss.close();
268e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
269e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
270e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
271e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_Socket_impl_notNull() throws Exception {
272e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
273e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket socket = sc.socket();
274e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Field f_impl = Socket.class.getDeclaredField("impl");
275e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        f_impl.setAccessible(true);
276e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Object implFieldValue = f_impl.get(socket);
277e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNotNull(implFieldValue);
278e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(implFieldValue instanceof SocketImpl);
279933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
280e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
281e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_setOption() throws Exception {
282e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
283e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.setOption(StandardSocketOptions.SO_LINGER, 1000);
284e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
285e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // Assert that we can read back the option from the channel...
286e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(1000, (int) sc.<Integer>getOption(StandardSocketOptions.SO_LINGER));
287e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // ... and its socket adaptor.
288e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(1000, sc.socket().getSoLinger());
289e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
290e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
291e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
292e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.setOption(StandardSocketOptions.SO_LINGER, 2000);
293e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
294e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (ClosedChannelException expected) {
295e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
296e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
297e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
298e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_bind() throws IOException {
299e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress socketAddress = new InetSocketAddress(Inet4Address.LOOPBACK, 0);
300e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
301e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.bind(socketAddress);
302e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(socketAddress.getAddress(),
303e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                ((InetSocketAddress) (sc.getLocalAddress())).getAddress());
304e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertTrue(((InetSocketAddress) (sc.getLocalAddress())).getPort() > 0);
305e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
306e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
307e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.bind(socketAddress);
308e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
309e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (AlreadyBoundException expected) {
310e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
311e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
312e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        socketAddress = new InetSocketAddress(Inet4Address.LOOPBACK,
313e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera                ((InetSocketAddress) (sc.getLocalAddress())).getPort());
314e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
315e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            SocketChannel.open().bind(socketAddress);
316e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
317e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (BindException expected) {
318e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
319e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
320e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.close();
321e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        socketAddress = new InetSocketAddress(Inet4Address.LOOPBACK, 0);
322e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
323e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            sc.bind(socketAddress);
324e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (ClosedChannelException expected) {
325e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
326e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
327e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
328e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_getRemoteAddress() throws IOException {
329e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel sc = SocketChannel.open();
330e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket ss = new ServerSocket(0);
331e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
332e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertNull(sc.getRemoteAddress());
333e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
334e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        sc.connect(ss.getLocalSocketAddress());
335e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(sc.getRemoteAddress(), ss.getLocalSocketAddress());
336e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
337e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
338e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_shutdownInput() throws IOException {
339e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel channel1 = SocketChannel.open();
340e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket server1 = new ServerSocket(0);
341e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress localAddr1 = new InetSocketAddress("127.0.0.1", server1.getLocalPort());
342e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
343e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // initialize write content
344e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        byte[] writeContent = new byte[10];
345e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        for (int i = 0; i < writeContent.length; i++) {
346e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            writeContent[i] = (byte) i;
347e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
348e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
349e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // establish connection
350e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.connect(localAddr1);
351e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        Socket acceptedSocket = server1.accept();
352e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // use OutputStream.write to write bytes data.
353e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        OutputStream out = acceptedSocket.getOutputStream();
354e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        out.write(writeContent);
355e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // use close to guarantee all data is sent
356e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        acceptedSocket.close();
357e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
358e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.configureBlocking(false);
359e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ByteBuffer readContent = ByteBuffer.allocate(10 + 1);
360e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.shutdownInput();
361e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        assertEquals(-1, channel1.read(readContent));
362e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    }
363e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
364e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera    public void test_shutdownOutput() throws IOException {
365e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        SocketChannel channel1 = SocketChannel.open();
366e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ServerSocket server1 = new ServerSocket(0);
367e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        InetSocketAddress localAddr1 = new InetSocketAddress("127.0.0.1", server1.getLocalPort());
368e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
369e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // initialize write content
370e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        ByteBuffer writeContent = ByteBuffer.allocate(10);
371e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        for (int i = 0; i < 10; i++) {
372e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            writeContent.put((byte) i);
373e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        }
374e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        writeContent.flip();
375e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
376e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
377e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            channel1.shutdownOutput();
378e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
379e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (NotYetConnectedException expected) {}
380e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
381e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        // establish connection
382e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.connect(localAddr1);
383e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.shutdownOutput();
384e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
385e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
386e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            channel1.write(writeContent);
387e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
388e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch (ClosedChannelException expected) {}
389e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
390e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        channel1.close();
391e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera
392e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        try {
393e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            channel1.shutdownOutput();
394e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera            fail();
395e5f08c57bc21f73466326ac0f505ef34d3a362deShubham Ajmera        } catch(ClosedChannelException expected) {}
396dbbe65b6a81ad02bc3bd432f21dccce6c0242cdbNarayan Kamath    }
3972620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes}
398