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 John Vint
6  */
7 
8 package jsr166;
9 
10 import static java.util.concurrent.TimeUnit.MILLISECONDS;
11 
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.NoSuchElementException;
18 import java.util.Queue;
19 import java.util.concurrent.BlockingQueue;
20 import java.util.concurrent.Callable;
21 import java.util.concurrent.CountDownLatch;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.ExecutorService;
24 import java.util.concurrent.LinkedTransferQueue;
25 
26 import junit.framework.Test;
27 
28 @SuppressWarnings({"unchecked", "rawtypes"})
29 public class LinkedTransferQueueTest extends JSR166TestCase {
30     static class Implementation implements CollectionImplementation {
klazz()31         public Class<?> klazz() { return LinkedTransferQueue.class; }
emptyCollection()32         public Collection emptyCollection() { return new LinkedTransferQueue(); }
makeElement(int i)33         public Object makeElement(int i) { return i; }
isConcurrent()34         public boolean isConcurrent() { return true; }
permitsNulls()35         public boolean permitsNulls() { return false; }
36     }
37 
38     // android-note: These tests have been moved into their own separate
39     // classes to work around CTS issues:
40     // LinkedTransferQueueBlockingQueueTest.java
41     // LinkedTransferQueueCollectionTest.java
42     //
43     // public static class Generic extends BlockingQueueTest {
44     //     protected BlockingQueue emptyCollection() {
45     //         return new LinkedTransferQueue();
46     //     }
47     // }
48 
49     // android-note: Removed because the CTS runner does a bad job of
50     // retrying tests that have suite() declarations.
51     //
52     // public static void main(String[] args) {
53     //     main(suite(), args);
54     // }
55     // public static Test suite() {
56     //     return newTestSuite(LinkedTransferQueueTest.class,
57     //                         new Generic().testSuite(),
58     //                         CollectionTest.testSuite(new Implementation()));
59     // }
60 
61     /**
62      * Constructor builds new queue with size being zero and empty
63      * being true
64      */
testConstructor1()65     public void testConstructor1() {
66         assertEquals(0, new LinkedTransferQueue().size());
67         assertTrue(new LinkedTransferQueue().isEmpty());
68     }
69 
70     /**
71      * Initializing constructor with null collection throws
72      * NullPointerException
73      */
testConstructor2()74     public void testConstructor2() {
75         try {
76             new LinkedTransferQueue(null);
77             shouldThrow();
78         } catch (NullPointerException success) {}
79     }
80 
81     /**
82      * Initializing from Collection of null elements throws
83      * NullPointerException
84      */
testConstructor3()85     public void testConstructor3() {
86         Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
87         try {
88             new LinkedTransferQueue(elements);
89             shouldThrow();
90         } catch (NullPointerException success) {}
91     }
92 
93     /**
94      * Initializing constructor with a collection containing some null elements
95      * throws NullPointerException
96      */
testConstructor4()97     public void testConstructor4() {
98         Integer[] ints = new Integer[SIZE];
99         for (int i = 0; i < SIZE - 1; ++i)
100             ints[i] = i;
101         Collection<Integer> elements = Arrays.asList(ints);
102         try {
103             new LinkedTransferQueue(elements);
104             shouldThrow();
105         } catch (NullPointerException success) {}
106     }
107 
108     /**
109      * Queue contains all elements of the collection it is initialized by
110      */
testConstructor5()111     public void testConstructor5() {
112         Integer[] ints = new Integer[SIZE];
113         for (int i = 0; i < SIZE; ++i) {
114             ints[i] = i;
115         }
116         List intList = Arrays.asList(ints);
117         LinkedTransferQueue q
118             = new LinkedTransferQueue(intList);
119         assertEquals(q.size(), intList.size());
120         assertEquals(q.toString(), intList.toString());
121         assertTrue(Arrays.equals(q.toArray(),
122                                      intList.toArray()));
123         assertTrue(Arrays.equals(q.toArray(new Object[0]),
124                                  intList.toArray(new Object[0])));
125         assertTrue(Arrays.equals(q.toArray(new Object[SIZE]),
126                                  intList.toArray(new Object[SIZE])));
127         for (int i = 0; i < SIZE; ++i) {
128             assertEquals(ints[i], q.poll());
129         }
130     }
131 
132     /**
133      * remainingCapacity() always returns Integer.MAX_VALUE
134      */
testRemainingCapacity()135     public void testRemainingCapacity() {
136         BlockingQueue q = populatedQueue(SIZE);
137         for (int i = 0; i < SIZE; ++i) {
138             assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
139             assertEquals(SIZE - i, q.size());
140             assertEquals(i, q.remove());
141         }
142         for (int i = 0; i < SIZE; ++i) {
143             assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
144             assertEquals(i, q.size());
145             assertTrue(q.add(i));
146         }
147     }
148 
149     /**
150      * addAll(this) throws IllegalArgumentException
151      */
testAddAllSelf()152     public void testAddAllSelf() {
153         LinkedTransferQueue q = populatedQueue(SIZE);
154         try {
155             q.addAll(q);
156             shouldThrow();
157         } catch (IllegalArgumentException success) {}
158     }
159 
160     /**
161      * addAll of a collection with any null elements throws
162      * NullPointerException after possibly adding some elements
163      */
testAddAll3()164     public void testAddAll3() {
165         LinkedTransferQueue q = new LinkedTransferQueue();
166         Integer[] ints = new Integer[SIZE];
167         for (int i = 0; i < SIZE - 1; ++i)
168             ints[i] = i;
169         try {
170             q.addAll(Arrays.asList(ints));
171             shouldThrow();
172         } catch (NullPointerException success) {}
173     }
174 
175     /**
176      * Queue contains all elements, in traversal order, of successful addAll
177      */
testAddAll5()178     public void testAddAll5() {
179         Integer[] empty = new Integer[0];
180         Integer[] ints = new Integer[SIZE];
181         for (int i = 0; i < SIZE; ++i) {
182             ints[i] = i;
183         }
184         LinkedTransferQueue q = new LinkedTransferQueue();
185         assertFalse(q.addAll(Arrays.asList(empty)));
186         assertTrue(q.addAll(Arrays.asList(ints)));
187         for (int i = 0; i < SIZE; ++i) {
188             assertEquals(ints[i], q.poll());
189         }
190     }
191 
192     /**
193      * all elements successfully put are contained
194      */
testPut()195     public void testPut() {
196         LinkedTransferQueue<Integer> q = new LinkedTransferQueue<Integer>();
197         for (int i = 0; i < SIZE; ++i) {
198             assertEquals(i, q.size());
199             q.put(i);
200             assertTrue(q.contains(i));
201         }
202     }
203 
204     /**
205      * take retrieves elements in FIFO order
206      */
testTake()207     public void testTake() throws InterruptedException {
208         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
209         for (int i = 0; i < SIZE; ++i) {
210             assertEquals(i, (int) q.take());
211         }
212     }
213 
214     /**
215      * take removes existing elements until empty, then blocks interruptibly
216      */
testBlockingTake()217     public void testBlockingTake() throws InterruptedException {
218         final BlockingQueue q = populatedQueue(SIZE);
219         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
220         Thread t = newStartedThread(new CheckedRunnable() {
221             public void realRun() throws InterruptedException {
222                 for (int i = 0; i < SIZE; ++i) {
223                     assertEquals(i, q.take());
224                 }
225 
226                 Thread.currentThread().interrupt();
227                 try {
228                     q.take();
229                     shouldThrow();
230                 } catch (InterruptedException success) {}
231                 assertFalse(Thread.interrupted());
232 
233                 pleaseInterrupt.countDown();
234                 try {
235                     q.take();
236                     shouldThrow();
237                 } catch (InterruptedException success) {}
238                 assertFalse(Thread.interrupted());
239             }});
240 
241         await(pleaseInterrupt);
242         assertThreadStaysAlive(t);
243         t.interrupt();
244         awaitTermination(t);
245     }
246 
247     /**
248      * poll succeeds unless empty
249      */
testPoll()250     public void testPoll() throws InterruptedException {
251         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
252         for (int i = 0; i < SIZE; ++i) {
253             assertEquals(i, (int) q.poll());
254         }
255         assertNull(q.poll());
256         checkEmpty(q);
257     }
258 
259     /**
260      * timed poll with zero timeout succeeds when non-empty, else times out
261      */
testTimedPoll0()262     public void testTimedPoll0() throws InterruptedException {
263         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
264         for (int i = 0; i < SIZE; ++i) {
265             assertEquals(i, (int) q.poll(0, MILLISECONDS));
266         }
267         assertNull(q.poll(0, MILLISECONDS));
268         checkEmpty(q);
269     }
270 
271     /**
272      * timed poll with nonzero timeout succeeds when non-empty, else times out
273      */
testTimedPoll()274     public void testTimedPoll() throws InterruptedException {
275         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
276         long startTime = System.nanoTime();
277         for (int i = 0; i < SIZE; ++i)
278             assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
279         assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
280 
281         startTime = System.nanoTime();
282         assertNull(q.poll(timeoutMillis(), MILLISECONDS));
283         assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
284         checkEmpty(q);
285     }
286 
287     /**
288      * Interrupted timed poll throws InterruptedException instead of
289      * returning timeout status
290      */
testInterruptedTimedPoll()291     public void testInterruptedTimedPoll() throws InterruptedException {
292         final BlockingQueue<Integer> q = populatedQueue(SIZE);
293         final CountDownLatch aboutToWait = new CountDownLatch(1);
294         Thread t = newStartedThread(new CheckedRunnable() {
295             public void realRun() throws InterruptedException {
296                 long startTime = System.nanoTime();
297                 for (int i = 0; i < SIZE; ++i)
298                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
299                 aboutToWait.countDown();
300                 try {
301                     q.poll(LONG_DELAY_MS, MILLISECONDS);
302                     shouldThrow();
303                 } catch (InterruptedException success) {}
304                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
305             }});
306 
307         aboutToWait.await();
308         waitForThreadToEnterWaitState(t);
309         t.interrupt();
310         awaitTermination(t);
311         checkEmpty(q);
312     }
313 
314     /**
315      * timed poll after thread interrupted throws InterruptedException
316      * instead of returning timeout status
317      */
testTimedPollAfterInterrupt()318     public void testTimedPollAfterInterrupt() throws InterruptedException {
319         final BlockingQueue<Integer> q = populatedQueue(SIZE);
320         Thread t = newStartedThread(new CheckedRunnable() {
321             public void realRun() throws InterruptedException {
322                 long startTime = System.nanoTime();
323                 Thread.currentThread().interrupt();
324                 for (int i = 0; i < SIZE; ++i)
325                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
326                 try {
327                     q.poll(LONG_DELAY_MS, MILLISECONDS);
328                     shouldThrow();
329                 } catch (InterruptedException success) {}
330                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
331             }});
332 
333         awaitTermination(t);
334         checkEmpty(q);
335     }
336 
337     /**
338      * peek returns next element, or null if empty
339      */
testPeek()340     public void testPeek() throws InterruptedException {
341         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
342         for (int i = 0; i < SIZE; ++i) {
343             assertEquals(i, (int) q.peek());
344             assertEquals(i, (int) q.poll());
345             assertTrue(q.peek() == null ||
346                        i != (int) q.peek());
347         }
348         assertNull(q.peek());
349         checkEmpty(q);
350     }
351 
352     /**
353      * element returns next element, or throws NoSuchElementException if empty
354      */
testElement()355     public void testElement() throws InterruptedException {
356         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
357         for (int i = 0; i < SIZE; ++i) {
358             assertEquals(i, (int) q.element());
359             assertEquals(i, (int) q.poll());
360         }
361         try {
362             q.element();
363             shouldThrow();
364         } catch (NoSuchElementException success) {}
365         checkEmpty(q);
366     }
367 
368     /**
369      * remove removes next element, or throws NoSuchElementException if empty
370      */
testRemove()371     public void testRemove() throws InterruptedException {
372         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
373         for (int i = 0; i < SIZE; ++i) {
374             assertEquals(i, (int) q.remove());
375         }
376         try {
377             q.remove();
378             shouldThrow();
379         } catch (NoSuchElementException success) {}
380         checkEmpty(q);
381     }
382 
383     /**
384      * An add following remove(x) succeeds
385      */
testRemoveElementAndAdd()386     public void testRemoveElementAndAdd() throws InterruptedException {
387         LinkedTransferQueue q = new LinkedTransferQueue();
388         assertTrue(q.add(one));
389         assertTrue(q.add(two));
390         assertTrue(q.remove(one));
391         assertTrue(q.remove(two));
392         assertTrue(q.add(three));
393         assertSame(q.take(), three);
394     }
395 
396     /**
397      * contains(x) reports true when elements added but not yet removed
398      */
testContains()399     public void testContains() {
400         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
401         for (int i = 0; i < SIZE; ++i) {
402             assertTrue(q.contains(i));
403             assertEquals(i, (int) q.poll());
404             assertFalse(q.contains(i));
405         }
406     }
407 
408     /**
409      * clear removes all elements
410      */
testClear()411     public void testClear() throws InterruptedException {
412         LinkedTransferQueue q = populatedQueue(SIZE);
413         q.clear();
414         checkEmpty(q);
415         assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
416         q.add(one);
417         assertFalse(q.isEmpty());
418         assertEquals(1, q.size());
419         assertTrue(q.contains(one));
420         q.clear();
421         checkEmpty(q);
422     }
423 
424     /**
425      * containsAll(c) is true when c contains a subset of elements
426      */
testContainsAll()427     public void testContainsAll() {
428         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
429         LinkedTransferQueue<Integer> p = new LinkedTransferQueue<Integer>();
430         for (int i = 0; i < SIZE; ++i) {
431             assertTrue(q.containsAll(p));
432             assertFalse(p.containsAll(q));
433             p.add(i);
434         }
435         assertTrue(p.containsAll(q));
436     }
437 
438     /**
439      * retainAll(c) retains only those elements of c and reports true
440      * if changed
441      */
testRetainAll()442     public void testRetainAll() {
443         LinkedTransferQueue q = populatedQueue(SIZE);
444         LinkedTransferQueue p = populatedQueue(SIZE);
445         for (int i = 0; i < SIZE; ++i) {
446             boolean changed = q.retainAll(p);
447             if (i == 0) {
448                 assertFalse(changed);
449             } else {
450                 assertTrue(changed);
451             }
452             assertTrue(q.containsAll(p));
453             assertEquals(SIZE - i, q.size());
454             p.remove();
455         }
456     }
457 
458     /**
459      * removeAll(c) removes only those elements of c and reports true
460      * if changed
461      */
testRemoveAll()462     public void testRemoveAll() {
463         for (int i = 1; i < SIZE; ++i) {
464             LinkedTransferQueue q = populatedQueue(SIZE);
465             LinkedTransferQueue p = populatedQueue(i);
466             assertTrue(q.removeAll(p));
467             assertEquals(SIZE - i, q.size());
468             for (int j = 0; j < i; ++j) {
469                 assertFalse(q.contains(p.remove()));
470             }
471         }
472     }
473 
474     /**
475      * toArray() contains all elements in FIFO order
476      */
testToArray()477     public void testToArray() {
478         LinkedTransferQueue q = populatedQueue(SIZE);
479         Object[] o = q.toArray();
480         for (int i = 0; i < o.length; i++) {
481             assertSame(o[i], q.poll());
482         }
483     }
484 
485     /**
486      * toArray(a) contains all elements in FIFO order
487      */
testToArray2()488     public void testToArray2() {
489         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
490         Integer[] ints = new Integer[SIZE];
491         Integer[] array = q.toArray(ints);
492         assertSame(ints, array);
493         for (int i = 0; i < ints.length; i++) {
494             assertSame(ints[i], q.poll());
495         }
496     }
497 
498     /**
499      * toArray(incompatible array type) throws ArrayStoreException
500      */
testToArray1_BadArg()501     public void testToArray1_BadArg() {
502         LinkedTransferQueue q = populatedQueue(SIZE);
503         try {
504             q.toArray(new String[10]);
505             shouldThrow();
506         } catch (ArrayStoreException success) {}
507     }
508 
509     /**
510      * iterator iterates through all elements
511      */
testIterator()512     public void testIterator() throws InterruptedException {
513         LinkedTransferQueue q = populatedQueue(SIZE);
514         Iterator it = q.iterator();
515         int i;
516         for (i = 0; it.hasNext(); i++)
517             assertTrue(q.contains(it.next()));
518         assertEquals(i, SIZE);
519         assertIteratorExhausted(it);
520 
521         it = q.iterator();
522         for (i = 0; it.hasNext(); i++)
523             assertEquals(it.next(), q.take());
524         assertEquals(i, SIZE);
525         assertIteratorExhausted(it);
526     }
527 
528     /**
529      * iterator of empty collection has no elements
530      */
testEmptyIterator()531     public void testEmptyIterator() {
532         assertIteratorExhausted(new LinkedTransferQueue().iterator());
533     }
534 
535     /**
536      * iterator.remove() removes current element
537      */
testIteratorRemove()538     public void testIteratorRemove() {
539         final LinkedTransferQueue q = new LinkedTransferQueue();
540         q.add(two);
541         q.add(one);
542         q.add(three);
543 
544         Iterator it = q.iterator();
545         it.next();
546         it.remove();
547 
548         it = q.iterator();
549         assertSame(it.next(), one);
550         assertSame(it.next(), three);
551         assertFalse(it.hasNext());
552     }
553 
554     /**
555      * iterator ordering is FIFO
556      */
testIteratorOrdering()557     public void testIteratorOrdering() {
558         final LinkedTransferQueue<Integer> q
559             = new LinkedTransferQueue<Integer>();
560         assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
561         q.add(one);
562         q.add(two);
563         q.add(three);
564         assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
565         int k = 0;
566         for (Integer n : q) {
567             assertEquals(++k, (int) n);
568         }
569         assertEquals(3, k);
570     }
571 
572     /**
573      * Modifications do not cause iterators to fail
574      */
testWeaklyConsistentIteration()575     public void testWeaklyConsistentIteration() {
576         final LinkedTransferQueue q = new LinkedTransferQueue();
577         q.add(one);
578         q.add(two);
579         q.add(three);
580         for (Iterator it = q.iterator(); it.hasNext();) {
581             q.remove();
582             it.next();
583         }
584         assertEquals(0, q.size());
585     }
586 
587     /**
588      * toString contains toStrings of elements
589      */
testToString()590     public void testToString() {
591         LinkedTransferQueue q = populatedQueue(SIZE);
592         String s = q.toString();
593         for (int i = 0; i < SIZE; ++i) {
594             assertTrue(s.contains(String.valueOf(i)));
595         }
596     }
597 
598     /**
599      * offer transfers elements across Executor tasks
600      */
testOfferInExecutor()601     public void testOfferInExecutor() {
602         final LinkedTransferQueue q = new LinkedTransferQueue();
603         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
604         final ExecutorService executor = Executors.newFixedThreadPool(2);
605         try (PoolCleaner cleaner = cleaner(executor)) {
606 
607             executor.execute(new CheckedRunnable() {
608                 public void realRun() throws InterruptedException {
609                     threadsStarted.await();
610                     long startTime = System.nanoTime();
611                     assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
612                     assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
613                 }});
614 
615             executor.execute(new CheckedRunnable() {
616                 public void realRun() throws InterruptedException {
617                     threadsStarted.await();
618                     assertSame(one, q.take());
619                     checkEmpty(q);
620                 }});
621         }
622     }
623 
624     /**
625      * timed poll retrieves elements across Executor threads
626      */
testPollInExecutor()627     public void testPollInExecutor() {
628         final LinkedTransferQueue q = new LinkedTransferQueue();
629         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
630         final ExecutorService executor = Executors.newFixedThreadPool(2);
631         try (PoolCleaner cleaner = cleaner(executor)) {
632 
633             executor.execute(new CheckedRunnable() {
634                 public void realRun() throws InterruptedException {
635                     assertNull(q.poll());
636                     threadsStarted.await();
637                     long startTime = System.nanoTime();
638                     assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
639                     assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
640                     checkEmpty(q);
641                 }});
642 
643             executor.execute(new CheckedRunnable() {
644                 public void realRun() throws InterruptedException {
645                     threadsStarted.await();
646                     q.put(one);
647                 }});
648         }
649     }
650 
651     /**
652      * A deserialized serialized queue has same elements in same order
653      */
testSerialization()654     public void testSerialization() throws Exception {
655         Queue x = populatedQueue(SIZE);
656         Queue y = serialClone(x);
657 
658         assertNotSame(y, x);
659         assertEquals(x.size(), y.size());
660         assertEquals(x.toString(), y.toString());
661         assertTrue(Arrays.equals(x.toArray(), y.toArray()));
662         while (!x.isEmpty()) {
663             assertFalse(y.isEmpty());
664             assertEquals(x.remove(), y.remove());
665         }
666         assertTrue(y.isEmpty());
667     }
668 
669     /**
670      * drainTo(c) empties queue into another collection c
671      */
testDrainTo()672     public void testDrainTo() {
673         LinkedTransferQueue q = populatedQueue(SIZE);
674         ArrayList l = new ArrayList();
675         q.drainTo(l);
676         assertEquals(0, q.size());
677         assertEquals(SIZE, l.size());
678         for (int i = 0; i < SIZE; ++i) {
679             assertEquals(i, l.get(i));
680         }
681         q.add(zero);
682         q.add(one);
683         assertFalse(q.isEmpty());
684         assertTrue(q.contains(zero));
685         assertTrue(q.contains(one));
686         l.clear();
687         q.drainTo(l);
688         assertEquals(0, q.size());
689         assertEquals(2, l.size());
690         for (int i = 0; i < 2; ++i) {
691             assertEquals(i, l.get(i));
692         }
693     }
694 
695     /**
696      * drainTo(c) empties full queue, unblocking a waiting put.
697      */
testDrainToWithActivePut()698     public void testDrainToWithActivePut() throws InterruptedException {
699         final LinkedTransferQueue q = populatedQueue(SIZE);
700         Thread t = newStartedThread(new CheckedRunnable() {
701             public void realRun() {
702                 q.put(SIZE + 1);
703             }});
704         ArrayList l = new ArrayList();
705         q.drainTo(l);
706         assertTrue(l.size() >= SIZE);
707         for (int i = 0; i < SIZE; ++i)
708             assertEquals(i, l.get(i));
709         awaitTermination(t);
710         assertTrue(q.size() + l.size() >= SIZE);
711     }
712 
713     /**
714      * drainTo(c, n) empties first min(n, size) elements of queue into c
715      */
testDrainToN()716     public void testDrainToN() {
717         LinkedTransferQueue q = new LinkedTransferQueue();
718         for (int i = 0; i < SIZE + 2; ++i) {
719             for (int j = 0; j < SIZE; j++) {
720                 assertTrue(q.offer(j));
721             }
722             ArrayList l = new ArrayList();
723             q.drainTo(l, i);
724             int k = (i < SIZE) ? i : SIZE;
725             assertEquals(k, l.size());
726             assertEquals(SIZE - k, q.size());
727             for (int j = 0; j < k; ++j)
728                 assertEquals(j, l.get(j));
729             do {} while (q.poll() != null);
730         }
731     }
732 
733     /**
734      * timed poll() or take() increments the waiting consumer count;
735      * offer(e) decrements the waiting consumer count
736      */
testWaitingConsumer()737     public void testWaitingConsumer() throws InterruptedException {
738         final LinkedTransferQueue q = new LinkedTransferQueue();
739         assertEquals(0, q.getWaitingConsumerCount());
740         assertFalse(q.hasWaitingConsumer());
741         final CountDownLatch threadStarted = new CountDownLatch(1);
742 
743         Thread t = newStartedThread(new CheckedRunnable() {
744             public void realRun() throws InterruptedException {
745                 threadStarted.countDown();
746                 long startTime = System.nanoTime();
747                 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
748                 assertEquals(0, q.getWaitingConsumerCount());
749                 assertFalse(q.hasWaitingConsumer());
750                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
751             }});
752 
753         threadStarted.await();
754         Callable<Boolean> oneConsumer
755             = new Callable<Boolean>() { public Boolean call() {
756                 return q.hasWaitingConsumer()
757                 && q.getWaitingConsumerCount() == 1; }};
758         waitForThreadToEnterWaitState(t, oneConsumer);
759 
760         assertTrue(q.offer(one));
761         assertEquals(0, q.getWaitingConsumerCount());
762         assertFalse(q.hasWaitingConsumer());
763 
764         awaitTermination(t);
765     }
766 
767     /**
768      * transfer(null) throws NullPointerException
769      */
testTransfer1()770     public void testTransfer1() throws InterruptedException {
771         try {
772             LinkedTransferQueue q = new LinkedTransferQueue();
773             q.transfer(null);
774             shouldThrow();
775         } catch (NullPointerException success) {}
776     }
777 
778     /**
779      * transfer waits until a poll occurs. The transfered element
780      * is returned by this associated poll.
781      */
testTransfer2()782     public void testTransfer2() throws InterruptedException {
783         final LinkedTransferQueue<Integer> q
784             = new LinkedTransferQueue<Integer>();
785         final CountDownLatch threadStarted = new CountDownLatch(1);
786 
787         Thread t = newStartedThread(new CheckedRunnable() {
788             public void realRun() throws InterruptedException {
789                 threadStarted.countDown();
790                 q.transfer(five);
791                 checkEmpty(q);
792             }});
793 
794         threadStarted.await();
795         Callable<Boolean> oneElement
796             = new Callable<Boolean>() { public Boolean call() {
797                 return !q.isEmpty() && q.size() == 1; }};
798         waitForThreadToEnterWaitState(t, oneElement);
799 
800         assertSame(five, q.poll());
801         checkEmpty(q);
802         awaitTermination(t);
803     }
804 
805     /**
806      * transfer waits until a poll occurs, and then transfers in fifo order
807      */
testTransfer3()808     public void testTransfer3() throws InterruptedException {
809         final LinkedTransferQueue<Integer> q
810             = new LinkedTransferQueue<Integer>();
811 
812         Thread first = newStartedThread(new CheckedRunnable() {
813             public void realRun() throws InterruptedException {
814                 q.transfer(four);
815                 assertTrue(!q.contains(four));
816                 assertEquals(1, q.size());
817             }});
818 
819         Thread interruptedThread = newStartedThread(
820             new CheckedInterruptedRunnable() {
821                 public void realRun() throws InterruptedException {
822                     while (q.isEmpty())
823                         Thread.yield();
824                     q.transfer(five);
825                 }});
826 
827         while (q.size() < 2)
828             Thread.yield();
829         assertEquals(2, q.size());
830         assertSame(four, q.poll());
831         first.join();
832         assertEquals(1, q.size());
833         interruptedThread.interrupt();
834         interruptedThread.join();
835         checkEmpty(q);
836     }
837 
838     /**
839      * transfer waits until a poll occurs, at which point the polling
840      * thread returns the element
841      */
testTransfer4()842     public void testTransfer4() throws InterruptedException {
843         final LinkedTransferQueue q = new LinkedTransferQueue();
844 
845         Thread t = newStartedThread(new CheckedRunnable() {
846             public void realRun() throws InterruptedException {
847                 q.transfer(four);
848                 assertFalse(q.contains(four));
849                 assertSame(three, q.poll());
850             }});
851 
852         while (q.isEmpty())
853             Thread.yield();
854         assertFalse(q.isEmpty());
855         assertEquals(1, q.size());
856         assertTrue(q.offer(three));
857         assertSame(four, q.poll());
858         awaitTermination(t);
859     }
860 
861     /**
862      * transfer waits until a take occurs. The transfered element
863      * is returned by this associated take.
864      */
testTransfer5()865     public void testTransfer5() throws InterruptedException {
866         final LinkedTransferQueue<Integer> q
867             = new LinkedTransferQueue<Integer>();
868 
869         Thread t = newStartedThread(new CheckedRunnable() {
870             public void realRun() throws InterruptedException {
871                 q.transfer(four);
872                 checkEmpty(q);
873             }});
874 
875         while (q.isEmpty())
876             Thread.yield();
877         assertFalse(q.isEmpty());
878         assertEquals(1, q.size());
879         assertSame(four, q.take());
880         checkEmpty(q);
881         awaitTermination(t);
882     }
883 
884     /**
885      * tryTransfer(null) throws NullPointerException
886      */
testTryTransfer1()887     public void testTryTransfer1() {
888         final LinkedTransferQueue q = new LinkedTransferQueue();
889         try {
890             q.tryTransfer(null);
891             shouldThrow();
892         } catch (NullPointerException success) {}
893     }
894 
895     /**
896      * tryTransfer returns false and does not enqueue if there are no
897      * consumers waiting to poll or take.
898      */
testTryTransfer2()899     public void testTryTransfer2() throws InterruptedException {
900         final LinkedTransferQueue q = new LinkedTransferQueue();
901         assertFalse(q.tryTransfer(new Object()));
902         assertFalse(q.hasWaitingConsumer());
903         checkEmpty(q);
904     }
905 
906     /**
907      * If there is a consumer waiting in timed poll, tryTransfer
908      * returns true while successfully transfering object.
909      */
testTryTransfer3()910     public void testTryTransfer3() throws InterruptedException {
911         final Object hotPotato = new Object();
912         final LinkedTransferQueue q = new LinkedTransferQueue();
913 
914         Thread t = newStartedThread(new CheckedRunnable() {
915             public void realRun() {
916                 while (! q.hasWaitingConsumer())
917                     Thread.yield();
918                 assertTrue(q.hasWaitingConsumer());
919                 checkEmpty(q);
920                 assertTrue(q.tryTransfer(hotPotato));
921             }});
922 
923         long startTime = System.nanoTime();
924         assertSame(hotPotato, q.poll(LONG_DELAY_MS, MILLISECONDS));
925         assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
926         checkEmpty(q);
927         awaitTermination(t);
928     }
929 
930     /**
931      * If there is a consumer waiting in take, tryTransfer returns
932      * true while successfully transfering object.
933      */
934     public void testTryTransfer4() throws InterruptedException {
935         final Object hotPotato = new Object();
936         final LinkedTransferQueue q = new LinkedTransferQueue();
937 
938         Thread t = newStartedThread(new CheckedRunnable() {
939             public void realRun() {
940                 while (! q.hasWaitingConsumer())
941                     Thread.yield();
942                 assertTrue(q.hasWaitingConsumer());
943                 checkEmpty(q);
944                 assertTrue(q.tryTransfer(hotPotato));
945             }});
946 
947         assertSame(q.take(), hotPotato);
948         checkEmpty(q);
949         awaitTermination(t);
950     }
951 
952     /**
953      * tryTransfer blocks interruptibly if no takers
954      */
955     public void testTryTransfer5() throws InterruptedException {
956         final LinkedTransferQueue q = new LinkedTransferQueue();
957         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
958         assertTrue(q.isEmpty());
959 
960         Thread t = newStartedThread(new CheckedRunnable() {
961             public void realRun() throws InterruptedException {
962                 long startTime = System.nanoTime();
963                 Thread.currentThread().interrupt();
964                 try {
965                     q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
966                     shouldThrow();
967                 } catch (InterruptedException success) {}
968                 assertFalse(Thread.interrupted());
969 
970                 pleaseInterrupt.countDown();
971                 try {
972                     q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
973                     shouldThrow();
974                 } catch (InterruptedException success) {}
975                 assertFalse(Thread.interrupted());
976                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
977             }});
978 
979         await(pleaseInterrupt);
980         assertThreadStaysAlive(t);
981         t.interrupt();
982         awaitTermination(t);
983         checkEmpty(q);
984     }
985 
986     /**
987      * tryTransfer gives up after the timeout and returns false
988      */
989     public void testTryTransfer6() throws InterruptedException {
990         final LinkedTransferQueue q = new LinkedTransferQueue();
991 
992         Thread t = newStartedThread(new CheckedRunnable() {
993             public void realRun() throws InterruptedException {
994                 long startTime = System.nanoTime();
995                 assertFalse(q.tryTransfer(new Object(),
996                                           timeoutMillis(), MILLISECONDS));
997                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
998                 checkEmpty(q);
999             }});
1000 
1001         awaitTermination(t);
1002         checkEmpty(q);
1003     }
1004 
1005     /**
1006      * tryTransfer waits for any elements previously in to be removed
1007      * before transfering to a poll or take
1008      */
1009     public void testTryTransfer7() throws InterruptedException {
1010         final LinkedTransferQueue q = new LinkedTransferQueue();
1011         assertTrue(q.offer(four));
1012 
1013         Thread t = newStartedThread(new CheckedRunnable() {
1014             public void realRun() throws InterruptedException {
1015                 long startTime = System.nanoTime();
1016                 assertTrue(q.tryTransfer(five, LONG_DELAY_MS, MILLISECONDS));
1017                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1018                 checkEmpty(q);
1019             }});
1020 
1021         while (q.size() != 2)
1022             Thread.yield();
1023         assertEquals(2, q.size());
1024         assertSame(four, q.poll());
1025         assertSame(five, q.poll());
1026         checkEmpty(q);
1027         awaitTermination(t);
1028     }
1029 
1030     /**
1031      * tryTransfer attempts to enqueue into the queue and fails
1032      * returning false not enqueueing and the successive poll is null
1033      */
1034     public void testTryTransfer8() throws InterruptedException {
1035         final LinkedTransferQueue q = new LinkedTransferQueue();
1036         assertTrue(q.offer(four));
1037         assertEquals(1, q.size());
1038         long startTime = System.nanoTime();
1039         assertFalse(q.tryTransfer(five, timeoutMillis(), MILLISECONDS));
1040         assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
1041         assertEquals(1, q.size());
1042         assertSame(four, q.poll());
1043         assertNull(q.poll());
1044         checkEmpty(q);
1045     }
1046 
1047     private LinkedTransferQueue<Integer> populatedQueue(int n) {
1048         LinkedTransferQueue<Integer> q = new LinkedTransferQueue<Integer>();
1049         checkEmpty(q);
1050         for (int i = 0; i < n; i++) {
1051             assertEquals(i, q.size());
1052             assertTrue(q.offer(i));
1053             assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
1054         }
1055         assertFalse(q.isEmpty());
1056         return q;
1057     }
1058 
1059     /**
1060      * remove(null), contains(null) always return false
1061      */
1062     public void testNeverContainsNull() {
1063         Collection<?>[] qs = {
1064             new LinkedTransferQueue<Object>(),
1065             populatedQueue(2),
1066         };
1067 
1068         for (Collection<?> q : qs) {
1069             assertFalse(q.contains(null));
1070             assertFalse(q.remove(null));
1071         }
1072     }
1073 }
1074