ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.5
Committed: Thu Sep 25 11:02:41 2003 UTC (20 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.4: +300 -101 lines
Log Message:
improve tck javadocs; rename and add a few tests

File Contents

# Content
1 /*
2 * Written by members of JCP JSR-166 Expert Group and released to the
3 * public domain. Use, modify, and redistribute this code in any way
4 * without acknowledgement. Other contributors include Andrew Wright,
5 * Jeffrey Hayes, Pat Fischer, Mike Judd.
6 */
7
8
9 import junit.framework.*;
10 import java.util.*;
11 import java.util.concurrent.*;
12 import java.math.BigInteger;
13
14 public class ExecutorsTest extends JSR166TestCase{
15 public static void main(String[] args) {
16 junit.textui.TestRunner.run (suite());
17 }
18 public static Test suite() {
19 return new TestSuite(ExecutorsTest.class);
20 }
21
22 private static final String TEST_STRING = "a test string";
23
24 private static class MyTask implements Runnable {
25 public void run() { completed = true; }
26 public boolean isCompleted() { return completed; }
27 public void reset() { completed = false; }
28 private boolean completed = false;
29 }
30
31 private static class StringTask implements Callable<String> {
32 public String call() { return TEST_STRING; }
33 }
34
35 static class DirectExecutor implements Executor {
36 public void execute(Runnable r) {
37 r.run();
38 }
39 }
40
41 static class TimedCallable<T> implements Callable<T> {
42 private final Executor exec;
43 private final Callable<T> func;
44 private final long msecs;
45
46 TimedCallable(Executor exec, Callable<T> func, long msecs) {
47 this.exec = exec;
48 this.func = func;
49 this.msecs = msecs;
50 }
51
52 public T call() throws Exception {
53 Future<T> ftask = Executors.execute(exec, func);
54 try {
55 return ftask.get(msecs, TimeUnit.MILLISECONDS);
56 } finally {
57 ftask.cancel(true);
58 }
59 }
60 }
61
62
63 private static class Fib implements Callable<BigInteger> {
64 private final BigInteger n;
65 Fib(long n) {
66 if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
67 this.n = BigInteger.valueOf(n);
68 }
69 public BigInteger call() {
70 BigInteger f1 = BigInteger.ONE;
71 BigInteger f2 = f1;
72 for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
73 BigInteger t = f1.add(f2);
74 f1 = f2;
75 f2 = t;
76 }
77 return f1;
78 }
79 };
80
81 /**
82 * For use as ThreadFactory in constructors
83 */
84 static class MyThreadFactory implements ThreadFactory{
85 public Thread newThread(Runnable r){
86 return new Thread(r);
87 }
88 }
89
90 /**
91 * A newCachedThreadPool can execute runnables
92 */
93 public void testNewCachedThreadPool1() {
94 ExecutorService e = Executors.newCachedThreadPool();
95 e.execute(new NoOpRunnable());
96 e.execute(new NoOpRunnable());
97 e.execute(new NoOpRunnable());
98 e.shutdown();
99 }
100
101 /**
102 * A newCachedThreadPool with given ThreadFactory can execute runnables
103 */
104 public void testNewCachedThreadPool2() {
105 ExecutorService e = Executors.newCachedThreadPool(new MyThreadFactory());
106 e.execute(new NoOpRunnable());
107 e.execute(new NoOpRunnable());
108 e.execute(new NoOpRunnable());
109 e.shutdown();
110 }
111
112 /**
113 * A newCachedThreadPool with null ThreadFactory throws NPE
114 */
115 public void testNewCachedThreadPool3() {
116 try {
117 ExecutorService e = Executors.newCachedThreadPool(null);
118 shouldThrow();
119 }
120 catch(NullPointerException success) {
121 }
122 }
123
124
125 /**
126 * A new SingleThreadExecutor can execute runnables
127 */
128 public void testNewSingleThreadExecutor1() {
129 ExecutorService e = Executors.newSingleThreadExecutor();
130 e.execute(new NoOpRunnable());
131 e.execute(new NoOpRunnable());
132 e.execute(new NoOpRunnable());
133 e.shutdown();
134 }
135
136 /**
137 * A new SingleThreadExecutor with given ThreadFactory can execute runnables
138 */
139 public void testNewSingleThreadExecutor2() {
140 ExecutorService e = Executors.newSingleThreadExecutor(new MyThreadFactory());
141 e.execute(new NoOpRunnable());
142 e.execute(new NoOpRunnable());
143 e.execute(new NoOpRunnable());
144 e.shutdown();
145 }
146
147 /**
148 * A new SingleThreadExecutor with null ThreadFactory throws NPE
149 */
150 public void testNewSingleThreadExecutor3() {
151 try {
152 ExecutorService e = Executors.newSingleThreadExecutor(null);
153 shouldThrow();
154 }
155 catch(NullPointerException success) {
156 }
157 }
158
159 /**
160 * A new newFixedThreadPool can execute runnables
161 */
162 public void testNewFixedThreadPool1() {
163 ExecutorService e = Executors.newFixedThreadPool(2);
164 e.execute(new NoOpRunnable());
165 e.execute(new NoOpRunnable());
166 e.execute(new NoOpRunnable());
167 e.shutdown();
168 }
169
170 /**
171 * A new newFixedThreadPool with given ThreadFactory can execute runnables
172 */
173 public void testNewFixedThreadPool2() {
174 ExecutorService e = Executors.newFixedThreadPool(2, new MyThreadFactory());
175 e.execute(new NoOpRunnable());
176 e.execute(new NoOpRunnable());
177 e.execute(new NoOpRunnable());
178 e.shutdown();
179 }
180
181 /**
182 * A new newFixedThreadPool with null ThreadFactory throws NPE
183 */
184 public void testNewFixedThreadPool3() {
185 try {
186 ExecutorService e = Executors.newFixedThreadPool(2, null);
187 shouldThrow();
188 }
189 catch(NullPointerException success) {
190 }
191 }
192
193 /**
194 * A new newFixedThreadPool with 0 threads throws IAE
195 */
196 public void testNewFixedThreadPool4() {
197 try {
198 ExecutorService e = Executors.newFixedThreadPool(0);
199 shouldThrow();
200 }
201 catch(IllegalArgumentException success) {
202 }
203 }
204
205 /**
206 * execute of runnable runs it to completion
207 */
208 public void testExecuteRunnable () {
209 try {
210 Executor e = new DirectExecutor();
211 MyTask task = new MyTask();
212 assertFalse(task.isCompleted());
213 Future<String> future = Executors.execute(e, task, TEST_STRING);
214 String result = future.get();
215 assertTrue(task.isCompleted());
216 assertSame(TEST_STRING, result);
217 }
218 catch (ExecutionException ex) {
219 unexpectedException();
220 }
221 catch (InterruptedException ex) {
222 unexpectedException();
223 }
224 }
225
226 /**
227 * invoke of a runnable runs it to completion
228 */
229 public void testInvokeRunnable () {
230 try {
231 Executor e = new DirectExecutor();
232 MyTask task = new MyTask();
233 assertFalse(task.isCompleted());
234 Executors.invoke(e, task);
235 assertTrue(task.isCompleted());
236 }
237 catch (ExecutionException ex) {
238 unexpectedException();
239 }
240 catch (InterruptedException ex) {
241 unexpectedException();
242 }
243 }
244
245 /**
246 * execute of a callable runs it to completion
247 */
248 public void testExecuteCallable () {
249 try {
250 Executor e = new DirectExecutor();
251 Future<String> future = Executors.execute(e, new StringTask());
252 String result = future.get();
253 assertSame(TEST_STRING, result);
254 }
255 catch (ExecutionException ex) {
256 unexpectedException();
257 }
258 catch (InterruptedException ex) {
259 unexpectedException();
260 }
261 }
262
263 /**
264 * invoke of a collable runs it to completion
265 */
266 public void testInvokeCallable () {
267 try {
268 Executor e = new DirectExecutor();
269 String result = Executors.invoke(e, new StringTask());
270
271 assertSame(TEST_STRING, result);
272 }
273 catch (ExecutionException ex) {
274 unexpectedException();
275 }
276 catch (InterruptedException ex) {
277 unexpectedException();
278 }
279 }
280
281 /**
282 * execute with null executor throws NPE
283 */
284 public void testNullExecuteRunnable () {
285 try {
286 MyTask task = new MyTask();
287 assertFalse(task.isCompleted());
288 Future<String> future = Executors.execute(null, task, TEST_STRING);
289 shouldThrow();
290 }
291 catch (NullPointerException success) {
292 }
293 catch (Exception ex) {
294 unexpectedException();
295 }
296 }
297
298 /**
299 * execute with a null runnable throws NPE
300 */
301 public void testExecuteNullRunnable() {
302 try {
303 Executor e = new DirectExecutor();
304 MyTask task = null;
305 Future<String> future = Executors.execute(e, task, TEST_STRING);
306 shouldThrow();
307 }
308 catch (NullPointerException success) {
309 }
310 catch (Exception ex) {
311 unexpectedException();
312 }
313 }
314
315 /**
316 * invoke of a null runnable throws NPE
317 */
318 public void testInvokeNullRunnable () {
319 try {
320 Executor e = new DirectExecutor();
321 MyTask task = null;
322 Executors.invoke(e, task);
323 shouldThrow();
324 }
325 catch (NullPointerException success) {
326 }
327 catch (Exception ex) {
328 unexpectedException();
329 }
330 }
331
332 /**
333 * execute of a null callable throws NPE
334 */
335 public void testExecuteNullCallable () {
336 try {
337 Executor e = new DirectExecutor();
338 StringTask t = null;
339 Future<String> future = Executors.execute(e, t);
340 shouldThrow();
341 }
342 catch (NullPointerException success) {
343 }
344 catch (Exception ex) {
345 unexpectedException();
346 }
347 }
348
349 /**
350 * invoke of a null callable throws NPE
351 */
352 public void testInvokeNullCallable () {
353 try {
354 Executor e = new DirectExecutor();
355 StringTask t = null;
356 String result = Executors.invoke(e, t);
357 shouldThrow();
358 }
359 catch (NullPointerException success) {
360 }
361 catch (Exception ex) {
362 unexpectedException();
363 }
364 }
365
366 /**
367 * execute(Executor, Runnable) throws RejectedExecutionException
368 * if saturated.
369 */
370 public void testExecute1() {
371 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
372 try {
373
374 for(int i = 0; i < 5; ++i){
375 Executors.execute(p, new MediumRunnable(), Boolean.TRUE);
376 }
377 shouldThrow();
378 } catch(RejectedExecutionException success){}
379 joinPool(p);
380 }
381
382 /**
383 * execute(Executor, Callable)throws RejectedExecutionException
384 * if saturated.
385 */
386 public void testExecute2() {
387 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
388 try {
389 for(int i = 0; i < 5; ++i) {
390 Executors.execute(p, new SmallCallable());
391 }
392 shouldThrow();
393 } catch(RejectedExecutionException e){}
394 joinPool(p);
395 }
396
397
398 /**
399 * invoke(Executor, Runnable) throws InterruptedException if
400 * caller interrupted.
401 */
402 public void testInterruptedInvoke() {
403 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
404 Thread t = new Thread(new Runnable() {
405 public void run() {
406 try {
407 Executors.invoke(p,new Runnable() {
408 public void run() {
409 try {
410 Thread.sleep(MEDIUM_DELAY_MS);
411 shouldThrow();
412 } catch(InterruptedException e){
413 }
414 }
415 });
416 } catch(InterruptedException success){
417 } catch(Exception e) {
418 unexpectedException();
419 }
420
421 }
422 });
423 try {
424 t.start();
425 Thread.sleep(SHORT_DELAY_MS);
426 t.interrupt();
427 } catch(Exception e){
428 unexpectedException();
429 }
430 joinPool(p);
431 }
432
433 /**
434 * invoke(Executor, Runnable) throws ExecutionException if
435 * runnable throws exception.
436 */
437 public void testInvoke3() {
438 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
439 try {
440 Runnable r = new Runnable() {
441 public void run() {
442 int i = 5/0;
443 }
444 };
445
446 for(int i =0; i < 5; i++){
447 Executors.invoke(p,r);
448 }
449
450 shouldThrow();
451 } catch(ExecutionException success){
452 } catch(Exception e){
453 unexpectedException();
454 }
455 joinPool(p);
456 }
457
458
459
460 /**
461 * invoke(Executor, Callable) throws InterruptedException if
462 * callable throws exception
463 */
464 public void testInvoke5() {
465 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
466
467 final Callable c = new Callable() {
468 public Object call() {
469 try {
470 Executors.invoke(p, new SmallCallable());
471 shouldThrow();
472 } catch(InterruptedException e){}
473 catch(RejectedExecutionException e2){}
474 catch(ExecutionException e3){}
475 return Boolean.TRUE;
476 }
477 };
478
479
480
481 Thread t = new Thread(new Runnable() {
482 public void run() {
483 try {
484 c.call();
485 } catch(Exception e){}
486 }
487 });
488 try {
489 t.start();
490 Thread.sleep(SHORT_DELAY_MS);
491 t.interrupt();
492 t.join();
493 } catch(InterruptedException e){
494 unexpectedException();
495 }
496
497 joinPool(p);
498 }
499
500 /**
501 * invoke(Executor, Callable) will throw ExecutionException
502 * if callable throws exception
503 */
504 public void testInvoke6() {
505 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
506
507 try {
508 Callable c = new Callable() {
509 public Object call() {
510 int i = 5/0;
511 return Boolean.TRUE;
512 }
513 };
514
515 for(int i =0; i < 5; i++){
516 Executors.invoke(p,c);
517 }
518
519 shouldThrow();
520 }
521 catch(ExecutionException success){
522 } catch(Exception e) {
523 unexpectedException();
524 }
525 joinPool(p);
526 }
527
528
529
530 /**
531 * timeouts from execute will time out if they compute too long.
532 */
533 public void testTimedCallable() {
534 int N = 10000;
535 ExecutorService executor = Executors.newSingleThreadExecutor();
536 List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
537 try {
538 long startTime = System.currentTimeMillis();
539
540 long i = 0;
541 while (tasks.size() < N) {
542 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
543 i += 10;
544 }
545
546 int iters = 0;
547 BigInteger sum = BigInteger.ZERO;
548 for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
549 try {
550 ++iters;
551 sum = sum.add(it.next().call());
552 }
553 catch (TimeoutException success) {
554 assertTrue(iters > 0);
555 return;
556 }
557 catch (Exception e) {
558 unexpectedException();
559 }
560 }
561 // if by chance we didn't ever time out, total time must be small
562 long elapsed = System.currentTimeMillis() - startTime;
563 assertTrue(elapsed < N);
564 }
565 finally {
566 joinPool(executor);
567 }
568 }
569
570
571
572
573 }