blob: b8f8b24b86f3b5e578c66348434999bc577fdc66 [file] [log] [blame]
The Android Open Source Project0eec4642012-04-01 00:00:00 -07001/*
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 Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package tests.api.java.util.concurrent; // android-added
10
11import junit.framework.*;
12import java.util.*;
13import java.util.concurrent.*;
14import java.util.concurrent.locks.*;
15import java.util.concurrent.atomic.*;
16import static java.util.concurrent.TimeUnit.MILLISECONDS;
17
18public class CyclicBarrierTest extends JSR166TestCase {
19 public static Test suite() {
20 return new TestSuite(CyclicBarrierTest.class);
21 }
22
23 private volatile int countAction;
24 private class MyAction implements Runnable {
25 public void run() { ++countAction; }
26 }
27
28 /**
29 * Creating with negative parties throws IAE
30 */
31 public void testConstructor1() {
32 try {
33 new CyclicBarrier(-1, (Runnable)null);
34 shouldThrow();
35 } catch (IllegalArgumentException success) {}
36 }
37
38 /**
39 * Creating with negative parties and no action throws IAE
40 */
41 public void testConstructor2() {
42 try {
43 new CyclicBarrier(-1);
44 shouldThrow();
45 } catch (IllegalArgumentException success) {}
46 }
47
48 /**
49 * getParties returns the number of parties given in constructor
50 */
51 public void testGetParties() {
52 CyclicBarrier b = new CyclicBarrier(2);
53 assertEquals(2, b.getParties());
54 assertEquals(0, b.getNumberWaiting());
55 }
56
57 /**
58 * A 1-party barrier triggers after single await
59 */
60 public void testSingleParty() throws Exception {
61 CyclicBarrier b = new CyclicBarrier(1);
62 assertEquals(1, b.getParties());
63 assertEquals(0, b.getNumberWaiting());
64 b.await();
65 b.await();
66 assertEquals(0, b.getNumberWaiting());
67 }
68
69 /**
70 * The supplied barrier action is run at barrier
71 */
72 public void testBarrierAction() throws Exception {
73 countAction = 0;
74 CyclicBarrier b = new CyclicBarrier(1, new MyAction());
75 assertEquals(1, b.getParties());
76 assertEquals(0, b.getNumberWaiting());
77 b.await();
78 b.await();
79 assertEquals(0, b.getNumberWaiting());
80 assertEquals(countAction, 2);
81 }
82
83 /**
84 * A 2-party/thread barrier triggers after both threads invoke await
85 */
86 public void testTwoParties() throws Exception {
87 final CyclicBarrier b = new CyclicBarrier(2);
88 Thread t = new Thread(new CheckedRunnable() {
89 public void realRun() throws Exception {
90 b.await();
91 b.await();
92 b.await();
93 b.await();
94 }});
95
96 t.start();
97 b.await();
98 b.await();
99 b.await();
100 b.await();
101 t.join();
102 }
103
104
105 /**
106 * An interruption in one party causes others waiting in await to
107 * throw BrokenBarrierException
108 */
109 public void testAwait1_Interrupted_BrokenBarrier() throws Exception {
110 final CyclicBarrier c = new CyclicBarrier(3);
111 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
112 public void realRun() throws Exception {
113 c.await();
114 }};
115 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
116 public void realRun() throws Exception {
117 c.await();
118 }};
119
120 t1.start();
121 t2.start();
122 Thread.sleep(SHORT_DELAY_MS);
123 t1.interrupt();
124 t1.join();
125 t2.join();
126 }
127
128 /**
129 * An interruption in one party causes others waiting in timed await to
130 * throw BrokenBarrierException
131 */
132 public void testAwait2_Interrupted_BrokenBarrier() throws Exception {
133 final CyclicBarrier c = new CyclicBarrier(3);
134 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
135 public void realRun() throws Exception {
136 c.await(LONG_DELAY_MS, MILLISECONDS);
137 }};
138 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
139 public void realRun() throws Exception {
140 c.await(LONG_DELAY_MS, MILLISECONDS);
141 }};
142
143 t1.start();
144 t2.start();
145 Thread.sleep(SHORT_DELAY_MS);
146 t1.interrupt();
147 t1.join();
148 t2.join();
149 }
150
151 /**
152 * A timeout in timed await throws TimeoutException
153 */
154 public void testAwait3_TimeOutException() throws InterruptedException {
155 final CyclicBarrier c = new CyclicBarrier(2);
156 Thread t = new ThreadShouldThrow(TimeoutException.class) {
157 public void realRun() throws Exception {
158 c.await(SHORT_DELAY_MS, MILLISECONDS);
159 }};
160
161 t.start();
162 t.join();
163 }
164
165 /**
166 * A timeout in one party causes others waiting in timed await to
167 * throw BrokenBarrierException
168 */
169 public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException {
170 final CyclicBarrier c = new CyclicBarrier(3);
171 Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
172 public void realRun() throws Exception {
173 c.await(SHORT_DELAY_MS, MILLISECONDS);
174 }};
175 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
176 public void realRun() throws Exception {
177 c.await(MEDIUM_DELAY_MS, MILLISECONDS);
178 }};
179
180 t1.start();
181 t2.start();
182 t1.join();
183 t2.join();
184 }
185
186 /**
187 * A timeout in one party causes others waiting in await to
188 * throw BrokenBarrierException
189 */
190 public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException {
191 final CyclicBarrier c = new CyclicBarrier(3);
192 Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
193 public void realRun() throws Exception {
194 c.await(SHORT_DELAY_MS, MILLISECONDS);
195 }};
196 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
197 public void realRun() throws Exception {
198 c.await();
199 }};
200
201 t1.start();
202 t2.start();
203 t1.join();
204 t2.join();
205 }
206
207 /**
208 * A reset of an active barrier causes waiting threads to throw
209 * BrokenBarrierException
210 */
211 public void testReset_BrokenBarrier() throws InterruptedException {
212 final CyclicBarrier c = new CyclicBarrier(3);
213 Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
214 public void realRun() throws Exception {
215 c.await();
216 }};
217 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
218 public void realRun() throws Exception {
219 c.await();
220 }};
221
222 t1.start();
223 t2.start();
224 Thread.sleep(SHORT_DELAY_MS);
225 c.reset();
226 t1.join();
227 t2.join();
228 }
229
230 /**
231 * A reset before threads enter barrier does not throw
232 * BrokenBarrierException
233 */
234 public void testReset_NoBrokenBarrier() throws Exception {
235 final CyclicBarrier c = new CyclicBarrier(3);
236 Thread t1 = new Thread(new CheckedRunnable() {
237 public void realRun() throws Exception {
238 c.await();
239 }});
240 Thread t2 = new Thread(new CheckedRunnable() {
241 public void realRun() throws Exception {
242 c.await();
243 }});
244
245 c.reset();
246 t1.start();
247 t2.start();
248 c.await();
249 t1.join();
250 t2.join();
251 }
252
253 /**
254 * All threads block while a barrier is broken.
255 */
256 public void testReset_Leakage() throws InterruptedException {
257 final CyclicBarrier c = new CyclicBarrier(2);
258 final AtomicBoolean done = new AtomicBoolean();
259 Thread t = new Thread() {
260 public void run() {
261 while (!done.get()) {
262 try {
263 while (c.isBroken())
264 c.reset();
265
266 c.await();
267 threadFail("await should not return");
268 }
269 catch (BrokenBarrierException e) {
270 }
271 catch (InterruptedException ie) {
272 }
273 }
274 }
275 };
276
277 t.start();
278 for (int i = 0; i < 4; i++) {
279 Thread.sleep(SHORT_DELAY_MS);
280 t.interrupt();
281 }
282 done.set(true);
283 t.interrupt();
284 t.join();
285 }
286
287 /**
288 * Reset of a non-broken barrier does not break barrier
289 */
290 public void testResetWithoutBreakage() throws Exception {
291 final CyclicBarrier start = new CyclicBarrier(3);
292 final CyclicBarrier barrier = new CyclicBarrier(3);
293 for (int i = 0; i < 3; i++) {
294 Thread t1 = new Thread(new CheckedRunnable() {
295 public void realRun() throws Exception {
296 start.await();
297 barrier.await();
298 }});
299
300 Thread t2 = new Thread(new CheckedRunnable() {
301 public void realRun() throws Exception {
302 start.await();
303 barrier.await();
304 }});
305
306 t1.start();
307 t2.start();
308 start.await();
309 barrier.await();
310 t1.join();
311 t2.join();
312 assertFalse(barrier.isBroken());
313 assertEquals(0, barrier.getNumberWaiting());
314 if (i == 1) barrier.reset();
315 assertFalse(barrier.isBroken());
316 assertEquals(0, barrier.getNumberWaiting());
317 }
318 }
319
320 /**
321 * Reset of a barrier after interruption reinitializes it.
322 */
323 public void testResetAfterInterrupt() throws Exception {
324 final CyclicBarrier start = new CyclicBarrier(3);
325 final CyclicBarrier barrier = new CyclicBarrier(3);
326 for (int i = 0; i < 2; i++) {
327 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
328 public void realRun() throws Exception {
329 start.await();
330 barrier.await();
331 }};
332
333 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
334 public void realRun() throws Exception {
335 start.await();
336 barrier.await();
337 }};
338
339 t1.start();
340 t2.start();
341 start.await();
342 t1.interrupt();
343 t1.join();
344 t2.join();
345 assertTrue(barrier.isBroken());
346 assertEquals(0, barrier.getNumberWaiting());
347 barrier.reset();
348 assertFalse(barrier.isBroken());
349 assertEquals(0, barrier.getNumberWaiting());
350 }
351 }
352
353 /**
354 * Reset of a barrier after timeout reinitializes it.
355 */
356 public void testResetAfterTimeout() throws Exception {
357 final CyclicBarrier start = new CyclicBarrier(3);
358 final CyclicBarrier barrier = new CyclicBarrier(3);
359 for (int i = 0; i < 2; i++) {
360 Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
361 public void realRun() throws Exception {
362 start.await();
363 barrier.await(MEDIUM_DELAY_MS, MILLISECONDS);
364 }};
365
366 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
367 public void realRun() throws Exception {
368 start.await();
369 barrier.await();
370 }};
371
372 t1.start();
373 t2.start();
374 start.await();
375 t1.join();
376 t2.join();
377 assertTrue(barrier.isBroken());
378 assertEquals(0, barrier.getNumberWaiting());
379 barrier.reset();
380 assertFalse(barrier.isBroken());
381 assertEquals(0, barrier.getNumberWaiting());
382 }
383 }
384
385
386 /**
387 * Reset of a barrier after a failed command reinitializes it.
388 */
389 public void testResetAfterCommandException() throws Exception {
390 final CyclicBarrier start = new CyclicBarrier(3);
391 final CyclicBarrier barrier =
392 new CyclicBarrier(3, new Runnable() {
393 public void run() {
394 throw new NullPointerException(); }});
395 for (int i = 0; i < 2; i++) {
396 Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
397 public void realRun() throws Exception {
398 start.await();
399 barrier.await();
400 }};
401
402 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
403 public void realRun() throws Exception {
404 start.await();
405 barrier.await();
406 }};
407
408 t1.start();
409 t2.start();
410 start.await();
411 while (barrier.getNumberWaiting() < 2) { Thread.yield(); }
412 try {
413 barrier.await();
414 shouldThrow();
415 } catch (NullPointerException success) {}
416 t1.join();
417 t2.join();
418 assertTrue(barrier.isBroken());
419 assertEquals(0, barrier.getNumberWaiting());
420 barrier.reset();
421 assertFalse(barrier.isBroken());
422 assertEquals(0, barrier.getNumberWaiting());
423 }
424 }
425}