1/*
2 * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* @test
25 * @bug 4640544
26 * @summary Unit test for channels that implement NetworkChannel
27 */
28
29import java.nio.*;
30import java.nio.channels.*;
31import java.net.*;
32import java.io.IOException;
33import java.util.*;
34
35public class NetworkChannelTests {
36
37    static interface ChannelFactory {
38        NetworkChannel open() throws IOException;
39    }
40
41    static class BogusSocketAddress extends SocketAddress {
42    }
43
44    /**
45     * Exercise bind method.
46     */
47    static void bindTests(ChannelFactory factory) throws IOException {
48        NetworkChannel ch;
49
50        // AlreadyBoundException
51        ch = factory.open().bind(new InetSocketAddress(0));
52        try {
53            ch.bind(new InetSocketAddress(0));
54            throw new RuntimeException("AlreadyBoundException not thrown");
55        } catch (AlreadyBoundException x) {
56        }
57        ch.close();
58
59        // bind(null)
60        ch = factory.open().bind(null);
61        if (ch.getLocalAddress() == null)
62            throw new RuntimeException("socket not found");
63        ch.close();
64
65        // UnsupportedAddressTypeException
66        ch = factory.open();
67        try {
68            ch.bind(new BogusSocketAddress());
69            throw new RuntimeException("UnsupportedAddressTypeException not thrown");
70        } catch (UnsupportedAddressTypeException x) {
71        }
72        ch.close();
73
74        // ClosedChannelException
75        try {
76            ch.bind(new InetSocketAddress(0));
77            throw new RuntimeException("ClosedChannelException not thrown");
78        } catch (ClosedChannelException x) {
79        }
80    }
81
82    /**
83     * Exercise getLocalAddress method.
84     */
85    static void localAddressTests(ChannelFactory factory) throws IOException {
86        NetworkChannel ch;
87
88        // not bound
89        ch = factory.open();
90        if (ch.getLocalAddress() != null) {
91            throw new RuntimeException("Local address returned when not bound");
92        }
93
94        // bound
95        InetSocketAddress local =
96            (InetSocketAddress)(ch.bind(new InetSocketAddress(0)).getLocalAddress());
97        if (!local.getAddress().isAnyLocalAddress()) {
98            if (NetworkInterface.getByInetAddress(local.getAddress()) == null)
99                throw new RuntimeException("not bound to local address");
100        }
101        if (local.getPort() <= 0)
102            throw new RuntimeException("not bound to local port");
103
104        // closed
105        ch.close();
106        try {
107            ch.getLocalAddress();
108            throw new RuntimeException("ClosedChannelException expected");
109        } catch (ClosedChannelException e) { }
110    }
111
112    /**
113     * Exercise getRemoteAddress method (SocketChannel only)
114     */
115    static void connectedAddressTests() throws IOException {
116        ServerSocketChannel ssc = ServerSocketChannel.open()
117            .bind(new InetSocketAddress(0));
118        InetSocketAddress local = (InetSocketAddress)(ssc.getLocalAddress());
119        int port = local.getPort();
120        InetSocketAddress server = new InetSocketAddress(InetAddress.getLocalHost(), port);
121
122        SocketChannel sc = SocketChannel.open();
123
124        // not connected
125        if (sc.getRemoteAddress() != null)
126            throw new RuntimeException("getRemoteAddress returned address when not connected");
127
128        // connected
129        sc.connect(server);
130        SocketAddress remote = sc.getRemoteAddress();
131        if (!remote.equals(server))
132            throw new RuntimeException("getRemoteAddress returned incorrect address");
133
134        // closed
135        sc.close();
136        try {
137            sc.getRemoteAddress();
138            throw new RuntimeException("ClosedChannelException expected");
139        } catch (ClosedChannelException e) { }
140
141        ssc.close();
142    }
143
144    public static void main(String[] args) throws IOException {
145        ChannelFactory factory;
146
147        // -- SocketChannel --
148
149        factory = new ChannelFactory() {
150            public NetworkChannel open() throws IOException {
151                return SocketChannel.open();
152            }
153        };
154
155        bindTests(factory);
156        localAddressTests(factory);
157        connectedAddressTests();
158
159        // -- ServerSocketChannel --
160
161        factory = new ChannelFactory() {
162            public NetworkChannel open() throws IOException {
163                return ServerSocketChannel.open();
164            }
165        };
166
167        bindTests(factory);
168        localAddressTests(factory);
169
170        // backlog values
171        ServerSocketChannel.open()
172            .bind(new InetSocketAddress(0), 100).close();
173        ServerSocketChannel.open()
174            .bind(new InetSocketAddress(0), 0).close();
175        ServerSocketChannel.open()
176            .bind(new InetSocketAddress(0), -1).close();
177
178        // -- DatagramChannel --
179
180        factory = new ChannelFactory() {
181            public NetworkChannel open() throws IOException {
182                return DatagramChannel.open();
183            }
184        };
185
186        bindTests(factory);
187        localAddressTests(factory);
188    }
189
190}
191