blob: db0f03dafa9cf22a7f0fbe5ffb23af623996421f [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
2 * Written by Doug Lea and Martin Buchholz with assistance from members
3 * of JCP JSR-166 Expert Group and released to the public domain, as
4 * explained at http://creativecommons.org/publicdomain/zero/1.0/
5 *
6 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
8 */
9
10package jsr166;
11
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010012import static java.util.concurrent.TimeUnit.MILLISECONDS;
13
Calin Juravle8f0d92b2013-08-01 17:26:00 +010014import java.util.ArrayList;
15import java.util.Arrays;
16import java.util.Collection;
17import java.util.Queue;
18import java.util.concurrent.BlockingQueue;
19import java.util.concurrent.CountDownLatch;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010020
21import junit.framework.Test;
22import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010023
24/**
25 * Contains "contract" tests applicable to all BlockingQueue implementations.
26 */
27public abstract class BlockingQueueTest extends JSR166TestCase {
28 /*
29 * This is the start of an attempt to refactor the tests for the
30 * various related implementations of related interfaces without
31 * too much duplicated code. junit does not really support such
32 * testing. Here subclasses of TestCase not only contain tests,
33 * but also configuration information that describes the
34 * implementation class, most importantly how to instantiate
35 * instances.
36 */
37
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010038 /** Like suite(), but non-static */
39 // android-note: Explicitly instantiated.
40 //
41 // public Test testSuite() {
42 // // TODO: filter the returned tests using the configuration
43 // // information provided by the subclass via protected methods.
44 // return new TestSuite(this.getClass());
45 // }
46
Calin Juravle8f0d92b2013-08-01 17:26:00 +010047 //----------------------------------------------------------------
48 // Configuration methods
49 //----------------------------------------------------------------
50
51 /** Returns an empty instance of the implementation class. */
52 protected abstract BlockingQueue emptyCollection();
53
54 /**
55 * Returns an element suitable for insertion in the collection.
56 * Override for collections with unusual element types.
57 */
58 protected Object makeElement(int i) {
59 return Integer.valueOf(i);
60 }
61
62 //----------------------------------------------------------------
63 // Tests
64 //----------------------------------------------------------------
65
66 /**
67 * offer(null) throws NullPointerException
68 */
69 public void testOfferNull() {
70 final Queue q = emptyCollection();
71 try {
72 q.offer(null);
73 shouldThrow();
74 } catch (NullPointerException success) {}
75 }
76
77 /**
78 * add(null) throws NullPointerException
79 */
80 public void testAddNull() {
81 final Collection q = emptyCollection();
82 try {
83 q.add(null);
84 shouldThrow();
85 } catch (NullPointerException success) {}
86 }
87
88 /**
89 * timed offer(null) throws NullPointerException
90 */
91 public void testTimedOfferNull() throws InterruptedException {
92 final BlockingQueue q = emptyCollection();
93 long startTime = System.nanoTime();
94 try {
95 q.offer(null, LONG_DELAY_MS, MILLISECONDS);
96 shouldThrow();
97 } catch (NullPointerException success) {}
98 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
99 }
100
101 /**
102 * put(null) throws NullPointerException
103 */
104 public void testPutNull() throws InterruptedException {
105 final BlockingQueue q = emptyCollection();
106 try {
107 q.put(null);
108 shouldThrow();
109 } catch (NullPointerException success) {}
110 }
111
112 /**
113 * put(null) throws NullPointerException
114 */
115 public void testAddAllNull() throws InterruptedException {
116 final Collection q = emptyCollection();
117 try {
118 q.addAll(null);
119 shouldThrow();
120 } catch (NullPointerException success) {}
121 }
122
123 /**
124 * addAll of a collection with null elements throws NullPointerException
125 */
126 public void testAddAllNullElements() {
127 final Collection q = emptyCollection();
128 final Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
129 try {
130 q.addAll(elements);
131 shouldThrow();
132 } catch (NullPointerException success) {}
133 }
134
135 /**
136 * toArray(null) throws NullPointerException
137 */
138 public void testToArray_NullArray() {
139 final Collection q = emptyCollection();
140 try {
141 q.toArray(null);
142 shouldThrow();
143 } catch (NullPointerException success) {}
144 }
145
146 /**
147 * drainTo(null) throws NullPointerException
148 */
149 public void testDrainToNull() {
150 final BlockingQueue q = emptyCollection();
151 try {
152 q.drainTo(null);
153 shouldThrow();
154 } catch (NullPointerException success) {}
155 }
156
157 /**
158 * drainTo(this) throws IllegalArgumentException
159 */
160 public void testDrainToSelf() {
161 final BlockingQueue q = emptyCollection();
162 try {
163 q.drainTo(q);
164 shouldThrow();
165 } catch (IllegalArgumentException success) {}
166 }
167
168 /**
169 * drainTo(null, n) throws NullPointerException
170 */
171 public void testDrainToNullN() {
172 final BlockingQueue q = emptyCollection();
173 try {
174 q.drainTo(null, 0);
175 shouldThrow();
176 } catch (NullPointerException success) {}
177 }
178
179 /**
180 * drainTo(this, n) throws IllegalArgumentException
181 */
182 public void testDrainToSelfN() {
183 final BlockingQueue q = emptyCollection();
184 try {
185 q.drainTo(q, 0);
186 shouldThrow();
187 } catch (IllegalArgumentException success) {}
188 }
189
190 /**
191 * drainTo(c, n) returns 0 and does nothing when n <= 0
192 */
193 public void testDrainToNonPositiveMaxElements() {
194 final BlockingQueue q = emptyCollection();
195 final int[] ns = { 0, -1, -42, Integer.MIN_VALUE };
196 for (int n : ns)
197 assertEquals(0, q.drainTo(new ArrayList(), n));
198 if (q.remainingCapacity() > 0) {
199 // Not SynchronousQueue, that is
200 Object one = makeElement(1);
201 q.add(one);
202 ArrayList c = new ArrayList();
203 for (int n : ns)
204 assertEquals(0, q.drainTo(new ArrayList(), n));
205 assertEquals(1, q.size());
206 assertSame(one, q.poll());
207 assertTrue(c.isEmpty());
208 }
209 }
210
211 /**
212 * timed poll before a delayed offer times out; after offer succeeds;
213 * on interruption throws
214 */
215 public void testTimedPollWithOffer() throws InterruptedException {
216 final BlockingQueue q = emptyCollection();
217 final CheckedBarrier barrier = new CheckedBarrier(2);
218 final Object zero = makeElement(0);
219 Thread t = newStartedThread(new CheckedRunnable() {
220 public void realRun() throws InterruptedException {
221 long startTime = System.nanoTime();
222 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
223 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
224
225 barrier.await();
226
227 assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
228
229 Thread.currentThread().interrupt();
230 try {
231 q.poll(LONG_DELAY_MS, MILLISECONDS);
232 shouldThrow();
233 } catch (InterruptedException success) {}
234 assertFalse(Thread.interrupted());
235
236 barrier.await();
237 try {
238 q.poll(LONG_DELAY_MS, MILLISECONDS);
239 shouldThrow();
240 } catch (InterruptedException success) {}
241 assertFalse(Thread.interrupted());
242 }});
243
244 barrier.await();
245 long startTime = System.nanoTime();
246 assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS));
247 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
248
249 barrier.await();
250 assertThreadStaysAlive(t);
251 t.interrupt();
252 awaitTermination(t);
253 }
254
255 /**
256 * take() blocks interruptibly when empty
257 */
258 public void testTakeFromEmptyBlocksInterruptibly() {
259 final BlockingQueue q = emptyCollection();
260 final CountDownLatch threadStarted = new CountDownLatch(1);
261 Thread t = newStartedThread(new CheckedRunnable() {
262 public void realRun() {
263 threadStarted.countDown();
264 try {
265 q.take();
266 shouldThrow();
267 } catch (InterruptedException success) {}
268 assertFalse(Thread.interrupted());
269 }});
270
271 await(threadStarted);
272 assertThreadStaysAlive(t);
273 t.interrupt();
274 awaitTermination(t);
275 }
276
277 /**
278 * take() throws InterruptedException immediately if interrupted
279 * before waiting
280 */
281 public void testTakeFromEmptyAfterInterrupt() {
282 final BlockingQueue q = emptyCollection();
283 Thread t = newStartedThread(new CheckedRunnable() {
284 public void realRun() {
285 Thread.currentThread().interrupt();
286 try {
287 q.take();
288 shouldThrow();
289 } catch (InterruptedException success) {}
290 assertFalse(Thread.interrupted());
291 }});
292
293 awaitTermination(t);
294 }
295
296 /**
297 * timed poll() blocks interruptibly when empty
298 */
299 public void testTimedPollFromEmptyBlocksInterruptibly() {
300 final BlockingQueue q = emptyCollection();
301 final CountDownLatch threadStarted = new CountDownLatch(1);
302 Thread t = newStartedThread(new CheckedRunnable() {
303 public void realRun() {
304 threadStarted.countDown();
305 try {
306 q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
307 shouldThrow();
308 } catch (InterruptedException success) {}
309 assertFalse(Thread.interrupted());
310 }});
311
312 await(threadStarted);
313 assertThreadStaysAlive(t);
314 t.interrupt();
315 awaitTermination(t);
316 }
317
318 /**
319 * timed poll() throws InterruptedException immediately if
320 * interrupted before waiting
321 */
322 public void testTimedPollFromEmptyAfterInterrupt() {
323 final BlockingQueue q = emptyCollection();
324 Thread t = newStartedThread(new CheckedRunnable() {
325 public void realRun() {
326 Thread.currentThread().interrupt();
327 try {
328 q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
329 shouldThrow();
330 } catch (InterruptedException success) {}
331 assertFalse(Thread.interrupted());
332 }});
333
334 awaitTermination(t);
335 }
336
337 /**
338 * remove(x) removes x and returns true if present
339 * TODO: move to superclass CollectionTest.java
340 */
341 public void testRemoveElement() {
342 final BlockingQueue q = emptyCollection();
343 final int size = Math.min(q.remainingCapacity(), SIZE);
344 final Object[] elts = new Object[size];
345 assertFalse(q.contains(makeElement(99)));
346 assertFalse(q.remove(makeElement(99)));
347 checkEmpty(q);
348 for (int i = 0; i < size; i++)
349 q.add(elts[i] = makeElement(i));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100350 for (int i = 1; i < size; i += 2) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100351 for (int pass = 0; pass < 2; pass++) {
352 assertEquals((pass == 0), q.contains(elts[i]));
353 assertEquals((pass == 0), q.remove(elts[i]));
354 assertFalse(q.contains(elts[i]));
355 assertTrue(q.contains(elts[i-1]));
356 if (i < size - 1)
357 assertTrue(q.contains(elts[i+1]));
358 }
359 }
360 if (size > 0)
361 assertTrue(q.contains(elts[0]));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100362 for (int i = size-2; i >= 0; i -= 2) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100363 assertTrue(q.contains(elts[i]));
364 assertFalse(q.contains(elts[i+1]));
365 assertTrue(q.remove(elts[i]));
366 assertFalse(q.contains(elts[i]));
367 assertFalse(q.remove(elts[i+1]));
368 assertFalse(q.contains(elts[i+1]));
369 }
370 checkEmpty(q);
371 }
372
373 /** For debugging. */
374 public void XXXXtestFails() {
375 fail(emptyCollection().getClass().toString());
376 }
377
378}