BlockingQueueTest.java revision 8e9a0e92906742b17eb08d7fb83cca91965f9b8e
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 10package jsr166; 11 12import static java.util.concurrent.TimeUnit.MILLISECONDS; 13 14import 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; 20 21import junit.framework.Test; 22import junit.framework.TestSuite; 23 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 38 /** Like suite(), but non-static */ 39 // android-note: Explicitly instantiated. 40 // 41 // public Test testSuite() { 42 // // TODO: filter the returned tests using the configuration 43 // // information provided by the subclass via protected methods. 44 // return new TestSuite(this.getClass()); 45 // } 46 47 //---------------------------------------------------------------- 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 { 141 q.toArray(null); 142 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()); 242 }}); 243 244 barrier.await(); 245 long startTime = System.nanoTime(); 246 assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); 247 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 248 249 barrier.await(); 250 assertThreadStaysAlive(t); 251 t.interrupt(); 252 awaitTermination(t); 253 } 254 255 /** 256 * take() blocks interruptibly when empty 257 */ 258 public void testTakeFromEmptyBlocksInterruptibly() { 259 final BlockingQueue q = emptyCollection(); 260 final CountDownLatch threadStarted = new CountDownLatch(1); 261 Thread t = newStartedThread(new CheckedRunnable() { 262 public void realRun() { 263 threadStarted.countDown(); 264 try { 265 q.take(); 266 shouldThrow(); 267 } catch (InterruptedException success) {} 268 assertFalse(Thread.interrupted()); 269 }}); 270 271 await(threadStarted); 272 assertThreadStaysAlive(t); 273 t.interrupt(); 274 awaitTermination(t); 275 } 276 277 /** 278 * take() throws InterruptedException immediately if interrupted 279 * before waiting 280 */ 281 public void testTakeFromEmptyAfterInterrupt() { 282 final BlockingQueue q = emptyCollection(); 283 Thread t = newStartedThread(new CheckedRunnable() { 284 public void realRun() { 285 Thread.currentThread().interrupt(); 286 try { 287 q.take(); 288 shouldThrow(); 289 } catch (InterruptedException success) {} 290 assertFalse(Thread.interrupted()); 291 }}); 292 293 awaitTermination(t); 294 } 295 296 /** 297 * timed poll() blocks interruptibly when empty 298 */ 299 public void testTimedPollFromEmptyBlocksInterruptibly() { 300 final BlockingQueue q = emptyCollection(); 301 final CountDownLatch threadStarted = new CountDownLatch(1); 302 Thread t = newStartedThread(new CheckedRunnable() { 303 public void realRun() { 304 threadStarted.countDown(); 305 try { 306 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 307 shouldThrow(); 308 } catch (InterruptedException success) {} 309 assertFalse(Thread.interrupted()); 310 }}); 311 312 await(threadStarted); 313 assertThreadStaysAlive(t); 314 t.interrupt(); 315 awaitTermination(t); 316 } 317 318 /** 319 * timed poll() throws InterruptedException immediately if 320 * interrupted before waiting 321 */ 322 public void testTimedPollFromEmptyAfterInterrupt() { 323 final BlockingQueue q = emptyCollection(); 324 Thread t = newStartedThread(new CheckedRunnable() { 325 public void realRun() { 326 Thread.currentThread().interrupt(); 327 try { 328 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 329 shouldThrow(); 330 } catch (InterruptedException success) {} 331 assertFalse(Thread.interrupted()); 332 }}); 333 334 awaitTermination(t); 335 } 336 337 /** 338 * remove(x) removes x and returns true if present 339 * TODO: move to superclass CollectionTest.java 340 */ 341 public void testRemoveElement() { 342 final BlockingQueue q = emptyCollection(); 343 final int size = Math.min(q.remainingCapacity(), SIZE); 344 final Object[] elts = new Object[size]; 345 assertFalse(q.contains(makeElement(99))); 346 assertFalse(q.remove(makeElement(99))); 347 checkEmpty(q); 348 for (int i = 0; i < size; i++) 349 q.add(elts[i] = makeElement(i)); 350 for (int i = 1; i < size; i += 2) { 351 for (int pass = 0; pass < 2; pass++) { 352 assertEquals((pass == 0), q.contains(elts[i])); 353 assertEquals((pass == 0), q.remove(elts[i])); 354 assertFalse(q.contains(elts[i])); 355 assertTrue(q.contains(elts[i-1])); 356 if (i < size - 1) 357 assertTrue(q.contains(elts[i+1])); 358 } 359 } 360 if (size > 0) 361 assertTrue(q.contains(elts[0])); 362 for (int i = size-2; i >= 0; i -= 2) { 363 assertTrue(q.contains(elts[i])); 364 assertFalse(q.contains(elts[i+1])); 365 assertTrue(q.remove(elts[i])); 366 assertFalse(q.contains(elts[i])); 367 assertFalse(q.remove(elts[i+1])); 368 assertFalse(q.contains(elts[i+1])); 369 } 370 checkEmpty(q); 371 } 372 373 /** For debugging. */ 374 public void XXXXtestFails() { 375 fail(emptyCollection().getClass().toString()); 376 } 377 378} 379