Basic.java revision 3261
829N/A/*
2362N/A * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
829N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
829N/A *
829N/A * This code is free software; you can redistribute it and/or modify it
829N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation.
829N/A *
2362N/A * This code is distributed in the hope that it will be useful, but WITHOUT
829N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
829N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
829N/A * version 2 for more details (a copy is included in the LICENSE file that
829N/A * accompanied this code).
829N/A *
829N/A * You should have received a copy of the GNU General Public License version
829N/A * 2 along with this work; if not, write to the Free Software Foundation,
829N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
829N/A *
829N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
829N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
2362N/A */
2362N/A
829N/A/* @test
829N/A * @bug 4607272
829N/A * @summary Unit test for AsynchronousChannelGroup
829N/A * @build Basic
829N/A * @run main/othervm -XX:-UseVMInterruptibleIO Basic
829N/A */
829N/A
829N/Aimport java.nio.ByteBuffer;
829N/Aimport java.nio.channels.*;
829N/Aimport java.net.*;
829N/Aimport java.util.*;
829N/Aimport java.util.concurrent.*;
829N/Aimport java.io.IOException;
829N/A
829N/Apublic class Basic {
829N/A static final Random rand = new Random();
829N/A static final ThreadFactory threadFactory = new ThreadFactory() {
829N/A @Override
829N/A public Thread newThread(final Runnable r) {
829N/A return new Thread(r);
829N/A }};
829N/A
829N/A
829N/A public static void main(String[] args) throws Exception {
829N/A shutdownTests();
829N/A shutdownNowTests();
829N/A afterShutdownTests();
829N/A miscTests();
829N/A }
829N/A
829N/A static void shutdownTests() throws Exception {
System.out.println("-- test shutdown --");
// test shutdown with no channels in groups
for (int i=0; i<500; i++) {
ExecutorService pool = null;
AsynchronousChannelGroup group;
if (rand.nextBoolean()) {
pool = Executors.newCachedThreadPool();
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
} else {
int nThreads = 1 + rand.nextInt(8);
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, threadFactory);
}
group.shutdown();
if (!group.isShutdown())
throw new RuntimeException("Group should be shutdown");
// group should terminate quickly
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group should have terminated");
if (pool != null && !pool.isTerminated())
throw new RuntimeException("Executor should have terminated");
}
// shutdown with channel in group
for (int i=0; i<500; i++) {
ExecutorService pool = null;
AsynchronousChannelGroup group;
if (rand.nextBoolean()) {
pool = Executors.newCachedThreadPool();
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(10));
} else {
int nThreads = 1 + rand.nextInt(8);
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, threadFactory);
}
// create channel that is bound to group
AsynchronousChannel ch;
switch (rand.nextInt(2)) {
case 0 : ch = AsynchronousSocketChannel.open(group); break;
case 1 : ch = AsynchronousServerSocketChannel.open(group); break;
default : throw new AssertionError();
}
group.shutdown();
if (!group.isShutdown())
throw new RuntimeException("Group should be shutdown");
// last channel so should terminate after this channel is closed
ch.close();
// group should terminate quickly
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group should have terminated");
if (pool != null && !pool.isTerminated())
throw new RuntimeException("Executor should have terminated");
}
}
static void shutdownNowTests() throws Exception {
System.out.println("-- test shutdownNow --");
for (int i=0; i< 10; i++) {
ExecutorService pool = null;
AsynchronousChannelGroup group;
if (rand.nextBoolean()) {
pool = Executors.newCachedThreadPool();
group = AsynchronousChannelGroup
.withCachedThreadPool(pool, rand.nextInt(5));
} else {
int nThreads = 1 + rand.nextInt(8);
group = AsynchronousChannelGroup
.withFixedThreadPool(nThreads, threadFactory);
}
// I/O in progress
AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel
.open(group).bind(new InetSocketAddress(0));
ch.accept();
// forceful shutdown
group.shutdownNow();
// shutdownNow is required to close all channels
if (ch.isOpen())
throw new RuntimeException("Channel should be closed");
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group should have terminated");
if (pool != null && !pool.isTerminated())
throw new RuntimeException("Executor should have terminated");
}
}
// test creating channels in group after group is shutdown
static void afterShutdownTests() throws Exception {
System.out.println("-- test operations after group is shutdown --");
AsynchronousChannelGroup group =
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group);
// initiate accept
listener.bind(new InetSocketAddress(0));
Future<AsynchronousSocketChannel> result = listener.accept();
// shutdown group
group.shutdown();
if (!group.isShutdown())
throw new RuntimeException("Group should be shutdown");
// attempt to create another channel
try {
AsynchronousSocketChannel.open(group);
throw new RuntimeException("ShutdownChannelGroupException expected");
} catch (ShutdownChannelGroupException x) {
}
try {
AsynchronousServerSocketChannel.open(group);
throw new RuntimeException("ShutdownChannelGroupException expected");
} catch (ShutdownChannelGroupException x) {
}
// attempt to create another channel by connecting. This should cause
// the accept operation to fail.
InetAddress lh = InetAddress.getLocalHost();
int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ch.connect(isa).get();
try {
result.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// initiate another accept even though channel group is shutdown.
Future<AsynchronousSocketChannel> res = listener.accept();
try {
res.get(3, TimeUnit.SECONDS);
throw new RuntimeException("TimeoutException expected");
} catch (TimeoutException x) {
}
// connect to the listener which should cause the accept to complete
AsynchronousSocketChannel.open().connect(isa);
try {
res.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// group should *not* terminate as channels are open
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (terminated)
throw new RuntimeException("Group should not have terminated");
// close channel; group should terminate quickly
ch.close();
listener.close();
terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group should have terminated");
}
static void miscTests() throws Exception {
System.out.println("-- miscellenous tests --");
try {
AsynchronousChannelGroup.withFixedThreadPool(1, null);
throw new RuntimeException("NPE expected");
} catch (NullPointerException x) {
}
try {
AsynchronousChannelGroup.withFixedThreadPool(0, threadFactory);
throw new RuntimeException("IAE expected");
} catch (IllegalArgumentException e) {
}
try {
AsynchronousChannelGroup.withCachedThreadPool(null, 0);
throw new RuntimeException("NPE expected");
} catch (NullPointerException x) {
}
}
}