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

# 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 jsr166 1.6 shouldThrow();
44 dl 1.1 } 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 jsr166 1.4 * Registering more than 65536 parties causes IllegalStateException
92 dl 1.1 */
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 jsr166 1.4 * IllegalArgumentException
139 dl 1.1 */
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 jsr166 1.4 * Registering with a number of parties greater than or equal to 1<<16
160     * throws IllegalStateException.
161 dl 1.1 */
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 jsr166 1.5 thread = new Thread(new CheckedRunnable() {
202     void realRun() {
203 dl 1.1 r.run();
204     phaser.arriveAndDeregister();
205 jsr166 1.5 }});
206 dl 1.1 thread.start();
207     }
208    
209     phaser.arrive();
210     assertTrue(thread.isAlive());
211     assertFalse(phaser.isTerminated());
212     }
213    
214     /**
215 jsr166 1.3 * arrive() returns a negative number if the Phaser is terminated
216 dl 1.1 */
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 jsr166 1.3 * registered or unarrived parties would become negative
227 dl 1.1 */
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 jsr166 1.3 * arriveAndDeregister deregisters reduces the number of arrived parties
239 dl 1.1 */
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 jsr166 1.5 new Thread(new CheckedRunnable() {
305     void realRun() {
306 dl 1.1 getRunnable(SHORT_DELAY_MS).run();
307     phaser.arrive();
308 jsr166 1.5 }}).start();
309 dl 1.1 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 jsr166 1.6 Phaser phaser = new Phaser();
328     phaser.awaitAdvance(-1);
329 dl 1.1 }
330    
331     /**
332     * awaitAdvance while waiting does not abort on interrupt.
333     */
334 jsr166 1.6 public void testAwaitAdvance3() throws InterruptedException {
335 dl 1.1 final Phaser phaser = new Phaser();
336    
337 jsr166 1.5 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 dl 1.1 phaser.register();
344     th1.start();
345 jsr166 1.6 Thread.sleep(SHORT_DELAY_MS);
346     th1.interrupt();
347     Thread.sleep(LONG_DELAY_MS);
348     phaser.arrive();
349 dl 1.1 assertFalse(th1.isInterrupted());
350     }
351    
352     /**
353     * awaitAdvance atomically waits for all parties within the same phase to
354     * complete before continuing
355     */
356 jsr166 1.5 public void testAwaitAdvance4() throws InterruptedException {
357     final Phaser phaser = new Phaser(4);
358 dl 1.1 final AtomicInteger phaseCount = new AtomicInteger(0);
359 jsr166 1.5 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 dl 1.1 int phase = phaser.arrive();
364     phaseCount.incrementAndGet();
365     getRunnable(LONG_DELAY_MS).run();
366     phaser.awaitAdvance(phase);
367 jsr166 1.5 threadAssertTrue(phaseCount.get() == 4);
368     }}));
369 dl 1.1 }
370 jsr166 1.5 for (Thread thread : threads)
371     thread.start();
372     for (Thread thread : threads)
373     thread.join();
374 dl 1.1 }
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 jsr166 1.5 new Thread(new CheckedRunnable() {
386     void realRun() {
387 dl 1.1 getRunnable(SHORT_DELAY_MS).run();
388     phaser.arrive();
389 jsr166 1.6 }}).start();
390 dl 1.1 phase = phaser.awaitAdvance(phaser.arrive());
391 jsr166 1.5 threadAssertEquals(phase, phaser.getPhase());
392 dl 1.1 }
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 jsr166 1.5 new Thread(new CheckedRunnable() {
407     void realRun() {
408 dl 1.1 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 jsr166 1.5 }}).start();
416 dl 1.1 /*
417     * This thread will cause the first thread run to wait, in doing so
418 jsr166 1.2 * the main thread will force termination in which the first thread
419     * should exit peacefully as this one
420 dl 1.1 */
421 jsr166 1.5 new Thread(new CheckedRunnable() {
422     void realRun() {
423 dl 1.1 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 jsr166 1.5 }}).start();
429 dl 1.1
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 jsr166 1.6 public void testArriveAndAwaitAdvance2() throws InterruptedException {
451 dl 1.1 final Phaser phaser = new Phaser(2);
452 jsr166 1.5 Thread th = new Thread(new CheckedRunnable() {
453     void realRun() {
454     phaser.arriveAndAwaitAdvance();
455     }});
456 dl 1.1
457 jsr166 1.6 th.start();
458     Thread.sleep(LONG_DELAY_MS);
459     th.interrupt();
460     Thread.sleep(LONG_DELAY_MS);
461     phaser.arrive();
462 dl 1.1 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 jsr166 1.5 new Thread(new CheckedRunnable() {
475     void realRun() {
476 dl 1.1 phaser.register();
477     run.run();
478     arrivingCount.getAndIncrement();
479     phaser.arrive();
480 jsr166 1.5 }}).start();
481 dl 1.1 }
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 jsr166 1.5 return new CheckedRunnable() {
499     void realRun() {
500 dl 1.1 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     }