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