1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea and Martin Buchholz with assistance from members 30 * of JCP JSR-166 Expert Group and released to the public domain, as 31 * explained at http://creativecommons.org/publicdomain/zero/1.0/ 32 * 33 * Other contributors include Andrew Wright, Jeffrey Hayes, 34 * Pat Fisher, Mike Judd. 35 */ 36 37 import static java.util.concurrent.TimeUnit.MILLISECONDS; 38 39 import java.util.ArrayList; 40 import java.util.Arrays; 41 import java.util.Collection; 42 import java.util.Queue; 43 import java.util.concurrent.BlockingQueue; 44 import java.util.concurrent.CountDownLatch; 45 46 import junit.framework.Test; 47 import junit.framework.TestSuite; 48 49 /** 50 * Contains "contract" tests applicable to all BlockingQueue implementations. 51 */ 52 public abstract class BlockingQueueTest extends JSR166TestCase { 53 /* 54 * This is the start of an attempt to refactor the tests for the 55 * various related implementations of related interfaces without 56 * too much duplicated code. junit does not really support such 57 * testing. Here subclasses of TestCase not only contain tests, 58 * but also configuration information that describes the 59 * implementation class, most importantly how to instantiate 60 * instances. 61 */ 62 63 /** Like suite(), but non-static */ 64 public Test testSuite() { 65 // TODO: filter the returned tests using the configuration 66 // information provided by the subclass via protected methods. 67 return new TestSuite(this.getClass()); 68 } 69 70 //---------------------------------------------------------------- 71 // Configuration methods 72 //---------------------------------------------------------------- 73 74 /** Returns an empty instance of the implementation class. */ 75 protected abstract BlockingQueue emptyCollection(); 76 77 /** 78 * Returns an element suitable for insertion in the collection. 79 * Override for collections with unusual element types. 80 */ 81 protected Object makeElement(int i) { 82 return Integer.valueOf(i); 83 } 84 85 //---------------------------------------------------------------- 86 // Tests 87 //---------------------------------------------------------------- 88 89 /** 90 * offer(null) throws NullPointerException 91 */ 92 public void testOfferNull() { 93 final Queue q = emptyCollection(); 94 try { 95 q.offer(null); 96 shouldThrow(); 97 } catch (NullPointerException success) {} 98 } 99 100 /** 101 * add(null) throws NullPointerException 102 */ 103 public void testAddNull() { 104 final Collection q = emptyCollection(); 105 try { 106 q.add(null); 107 shouldThrow(); 108 } catch (NullPointerException success) {} 109 } 110 111 /** 112 * timed offer(null) throws NullPointerException 113 */ 114 public void testTimedOfferNull() throws InterruptedException { 115 final BlockingQueue q = emptyCollection(); 116 long startTime = System.nanoTime(); 117 try { 118 q.offer(null, LONG_DELAY_MS, MILLISECONDS); 119 shouldThrow(); 120 } catch (NullPointerException success) {} 121 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 122 } 123 124 /** 125 * put(null) throws NullPointerException 126 */ 127 public void testPutNull() throws InterruptedException { 128 final BlockingQueue q = emptyCollection(); 129 try { 130 q.put(null); 131 shouldThrow(); 132 } catch (NullPointerException success) {} 133 } 134 135 /** 136 * addAll(null) throws NullPointerException 137 */ 138 public void testAddAllNull() throws InterruptedException { 139 final Collection q = emptyCollection(); 140 try { 141 q.addAll(null); 142 shouldThrow(); 143 } catch (NullPointerException success) {} 144 } 145 146 /** 147 * addAll of a collection with null elements throws NullPointerException 148 */ 149 public void testAddAllNullElements() { 150 final Collection q = emptyCollection(); 151 final Collection<Integer> elements = Arrays.asList(new Integer[SIZE]); 152 try { 153 q.addAll(elements); 154 shouldThrow(); 155 } catch (NullPointerException success) {} 156 } 157 158 /** 159 * toArray(null) throws NullPointerException 160 */ 161 public void testToArray_NullArray() { 162 final Collection q = emptyCollection(); 163 try { 164 q.toArray((Object[])null); 165 shouldThrow(); 166 } catch (NullPointerException success) {} 167 } 168 169 /** 170 * drainTo(null) throws NullPointerException 171 */ 172 public void testDrainToNull() { 173 final BlockingQueue q = emptyCollection(); 174 try { 175 q.drainTo(null); 176 shouldThrow(); 177 } catch (NullPointerException success) {} 178 } 179 180 /** 181 * drainTo(this) throws IllegalArgumentException 182 */ 183 public void testDrainToSelf() { 184 final BlockingQueue q = emptyCollection(); 185 try { 186 q.drainTo(q); 187 shouldThrow(); 188 } catch (IllegalArgumentException success) {} 189 } 190 191 /** 192 * drainTo(null, n) throws NullPointerException 193 */ 194 public void testDrainToNullN() { 195 final BlockingQueue q = emptyCollection(); 196 try { 197 q.drainTo(null, 0); 198 shouldThrow(); 199 } catch (NullPointerException success) {} 200 } 201 202 /** 203 * drainTo(this, n) throws IllegalArgumentException 204 */ 205 public void testDrainToSelfN() { 206 final BlockingQueue q = emptyCollection(); 207 try { 208 q.drainTo(q, 0); 209 shouldThrow(); 210 } catch (IllegalArgumentException success) {} 211 } 212 213 /** 214 * drainTo(c, n) returns 0 and does nothing when n <= 0 215 */ 216 public void testDrainToNonPositiveMaxElements() { 217 final BlockingQueue q = emptyCollection(); 218 final int[] ns = { 0, -1, -42, Integer.MIN_VALUE }; 219 for (int n : ns) 220 assertEquals(0, q.drainTo(new ArrayList(), n)); 221 if (q.remainingCapacity() > 0) { 222 // Not SynchronousQueue, that is 223 Object one = makeElement(1); 224 q.add(one); 225 ArrayList c = new ArrayList(); 226 for (int n : ns) 227 assertEquals(0, q.drainTo(new ArrayList(), n)); 228 assertEquals(1, q.size()); 229 assertSame(one, q.poll()); 230 assertTrue(c.isEmpty()); 231 } 232 } 233 234 /** 235 * timed poll before a delayed offer times out; after offer succeeds; 236 * on interruption throws 237 */ 238 public void testTimedPollWithOffer() throws InterruptedException { 239 final BlockingQueue q = emptyCollection(); 240 final CheckedBarrier barrier = new CheckedBarrier(2); 241 final Object zero = makeElement(0); 242 Thread t = newStartedThread(new CheckedRunnable() { 243 public void realRun() throws InterruptedException { 244 long startTime = System.nanoTime(); 245 assertNull(q.poll(timeoutMillis(), MILLISECONDS)); 246 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 247 248 barrier.await(); 249 250 assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS)); 251 252 Thread.currentThread().interrupt(); 253 try { 254 q.poll(LONG_DELAY_MS, MILLISECONDS); 255 shouldThrow(); 256 } catch (InterruptedException success) {} 257 assertFalse(Thread.interrupted()); 258 259 barrier.await(); 260 try { 261 q.poll(LONG_DELAY_MS, MILLISECONDS); 262 shouldThrow(); 263 } catch (InterruptedException success) {} 264 assertFalse(Thread.interrupted()); 265 266 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 267 }}); 268 269 barrier.await(); 270 long startTime = System.nanoTime(); 271 assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); 272 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 273 274 barrier.await(); 275 assertThreadBlocks(t, Thread.State.TIMED_WAITING); 276 t.interrupt(); 277 awaitTermination(t); 278 } 279 280 /** 281 * take() blocks interruptibly when empty 282 */ 283 public void testTakeFromEmptyBlocksInterruptibly() { 284 final BlockingQueue q = emptyCollection(); 285 final CountDownLatch threadStarted = new CountDownLatch(1); 286 Thread t = newStartedThread(new CheckedRunnable() { 287 public void realRun() { 288 threadStarted.countDown(); 289 try { 290 q.take(); 291 shouldThrow(); 292 } catch (InterruptedException success) {} 293 assertFalse(Thread.interrupted()); 294 }}); 295 296 await(threadStarted); 297 assertThreadBlocks(t, Thread.State.WAITING); 298 t.interrupt(); 299 awaitTermination(t); 300 } 301 302 /** 303 * take() throws InterruptedException immediately if interrupted 304 * before waiting 305 */ 306 public void testTakeFromEmptyAfterInterrupt() { 307 final BlockingQueue q = emptyCollection(); 308 Thread t = newStartedThread(new CheckedRunnable() { 309 public void realRun() { 310 Thread.currentThread().interrupt(); 311 try { 312 q.take(); 313 shouldThrow(); 314 } catch (InterruptedException success) {} 315 assertFalse(Thread.interrupted()); 316 }}); 317 318 awaitTermination(t); 319 } 320 321 /** 322 * timed poll() blocks interruptibly when empty 323 */ 324 public void testTimedPollFromEmptyBlocksInterruptibly() { 325 final BlockingQueue q = emptyCollection(); 326 final CountDownLatch threadStarted = new CountDownLatch(1); 327 Thread t = newStartedThread(new CheckedRunnable() { 328 public void realRun() { 329 threadStarted.countDown(); 330 try { 331 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 332 shouldThrow(); 333 } catch (InterruptedException success) {} 334 assertFalse(Thread.interrupted()); 335 }}); 336 337 await(threadStarted); 338 assertThreadBlocks(t, Thread.State.TIMED_WAITING); 339 t.interrupt(); 340 awaitTermination(t); 341 } 342 343 /** 344 * timed poll() throws InterruptedException immediately if 345 * interrupted before waiting 346 */ 347 public void testTimedPollFromEmptyAfterInterrupt() { 348 final BlockingQueue q = emptyCollection(); 349 Thread t = newStartedThread(new CheckedRunnable() { 350 public void realRun() { 351 Thread.currentThread().interrupt(); 352 try { 353 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 354 shouldThrow(); 355 } catch (InterruptedException success) {} 356 assertFalse(Thread.interrupted()); 357 }}); 358 359 awaitTermination(t); 360 } 361 362 /** 363 * remove(x) removes x and returns true if present 364 * TODO: move to superclass CollectionTest.java 365 */ 366 public void testRemoveElement() { 367 final BlockingQueue q = emptyCollection(); 368 final int size = Math.min(q.remainingCapacity(), SIZE); 369 final Object[] elts = new Object[size]; 370 assertFalse(q.contains(makeElement(99))); 371 assertFalse(q.remove(makeElement(99))); 372 checkEmpty(q); 373 for (int i = 0; i < size; i++) 374 q.add(elts[i] = makeElement(i)); 375 for (int i = 1; i < size; i += 2) { 376 for (int pass = 0; pass < 2; pass++) { 377 assertEquals((pass == 0), q.contains(elts[i])); 378 assertEquals((pass == 0), q.remove(elts[i])); 379 assertFalse(q.contains(elts[i])); 380 assertTrue(q.contains(elts[i - 1])); 381 if (i < size - 1) 382 assertTrue(q.contains(elts[i + 1])); 383 } 384 } 385 if (size > 0) 386 assertTrue(q.contains(elts[0])); 387 for (int i = size - 2; i >= 0; i -= 2) { 388 assertTrue(q.contains(elts[i])); 389 assertFalse(q.contains(elts[i + 1])); 390 assertTrue(q.remove(elts[i])); 391 assertFalse(q.contains(elts[i])); 392 assertFalse(q.remove(elts[i + 1])); 393 assertFalse(q.contains(elts[i + 1])); 394 } 395 checkEmpty(q); 396 } 397 398 /** For debugging. */ 399 public void XXXXtestFails() { 400 fail(emptyCollection().getClass().toString()); 401 } 402 403 }