View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.pool2.impl;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.time.Duration;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.Iterator;
30  import java.util.NoSuchElementException;
31  import java.util.concurrent.TimeUnit;
32  
33  import org.junit.jupiter.api.BeforeEach;
34  import org.junit.jupiter.api.Test;
35  import org.junit.jupiter.api.Timeout;
36  
37  /**
38   * Tests for {@link LinkedBlockingDeque}.
39   */
40  public class TestLinkedBlockingDeque {
41  
42      private static final Duration TIMEOUT_50_MILLIS = Duration.ofMillis(50);
43      private static final Integer ONE = Integer.valueOf(1);
44      private static final Integer TWO = Integer.valueOf(2);
45      private static final Integer THREE = Integer.valueOf(3);
46  
47      LinkedBlockingDeque<Integer> deque;
48  
49      @BeforeEach
50      public void setUp() {
51          deque = new LinkedBlockingDeque<>(2);
52      }
53  
54      @Test
55      public void testAdd() {
56          assertTrue(deque.add(ONE));
57          assertTrue(deque.add(TWO));
58          assertThrows(IllegalStateException.class, () -> deque.add(THREE));
59          assertThrows(NullPointerException.class, () -> deque.add(null));
60      }
61  
62      @Test
63      public void testAddFirst() {
64          deque.addFirst(ONE);
65          deque.addFirst(TWO);
66          assertEquals(2, deque.size());
67          assertThrows(IllegalStateException.class, () -> deque.add(THREE));
68          assertEquals(Integer.valueOf(2), deque.pop());
69      }
70  
71      @Test
72      public void testAddLast() {
73          deque.addLast(ONE);
74          deque.addLast(TWO);
75          assertEquals(2, deque.size());
76          assertThrows(IllegalStateException.class, () -> deque.add(THREE));
77          assertEquals(Integer.valueOf(1), deque.pop());
78      }
79  
80      @Test
81      public void testClear() {
82          deque.add(ONE);
83          deque.add(TWO);
84          deque.clear();
85          deque.add(ONE);
86          assertEquals(1, deque.size());
87      }
88  
89      @Test
90      public void testConstructors() {
91          LinkedBlockingDeque<Integer> deque = new LinkedBlockingDeque<>();
92          assertEquals(Integer.MAX_VALUE, deque.remainingCapacity());
93  
94          deque = new LinkedBlockingDeque<>(2);
95          assertEquals(2, deque.remainingCapacity());
96  
97          deque = new LinkedBlockingDeque<>(Arrays.asList(ONE, TWO));
98          assertEquals(2, deque.size());
99  
100         assertThrows(NullPointerException.class, () -> new LinkedBlockingDeque<>(Arrays.asList(ONE, null)));
101     }
102 
103     @Test
104     public void testContains() {
105         deque.add(ONE);
106         assertTrue(deque.contains(ONE));
107         assertFalse(deque.contains(TWO));
108         assertFalse(deque.contains(null));
109         deque.add(TWO);
110         assertTrue(deque.contains(TWO));
111         assertFalse(deque.contains(THREE));
112     }
113 
114     @Test
115     public void testDescendingIterator() {
116         assertThrows(NoSuchElementException.class, () -> deque.descendingIterator().next());
117         deque.add(ONE);
118         deque.add(TWO);
119         final Iterator<Integer> iter = deque.descendingIterator();
120         assertEquals(Integer.valueOf(2), iter.next());
121         iter.remove();
122         assertEquals(Integer.valueOf(1), iter.next());
123     }
124 
125     @Test
126     public void testDrainTo() {
127         Collection<Integer> c = new ArrayList<>();
128         deque.add(ONE);
129         deque.add(TWO);
130         assertEquals(2, deque.drainTo(c));
131         assertEquals(2, c.size());
132 
133         c = new ArrayList<>();
134         deque.add(ONE);
135         deque.add(TWO);
136         assertEquals(1, deque.drainTo(c, 1));
137         assertEquals(1, deque.size());
138         assertEquals(1, c.size());
139         assertEquals(Integer.valueOf(1), c.iterator().next());
140     }
141 
142     @Test
143     public void testElement() {
144         assertThrows(NoSuchElementException.class, () -> deque.element());
145         deque.add(ONE);
146         deque.add(TWO);
147         assertEquals(Integer.valueOf(1), deque.element());
148     }
149 
150     @Test
151     public void testGetFirst() {
152         assertThrows(NoSuchElementException.class, () -> deque.getFirst());
153         deque.add(ONE);
154         deque.add(TWO);
155         assertEquals(Integer.valueOf(1), deque.getFirst());
156     }
157 
158     @Test
159     public void testGetLast() {
160         assertThrows(NoSuchElementException.class, () -> deque.getLast());
161         deque.add(ONE);
162         deque.add(TWO);
163         assertEquals(Integer.valueOf(2), deque.getLast());
164     }
165 
166     @Test
167     public void testIterator() {
168         assertThrows(NoSuchElementException.class, () -> deque.iterator().next());
169         deque.add(ONE);
170         deque.add(TWO);
171         final Iterator<Integer> iter = deque.iterator();
172         assertEquals(Integer.valueOf(1), iter.next());
173         iter.remove();
174         assertEquals(Integer.valueOf(2), iter.next());
175     }
176 
177     @Test
178     public void testOffer() {
179         assertTrue(deque.offer(ONE));
180         assertTrue(deque.offer(TWO));
181         assertFalse(deque.offer(THREE));
182         assertThrows(NullPointerException.class, () -> deque.offer(null));
183     }
184 
185     @Test
186     public void testOfferFirst() {
187         deque.offerFirst(ONE);
188         deque.offerFirst(TWO);
189         assertEquals(2, deque.size());
190         assertThrows(NullPointerException.class, () -> deque.offerFirst(null));
191         assertEquals(Integer.valueOf(2), deque.pop());
192     }
193 
194     @Test
195     public void testOfferFirstWithTimeout() throws InterruptedException {
196         assertThrows(NullPointerException.class, () -> deque.offerFirst(null, TIMEOUT_50_MILLIS));
197         assertTrue(deque.offerFirst(ONE, TIMEOUT_50_MILLIS));
198         assertTrue(deque.offerFirst(TWO, TIMEOUT_50_MILLIS));
199         assertFalse(deque.offerFirst(THREE, TIMEOUT_50_MILLIS));
200     }
201 
202     @Test
203     public void testOfferLast() {
204         deque.offerLast(ONE);
205         deque.offerLast(TWO);
206         assertEquals(2, deque.size());
207         assertThrows(NullPointerException.class, () -> deque.offerLast(null));
208         assertEquals(Integer.valueOf(1), deque.pop());
209     }
210 
211     @Test
212     public void testOfferLastWithTimeout() throws InterruptedException {
213         assertThrows(NullPointerException.class, () -> deque.offerLast(null, TIMEOUT_50_MILLIS));
214         assertTrue(deque.offerLast(ONE, TIMEOUT_50_MILLIS));
215         assertTrue(deque.offerLast(TWO, TIMEOUT_50_MILLIS));
216         assertFalse(deque.offerLast(THREE, TIMEOUT_50_MILLIS));
217     }
218 
219     @Test
220     public void testOfferWithTimeout() throws InterruptedException {
221         assertTrue(deque.offer(ONE, TIMEOUT_50_MILLIS));
222         assertTrue(deque.offer(TWO, TIMEOUT_50_MILLIS));
223         assertFalse(deque.offer(THREE, TIMEOUT_50_MILLIS));
224         assertThrows(NullPointerException.class, () -> deque.offer(null, TIMEOUT_50_MILLIS));
225     }
226 
227     @Test
228     public void testPeek() {
229         assertNull(deque.peek());
230         deque.add(ONE);
231         deque.add(TWO);
232         assertEquals(Integer.valueOf(1), deque.peek());
233     }
234 
235     @Test
236     public void testPeekFirst() {
237         assertNull(deque.peekFirst());
238         deque.add(ONE);
239         deque.add(TWO);
240         assertEquals(Integer.valueOf(1), deque.peekFirst());
241     }
242 
243     @Test
244     public void testPeekLast() {
245         assertNull(deque.peekLast());
246         deque.add(ONE);
247         deque.add(TWO);
248         assertEquals(Integer.valueOf(2), deque.peekLast());
249     }
250 
251     @Test
252     public void testPollFirst() {
253         assertNull(deque.pollFirst());
254         assertTrue(deque.offerFirst(ONE));
255         assertTrue(deque.offerFirst(TWO));
256         assertEquals(Integer.valueOf(2), deque.pollFirst());
257     }
258 
259     @Test
260     public void testPollFirstWithTimeout() throws InterruptedException {
261         assertNull(deque.pollFirst());
262         assertNull(deque.pollFirst(TIMEOUT_50_MILLIS));
263     }
264 
265     @Test
266     public void testPollLast() {
267         assertNull(deque.pollLast());
268         assertTrue(deque.offerFirst(ONE));
269         assertTrue(deque.offerFirst(TWO));
270         assertEquals(Integer.valueOf(1), deque.pollLast());
271     }
272 
273     @Test
274     public void testPollLastWithTimeout() throws InterruptedException {
275         assertNull(deque.pollLast());
276         assertNull(deque.pollLast(TIMEOUT_50_MILLIS));
277     }
278 
279     @Test
280     public void testPollWithTimeout() throws InterruptedException {
281         assertNull(deque.poll(TIMEOUT_50_MILLIS));
282         assertNull(deque.poll(TIMEOUT_50_MILLIS));
283     }
284 
285     @Test
286     public void testPop() {
287         assertThrows(NoSuchElementException.class, () -> deque.pop());
288         deque.add(ONE);
289         deque.add(TWO);
290         assertEquals(Integer.valueOf(1), deque.pop());
291         assertThrows(NoSuchElementException.class, () -> {
292             deque.pop();
293             deque.pop();
294         });
295     }
296 
297     /*
298      * https://issues.apache.org/jira/browse/POOL-281
299      *
300      * Should complete almost instantly when the issue is fixed.
301      */
302     @Test
303     @Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
304     public void testPossibleBug() {
305 
306         deque = new LinkedBlockingDeque<>();
307         for (int i = 0; i < 3; i++) {
308             deque.add(Integer.valueOf(i));
309         }
310 
311         // This particular sequence of method calls() (there may be others)
312         // creates an internal state that triggers an infinite loop in the
313         // iterator.
314         final Iterator<Integer> iter = deque.iterator();
315         iter.next();
316 
317         deque.remove(Integer.valueOf(1));
318         deque.remove(Integer.valueOf(0));
319         deque.remove(Integer.valueOf(2));
320 
321         iter.next();
322     }
323 
324     @Test
325     public void testPush() {
326         deque.push(ONE);
327         deque.push(TWO);
328         assertEquals(2, deque.size());
329         assertThrows(IllegalStateException.class, () -> deque.push(THREE));
330         assertEquals(Integer.valueOf(2), deque.pop());
331     }
332 
333     @Test
334     public void testPut() throws InterruptedException {
335         assertThrows(NullPointerException.class, () -> deque.put(null));
336         deque.put(ONE);
337         deque.put(TWO);
338     }
339 
340     @Test
341     public void testPutFirst() throws InterruptedException {
342         assertThrows(NullPointerException.class, () -> deque.putFirst(null));
343         deque.putFirst(ONE);
344         deque.putFirst(TWO);
345         assertEquals(2, deque.size());
346         assertEquals(Integer.valueOf(2), deque.pop());
347     }
348 
349     @Test
350     public void testPutLast() throws InterruptedException {
351         assertThrows(NullPointerException.class, () -> deque.putLast(null));
352         deque.putLast(ONE);
353         deque.putLast(TWO);
354         assertEquals(2, deque.size());
355         assertEquals(Integer.valueOf(1), deque.pop());
356     }
357 
358     @Test
359     public void testRemove() {
360         assertThrows(NoSuchElementException.class, deque::remove);
361         deque.add(ONE);
362         deque.add(TWO);
363         assertEquals(Integer.valueOf(1), deque.remove());
364     }
365 
366     @Test
367     public void testRemoveFirst() {
368         assertThrows(NoSuchElementException.class, deque::removeFirst);
369         deque.add(ONE);
370         deque.add(TWO);
371         assertEquals(Integer.valueOf(1), deque.removeFirst());
372         assertThrows(NoSuchElementException.class, () -> {
373             deque.removeFirst();
374             deque.removeFirst();
375         });
376     }
377 
378     @Test
379     public void testRemoveLast() {
380         assertThrows(NoSuchElementException.class, deque::removeLast);
381         deque.add(ONE);
382         deque.add(TWO);
383         assertEquals(Integer.valueOf(2), deque.removeLast());
384         assertThrows(NoSuchElementException.class, () -> {
385             deque.removeLast();
386             deque.removeLast();
387         });
388     }
389 
390     @Test
391     public void testRemoveLastOccurrence() {
392         assertFalse(deque.removeLastOccurrence(null));
393         assertFalse(deque.removeLastOccurrence(ONE));
394         deque.add(ONE);
395         deque.add(ONE);
396         assertTrue(deque.removeLastOccurrence(ONE));
397         assertEquals(1, deque.size());
398     }
399 
400     @Test
401     public void testTake() throws InterruptedException {
402         assertTrue(deque.offerFirst(ONE));
403         assertTrue(deque.offerFirst(TWO));
404         assertEquals(Integer.valueOf(2), deque.take());
405     }
406 
407     @Test
408     public void testTakeFirst() throws InterruptedException {
409         assertTrue(deque.offerFirst(ONE));
410         assertTrue(deque.offerFirst(TWO));
411         assertEquals(Integer.valueOf(2), deque.takeFirst());
412     }
413 
414     @Test
415     public void testTakeLast() throws InterruptedException {
416         assertTrue(deque.offerFirst(ONE));
417         assertTrue(deque.offerFirst(TWO));
418         assertEquals(Integer.valueOf(1), deque.takeLast());
419     }
420 
421     @Test
422     public void testToArray() {
423         deque.add(ONE);
424         deque.add(TWO);
425         Object[] arr = deque.toArray();
426         assertEquals(Integer.valueOf(1), arr[0]);
427         assertEquals(Integer.valueOf(2), arr[1]);
428 
429         arr = deque.toArray(new Integer[0]);
430         assertEquals(Integer.valueOf(1), arr[0]);
431         assertEquals(Integer.valueOf(2), arr[1]);
432 
433         arr = deque.toArray(new Integer[0]);
434         assertEquals(Integer.valueOf(1), arr[0]);
435         assertEquals(Integer.valueOf(2), arr[1]);
436     }
437 }