Basic.java revision 6073:cea72c2bf071
1/* 2 * Copyright (c) 2008, 2012, 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 4607272 26 * @summary Unit test for AsynchronousChannelGroup 27 * @build Basic 28 * @run main/othervm -XX:-UseVMInterruptibleIO Basic 29 */ 30 31import java.nio.ByteBuffer; 32import java.nio.channels.*; 33import java.net.*; 34import java.util.*; 35import java.util.concurrent.*; 36import java.io.IOException; 37 38public class Basic { 39 static final Random rand = new Random(); 40 static final ThreadFactory threadFactory = new ThreadFactory() { 41 @Override 42 public Thread newThread(final Runnable r) { 43 return new Thread(r); 44 }}; 45 46 47 public static void main(String[] args) throws Exception { 48 shutdownTests(); 49 shutdownNowTests(); 50 afterShutdownTests(); 51 miscTests(); 52 } 53 54 static void testShutdownWithNoChannels(ExecutorService pool, 55 AsynchronousChannelGroup group) 56 throws Exception 57 { 58 group.shutdown(); 59 if (!group.isShutdown()) 60 throw new RuntimeException("Group should be shutdown"); 61 // group should terminate quickly 62 boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); 63 if (!terminated) 64 throw new RuntimeException("Group should have terminated"); 65 if (pool != null && !pool.isTerminated()) 66 throw new RuntimeException("Executor should have terminated"); 67 } 68 69 static void testShutdownWithChannels(ExecutorService pool, 70 AsynchronousChannelGroup group) 71 throws Exception 72 { 73 74 // create channel that is bound to group 75 AsynchronousChannel ch; 76 switch (rand.nextInt(2)) { 77 case 0 : ch = AsynchronousSocketChannel.open(group); break; 78 case 1 : ch = AsynchronousServerSocketChannel.open(group); break; 79 default : throw new AssertionError(); 80 } 81 group.shutdown(); 82 if (!group.isShutdown()) 83 throw new RuntimeException("Group should be shutdown"); 84 85 // last channel so should terminate after this channel is closed 86 ch.close(); 87 88 // group should terminate quickly 89 boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); 90 if (!terminated) 91 throw new RuntimeException("Group should have terminated"); 92 if (pool != null && !pool.isTerminated()) 93 throw new RuntimeException("Executor should have terminated"); 94 } 95 96 static void shutdownTests() throws Exception { 97 System.out.println("-- test shutdown --"); 98 99 // test shutdown with no channels in groups 100 for (int i = 0; i < 100; i++) { 101 ExecutorService pool = Executors.newCachedThreadPool(); 102 AsynchronousChannelGroup group = AsynchronousChannelGroup 103 .withCachedThreadPool(pool, rand.nextInt(5)); 104 testShutdownWithNoChannels(pool, group); 105 } 106 for (int i = 0; i < 100; i++) { 107 int nThreads = 1 + rand.nextInt(8); 108 AsynchronousChannelGroup group = AsynchronousChannelGroup 109 .withFixedThreadPool(nThreads, threadFactory); 110 testShutdownWithNoChannels(null, group); 111 } 112 for (int i = 0; i < 100; i++) { 113 ExecutorService pool = Executors.newCachedThreadPool(); 114 AsynchronousChannelGroup group = AsynchronousChannelGroup 115 .withThreadPool(pool); 116 testShutdownWithNoChannels(pool, group); 117 } 118 119 // test shutdown with channel in group 120 for (int i = 0; i < 100; i++) { 121 ExecutorService pool = Executors.newCachedThreadPool(); 122 AsynchronousChannelGroup group = AsynchronousChannelGroup 123 .withCachedThreadPool(pool, rand.nextInt(10)); 124 testShutdownWithChannels(pool, group); 125 } 126 for (int i = 0; i < 100; i++) { 127 int nThreads = 1 + rand.nextInt(8); 128 AsynchronousChannelGroup group = AsynchronousChannelGroup 129 .withFixedThreadPool(nThreads, threadFactory); 130 testShutdownWithChannels(null, group); 131 } 132 for (int i = 0; i < 100; i++) { 133 ExecutorService pool = Executors.newCachedThreadPool(); 134 AsynchronousChannelGroup group = AsynchronousChannelGroup 135 .withThreadPool(pool); 136 testShutdownWithChannels(pool, group); 137 } 138 } 139 140 static void testShutdownNow(ExecutorService pool, 141 AsynchronousChannelGroup group) 142 throws Exception 143 { 144 // I/O in progress 145 AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel 146 .open(group).bind(new InetSocketAddress(0)); 147 ch.accept(); 148 149 // forceful shutdown 150 group.shutdownNow(); 151 152 // shutdownNow is required to close all channels 153 if (ch.isOpen()) 154 throw new RuntimeException("Channel should be closed"); 155 156 boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); 157 if (!terminated) 158 throw new RuntimeException("Group should have terminated"); 159 if (pool != null && !pool.isTerminated()) 160 throw new RuntimeException("Executor should have terminated"); 161 } 162 163 static void shutdownNowTests() throws Exception { 164 System.out.println("-- test shutdownNow --"); 165 166 for (int i = 0; i < 10; i++) { 167 ExecutorService pool = pool = Executors.newCachedThreadPool(); 168 AsynchronousChannelGroup group = AsynchronousChannelGroup 169 .withCachedThreadPool(pool, rand.nextInt(5)); 170 testShutdownNow(pool, group); 171 } 172 for (int i = 0; i < 10; i++) { 173 int nThreads = 1 + rand.nextInt(8); 174 AsynchronousChannelGroup group = AsynchronousChannelGroup 175 .withFixedThreadPool(nThreads, threadFactory); 176 testShutdownNow(null, group); 177 } 178 for (int i = 0; i < 10; i++) { 179 ExecutorService pool = Executors.newCachedThreadPool(); 180 AsynchronousChannelGroup group = AsynchronousChannelGroup 181 .withThreadPool(pool); 182 testShutdownNow(pool, group); 183 } 184 } 185 186 // test creating channels in group after group is shutdown 187 static void afterShutdownTests() throws Exception { 188 System.out.println("-- test operations after group is shutdown --"); 189 AsynchronousChannelGroup group = 190 AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory); 191 192 AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); 193 AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group); 194 195 // initiate accept 196 listener.bind(new InetSocketAddress(0)); 197 Future<AsynchronousSocketChannel> result = listener.accept(); 198 199 // shutdown group 200 group.shutdown(); 201 if (!group.isShutdown()) 202 throw new RuntimeException("Group should be shutdown"); 203 204 // attempt to create another channel 205 try { 206 AsynchronousSocketChannel.open(group); 207 throw new RuntimeException("ShutdownChannelGroupException expected"); 208 } catch (ShutdownChannelGroupException x) { 209 } 210 try { 211 AsynchronousServerSocketChannel.open(group); 212 throw new RuntimeException("ShutdownChannelGroupException expected"); 213 } catch (ShutdownChannelGroupException x) { 214 } 215 216 // attempt to create another channel by connecting. This should cause 217 // the accept operation to fail. 218 InetAddress lh = InetAddress.getLocalHost(); 219 int port = ((InetSocketAddress)listener.getLocalAddress()).getPort(); 220 InetSocketAddress isa = new InetSocketAddress(lh, port); 221 ch.connect(isa).get(); 222 try { 223 result.get(); 224 throw new RuntimeException("Connection was accepted"); 225 } catch (ExecutionException x) { 226 Throwable cause = x.getCause(); 227 if (!(cause instanceof IOException)) 228 throw new RuntimeException("Cause should be IOException"); 229 cause = cause.getCause(); 230 if (!(cause instanceof ShutdownChannelGroupException)) 231 throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); 232 } 233 234 // initiate another accept even though channel group is shutdown. 235 Future<AsynchronousSocketChannel> res = listener.accept(); 236 try { 237 res.get(3, TimeUnit.SECONDS); 238 throw new RuntimeException("TimeoutException expected"); 239 } catch (TimeoutException x) { 240 } 241 // connect to the listener which should cause the accept to complete 242 AsynchronousSocketChannel.open().connect(isa); 243 try { 244 res.get(); 245 throw new RuntimeException("Connection was accepted"); 246 } catch (ExecutionException x) { 247 Throwable cause = x.getCause(); 248 if (!(cause instanceof IOException)) 249 throw new RuntimeException("Cause should be IOException"); 250 cause = cause.getCause(); 251 if (!(cause instanceof ShutdownChannelGroupException)) 252 throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); 253 } 254 255 // group should *not* terminate as channels are open 256 boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); 257 if (terminated) 258 throw new RuntimeException("Group should not have terminated"); 259 260 // close channel; group should terminate quickly 261 ch.close(); 262 listener.close(); 263 terminated = group.awaitTermination(3, TimeUnit.SECONDS); 264 if (!terminated) 265 throw new RuntimeException("Group should have terminated"); 266 } 267 268 static void miscTests() throws Exception { 269 System.out.println("-- miscellenous tests --"); 270 try { 271 AsynchronousChannelGroup.withFixedThreadPool(1, null); 272 throw new RuntimeException("NPE expected"); 273 } catch (NullPointerException x) { 274 } 275 try { 276 AsynchronousChannelGroup.withFixedThreadPool(0, threadFactory); 277 throw new RuntimeException("IAE expected"); 278 } catch (IllegalArgumentException e) { 279 } 280 try { 281 AsynchronousChannelGroup.withCachedThreadPool(null, 0); 282 throw new RuntimeException("NPE expected"); 283 } catch (NullPointerException x) { 284 } 285 try { 286 AsynchronousChannelGroup.withThreadPool(null); 287 throw new RuntimeException("NPE expected"); 288 } catch (NullPointerException e) { 289 } 290 } 291} 292