ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.2
Committed: Sun Sep 7 20:39:11 2003 UTC (20 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.1: +85 -0 lines
Log Message:
Added serialization and lock 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 TestCase{
15
16 public static void main(String[] args) {
17 junit.textui.TestRunner.run (suite());
18 }
19
20
21 public static Test suite() {
22 return new TestSuite(ExecutorsTest.class);
23 }
24
25 private static long SHORT_DELAY_MS = 100;
26 private static long MEDIUM_DELAY_MS = 1000;
27 private static long LONG_DELAY_MS = 10000;
28
29 class SleepRun implements Runnable {
30 public void run() {
31 try{
32 Thread.sleep(MEDIUM_DELAY_MS);
33 } catch(InterruptedException e){
34 fail("unexpected exception");
35 }
36 }
37 }
38
39
40 class SleepCall implements Callable {
41 public Object call(){
42 try{
43 Thread.sleep(MEDIUM_DELAY_MS);
44 }catch(InterruptedException e){
45 fail("unexpected exception");
46 }
47 return Boolean.TRUE;
48 }
49 }
50
51
52
53 /**
54 * Test to verify execute(Executor, Runnable) will throw
55 * RejectedExecutionException Attempting to execute a runnable on
56 * a full ThreadPool will cause such an exception here, up to 5
57 * runnables are attempted on a pool capable on handling one
58 * until it throws an exception
59 */
60 public void testExecute1(){
61 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
62 try{
63
64 for(int i = 0; i < 5; ++i){
65 Executors.execute(p, new SleepRun(), Boolean.TRUE);
66 }
67 fail("should throw");
68 } catch(RejectedExecutionException success){}
69 p.shutdownNow();
70 }
71
72 /**
73 * Test to verify execute(Executor, Callable) will throw
74 * RejectedExecutionException Attempting to execute a callable on
75 * a full ThreadPool will cause such an exception here, up to 5
76 * runnables are attempted on a pool capable on handling one
77 * until it throws an exception
78 */
79 public void testExecute2(){
80 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
81 try{
82 for(int i = 0; i < 5; ++i) {
83 Executors.execute(p, new SleepCall());
84 }
85 fail("should throw");
86 }catch(RejectedExecutionException e){}
87 p.shutdownNow();
88 }
89
90
91 /**
92 * Test to verify invoke(Executor, Runnable) throws InterruptedException
93 * A single use of invoke starts that will wait long enough
94 * for the invoking thread to be interrupted
95 */
96 public void testInvoke2(){
97 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
98 Thread t = new Thread(new Runnable() {
99 public void run(){
100 try{
101 Executors.invoke(p,new Runnable(){
102 public void run(){
103 try{
104 Thread.sleep(MEDIUM_DELAY_MS);
105 fail("should throw");
106 }catch(InterruptedException e){
107 }
108 }
109 });
110 } catch(InterruptedException success){
111 } catch(Exception e) {
112 fail("unexpected exception");
113 }
114
115 }
116 });
117 try{
118 t.start();
119 Thread.sleep(SHORT_DELAY_MS);
120 t.interrupt();
121 }catch(Exception e){
122 fail("unexpected exception");
123 }
124 p.shutdownNow();
125 }
126
127 /**
128 * Test to verify invoke(Executor, Runnable) will throw
129 * ExecutionException An ExecutionException occurs when the
130 * underlying Runnable throws an exception, here the
131 * DivideByZeroException will cause an ExecutionException
132 */
133 public void testInvoke3(){
134 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
135 try{
136 Runnable r = new Runnable(){
137 public void run(){
138 int i = 5/0;
139 }
140 };
141
142 for(int i =0; i < 5; i++){
143 Executors.invoke(p,r);
144 }
145
146 fail("should throw");
147 } catch(ExecutionException success){
148 } catch(Exception e){
149 fail("should throw EE");
150 }
151 p.shutdownNow();
152 }
153
154
155
156 /**
157 * Test to verify invoke(Executor, Callable) throws
158 * InterruptedException A single use of invoke starts that will
159 * wait long enough for the invoking thread to be interrupted
160 */
161 public void testInvoke5(){
162 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
163
164 final Callable c = new Callable(){
165 public Object call(){
166 try{
167 Executors.invoke(p, new SleepCall());
168 fail("should throw");
169 }catch(InterruptedException e){}
170 catch(RejectedExecutionException e2){}
171 catch(ExecutionException e3){}
172 return Boolean.TRUE;
173 }
174 };
175
176
177
178 Thread t = new Thread(new Runnable(){
179 public void run(){
180 try{
181 c.call();
182 }catch(Exception e){}
183 }
184 });
185 try{
186 t.start();
187 Thread.sleep(SHORT_DELAY_MS);
188 t.interrupt();
189 t.join();
190 }catch(InterruptedException e){
191 fail("unexpected exception");
192 }
193
194 p.shutdownNow();
195 }
196
197 /**
198 * Test to verify invoke(Executor, Callable) will throw ExecutionException
199 * An ExecutionException occurs when the underlying Runnable throws
200 * an exception, here the DivideByZeroException will cause an ExecutionException
201 */
202 public void testInvoke6(){
203 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,100L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
204
205 try{
206 Callable c = new Callable(){
207 public Object call(){
208 int i = 5/0;
209 return Boolean.TRUE;
210 }
211 };
212
213 for(int i =0; i < 5; i++){
214 Executors.invoke(p,c);
215 }
216
217 fail("should throw");
218 }catch(RejectedExecutionException e){}
219 catch(InterruptedException e2){}
220 catch(ExecutionException e3){}
221 p.shutdownNow();
222 }
223
224 public void testExecuteRunnable () {
225 try {
226 Executor e = new DirectExecutor();
227 Task task = new Task();
228
229 assertFalse("task should not be complete", task.isCompleted());
230
231 Future<String> future = Executors.execute(e, task, TEST_STRING);
232 String result = future.get();
233
234 assertTrue("task should be complete", task.isCompleted());
235 assertSame("should return test string", TEST_STRING, result);
236 }
237 catch (ExecutionException ex) {
238 fail("Unexpected exception");
239 }
240 catch (InterruptedException ex) {
241 fail("Unexpected exception");
242 }
243 }
244
245 public void testInvokeRunnable () {
246 try {
247 Executor e = new DirectExecutor();
248 Task task = new Task();
249
250 assertFalse("task should not be complete", task.isCompleted());
251
252 Executors.invoke(e, task);
253
254 assertTrue("task should be complete", task.isCompleted());
255 }
256 catch (ExecutionException ex) {
257 fail("Unexpected exception");
258 }
259 catch (InterruptedException ex) {
260 fail("Unexpected exception");
261 }
262 }
263
264 public void testExecuteCallable () {
265 try {
266 Executor e = new DirectExecutor();
267 Future<String> future = Executors.execute(e, new StringTask());
268 String result = future.get();
269
270 assertSame("should return test string", TEST_STRING, result);
271 }
272 catch (ExecutionException ex) {
273 fail("Unexpected exception");
274 }
275 catch (InterruptedException ex) {
276 fail("Unexpected exception");
277 }
278 }
279
280 public void testInvokeCallable () {
281 try {
282 Executor e = new DirectExecutor();
283 String result = Executors.invoke(e, new StringTask());
284
285 assertSame("should return test string", TEST_STRING, result);
286 }
287 catch (ExecutionException ex) {
288 fail("Unexpected exception" );
289 }
290 catch (InterruptedException ex) {
291 fail("Unexpected exception");
292 }
293 }
294
295 private static final String TEST_STRING = "a test string";
296
297 private static class Task implements Runnable {
298 public void run() { completed = true; }
299 public boolean isCompleted() { return completed; }
300 public void reset() { completed = false; }
301 private boolean completed = false;
302 }
303
304 private static class StringTask implements Callable<String> {
305 public String call() { return TEST_STRING; }
306 }
307
308 static class DirectExecutor implements Executor {
309 public void execute(Runnable r) {
310 r.run();
311 }
312 }
313
314 /**
315 * Check that timeouts from execute will time out if they compute
316 * too long.
317 */
318
319 public void testTimedCallable() {
320 int N = 10000;
321 ExecutorService executor = Executors.newSingleThreadExecutor();
322 List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
323 try {
324 long startTime = System.currentTimeMillis();
325
326 long i = 0;
327 while (tasks.size() < N) {
328 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
329 i += 10;
330 }
331
332 int iters = 0;
333 BigInteger sum = BigInteger.ZERO;
334 for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
335 try {
336 ++iters;
337 sum = sum.add(it.next().call());
338 }
339 catch (TimeoutException success) {
340 assertTrue(iters > 0);
341 return;
342 }
343 catch (Exception e) {
344 fail("unexpected exception: " + e);
345 }
346 }
347 // if by chance we didn't ever time out, total time must be small
348 long elapsed = System.currentTimeMillis() - startTime;
349 assertTrue(elapsed < N);
350 }
351 finally {
352 executor.shutdownNow();
353 }
354 }
355
356
357 static class TimedCallable<T> implements Callable<T> {
358 private final Executor exec;
359 private final Callable<T> func;
360 private final long msecs;
361
362 TimedCallable(Executor exec, Callable<T> func, long msecs) {
363 this.exec = exec;
364 this.func = func;
365 this.msecs = msecs;
366 }
367
368 public T call() throws Exception {
369 Future<T> ftask = Executors.execute(exec, func);
370 try {
371 return ftask.get(msecs, TimeUnit.MILLISECONDS);
372 } finally {
373 ftask.cancel(true);
374 }
375 }
376 }
377
378
379 private static class Fib implements Callable<BigInteger> {
380 private final BigInteger n;
381 Fib(long n) {
382 if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
383 this.n = BigInteger.valueOf(n);
384 }
385 public BigInteger call() {
386 BigInteger f1 = BigInteger.ONE;
387 BigInteger f2 = f1;
388 for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
389 BigInteger t = f1.add(f2);
390 f1 = f2;
391 f2 = t;
392 }
393 return f1;
394 }
395 };
396
397
398
399 }