ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/Collection8Test.java
Revision: 1.10
Committed: Sat Nov 5 01:27:00 2016 UTC (7 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +11 -0 lines
Log Message:
testEmptyMeansEmpty: more assertions

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea and Martin Buchholz with assistance from
3     * members of JCP JSR-166 Expert Group and released to the public
4     * domain, as explained at
5     * http://creativecommons.org/publicdomain/zero/1.0/
6     */
7    
8     import static java.util.concurrent.TimeUnit.MILLISECONDS;
9    
10     import java.util.ArrayList;
11     import java.util.Collection;
12     import java.util.Collections;
13 jsr166 1.5 import java.util.Deque;
14     import java.util.HashSet;
15     import java.util.Iterator;
16     import java.util.List;
17     import java.util.NoSuchElementException;
18     import java.util.Queue;
19     import java.util.Spliterator;
20 jsr166 1.2 import java.util.concurrent.CountDownLatch;
21 jsr166 1.1 import java.util.concurrent.Executors;
22     import java.util.concurrent.ExecutorService;
23     import java.util.concurrent.Future;
24 jsr166 1.5 import java.util.concurrent.ThreadLocalRandom;
25 jsr166 1.1 import java.util.concurrent.atomic.AtomicBoolean;
26     import java.util.concurrent.atomic.AtomicLong;
27 jsr166 1.5 import java.util.concurrent.atomic.AtomicReference;
28 jsr166 1.1 import java.util.function.Consumer;
29 jsr166 1.5 import java.util.function.Predicate;
30 jsr166 1.1
31     import junit.framework.Test;
32    
33     /**
34     * Contains tests applicable to all jdk8+ Collection implementations.
35     * An extension of CollectionTest.
36     */
37     public class Collection8Test extends JSR166TestCase {
38     final CollectionImplementation impl;
39    
40     /** Tests are parameterized by a Collection implementation. */
41     Collection8Test(CollectionImplementation impl, String methodName) {
42     super(methodName);
43     this.impl = impl;
44     }
45    
46     public static Test testSuite(CollectionImplementation impl) {
47     return parameterizedTestSuite(Collection8Test.class,
48     CollectionImplementation.class,
49     impl);
50     }
51    
52 jsr166 1.10 Object bomb() {
53     return new Object() {
54     public boolean equals(Object x) { throw new AssertionError(); }
55     public int hashCode() { throw new AssertionError(); }
56     };
57     }
58    
59 jsr166 1.5 /** Checks properties of empty collections. */
60     public void testEmptyMeansEmpty() {
61     Collection c = impl.emptyCollection();
62     assertTrue(c.isEmpty());
63     assertEquals(0, c.size());
64     assertEquals("[]", c.toString());
65     {
66     Object[] a = c.toArray();
67     assertEquals(0, a.length);
68     assertSame(Object[].class, a.getClass());
69     }
70     {
71     Object[] a = new Object[0];
72     assertSame(a, c.toArray(a));
73     }
74     {
75     Integer[] a = new Integer[0];
76     assertSame(a, c.toArray(a));
77     }
78     {
79     Integer[] a = { 1, 2, 3};
80     assertSame(a, c.toArray(a));
81     assertNull(a[0]);
82     assertSame(2, a[1]);
83     assertSame(3, a[2]);
84     }
85     assertIteratorExhausted(c.iterator());
86     Consumer alwaysThrows = (e) -> { throw new AssertionError(); };
87     c.forEach(alwaysThrows);
88     c.iterator().forEachRemaining(alwaysThrows);
89     c.spliterator().forEachRemaining(alwaysThrows);
90     assertFalse(c.spliterator().tryAdvance(alwaysThrows));
91 jsr166 1.9 if (c.spliterator().hasCharacteristics(Spliterator.SIZED))
92     assertEquals(0, c.spliterator().estimateSize());
93 jsr166 1.10 assertFalse(c.contains(bomb()));
94     assertFalse(c.remove(bomb()));
95 jsr166 1.5 if (Queue.class.isAssignableFrom(impl.klazz())) {
96     Queue q = (Queue) c;
97     assertNull(q.peek());
98     assertNull(q.poll());
99     }
100     if (Deque.class.isAssignableFrom(impl.klazz())) {
101     Deque d = (Deque) c;
102     assertNull(d.peekFirst());
103     assertNull(d.peekLast());
104     assertNull(d.pollFirst());
105     assertNull(d.pollLast());
106     assertIteratorExhausted(d.descendingIterator());
107 jsr166 1.9 d.descendingIterator().forEachRemaining(alwaysThrows);
108 jsr166 1.10 assertFalse(d.removeFirstOccurrence(bomb()));
109     assertFalse(d.removeLastOccurrence(bomb()));
110 jsr166 1.5 }
111     }
112    
113     public void testNullPointerExceptions() {
114     Collection c = impl.emptyCollection();
115     assertThrows(
116     NullPointerException.class,
117     () -> c.addAll(null),
118     () -> c.containsAll(null),
119     () -> c.retainAll(null),
120     () -> c.removeAll(null),
121     () -> c.removeIf(null),
122 jsr166 1.6 () -> c.forEach(null),
123     () -> c.iterator().forEachRemaining(null),
124     () -> c.spliterator().forEachRemaining(null),
125     () -> c.spliterator().tryAdvance(null),
126 jsr166 1.5 () -> c.toArray(null));
127    
128     if (!impl.permitsNulls()) {
129     assertThrows(
130     NullPointerException.class,
131     () -> c.add(null));
132     }
133     if (!impl.permitsNulls()
134     && Queue.class.isAssignableFrom(impl.klazz())) {
135     Queue q = (Queue) c;
136     assertThrows(
137     NullPointerException.class,
138     () -> q.offer(null));
139     }
140     if (!impl.permitsNulls()
141     && Deque.class.isAssignableFrom(impl.klazz())) {
142     Deque d = (Deque) c;
143     assertThrows(
144     NullPointerException.class,
145     () -> d.addFirst(null),
146     () -> d.addLast(null),
147     () -> d.offerFirst(null),
148     () -> d.offerLast(null),
149 jsr166 1.6 () -> d.push(null),
150     () -> d.descendingIterator().forEachRemaining(null));
151 jsr166 1.5 }
152     }
153    
154     public void testNoSuchElementExceptions() {
155     Collection c = impl.emptyCollection();
156     assertThrows(
157     NoSuchElementException.class,
158     () -> c.iterator().next());
159    
160     if (Queue.class.isAssignableFrom(impl.klazz())) {
161     Queue q = (Queue) c;
162     assertThrows(
163     NoSuchElementException.class,
164     () -> q.element(),
165     () -> q.remove());
166     }
167     if (Deque.class.isAssignableFrom(impl.klazz())) {
168     Deque d = (Deque) c;
169     assertThrows(
170     NoSuchElementException.class,
171     () -> d.getFirst(),
172     () -> d.getLast(),
173     () -> d.removeFirst(),
174     () -> d.removeLast(),
175     () -> d.pop(),
176     () -> d.descendingIterator().next());
177     }
178     }
179    
180     public void testRemoveIf() {
181     Collection c = impl.emptyCollection();
182     ThreadLocalRandom rnd = ThreadLocalRandom.current();
183     int n = rnd.nextInt(6);
184     for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
185     AtomicReference threwAt = new AtomicReference(null);
186     ArrayList survivors = new ArrayList(c);
187     ArrayList accepts = new ArrayList();
188     ArrayList rejects = new ArrayList();
189     Predicate randomPredicate = (e) -> {
190     assertNull(threwAt.get());
191     switch (rnd.nextInt(3)) {
192     case 0: accepts.add(e); return true;
193     case 1: rejects.add(e); return false;
194     case 2: threwAt.set(e); throw new ArithmeticException();
195     default: throw new AssertionError();
196     }
197     };
198     try {
199 jsr166 1.8 assertFalse(survivors.contains(null));
200 jsr166 1.7 try {
201     boolean modified = c.removeIf(randomPredicate);
202     if (!modified) {
203     assertNull(threwAt.get());
204     assertEquals(n, rejects.size());
205     assertEquals(0, accepts.size());
206     }
207     } catch (ArithmeticException ok) {}
208     survivors.removeAll(accepts);
209     assertEquals(n - accepts.size(), c.size());
210     assertTrue(c.containsAll(survivors));
211     assertTrue(survivors.containsAll(rejects));
212     for (Object x : accepts) assertFalse(c.contains(x));
213     if (threwAt.get() == null)
214     assertEquals(accepts.size() + rejects.size(), n);
215     } catch (Throwable ex) {
216 jsr166 1.5 System.err.println(impl.klazz());
217 jsr166 1.7 System.err.printf("c=%s%n", c);
218     System.err.printf("n=%d%n", n);
219     System.err.printf("accepts=%s%n", accepts);
220     System.err.printf("rejects=%s%n", rejects);
221 jsr166 1.8 System.err.printf("survivors=%s%n", survivors);
222 jsr166 1.7 System.err.printf("threw=%s%n", threwAt.get());
223     throw ex;
224 jsr166 1.5 }
225     }
226    
227     /**
228     * Various ways of traversing a collection yield same elements
229     */
230     public void testIteratorEquivalence() {
231     Collection c = impl.emptyCollection();
232     ThreadLocalRandom rnd = ThreadLocalRandom.current();
233     int n = rnd.nextInt(6);
234     for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
235     ArrayList iterated = new ArrayList();
236     ArrayList iteratedForEachRemaining = new ArrayList();
237     ArrayList spliterated = new ArrayList();
238     ArrayList foreached = new ArrayList();
239     for (Object x : c) iterated.add(x);
240     c.iterator().forEachRemaining(e -> iteratedForEachRemaining.add(e));
241     c.spliterator().forEachRemaining(e -> spliterated.add(e));
242     c.forEach(e -> foreached.add(e));
243     boolean ordered =
244     c.spliterator().hasCharacteristics(Spliterator.ORDERED);
245     if (c instanceof List || c instanceof Deque)
246     assertTrue(ordered);
247     if (ordered) {
248     assertEquals(iterated, iteratedForEachRemaining);
249     assertEquals(iterated, spliterated);
250     assertEquals(iterated, foreached);
251     } else {
252     HashSet cset = new HashSet(c);
253     assertEquals(cset, new HashSet(iterated));
254     assertEquals(cset, new HashSet(iteratedForEachRemaining));
255     assertEquals(cset, new HashSet(spliterated));
256     assertEquals(cset, new HashSet(foreached));
257     }
258     if (c instanceof Deque) {
259     Deque d = (Deque) c;
260     ArrayList descending = new ArrayList();
261     ArrayList descendingForEachRemaining = new ArrayList();
262     for (Iterator it = d.descendingIterator(); it.hasNext(); )
263     descending.add(it.next());
264     d.descendingIterator().forEachRemaining(
265     e -> descendingForEachRemaining.add(e));
266     Collections.reverse(descending);
267     Collections.reverse(descendingForEachRemaining);
268     assertEquals(iterated, descending);
269     assertEquals(iterated, descendingForEachRemaining);
270     }
271     }
272    
273     /**
274     * Calling Iterator#remove() after Iterator#forEachRemaining
275     * should remove last element
276     */
277     public void testRemoveAfterForEachRemaining() {
278     Collection c = impl.emptyCollection();
279     ThreadLocalRandom rnd = ThreadLocalRandom.current();
280     {
281     int n = 3 + rnd.nextInt(2);
282     for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
283     Iterator it = c.iterator();
284     assertTrue(it.hasNext());
285     assertEquals(impl.makeElement(0), it.next());
286     assertTrue(it.hasNext());
287     assertEquals(impl.makeElement(1), it.next());
288     it.forEachRemaining((e) -> {});
289     it.remove();
290     assertEquals(n - 1, c.size());
291     for (int i = 0; i < n - 1; i++)
292     assertTrue(c.contains(impl.makeElement(i)));
293     assertFalse(c.contains(impl.makeElement(n - 1)));
294     }
295     if (c instanceof Deque) {
296     Deque d = (Deque) impl.emptyCollection();
297     int n = 3 + rnd.nextInt(2);
298     for (int i = 0; i < n; i++) d.add(impl.makeElement(i));
299     Iterator it = d.descendingIterator();
300     assertTrue(it.hasNext());
301     assertEquals(impl.makeElement(n - 1), it.next());
302     assertTrue(it.hasNext());
303     assertEquals(impl.makeElement(n - 2), it.next());
304     it.forEachRemaining((e) -> {});
305     it.remove();
306     assertEquals(n - 1, d.size());
307     for (int i = 1; i < n; i++)
308     assertTrue(d.contains(impl.makeElement(i)));
309     assertFalse(d.contains(impl.makeElement(0)));
310     }
311     }
312    
313 jsr166 1.1 /**
314     * stream().forEach returns elements in the collection
315     */
316 jsr166 1.3 public void testStreamForEach() throws Throwable {
317 jsr166 1.1 final Collection c = impl.emptyCollection();
318     final AtomicLong count = new AtomicLong(0L);
319     final Object x = impl.makeElement(1);
320     final Object y = impl.makeElement(2);
321     final ArrayList found = new ArrayList();
322     Consumer<Object> spy = (o) -> { found.add(o); };
323     c.stream().forEach(spy);
324     assertTrue(found.isEmpty());
325    
326     assertTrue(c.add(x));
327     c.stream().forEach(spy);
328     assertEquals(Collections.singletonList(x), found);
329     found.clear();
330    
331     assertTrue(c.add(y));
332     c.stream().forEach(spy);
333     assertEquals(2, found.size());
334     assertTrue(found.contains(x));
335     assertTrue(found.contains(y));
336     found.clear();
337    
338     c.clear();
339     c.stream().forEach(spy);
340     assertTrue(found.isEmpty());
341     }
342    
343 jsr166 1.3 public void testStreamForEachConcurrentStressTest() throws Throwable {
344     if (!impl.isConcurrent()) return;
345     final Collection c = impl.emptyCollection();
346     final long testDurationMillis = timeoutMillis();
347     final AtomicBoolean done = new AtomicBoolean(false);
348     final Object elt = impl.makeElement(1);
349     final Future<?> f1, f2;
350     final ExecutorService pool = Executors.newCachedThreadPool();
351     try (PoolCleaner cleaner = cleaner(pool, done)) {
352     final CountDownLatch threadsStarted = new CountDownLatch(2);
353     Runnable checkElt = () -> {
354     threadsStarted.countDown();
355     while (!done.get())
356     c.stream().forEach((x) -> { assertSame(x, elt); }); };
357     Runnable addRemove = () -> {
358     threadsStarted.countDown();
359     while (!done.get()) {
360     assertTrue(c.add(elt));
361     assertTrue(c.remove(elt));
362     }};
363     f1 = pool.submit(checkElt);
364     f2 = pool.submit(addRemove);
365     Thread.sleep(testDurationMillis);
366     }
367     assertNull(f1.get(0L, MILLISECONDS));
368     assertNull(f2.get(0L, MILLISECONDS));
369     }
370    
371     /**
372     * collection.forEach returns elements in the collection
373     */
374     public void testForEach() throws Throwable {
375     final Collection c = impl.emptyCollection();
376     final AtomicLong count = new AtomicLong(0L);
377     final Object x = impl.makeElement(1);
378     final Object y = impl.makeElement(2);
379     final ArrayList found = new ArrayList();
380     Consumer<Object> spy = (o) -> { found.add(o); };
381     c.forEach(spy);
382     assertTrue(found.isEmpty());
383    
384     assertTrue(c.add(x));
385     c.forEach(spy);
386     assertEquals(Collections.singletonList(x), found);
387     found.clear();
388    
389     assertTrue(c.add(y));
390     c.forEach(spy);
391     assertEquals(2, found.size());
392     assertTrue(found.contains(x));
393     assertTrue(found.contains(y));
394     found.clear();
395    
396     c.clear();
397     c.forEach(spy);
398     assertTrue(found.isEmpty());
399     }
400    
401 jsr166 1.1 public void testForEachConcurrentStressTest() throws Throwable {
402     if (!impl.isConcurrent()) return;
403     final Collection c = impl.emptyCollection();
404 jsr166 1.2 final long testDurationMillis = timeoutMillis();
405 jsr166 1.1 final AtomicBoolean done = new AtomicBoolean(false);
406     final Object elt = impl.makeElement(1);
407 jsr166 1.2 final Future<?> f1, f2;
408     final ExecutorService pool = Executors.newCachedThreadPool();
409     try (PoolCleaner cleaner = cleaner(pool, done)) {
410     final CountDownLatch threadsStarted = new CountDownLatch(2);
411     Runnable checkElt = () -> {
412     threadsStarted.countDown();
413     while (!done.get())
414 jsr166 1.3 c.forEach((x) -> { assertSame(x, elt); }); };
415 jsr166 1.2 Runnable addRemove = () -> {
416     threadsStarted.countDown();
417     while (!done.get()) {
418     assertTrue(c.add(elt));
419     assertTrue(c.remove(elt));
420     }};
421     f1 = pool.submit(checkElt);
422     f2 = pool.submit(addRemove);
423     Thread.sleep(testDurationMillis);
424     }
425     assertNull(f1.get(0L, MILLISECONDS));
426     assertNull(f2.get(0L, MILLISECONDS));
427 jsr166 1.1 }
428    
429 jsr166 1.4 // public void testCollection8DebugFail() {
430     // fail(impl.klazz().getSimpleName());
431     // }
432 jsr166 1.1 }