ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
Revision: 1.2
Committed: Fri Jul 31 23:37:31 2009 UTC (14 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +3 -3 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.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     this.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 any more then 65536 parties causes IllegalStateExceptiom
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     } catch (Exception ex) {
105     threadUnexpectedException(ex);
106     }
107     }
108    
109     /**
110     * register() correctly returns the current barrier phase number when
111     * invoked
112     */
113     public void testRegister3() {
114     Phaser phaser = new Phaser();
115     assertEquals(0, phaser.register());
116     phaser.arrive();
117     assertEquals(1, phaser.register());
118     }
119    
120     /**
121     * register causes the next arrive to not increment the phase rather retain
122     * the phase number
123     */
124     public void testRegister4() {
125     Phaser phaser = new Phaser(1);
126     phaser.arrive();
127     int expectedPhase = phaser.register();
128     phaser.arrive();
129     assertEquals(expectedPhase, phaser.getPhase());
130     }
131    
132     public void testRegister5() {
133     Phaser phaser = new Phaser();
134     phaser.register();
135     assertEquals(1, phaser.getUnarrivedParties());
136     }
137    
138     /**
139     * Invoking bulkRegister with a negative parameter throws an
140     * IllegalArgumentExceptiom
141     */
142     public void testBulkRegister1() {
143     try {
144     new Phaser().bulkRegister(-1);
145     shouldThrow();
146     } catch (IllegalArgumentException success) {
147     }
148     }
149    
150     /**
151     * bulkRegister should correctly record the number of unarrived parties with
152     * the number of parties being registered
153     */
154     public void testBulkRegister2() {
155     Phaser phaser = new Phaser();
156     phaser.bulkRegister(20);
157     assertEquals(20, phaser.getUnarrivedParties());
158     }
159    
160     /**
161     * Registering with a number of parties greater then or equal to 1<<16
162     * throws IllegalStateExceptiom.
163     */
164     public void testBulkRegister3() {
165     try {
166     new Phaser().bulkRegister(1 << 16);
167     shouldThrow();
168     } catch (IllegalStateException success) {
169     }
170     }
171    
172     /**
173     * the phase number increments correctly when tripping the barrier
174     */
175     public void testPhaseIncrement1() {
176     for (int size = 1; size < nine; size++) {
177     final Phaser phaser = new Phaser(size);
178     for (int index = 0; index <= (1 << size); index++) {
179     int phase = phaser.arrive();
180     assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
181     }
182     }
183     }
184    
185     /**
186     * Arrive() on a registered phaser increments phase.
187     */
188     public void testArrive1() {
189     Phaser phaser = new Phaser(1);
190     phaser.arrive();
191     assertEquals(1, phaser.getPhase());
192     }
193    
194     /**
195     * arrive does not wait for others to arrive at barrier
196     */
197     public void testArrive2() {
198     final Phaser phaser = new Phaser(1);
199     phaser.register();
200     Thread thread = null;
201     for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
202     phaser.register();
203     thread = new Thread() {
204    
205     public void run() {
206     r.run();
207     phaser.arriveAndDeregister();
208     }
209     };
210     thread.start();
211     }
212    
213     phaser.arrive();
214     assertTrue(thread.isAlive());
215     assertFalse(phaser.isTerminated());
216     }
217    
218     /**
219     * arrive() returns a negative number if the Phaser is termindated
220     */
221     public void testArrive3() {
222     Phaser phaser = new Phaser(1);
223     phaser.forceTermination();
224     assertTrue(phaser.arrive() < 0);
225    
226     }
227    
228     /**
229     * arriveAndDeregister() throws IllegalStateException if number of
230     * registered or unnarived parties would become negative
231     */
232     public void testArriveAndDeregister1() {
233     try {
234     Phaser phaser = new Phaser();
235     phaser.arriveAndDeregister();
236     shouldThrow();
237    
238     } catch (IllegalStateException success) {
239     }
240     }
241    
242     /**
243     * arriveAndDeregister derigisters reduces the number of arrived parties
244     */
245     public void testArriveAndDergeister2() {
246     final Phaser phaser = new Phaser(1);
247     phaser.register();
248     phaser.arrive();
249     int p = phaser.getArrivedParties();
250     assertTrue(p == 1);
251     phaser.arriveAndDeregister();
252     assertTrue(phaser.getArrivedParties() < p);
253     }
254    
255     /**
256     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
257     * when a deregistration occurs and causes the phaser to have zero parties
258     * its parent will be deregistered as well
259     */
260     public void testArriveAndDeregsiter3() {
261     Phaser parent = new Phaser();
262     Phaser root = new Phaser(parent);
263     root.register();
264     assertTrue(parent.getUnarrivedParties() > 0);
265     assertTrue(root.getUnarrivedParties() > 0);
266     root.arriveAndDeregister();
267     assertTrue(parent.getUnarrivedParties() == 0);
268     assertTrue(root.getUnarrivedParties() == 0);
269     assertTrue(root.isTerminated() && parent.isTerminated());
270     }
271    
272     /**
273     * arriveAndDeregister deregisters one party from its parent when
274     * the number of parties of root is zero after deregistration
275     */
276     public void testArriveAndDeregsiter4() {
277     Phaser parent = new Phaser();
278     Phaser root = new Phaser(parent);
279     parent.register();
280     root.register();
281     int parentParties = parent.getUnarrivedParties();
282     root.arriveAndDeregister();
283     assertEquals(parentParties - 1, parent.getUnarrivedParties());
284     }
285    
286     /**
287     * arriveAndDeregister deregisters one party from its parent when
288     * the number of parties of root is nonzero after deregistration.
289     */
290     public void testArriveAndDeregister5() {
291     Phaser parent = new Phaser();
292     Phaser child = new Phaser(parent);
293     Phaser root = new Phaser(child);
294     assertTrue(parent.getUnarrivedParties() > 0);
295     assertTrue(child.getUnarrivedParties() > 0);
296     root.register();
297     root.arriveAndDeregister();
298     assertTrue(parent.getUnarrivedParties() == 0);
299     assertTrue(child.getUnarrivedParties() == 0);
300     assertTrue(root.isTerminated());
301     }
302    
303     /**
304     * arriveAndDeregister returns the phase in which it leaves the
305     * phaser in after deregistration
306     */
307     public void testArriveAndDeregister6() {
308     final Phaser phaser = new Phaser(2);
309     new Thread() {
310    
311     public void run() {
312     getRunnable(SHORT_DELAY_MS).run();
313     phaser.arrive();
314     }
315     }.start();
316     phaser.arriveAndAwaitAdvance();
317     int phase = phaser.arriveAndDeregister();
318     assertEquals(phase, phaser.getPhase());
319     }
320    
321     /**
322     * awaitAdvance succeeds upon advance
323     */
324     public void testAwaitAdvance1() {
325     final Phaser phaser = new Phaser(1);
326     phaser.awaitAdvance(phaser.arrive());
327     }
328    
329     /**
330     * awaitAdvance with a negative parameter will return without affecting the
331     * phaser
332     */
333     public void testAwaitAdvance2() {
334     try {
335     Phaser phaser = new Phaser();
336     phaser.awaitAdvance(-1);
337     } catch (Exception failure) {
338     this.unexpectedException();
339     }
340     }
341    
342     /**
343     * awaitAdvance while waiting does not abort on interrupt.
344     */
345     public void testAwaitAdvance3() {
346     final Phaser phaser = new Phaser();
347     Thread th1 = new Thread() {
348    
349     public void run() {
350     try {
351     phaser.register();
352     getRunnable(LONG_DELAY_MS).run();
353     phaser.awaitAdvance(phaser.arrive());
354     } catch (Exception failure) {
355     threadUnexpectedException(failure);
356     }
357    
358     }
359     };
360     phaser.register();
361     th1.start();
362     try {
363     Thread.sleep(SHORT_DELAY_MS);
364     th1.interrupt();
365     Thread.sleep(LONG_DELAY_MS);
366     phaser.arrive();
367     } catch (Exception failure) {
368     unexpectedException();
369     }
370     assertFalse(th1.isInterrupted());
371     }
372    
373     /**
374     * awaitAdvance atomically waits for all parties within the same phase to
375     * complete before continuing
376     */
377     public void testAwaitAdvance4() {
378     final Phaser phaser = new Phaser(four);
379     final AtomicInteger phaseCount = new AtomicInteger(0);
380     for (int i = 0; i < four; i++) {
381     new Thread() {
382    
383     public void run() {
384     int phase = phaser.arrive();
385     phaseCount.incrementAndGet();
386     getRunnable(LONG_DELAY_MS).run();
387     phaser.awaitAdvance(phase);
388     assertTrue(phaseCount.get() == four);
389     }
390     }.start();
391     }
392     }
393    
394     /**
395     * awaitAdvance returns the current phase
396     */
397     public void testAwaitAdvance5() {
398     final Phaser phaser = new Phaser(1);
399     int phase = phaser.awaitAdvance(phaser.arrive());
400     assertEquals(phase, phaser.getPhase());
401     phaser.register();
402     for (int i = 0; i < eight; i++) {
403     new Thread() {
404    
405     public void run() {
406     getRunnable(SHORT_DELAY_MS).run();
407     phaser.arrive();
408     }
409     }.start();
410     phase = phaser.awaitAdvance(phaser.arrive());
411     assertEquals(phase, phaser.getPhase());
412     }
413     }
414    
415     /**
416     * awaitAdvance returns when the phaser is externally terminated
417     */
418     public void testAwaitAdvance6() {
419     final Phaser phaser = new Phaser(3);
420     /*
421     * Start new thread. This thread waits a small amount of time
422     * and waits for the other two parties to arrive. The party
423     * in the main thread arrives quickly so at best this thread
424     * waits for the second thread's party to arrive
425     */
426     new Thread() {
427 jsr166 1.2
428 dl 1.1 public void run() {
429     getRunnable(SMALL_DELAY_MS).run();
430     int phase = phaser.awaitAdvance(phaser.arrive());
431     /*
432     * This point is reached when force termination is called in which phase = -1
433     */
434     threadAssertTrue(phase < 0);
435     threadAssertTrue(phaser.isTerminated());
436     }
437     }.start();
438     /*
439     * This thread will cause the first thread run to wait, in doing so
440 jsr166 1.2 * the main thread will force termination in which the first thread
441     * should exit peacefully as this one
442 dl 1.1 */
443     new Thread() {
444    
445     public void run() {
446     getRunnable(LONG_DELAY_MS).run();
447     int p1 = phaser.arrive();
448     int phase = phaser.awaitAdvance(p1);
449     threadAssertTrue(phase < 0);
450     threadAssertTrue(phaser.isTerminated());
451     }
452     }.start();
453    
454     phaser.arrive();
455     phaser.forceTermination();
456     }
457    
458     /**
459     * arriveAndAwaitAdvance throws IllegalStateException with no
460     * unarrived parties
461     */
462     public void testArriveAndAwaitAdvance1() {
463     try {
464     Phaser phaser = new Phaser();
465     phaser.arriveAndAwaitAdvance();
466     shouldThrow();
467     } catch (IllegalStateException success) {
468     }
469     }
470    
471     /**
472     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
473     */
474     public void testArriveAndAwaitAdvance2() {
475     final Phaser phaser = new Phaser(2);
476     Thread th = new Thread() {
477     public void run() {
478     try {
479     phaser.arriveAndAwaitAdvance();
480     } catch (Exception failure) {
481     threadUnexpectedException(failure);
482     }
483     }
484     };
485    
486     try {
487     th.start();
488     Thread.sleep(LONG_DELAY_MS);
489     th.interrupt();
490     Thread.sleep(LONG_DELAY_MS);
491     phaser.arrive();
492     } catch (InterruptedException failure) {
493     this.unexpectedException();
494     }
495     assertFalse(th.isInterrupted());
496     }
497    
498     /**
499     * arriveAndAwaitAdvance waits for all threads to arrive, the
500     * number of arrived parties is the same number that is accounted
501     * for when the main thread awaitsAdvance
502     */
503     public void testArriveAndAwaitAdvance3() {
504     final Phaser phaser = new Phaser(1);
505     final AtomicInteger arrivingCount = new AtomicInteger(0);
506     for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
507     new Thread() {
508    
509     public void run() {
510     phaser.register();
511     run.run();
512     arrivingCount.getAndIncrement();
513     phaser.arrive();
514     }
515     }.start();
516     }
517     int phaseNumber = phaser.arriveAndAwaitAdvance();
518     arrivingCount.incrementAndGet();
519     //the + 1 adds to expectedArrive to account for the main threads arrival
520     int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
521     threadAssertEquals(expectedArrived, arrivingCount.get());
522     }
523     // .. initially called, for n tasks via
524     private List<Runnable> getRunnables(int size, long wait) {
525     List<Runnable> list = new ArrayList<Runnable>();
526     for (int i = 0; i < size; i++) {
527     list.add(getRunnable(wait));
528     }
529     return list;
530     }
531    
532     private Runnable getRunnable(final long wait) {
533     return new Runnable() {
534    
535     public void run() {
536     try {
537     Thread.sleep(wait);
538     } catch (InterruptedException noop) {
539     // sleep interruption isn't a problem case for these example
540     } catch (Exception ex) {
541     threadUnexpectedException(ex);
542     }
543    
544     }
545     };
546     }
547    
548     }