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/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
11import static java.util.concurrent.TimeUnit.MILLISECONDS;
12
13import java.util.concurrent.CountDownLatch;
14
15import junit.framework.Test;
16import junit.framework.TestSuite;
17
18public class CountDownLatchTest extends JSR166TestCase {
19    // android-note: Removed because the CTS runner does a bad job of
20    // retrying tests that have suite() declarations.
21    //
22    // public static void main(String[] args) {
23    //     main(suite(), args);
24    // }
25    // public static Test suite() {
26    //     return new TestSuite(...);
27    // }
28
29    /**
30     * negative constructor argument throws IAE
31     */
32    public void testConstructor() {
33        try {
34            new CountDownLatch(-1);
35            shouldThrow();
36        } catch (IllegalArgumentException success) {}
37    }
38
39    /**
40     * getCount returns initial count and decreases after countDown
41     */
42    public void testGetCount() {
43        final CountDownLatch l = new CountDownLatch(2);
44        assertEquals(2, l.getCount());
45        l.countDown();
46        assertEquals(1, l.getCount());
47    }
48
49    /**
50     * countDown decrements count when positive and has no effect when zero
51     */
52    public void testCountDown() {
53        final CountDownLatch l = new CountDownLatch(1);
54        assertEquals(1, l.getCount());
55        l.countDown();
56        assertEquals(0, l.getCount());
57        l.countDown();
58        assertEquals(0, l.getCount());
59    }
60
61    /**
62     * await returns after countDown to zero, but not before
63     */
64    public void testAwait() {
65        final CountDownLatch l = new CountDownLatch(2);
66        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
67
68        Thread t = newStartedThread(new CheckedRunnable() {
69            public void realRun() throws InterruptedException {
70                assertEquals(2, l.getCount());
71                pleaseCountDown.countDown();
72                l.await();
73                assertEquals(0, l.getCount());
74            }});
75
76        await(pleaseCountDown);
77        assertEquals(2, l.getCount());
78        l.countDown();
79        assertEquals(1, l.getCount());
80        assertThreadStaysAlive(t);
81        l.countDown();
82        assertEquals(0, l.getCount());
83        awaitTermination(t);
84    }
85
86    /**
87     * timed await returns after countDown to zero
88     */
89    public void testTimedAwait() {
90        final CountDownLatch l = new CountDownLatch(2);
91        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
92
93        Thread t = newStartedThread(new CheckedRunnable() {
94            public void realRun() throws InterruptedException {
95                assertEquals(2, l.getCount());
96                pleaseCountDown.countDown();
97                assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
98                assertEquals(0, l.getCount());
99            }});
100
101        await(pleaseCountDown);
102        assertEquals(2, l.getCount());
103        l.countDown();
104        assertEquals(1, l.getCount());
105        assertThreadStaysAlive(t);
106        l.countDown();
107        assertEquals(0, l.getCount());
108        awaitTermination(t);
109    }
110
111    /**
112     * await throws IE if interrupted before counted down
113     */
114    public void testAwait_Interruptible() {
115        final CountDownLatch l = new CountDownLatch(1);
116        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
117        Thread t = newStartedThread(new CheckedRunnable() {
118            public void realRun() throws InterruptedException {
119                Thread.currentThread().interrupt();
120                try {
121                    l.await();
122                    shouldThrow();
123                } catch (InterruptedException success) {}
124                assertFalse(Thread.interrupted());
125
126                pleaseInterrupt.countDown();
127                try {
128                    l.await();
129                    shouldThrow();
130                } catch (InterruptedException success) {}
131                assertFalse(Thread.interrupted());
132
133                assertEquals(1, l.getCount());
134            }});
135
136        await(pleaseInterrupt);
137        assertThreadStaysAlive(t);
138        t.interrupt();
139        awaitTermination(t);
140    }
141
142    /**
143     * timed await throws IE if interrupted before counted down
144     */
145    public void testTimedAwait_Interruptible() {
146        final CountDownLatch l = new CountDownLatch(1);
147        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
148        Thread t = newStartedThread(new CheckedRunnable() {
149            public void realRun() throws InterruptedException {
150                Thread.currentThread().interrupt();
151                try {
152                    l.await(LONG_DELAY_MS, MILLISECONDS);
153                    shouldThrow();
154                } catch (InterruptedException success) {}
155                assertFalse(Thread.interrupted());
156
157                pleaseInterrupt.countDown();
158                try {
159                    l.await(LONG_DELAY_MS, MILLISECONDS);
160                    shouldThrow();
161                } catch (InterruptedException success) {}
162                assertFalse(Thread.interrupted());
163
164                assertEquals(1, l.getCount());
165            }});
166
167        await(pleaseInterrupt);
168        assertThreadStaysAlive(t);
169        t.interrupt();
170        awaitTermination(t);
171    }
172
173    /**
174     * timed await times out if not counted down before timeout
175     */
176    public void testAwaitTimeout() throws InterruptedException {
177        final CountDownLatch l = new CountDownLatch(1);
178        Thread t = newStartedThread(new CheckedRunnable() {
179            public void realRun() throws InterruptedException {
180                assertEquals(1, l.getCount());
181                assertFalse(l.await(timeoutMillis(), MILLISECONDS));
182                assertEquals(1, l.getCount());
183            }});
184
185        awaitTermination(t);
186        assertEquals(1, l.getCount());
187    }
188
189    /**
190     * toString indicates current count
191     */
192    public void testToString() {
193        CountDownLatch s = new CountDownLatch(2);
194        assertTrue(s.toString().contains("Count = 2"));
195        s.countDown();
196        assertTrue(s.toString().contains("Count = 1"));
197        s.countDown();
198        assertTrue(s.toString().contains("Count = 0"));
199    }
200
201}
202