blob: 0da4e78f4a5e6c18dfc58c6120fa7258648d321c [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() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000042 // // TODO: filter the returned tests using the configuration
43 // // information provided by the subclass via protected methods.
44 // return new TestSuite(this.getClass());
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010045 // }
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 {
Nikita Iashchenkoc6041892021-09-14 18:44:42 +0100141 q.toArray((Object[]) null);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100142 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());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000242
243 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100244 }});
245
246 barrier.await();
247 long startTime = System.nanoTime();
248 assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS));
249 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
250
251 barrier.await();
252 assertThreadStaysAlive(t);
253 t.interrupt();
254 awaitTermination(t);
255 }
256
257 /**
258 * take() blocks interruptibly when empty
259 */
260 public void testTakeFromEmptyBlocksInterruptibly() {
261 final BlockingQueue q = emptyCollection();
262 final CountDownLatch threadStarted = new CountDownLatch(1);
263 Thread t = newStartedThread(new CheckedRunnable() {
264 public void realRun() {
265 threadStarted.countDown();
266 try {
267 q.take();
268 shouldThrow();
269 } catch (InterruptedException success) {}
270 assertFalse(Thread.interrupted());
271 }});
272
273 await(threadStarted);
274 assertThreadStaysAlive(t);
275 t.interrupt();
276 awaitTermination(t);
277 }
278
279 /**
280 * take() throws InterruptedException immediately if interrupted
281 * before waiting
282 */
283 public void testTakeFromEmptyAfterInterrupt() {
284 final BlockingQueue q = emptyCollection();
285 Thread t = newStartedThread(new CheckedRunnable() {
286 public void realRun() {
287 Thread.currentThread().interrupt();
288 try {
289 q.take();
290 shouldThrow();
291 } catch (InterruptedException success) {}
292 assertFalse(Thread.interrupted());
293 }});
294
295 awaitTermination(t);
296 }
297
298 /**
299 * timed poll() blocks interruptibly when empty
300 */
301 public void testTimedPollFromEmptyBlocksInterruptibly() {
302 final BlockingQueue q = emptyCollection();
303 final CountDownLatch threadStarted = new CountDownLatch(1);
304 Thread t = newStartedThread(new CheckedRunnable() {
305 public void realRun() {
306 threadStarted.countDown();
307 try {
308 q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
309 shouldThrow();
310 } catch (InterruptedException success) {}
311 assertFalse(Thread.interrupted());
312 }});
313
314 await(threadStarted);
315 assertThreadStaysAlive(t);
316 t.interrupt();
317 awaitTermination(t);
318 }
319
320 /**
321 * timed poll() throws InterruptedException immediately if
322 * interrupted before waiting
323 */
324 public void testTimedPollFromEmptyAfterInterrupt() {
325 final BlockingQueue q = emptyCollection();
326 Thread t = newStartedThread(new CheckedRunnable() {
327 public void realRun() {
328 Thread.currentThread().interrupt();
329 try {
330 q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
331 shouldThrow();
332 } catch (InterruptedException success) {}
333 assertFalse(Thread.interrupted());
334 }});
335
336 awaitTermination(t);
337 }
338
339 /**
340 * remove(x) removes x and returns true if present
341 * TODO: move to superclass CollectionTest.java
342 */
343 public void testRemoveElement() {
344 final BlockingQueue q = emptyCollection();
345 final int size = Math.min(q.remainingCapacity(), SIZE);
346 final Object[] elts = new Object[size];
347 assertFalse(q.contains(makeElement(99)));
348 assertFalse(q.remove(makeElement(99)));
349 checkEmpty(q);
350 for (int i = 0; i < size; i++)
351 q.add(elts[i] = makeElement(i));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100352 for (int i = 1; i < size; i += 2) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100353 for (int pass = 0; pass < 2; pass++) {
354 assertEquals((pass == 0), q.contains(elts[i]));
355 assertEquals((pass == 0), q.remove(elts[i]));
356 assertFalse(q.contains(elts[i]));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000357 assertTrue(q.contains(elts[i - 1]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100358 if (i < size - 1)
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000359 assertTrue(q.contains(elts[i + 1]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100360 }
361 }
362 if (size > 0)
363 assertTrue(q.contains(elts[0]));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000364 for (int i = size - 2; i >= 0; i -= 2) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100365 assertTrue(q.contains(elts[i]));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000366 assertFalse(q.contains(elts[i + 1]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100367 assertTrue(q.remove(elts[i]));
368 assertFalse(q.contains(elts[i]));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000369 assertFalse(q.remove(elts[i + 1]));
370 assertFalse(q.contains(elts[i + 1]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100371 }
372 checkEmpty(q);
373 }
374
375 /** For debugging. */
376 public void XXXXtestFails() {
377 fail(emptyCollection().getClass().toString());
378 }
379
380}