ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
Revision: 1.6
Committed: Mon Aug 3 22:06:50 2009 UTC (14 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.5: +15 -29 lines
Log Message:
remove calls to unexpectedException

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 * Other contributors include John Vint
6 */
7
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.concurrent.atomic.AtomicInteger;
11 import java.util.concurrent.*;
12 import junit.framework.Test;
13 import junit.framework.TestSuite;
14
15 public class PhaserTest extends JSR166TestCase {
16
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run(suite());
19 }
20
21 public static Test suite() {
22 return new TestSuite(PhaserTest.class);
23 }
24
25 /**
26 * Empty constructor builds a new Phaser with no parent, no registered
27 * parties and initial phase number of 0
28 */
29 public void testConstructor1() {
30 Phaser phaser = new Phaser();
31 assertNull(phaser.getParent());
32 assertEquals(0, phaser.getArrivedParties());
33 assertEquals(0, phaser.getPhase());
34 }
35
36 /**
37 * A negative party number for the constructor throws illegal argument
38 * exception
39 */
40 public void testConstructor2() {
41 try {
42 new Phaser(-1);
43 shouldThrow();
44 } catch (IllegalArgumentException success) {
45 }
46 }
47
48 /**
49 * The parent being input into the constructor should equal the original
50 * parent when being returned
51 */
52 public void testConstructor3() {
53 Phaser parent = new Phaser();
54 assertEquals(parent, new Phaser(parent).getParent());
55 }
56
57 /**
58 * A negative party number for the constructor throws illegal argument
59 * exception
60 */
61 public void testConstructor4() {
62 try {
63 new Phaser(new Phaser(), -1);
64 shouldThrow();
65 } catch (IllegalArgumentException success) {
66 }
67 }
68
69 /**
70 * The parent being input into the parameter should equal the original
71 * parent when being returned
72 */
73 public void testConstructor5() {
74 Phaser parent = new Phaser();
75 assertEquals(parent, new Phaser(parent, 0).getParent());
76 }
77
78 /**
79 * register() will increment the number of unarrived parties by one and not
80 * affect its arrived parties
81 */
82 public void testRegister1() {
83 Phaser phaser = new Phaser();
84 assertEquals(0, phaser.getUnarrivedParties());
85 phaser.register();
86 assertEquals(1, phaser.getUnarrivedParties());
87 assertEquals(0, phaser.getArrivedParties());
88 }
89
90 /**
91 * Registering more than 65536 parties causes IllegalStateException
92 */
93 public void testRegister2() {
94 Phaser phaser = new Phaser(0);
95 int expectedUnnarivedParties = (1 << 16) - 1;
96 for (int i = 0; i < expectedUnnarivedParties; i++) {
97 phaser.register();
98 assertEquals(i + 1, phaser.getUnarrivedParties());
99 }
100 try {
101 phaser.register();
102 shouldThrow();
103 } catch (IllegalStateException success) {
104 }
105 }
106
107 /**
108 * register() correctly returns the current barrier phase number when
109 * invoked
110 */
111 public void testRegister3() {
112 Phaser phaser = new Phaser();
113 assertEquals(0, phaser.register());
114 phaser.arrive();
115 assertEquals(1, phaser.register());
116 }
117
118 /**
119 * register causes the next arrive to not increment the phase rather retain
120 * the phase number
121 */
122 public void testRegister4() {
123 Phaser phaser = new Phaser(1);
124 phaser.arrive();
125 int expectedPhase = phaser.register();
126 phaser.arrive();
127 assertEquals(expectedPhase, phaser.getPhase());
128 }
129
130 public void testRegister5() {
131 Phaser phaser = new Phaser();
132 phaser.register();
133 assertEquals(1, phaser.getUnarrivedParties());
134 }
135
136 /**
137 * Invoking bulkRegister with a negative parameter throws an
138 * IllegalArgumentException
139 */
140 public void testBulkRegister1() {
141 try {
142 new Phaser().bulkRegister(-1);
143 shouldThrow();
144 } catch (IllegalArgumentException success) {
145 }
146 }
147
148 /**
149 * bulkRegister should correctly record the number of unarrived parties with
150 * the number of parties being registered
151 */
152 public void testBulkRegister2() {
153 Phaser phaser = new Phaser();
154 phaser.bulkRegister(20);
155 assertEquals(20, phaser.getUnarrivedParties());
156 }
157
158 /**
159 * Registering with a number of parties greater than or equal to 1<<16
160 * throws IllegalStateException.
161 */
162 public void testBulkRegister3() {
163 try {
164 new Phaser().bulkRegister(1 << 16);
165 shouldThrow();
166 } catch (IllegalStateException success) {
167 }
168 }
169
170 /**
171 * the phase number increments correctly when tripping the barrier
172 */
173 public void testPhaseIncrement1() {
174 for (int size = 1; size < nine; size++) {
175 final Phaser phaser = new Phaser(size);
176 for (int index = 0; index <= (1 << size); index++) {
177 int phase = phaser.arrive();
178 assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
179 }
180 }
181 }
182
183 /**
184 * Arrive() on a registered phaser increments phase.
185 */
186 public void testArrive1() {
187 Phaser phaser = new Phaser(1);
188 phaser.arrive();
189 assertEquals(1, phaser.getPhase());
190 }
191
192 /**
193 * arrive does not wait for others to arrive at barrier
194 */
195 public void testArrive2() {
196 final Phaser phaser = new Phaser(1);
197 phaser.register();
198 Thread thread = null;
199 for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
200 phaser.register();
201 thread = new Thread(new CheckedRunnable() {
202 void realRun() {
203 r.run();
204 phaser.arriveAndDeregister();
205 }});
206 thread.start();
207 }
208
209 phaser.arrive();
210 assertTrue(thread.isAlive());
211 assertFalse(phaser.isTerminated());
212 }
213
214 /**
215 * arrive() returns a negative number if the Phaser is terminated
216 */
217 public void testArrive3() {
218 Phaser phaser = new Phaser(1);
219 phaser.forceTermination();
220 assertTrue(phaser.arrive() < 0);
221
222 }
223
224 /**
225 * arriveAndDeregister() throws IllegalStateException if number of
226 * registered or unarrived parties would become negative
227 */
228 public void testArriveAndDeregister1() {
229 try {
230 Phaser phaser = new Phaser();
231 phaser.arriveAndDeregister();
232 shouldThrow();
233 } catch (IllegalStateException success) {
234 }
235 }
236
237 /**
238 * arriveAndDeregister deregisters reduces the number of arrived parties
239 */
240 public void testArriveAndDergeister2() {
241 final Phaser phaser = new Phaser(1);
242 phaser.register();
243 phaser.arrive();
244 int p = phaser.getArrivedParties();
245 assertTrue(p == 1);
246 phaser.arriveAndDeregister();
247 assertTrue(phaser.getArrivedParties() < p);
248 }
249
250 /**
251 * arriveAndDeregister arrives to the barrier on a phaser with a parent and
252 * when a deregistration occurs and causes the phaser to have zero parties
253 * its parent will be deregistered as well
254 */
255 public void testArriveAndDeregsiter3() {
256 Phaser parent = new Phaser();
257 Phaser root = new Phaser(parent);
258 root.register();
259 assertTrue(parent.getUnarrivedParties() > 0);
260 assertTrue(root.getUnarrivedParties() > 0);
261 root.arriveAndDeregister();
262 assertTrue(parent.getUnarrivedParties() == 0);
263 assertTrue(root.getUnarrivedParties() == 0);
264 assertTrue(root.isTerminated() && parent.isTerminated());
265 }
266
267 /**
268 * arriveAndDeregister deregisters one party from its parent when
269 * the number of parties of root is zero after deregistration
270 */
271 public void testArriveAndDeregsiter4() {
272 Phaser parent = new Phaser();
273 Phaser root = new Phaser(parent);
274 parent.register();
275 root.register();
276 int parentParties = parent.getUnarrivedParties();
277 root.arriveAndDeregister();
278 assertEquals(parentParties - 1, parent.getUnarrivedParties());
279 }
280
281 /**
282 * arriveAndDeregister deregisters one party from its parent when
283 * the number of parties of root is nonzero after deregistration.
284 */
285 public void testArriveAndDeregister5() {
286 Phaser parent = new Phaser();
287 Phaser child = new Phaser(parent);
288 Phaser root = new Phaser(child);
289 assertTrue(parent.getUnarrivedParties() > 0);
290 assertTrue(child.getUnarrivedParties() > 0);
291 root.register();
292 root.arriveAndDeregister();
293 assertTrue(parent.getUnarrivedParties() == 0);
294 assertTrue(child.getUnarrivedParties() == 0);
295 assertTrue(root.isTerminated());
296 }
297
298 /**
299 * arriveAndDeregister returns the phase in which it leaves the
300 * phaser in after deregistration
301 */
302 public void testArriveAndDeregister6() {
303 final Phaser phaser = new Phaser(2);
304 new Thread(new CheckedRunnable() {
305 void realRun() {
306 getRunnable(SHORT_DELAY_MS).run();
307 phaser.arrive();
308 }}).start();
309 phaser.arriveAndAwaitAdvance();
310 int phase = phaser.arriveAndDeregister();
311 assertEquals(phase, phaser.getPhase());
312 }
313
314 /**
315 * awaitAdvance succeeds upon advance
316 */
317 public void testAwaitAdvance1() {
318 final Phaser phaser = new Phaser(1);
319 phaser.awaitAdvance(phaser.arrive());
320 }
321
322 /**
323 * awaitAdvance with a negative parameter will return without affecting the
324 * phaser
325 */
326 public void testAwaitAdvance2() {
327 Phaser phaser = new Phaser();
328 phaser.awaitAdvance(-1);
329 }
330
331 /**
332 * awaitAdvance while waiting does not abort on interrupt.
333 */
334 public void testAwaitAdvance3() throws InterruptedException {
335 final Phaser phaser = new Phaser();
336
337 Thread th1 = new Thread(new CheckedRunnable() {
338 void realRun() throws InterruptedException {
339 phaser.register();
340 getRunnable(LONG_DELAY_MS).run();
341 phaser.awaitAdvance(phaser.arrive());
342 }});
343 phaser.register();
344 th1.start();
345 Thread.sleep(SHORT_DELAY_MS);
346 th1.interrupt();
347 Thread.sleep(LONG_DELAY_MS);
348 phaser.arrive();
349 assertFalse(th1.isInterrupted());
350 }
351
352 /**
353 * awaitAdvance atomically waits for all parties within the same phase to
354 * complete before continuing
355 */
356 public void testAwaitAdvance4() throws InterruptedException {
357 final Phaser phaser = new Phaser(4);
358 final AtomicInteger phaseCount = new AtomicInteger(0);
359 List<Thread> threads = new ArrayList<Thread>();
360 for (int i = 0; i < 4; i++) {
361 threads.add(new Thread(new CheckedRunnable() {
362 void realRun() {
363 int phase = phaser.arrive();
364 phaseCount.incrementAndGet();
365 getRunnable(LONG_DELAY_MS).run();
366 phaser.awaitAdvance(phase);
367 threadAssertTrue(phaseCount.get() == 4);
368 }}));
369 }
370 for (Thread thread : threads)
371 thread.start();
372 for (Thread thread : threads)
373 thread.join();
374 }
375
376 /**
377 * awaitAdvance returns the current phase
378 */
379 public void testAwaitAdvance5() {
380 final Phaser phaser = new Phaser(1);
381 int phase = phaser.awaitAdvance(phaser.arrive());
382 assertEquals(phase, phaser.getPhase());
383 phaser.register();
384 for (int i = 0; i < eight; i++) {
385 new Thread(new CheckedRunnable() {
386 void realRun() {
387 getRunnable(SHORT_DELAY_MS).run();
388 phaser.arrive();
389 }}).start();
390 phase = phaser.awaitAdvance(phaser.arrive());
391 threadAssertEquals(phase, phaser.getPhase());
392 }
393 }
394
395 /**
396 * awaitAdvance returns when the phaser is externally terminated
397 */
398 public void testAwaitAdvance6() {
399 final Phaser phaser = new Phaser(3);
400 /*
401 * Start new thread. This thread waits a small amount of time
402 * and waits for the other two parties to arrive. The party
403 * in the main thread arrives quickly so at best this thread
404 * waits for the second thread's party to arrive
405 */
406 new Thread(new CheckedRunnable() {
407 void realRun() {
408 getRunnable(SMALL_DELAY_MS).run();
409 int phase = phaser.awaitAdvance(phaser.arrive());
410 /*
411 * This point is reached when force termination is called in which phase = -1
412 */
413 threadAssertTrue(phase < 0);
414 threadAssertTrue(phaser.isTerminated());
415 }}).start();
416 /*
417 * This thread will cause the first thread run to wait, in doing so
418 * the main thread will force termination in which the first thread
419 * should exit peacefully as this one
420 */
421 new Thread(new CheckedRunnable() {
422 void realRun() {
423 getRunnable(LONG_DELAY_MS).run();
424 int p1 = phaser.arrive();
425 int phase = phaser.awaitAdvance(p1);
426 threadAssertTrue(phase < 0);
427 threadAssertTrue(phaser.isTerminated());
428 }}).start();
429
430 phaser.arrive();
431 phaser.forceTermination();
432 }
433
434 /**
435 * arriveAndAwaitAdvance throws IllegalStateException with no
436 * unarrived parties
437 */
438 public void testArriveAndAwaitAdvance1() {
439 try {
440 Phaser phaser = new Phaser();
441 phaser.arriveAndAwaitAdvance();
442 shouldThrow();
443 } catch (IllegalStateException success) {
444 }
445 }
446
447 /**
448 * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
449 */
450 public void testArriveAndAwaitAdvance2() throws InterruptedException {
451 final Phaser phaser = new Phaser(2);
452 Thread th = new Thread(new CheckedRunnable() {
453 void realRun() {
454 phaser.arriveAndAwaitAdvance();
455 }});
456
457 th.start();
458 Thread.sleep(LONG_DELAY_MS);
459 th.interrupt();
460 Thread.sleep(LONG_DELAY_MS);
461 phaser.arrive();
462 assertFalse(th.isInterrupted());
463 }
464
465 /**
466 * arriveAndAwaitAdvance waits for all threads to arrive, the
467 * number of arrived parties is the same number that is accounted
468 * for when the main thread awaitsAdvance
469 */
470 public void testArriveAndAwaitAdvance3() {
471 final Phaser phaser = new Phaser(1);
472 final AtomicInteger arrivingCount = new AtomicInteger(0);
473 for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
474 new Thread(new CheckedRunnable() {
475 void realRun() {
476 phaser.register();
477 run.run();
478 arrivingCount.getAndIncrement();
479 phaser.arrive();
480 }}).start();
481 }
482 int phaseNumber = phaser.arriveAndAwaitAdvance();
483 arrivingCount.incrementAndGet();
484 //the + 1 adds to expectedArrive to account for the main threads arrival
485 int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
486 threadAssertEquals(expectedArrived, arrivingCount.get());
487 }
488 // .. initially called, for n tasks via
489 private List<Runnable> getRunnables(int size, long wait) {
490 List<Runnable> list = new ArrayList<Runnable>();
491 for (int i = 0; i < size; i++) {
492 list.add(getRunnable(wait));
493 }
494 return list;
495 }
496
497 private Runnable getRunnable(final long wait) {
498 return new CheckedRunnable() {
499 void realRun() {
500 try {
501 Thread.sleep(wait);
502 } catch (InterruptedException noop) {
503 // sleep interruption isn't a problem case for these example
504 }
505 }
506 };
507 }
508
509 }