893N/A/*
3261N/A * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
893N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
893N/A *
893N/A * This code is free software; you can redistribute it and/or modify it
893N/A * under the terms of the GNU General Public License version 2 only, as
893N/A * published by the Free Software Foundation.
893N/A *
893N/A * This code is distributed in the hope that it will be useful, but WITHOUT
893N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
893N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
893N/A * version 2 for more details (a copy is included in the LICENSE file that
893N/A * accompanied this code).
893N/A *
893N/A * You should have received a copy of the GNU General Public License version
893N/A * 2 along with this work; if not, write to the Free Software Foundation,
893N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
893N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
893N/A */
893N/A
893N/A/* @test
1580N/A * @bug 4607272 6842687
893N/A * @summary Unit test for AsynchronousServerSocketChannel
893N/A * @run main/timeout=180 Basic
893N/A */
893N/A
893N/Aimport java.nio.channels.*;
893N/Aimport java.net.*;
4216N/Aimport static java.net.StandardSocketOptions.*;
893N/Aimport java.io.IOException;
2827N/Aimport java.util.Set;
893N/Aimport java.util.concurrent.ExecutionException;
893N/Aimport java.util.concurrent.Future;
893N/Aimport java.util.concurrent.atomic.AtomicReference;
893N/A
893N/Apublic class Basic {
893N/A
893N/A public static void main(String[] args) throws Exception {
893N/A testBind();
893N/A testAccept();
2827N/A testSocketOptions();
893N/A }
893N/A
893N/A static void testBind() throws Exception {
893N/A System.out.println("-- bind --");
893N/A
893N/A AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
893N/A if (ch.getLocalAddress() != null)
893N/A throw new RuntimeException("Local address should be 'null'");
893N/A ch.bind(new InetSocketAddress(0), 20);
893N/A
893N/A // check local address after binding
893N/A InetSocketAddress local = (InetSocketAddress)ch.getLocalAddress();
893N/A if (local.getPort() == 0)
893N/A throw new RuntimeException("Unexpected port");
893N/A if (!local.getAddress().isAnyLocalAddress())
893N/A throw new RuntimeException("Not bound to a wildcard address");
893N/A
893N/A // try to re-bind
893N/A try {
893N/A ch.bind(new InetSocketAddress(0));
893N/A throw new RuntimeException("AlreadyBoundException expected");
893N/A } catch (AlreadyBoundException x) {
893N/A }
893N/A ch.close();
893N/A
893N/A // check ClosedChannelException
893N/A ch = AsynchronousServerSocketChannel.open();
893N/A ch.close();
893N/A try {
893N/A ch.bind(new InetSocketAddress(0));
893N/A throw new RuntimeException("ClosedChannelException expected");
893N/A } catch (ClosedChannelException x) {
893N/A }
893N/A }
893N/A
893N/A static void testAccept() throws Exception {
893N/A System.out.println("-- accept --");
893N/A
893N/A final AsynchronousServerSocketChannel listener =
893N/A AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
893N/A
893N/A InetAddress lh = InetAddress.getLocalHost();
893N/A int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
893N/A final InetSocketAddress isa = new InetSocketAddress(lh, port);
893N/A
893N/A // establish a few loopback connections
893N/A for (int i=0; i<100; i++) {
893N/A SocketChannel sc = SocketChannel.open(isa);
893N/A AsynchronousSocketChannel ch = listener.accept().get();
893N/A sc.close();
893N/A ch.close();
893N/A }
893N/A
893N/A final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
893N/A
893N/A // start accepting
1434N/A listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
893N/A public void completed(AsynchronousSocketChannel ch, Void att) {
893N/A try {
893N/A ch.close();
893N/A } catch (IOException ignore) { }
893N/A }
893N/A public void failed(Throwable exc, Void att) {
893N/A exception.set(exc);
893N/A }
893N/A });
893N/A
893N/A // check AcceptPendingException
893N/A try {
893N/A listener.accept();
893N/A throw new RuntimeException("AcceptPendingException expected");
893N/A } catch (AcceptPendingException x) {
893N/A }
893N/A
893N/A // asynchronous close
893N/A listener.close();
893N/A while (exception.get() == null)
893N/A Thread.sleep(100);
893N/A if (!(exception.get() instanceof AsynchronousCloseException))
893N/A throw new RuntimeException("AsynchronousCloseException expected");
893N/A
893N/A // once closed when a further attemt should throw ClosedChannelException
893N/A try {
893N/A listener.accept().get();
893N/A throw new RuntimeException("ExecutionException expected");
893N/A } catch (ExecutionException x) {
893N/A if (!(x.getCause() instanceof ClosedChannelException))
893N/A throw new RuntimeException("Cause of ClosedChannelException expected");
893N/A } catch (InterruptedException x) {
893N/A }
893N/A
893N/A }
2827N/A
2827N/A static void testSocketOptions() throws Exception {
2827N/A System.out.println("-- socket options --");
2827N/A AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
2827N/A try {
2827N/A // check supported options
2827N/A Set<SocketOption<?>> options = ch.supportedOptions();
2827N/A if (!options.contains(SO_REUSEADDR))
2827N/A throw new RuntimeException("SO_REUSEADDR should be supported");
2827N/A if (!options.contains(SO_RCVBUF))
2827N/A throw new RuntimeException("SO_RCVBUF should be supported");
2827N/A
2827N/A // allowed to change when not bound
2827N/A ch.setOption(SO_RCVBUF, 256*1024); // can't check
2827N/A int before = ch.getOption(SO_RCVBUF);
2827N/A int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
2827N/A if (after < before)
2827N/A throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
2827N/A ch.setOption(SO_REUSEADDR, true);
2827N/A checkOption(ch, SO_REUSEADDR, true);
2827N/A ch.setOption(SO_REUSEADDR, false);
2827N/A checkOption(ch, SO_REUSEADDR, false);
2827N/A } finally {
2827N/A ch.close();
2827N/A }
2827N/A }
2827N/A
2827N/A static void checkOption(AsynchronousServerSocketChannel ch,
2827N/A SocketOption name, Object expectedValue)
2827N/A throws IOException
2827N/A {
2827N/A Object value = ch.getOption(name);
2827N/A if (!value.equals(expectedValue))
2827N/A throw new RuntimeException("value not as expected");
2827N/A }
893N/A}