--- jsr166/src/test/tck/Collection8Test.java 2016/12/12 20:49:34 1.42 +++ jsr166/src/test/tck/Collection8Test.java 2018/04/04 03:35:13 1.50 @@ -19,6 +19,7 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.Set; import java.util.Spliterator; import java.util.concurrent.BlockingDeque; import java.util.concurrent.BlockingQueue; @@ -59,9 +60,10 @@ public class Collection8Test extends JSR Object bomb() { return new Object() { - public boolean equals(Object x) { throw new AssertionError(); } - public int hashCode() { throw new AssertionError(); } - }; + @Override public boolean equals(Object x) { throw new AssertionError(); } + @Override public int hashCode() { throw new AssertionError(); } + @Override public String toString() { throw new AssertionError(); } + }; } /** Checks properties of empty collections. */ @@ -92,6 +94,23 @@ public class Collection8Test extends JSR assertTrue(c.isEmpty()); assertEquals(0, c.size()); assertEquals("[]", c.toString()); + if (c instanceof List) { + List x = (List) c; + assertEquals(1, x.hashCode()); + assertEquals(x, Collections.emptyList()); + assertEquals(Collections.emptyList(), x); + assertEquals(-1, x.indexOf(impl.makeElement(86))); + assertEquals(-1, x.lastIndexOf(impl.makeElement(99))); + assertThrows( + IndexOutOfBoundsException.class, + () -> x.get(0), + () -> x.set(0, impl.makeElement(42))); + } + else if (c instanceof Set) { + assertEquals(0, c.hashCode()); + assertEquals(c, Collections.emptySet()); + assertEquals(Collections.emptySet(), c); + } { Object[] a = c.toArray(); assertEquals(0, a.length); @@ -140,12 +159,12 @@ public class Collection8Test extends JSR } if (c instanceof BlockingQueue) { BlockingQueue q = (BlockingQueue) c; - assertNull(q.poll(0L, MILLISECONDS)); + assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit())); } if (c instanceof BlockingDeque) { BlockingDeque q = (BlockingDeque) c; - assertNull(q.pollFirst(0L, MILLISECONDS)); - assertNull(q.pollLast(0L, MILLISECONDS)); + assertNull(q.pollFirst(randomExpiredTimeout(), randomTimeUnit())); + assertNull(q.pollLast(randomExpiredTimeout(), randomTimeUnit())); } } @@ -252,6 +271,16 @@ public class Collection8Test extends JSR () -> d.pop(), () -> d.descendingIterator().next()); } + if (c instanceof List) { + List x = (List) c; + assertThrows( + NoSuchElementException.class, + () -> x.iterator().next(), + () -> x.listIterator().next(), + () -> x.listIterator(0).next(), + () -> x.listIterator().previous(), + () -> x.listIterator(0).previous()); + } } public void testRemoveIf() { @@ -541,18 +570,14 @@ public class Collection8Test extends JSR } catch (ConcurrentModificationException ex) { r1 = ConcurrentModificationException.class; assertFalse(impl.isConcurrent()); - } catch (UnsupportedOperationException ex) { - r1 = UnsupportedOperationException.class; } try { it2.forEachRemaining(iteratedForEachRemaining::add); r2 = iteratedForEachRemaining; } catch (ConcurrentModificationException ex) { r2 = ConcurrentModificationException.class; - } catch (UnsupportedOperationException ex) { - r2 = UnsupportedOperationException.class; + assertFalse(impl.isConcurrent()); } - if (!r1.equals(r2)) System.err.println(impl.klazz()); assertEquals(r1, r2); } @@ -731,6 +756,31 @@ public class Collection8Test extends JSR } /** + * Concurrent Spliterators, once exhausted, stay exhausted. + */ + public void testStickySpliteratorExhaustion() throws Throwable { + if (!impl.isConcurrent()) return; + if (!testImplementationDetails) return; + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final Consumer alwaysThrows = e -> { throw new AssertionError(); }; + final Collection c = impl.emptyCollection(); + final Spliterator s = c.spliterator(); + if (rnd.nextBoolean()) { + assertFalse(s.tryAdvance(alwaysThrows)); + } else { + s.forEachRemaining(alwaysThrows); + } + final Object one = impl.makeElement(1); + // Spliterator should not notice added element + c.add(one); + if (rnd.nextBoolean()) { + assertFalse(s.tryAdvance(alwaysThrows)); + } else { + s.forEachRemaining(alwaysThrows); + } + } + + /** * Motley crew of threads concurrently randomly hammer the collection. */ public void testDetectRaces() throws Throwable { @@ -856,6 +906,26 @@ public class Collection8Test extends JSR } } + public void testObjectMethods() { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + Collection c = impl.emptyCollection(); + for (int n = rnd.nextInt(3); n--> 0; ) + c.add(impl.makeElement(rnd.nextInt())); + assertEquals(c, c); + if (c instanceof List) { + List copy = new ArrayList(c); + assertEquals(copy, c); + assertEquals(c, copy); + assertEquals(copy.hashCode(), c.hashCode()); + } + if (c instanceof Set) { + Set copy = new HashSet(c); + assertEquals(copy, c); + assertEquals(c, copy); + assertEquals(copy.hashCode(), c.hashCode()); + } + } + // public void testCollection8DebugFail() { // fail(impl.klazz().getSimpleName()); // }