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 static java.util.concurrent.TimeUnit.MILLISECONDS; 13 14 import java.util.ArrayList; 15 import java.util.Arrays; 16 import java.util.Collection; 17 import java.util.Queue; 18 import java.util.concurrent.BlockingQueue; 19 import java.util.concurrent.CountDownLatch; 20 21 import junit.framework.Test; 22 import junit.framework.TestSuite; 23 24 /** 25 * Contains "contract" tests applicable to all BlockingQueue implementations. 26 */ 27 public 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. */ emptyCollection()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 */ makeElement(int i)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 */ testOfferNull()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 */ testAddNull()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 */ testTimedOfferNull()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 */ testTimedPollWithOffer()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 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 244 }}); 245 246 barrier.await(); 247 long startTime = System.nanoTime(); 248 assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); 249 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 250 251 barrier.await(); 252 assertThreadStaysAlive(t); 253 t.interrupt(); 254 awaitTermination(t); 255 } 256 257 /** 258 * take() blocks interruptibly when empty 259 */ 260 public void testTakeFromEmptyBlocksInterruptibly() { 261 final BlockingQueue q = emptyCollection(); 262 final CountDownLatch threadStarted = new CountDownLatch(1); 263 Thread t = newStartedThread(new CheckedRunnable() { 264 public void realRun() { 265 threadStarted.countDown(); 266 try { 267 q.take(); 268 shouldThrow(); 269 } catch (InterruptedException success) {} 270 assertFalse(Thread.interrupted()); 271 }}); 272 273 await(threadStarted); 274 assertThreadStaysAlive(t); 275 t.interrupt(); 276 awaitTermination(t); 277 } 278 279 /** 280 * take() throws InterruptedException immediately if interrupted 281 * before waiting 282 */ 283 public void testTakeFromEmptyAfterInterrupt() { 284 final BlockingQueue q = emptyCollection(); 285 Thread t = newStartedThread(new CheckedRunnable() { 286 public void realRun() { 287 Thread.currentThread().interrupt(); 288 try { 289 q.take(); 290 shouldThrow(); 291 } catch (InterruptedException success) {} 292 assertFalse(Thread.interrupted()); 293 }}); 294 295 awaitTermination(t); 296 } 297 298 /** 299 * timed poll() blocks interruptibly when empty 300 */ 301 public void testTimedPollFromEmptyBlocksInterruptibly() { 302 final BlockingQueue q = emptyCollection(); 303 final CountDownLatch threadStarted = new CountDownLatch(1); 304 Thread t = newStartedThread(new CheckedRunnable() { 305 public void realRun() { 306 threadStarted.countDown(); 307 try { 308 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 309 shouldThrow(); 310 } catch (InterruptedException success) {} 311 assertFalse(Thread.interrupted()); 312 }}); 313 314 await(threadStarted); 315 assertThreadStaysAlive(t); 316 t.interrupt(); 317 awaitTermination(t); 318 } 319 320 /** 321 * timed poll() throws InterruptedException immediately if 322 * interrupted before waiting 323 */ 324 public void testTimedPollFromEmptyAfterInterrupt() { 325 final BlockingQueue q = emptyCollection(); 326 Thread t = newStartedThread(new CheckedRunnable() { 327 public void realRun() { 328 Thread.currentThread().interrupt(); 329 try { 330 q.poll(2 * LONG_DELAY_MS, MILLISECONDS); 331 shouldThrow(); 332 } catch (InterruptedException success) {} 333 assertFalse(Thread.interrupted()); 334 }}); 335 336 awaitTermination(t); 337 } 338 339 /** 340 * remove(x) removes x and returns true if present 341 * TODO: move to superclass CollectionTest.java 342 */ 343 public void testRemoveElement() { 344 final BlockingQueue q = emptyCollection(); 345 final int size = Math.min(q.remainingCapacity(), SIZE); 346 final Object[] elts = new Object[size]; 347 assertFalse(q.contains(makeElement(99))); 348 assertFalse(q.remove(makeElement(99))); 349 checkEmpty(q); 350 for (int i = 0; i < size; i++) 351 q.add(elts[i] = makeElement(i)); 352 for (int i = 1; i < size; i += 2) { 353 for (int pass = 0; pass < 2; pass++) { 354 assertEquals((pass == 0), q.contains(elts[i])); 355 assertEquals((pass == 0), q.remove(elts[i])); 356 assertFalse(q.contains(elts[i])); 357 assertTrue(q.contains(elts[i - 1])); 358 if (i < size - 1) 359 assertTrue(q.contains(elts[i + 1])); 360 } 361 } 362 if (size > 0) 363 assertTrue(q.contains(elts[0])); 364 for (int i = size - 2; i >= 0; i -= 2) { 365 assertTrue(q.contains(elts[i])); 366 assertFalse(q.contains(elts[i + 1])); 367 assertTrue(q.remove(elts[i])); 368 assertFalse(q.contains(elts[i])); 369 assertFalse(q.remove(elts[i + 1])); 370 assertFalse(q.contains(elts[i + 1])); 371 } 372 checkEmpty(q); 373 } 374 375 /** For debugging. */ 376 public void XXXXtestFails() { 377 fail(emptyCollection().getClass().toString()); 378 } 379 380 } 381