ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jtreg/util/Collection/MOAT.java
Revision: 1.11
Committed: Tue Sep 29 22:46:00 2015 UTC (8 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.10: +1 -0 lines
Log Message:
disable testing of WeakHashMap due to (rare) flakiness; add conditional code for bug 6260652

File Contents

# User Rev Content
1 jsr166 1.1 /*
2 jsr166 1.8 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
3 jsr166 1.1 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4     *
5     * This code is free software; you can redistribute it and/or modify it
6     * under the terms of the GNU General Public License version 2 only, as
7     * published by the Free Software Foundation.
8     *
9     * This code is distributed in the hope that it will be useful, but WITHOUT
10     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12     * version 2 for more details (a copy is included in the LICENSE file that
13     * accompanied this code).
14     *
15     * You should have received a copy of the GNU General Public License version
16     * 2 along with this work; if not, write to the Free Software Foundation,
17     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18     *
19 jsr166 1.3 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20     * or visit www.oracle.com if you need additional information or have any
21     * questions.
22 jsr166 1.1 */
23    
24     /*
25     * @test
26     * @bug 6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
27     * 4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
28     * 6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
29 jsr166 1.8 * 4802647 7123424 8024709
30 jsr166 1.1 * @summary Run many tests on many Collection and Map implementations
31     * @author Martin Buchholz
32 jsr166 1.8 * @run main MOAT
33     * @key randomness
34 jsr166 1.1 */
35    
36     /* Mother Of All (Collection) Tests
37     *
38     * Testing of collection classes is often spotty, because many tests
39     * need to be performed on many implementations, but the onus on
40     * writing the tests falls on the engineer introducing the new
41     * implementation.
42     *
43     * The idea of this mega-test is that:
44     *
45     * An engineer adding a new collection implementation could simply add
46     * their new implementation to a list of implementations in this
47     * test's main method. Any general purpose Collection<Integer> or
48     * Map<Integer,Integer> class is appropriate.
49     *
50     * An engineer fixing a regression could add their regression test here and
51     * simultaneously test all other implementations.
52     */
53    
54     import java.io.*;
55     import java.util.*;
56     import java.util.concurrent.*;
57     import static java.util.Collections.*;
58 jsr166 1.8 import java.lang.reflect.*;
59 jsr166 1.1
60     public class MOAT {
61     public static void realMain(String[] args) {
62    
63 jsr166 1.8 testCollection(new NewAbstractCollection<Integer>());
64     testCollection(new NewAbstractSet<Integer>());
65 jsr166 1.1 testCollection(new LinkedHashSet<Integer>());
66     testCollection(new HashSet<Integer>());
67     testCollection(new Vector<Integer>());
68     testCollection(new Vector<Integer>().subList(0,0));
69     testCollection(new ArrayDeque<Integer>());
70     testCollection(new ArrayList<Integer>());
71     testCollection(new ArrayList<Integer>().subList(0,0));
72     testCollection(new LinkedList<Integer>());
73     testCollection(new LinkedList<Integer>().subList(0,0));
74     testCollection(new TreeSet<Integer>());
75 jsr166 1.8 testCollection(Collections.checkedList(new ArrayList<Integer>(), Integer.class));
76     testCollection(Collections.synchronizedList(new ArrayList<Integer>()));
77     testCollection(Collections.checkedSet(new HashSet<Integer>(), Integer.class));
78     testCollection(Collections.checkedSortedSet(new TreeSet<Integer>(), Integer.class));
79     testCollection(Collections.checkedNavigableSet(new TreeSet<Integer>(), Integer.class));
80     testCollection(Collections.synchronizedSet(new HashSet<Integer>()));
81     testCollection(Collections.synchronizedSortedSet(new TreeSet<Integer>()));
82     testCollection(Collections.synchronizedNavigableSet(new TreeSet<Integer>()));
83 jsr166 1.1
84     testCollection(new CopyOnWriteArrayList<Integer>());
85     testCollection(new CopyOnWriteArrayList<Integer>().subList(0,0));
86     testCollection(new CopyOnWriteArraySet<Integer>());
87     testCollection(new PriorityQueue<Integer>());
88     testCollection(new PriorityBlockingQueue<Integer>());
89     testCollection(new ArrayBlockingQueue<Integer>(20));
90     testCollection(new LinkedBlockingQueue<Integer>(20));
91     testCollection(new LinkedBlockingDeque<Integer>(20));
92 jsr166 1.2 testCollection(new ConcurrentLinkedDeque<Integer>());
93 jsr166 1.1 testCollection(new ConcurrentLinkedQueue<Integer>());
94     testCollection(new LinkedTransferQueue<Integer>());
95     testCollection(new ConcurrentSkipListSet<Integer>());
96     testCollection(Arrays.asList(new Integer(42)));
97     testCollection(Arrays.asList(1,2,3));
98     testCollection(nCopies(25,1));
99     testImmutableList(nCopies(25,1));
100     testImmutableList(unmodifiableList(Arrays.asList(1,2,3)));
101    
102     testMap(new HashMap<Integer,Integer>());
103     testMap(new LinkedHashMap<Integer,Integer>());
104 jsr166 1.10
105     // TODO: Add reliable support for WeakHashMap.
106     // This test is subject to very rare failures because the GC
107     // may remove unreferenced-keys from the map at any time.
108     // testMap(new WeakHashMap<Integer,Integer>());
109    
110 jsr166 1.1 testMap(new IdentityHashMap<Integer,Integer>());
111     testMap(new TreeMap<Integer,Integer>());
112     testMap(new Hashtable<Integer,Integer>());
113     testMap(new ConcurrentHashMap<Integer,Integer>(10, 0.5f));
114     testMap(new ConcurrentSkipListMap<Integer,Integer>());
115 jsr166 1.8 testMap(Collections.checkedMap(new HashMap<Integer,Integer>(), Integer.class, Integer.class));
116     testMap(Collections.checkedSortedMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));
117     testMap(Collections.checkedNavigableMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));
118     testMap(Collections.synchronizedMap(new HashMap<Integer,Integer>()));
119     testMap(Collections.synchronizedSortedMap(new TreeMap<Integer,Integer>()));
120     testMap(Collections.synchronizedNavigableMap(new TreeMap<Integer,Integer>()));
121 jsr166 1.1
122     // Empty collections
123     final List<Integer> emptyArray = Arrays.asList(new Integer[]{});
124     testCollection(emptyArray);
125     testEmptyList(emptyArray);
126 jsr166 1.8 THROWS(IndexOutOfBoundsException.class, () -> emptyArray.set(0,1));
127     THROWS(UnsupportedOperationException.class, () -> emptyArray.add(0,1));
128 jsr166 1.1
129     List<Integer> noOne = nCopies(0,1);
130     testCollection(noOne);
131     testEmptyList(noOne);
132     testImmutableList(noOne);
133    
134     Set<Integer> emptySet = emptySet();
135     testCollection(emptySet);
136     testEmptySet(emptySet);
137     testEmptySet(EMPTY_SET);
138 jsr166 1.8 testEmptySet(Collections.emptySet());
139     testEmptySet(Collections.emptySortedSet());
140     testEmptySet(Collections.emptyNavigableSet());
141 jsr166 1.1 testImmutableSet(emptySet);
142    
143     List<Integer> emptyList = emptyList();
144     testCollection(emptyList);
145     testEmptyList(emptyList);
146     testEmptyList(EMPTY_LIST);
147 jsr166 1.8 testEmptyList(Collections.emptyList());
148 jsr166 1.1 testImmutableList(emptyList);
149    
150     Map<Integer,Integer> emptyMap = emptyMap();
151     testMap(emptyMap);
152     testEmptyMap(emptyMap);
153     testEmptyMap(EMPTY_MAP);
154 jsr166 1.8 testEmptyMap(Collections.emptyMap());
155     testEmptyMap(Collections.emptySortedMap());
156     testEmptyMap(Collections.emptyNavigableMap());
157 jsr166 1.1 testImmutableMap(emptyMap);
158 jsr166 1.8 testImmutableMap(Collections.emptyMap());
159     testImmutableMap(Collections.emptySortedMap());
160     testImmutableMap(Collections.emptyNavigableMap());
161 jsr166 1.1
162     // Singleton collections
163     Set<Integer> singletonSet = singleton(1);
164     equal(singletonSet.size(), 1);
165     testCollection(singletonSet);
166     testImmutableSet(singletonSet);
167    
168     List<Integer> singletonList = singletonList(1);
169     equal(singletonList.size(), 1);
170     testCollection(singletonList);
171     testImmutableList(singletonList);
172     testImmutableList(singletonList.subList(0,1));
173     testImmutableList(singletonList.subList(0,1).subList(0,1));
174     testEmptyList(singletonList.subList(0,0));
175     testEmptyList(singletonList.subList(0,0).subList(0,0));
176    
177     Map<Integer,Integer> singletonMap = singletonMap(1,2);
178     equal(singletonMap.size(), 1);
179     testMap(singletonMap);
180     testImmutableMap(singletonMap);
181     }
182    
183     private static void checkContainsSelf(Collection<Integer> c) {
184     check(c.containsAll(c));
185     check(c.containsAll(Arrays.asList(c.toArray())));
186     check(c.containsAll(Arrays.asList(c.toArray(new Integer[0]))));
187     }
188    
189     private static void checkContainsEmpty(Collection<Integer> c) {
190     check(c.containsAll(new ArrayList<Integer>()));
191     }
192    
193     private static <T> void testEmptyCollection(Collection<T> c) {
194     check(c.isEmpty());
195     equal(c.size(), 0);
196     equal(c.toString(),"[]");
197     equal(c.toArray().length, 0);
198     equal(c.toArray(new Object[0]).length, 0);
199     check(c.toArray(new Object[]{42})[0] == null);
200    
201     Object[] a = new Object[1]; a[0] = Boolean.TRUE;
202     equal(c.toArray(a), a);
203     equal(a[0], null);
204     testEmptyIterator(c.iterator());
205     }
206    
207     static <T> void testEmptyIterator(final Iterator<T> it) {
208     if (rnd.nextBoolean())
209     check(! it.hasNext());
210    
211 jsr166 1.8 THROWS(NoSuchElementException.class, () -> it.next());
212 jsr166 1.1
213     try { it.remove(); }
214 jsr166 1.6 catch (IllegalStateException ignored) { pass(); }
215     catch (UnsupportedOperationException ignored) { pass(); }
216 jsr166 1.1 catch (Throwable t) { unexpected(t); }
217    
218     if (rnd.nextBoolean())
219     check(! it.hasNext());
220     }
221    
222     private static void testEmptyList(List<?> c) {
223     testEmptyCollection(c);
224     equal(c.hashCode(), 1);
225     equal2(c, Collections.<Integer>emptyList());
226     }
227    
228     private static <T> void testEmptySet(Set<T> c) {
229     testEmptyCollection(c);
230     equal(c.hashCode(), 0);
231     equal2(c, Collections.<Integer>emptySet());
232     if (c instanceof NavigableSet<?>)
233     testEmptyIterator(((NavigableSet<T>)c).descendingIterator());
234     }
235    
236     private static void testImmutableCollection(final Collection<Integer> c) {
237     THROWS(UnsupportedOperationException.class,
238 jsr166 1.8 () -> c.add(99),
239     () -> c.addAll(singleton(99)));
240 jsr166 1.1 if (! c.isEmpty()) {
241     final Integer first = c.iterator().next();
242     THROWS(UnsupportedOperationException.class,
243 jsr166 1.8 () -> c.clear(),
244     () -> c.remove(first),
245     () -> c.removeAll(singleton(first)),
246     () -> c.retainAll(emptyList()));
247 jsr166 1.1 }
248     }
249    
250     private static void testImmutableSet(final Set<Integer> c) {
251     testImmutableCollection(c);
252     }
253    
254     private static void testImmutableList(final List<Integer> c) {
255     testList(c);
256     testImmutableCollection(c);
257     THROWS(UnsupportedOperationException.class,
258 jsr166 1.8 () -> c.set(0,42),
259     () -> c.add(0,42),
260     () -> c.addAll(0,singleton(86)));
261 jsr166 1.1 if (! c.isEmpty())
262     THROWS(UnsupportedOperationException.class,
263 jsr166 1.8 () -> { Iterator<Integer> it = c.iterator();
264     it.next();
265     it.remove(); },
266     () -> { ListIterator<Integer> it = c.listIterator();
267     it.next();
268     it.remove(); });
269 jsr166 1.1 }
270    
271     private static void clear(Collection<Integer> c) {
272     try { c.clear(); }
273     catch (Throwable t) { unexpected(t); }
274     testEmptyCollection(c);
275     }
276    
277     private static <K,V> void testEmptyMap(final Map<K,V> m) {
278     check(m.isEmpty());
279     equal(m.size(), 0);
280     equal(m.toString(),"{}");
281     testEmptySet(m.keySet());
282     testEmptySet(m.entrySet());
283     testEmptyCollection(m.values());
284    
285     try { check(! m.containsValue(null)); }
286 jsr166 1.6 catch (NullPointerException ignored) { /* OK */ }
287 jsr166 1.1 try { check(! m.containsKey(null)); }
288 jsr166 1.6 catch (NullPointerException ignored) { /* OK */ }
289 jsr166 1.1 check(! m.containsValue(1));
290     check(! m.containsKey(1));
291     }
292    
293     private static void testImmutableMap(final Map<Integer,Integer> m) {
294     THROWS(UnsupportedOperationException.class,
295 jsr166 1.8 () -> m.put(1,1),
296     () -> m.putAll(singletonMap(1,1)));
297 jsr166 1.1 if (! m.isEmpty()) {
298     final Integer first = m.keySet().iterator().next();
299     THROWS(UnsupportedOperationException.class,
300 jsr166 1.8 () -> m.remove(first),
301     () -> m.clear());
302 jsr166 1.1 final Map.Entry<Integer,Integer> me
303     = m.entrySet().iterator().next();
304     Integer key = me.getKey();
305     Integer val = me.getValue();
306     THROWS(UnsupportedOperationException.class,
307 jsr166 1.8 () -> me.setValue(3));
308 jsr166 1.1 equal(key, me.getKey());
309     equal(val, me.getValue());
310     }
311     testImmutableSet(m.keySet());
312     testImmutableCollection(m.values());
313     //testImmutableSet(m.entrySet());
314     }
315    
316     private static void clear(Map<?,?> m) {
317     try { m.clear(); }
318     catch (Throwable t) { unexpected(t); }
319     testEmptyMap(m);
320     }
321    
322     private static void oneElement(Collection<Integer> c) {
323     clear(c);
324     try {
325     check(c.add(-42));
326     equal(c.toString(), "[-42]");
327     if (c instanceof Set) check(! c.add(-42));
328     } catch (Throwable t) { unexpected(t); }
329     check(! c.isEmpty()); check(c.size() == 1);
330     }
331    
332     private static boolean supportsAdd(Collection<Integer> c) {
333     try { check(c.add(778347983)); }
334     catch (UnsupportedOperationException t) { return false; }
335     catch (Throwable t) { unexpected(t); }
336    
337     try {
338     check(c.contains(778347983));
339     check(c.remove(778347983));
340     } catch (Throwable t) { unexpected(t); }
341     return true;
342     }
343    
344     private static boolean supportsRemove(Collection<Integer> c) {
345     try { check(! c.remove(19134032)); }
346     catch (UnsupportedOperationException t) { return false; }
347     catch (Throwable t) { unexpected(t); }
348     return true;
349     }
350    
351 jsr166 1.10 // 6260652: (coll) Arrays.asList(x).toArray().getClass()
352 jsr166 1.11 // should be Object[].class
353 jsr166 1.10 // Fixed in jdk9, but not jdk8 ...
354     static final boolean needToWorkAround6260652 =
355     Arrays.asList("").toArray().getClass() != Object[].class;
356    
357 jsr166 1.1 private static void checkFunctionalInvariants(Collection<Integer> c) {
358     try {
359     checkContainsSelf(c);
360     checkContainsEmpty(c);
361     check(c.size() != 0 ^ c.isEmpty());
362    
363     {
364     int size = 0;
365     for (Integer i : c) size++;
366     check(c.size() == size);
367     }
368    
369     check(c.toArray().length == c.size());
370     check(c.toArray().getClass() == Object[].class
371     ||
372 jsr166 1.10 (needToWorkAround6260652 &&
373     c.getClass().getName().equals("java.util.Arrays$ArrayList")));
374 jsr166 1.1 for (int size : new int[]{0,1,c.size(), c.size()+1}) {
375     Integer[] a = c.toArray(new Integer[size]);
376     check((size > c.size()) || a.length == c.size());
377     int i = 0; for (Integer j : c) check(a[i++] == j);
378     check((size <= c.size()) || (a[c.size()] == null));
379     check(a.getClass() == Integer[].class);
380     }
381    
382     check(c.equals(c));
383     if (c instanceof Serializable) {
384     //System.out.printf("Serializing %s%n", c.getClass().getName());
385     try {
386     Object clone = serialClone(c);
387     equal(c instanceof Serializable,
388     clone instanceof Serializable);
389     equal(c instanceof RandomAccess,
390     clone instanceof RandomAccess);
391     if ((c instanceof List) || (c instanceof Set))
392     equal(c, clone);
393     else
394     equal(new HashSet<Integer>(c),
395     new HashSet<Integer>(serialClone(c)));
396     } catch (Error xxx) {
397     if (! (xxx.getCause() instanceof NotSerializableException))
398     throw xxx;
399     }
400     }
401     }
402     catch (Throwable t) { unexpected(t); }
403     }
404    
405     //----------------------------------------------------------------
406     // If add(null) succeeds, contains(null) & remove(null) should succeed
407     //----------------------------------------------------------------
408     private static void testNullElement(Collection<Integer> c) {
409    
410     try {
411     check(c.add(null));
412     if (c.size() == 1)
413     equal(c.toString(), "[null]");
414     try {
415     checkFunctionalInvariants(c);
416     check(c.contains(null));
417     check(c.remove(null));
418     }
419     catch (Throwable t) { unexpected(t); }
420     }
421     catch (NullPointerException e) { /* OK */ }
422     catch (Throwable t) { unexpected(t); }
423     }
424    
425    
426     //----------------------------------------------------------------
427     // If add("x") succeeds, contains("x") & remove("x") should succeed
428     //----------------------------------------------------------------
429     @SuppressWarnings("unchecked")
430     private static void testStringElement(Collection<Integer> c) {
431     Collection x = (Collection)c; // Make type-unsafe
432     try {
433     check(x.add("x"));
434     try {
435     check(x.contains("x"));
436     check(x.remove("x"));
437     } catch (Throwable t) { unexpected(t); }
438     }
439     catch (ClassCastException e) { /* OK */ }
440     catch (Throwable t) { unexpected(t); }
441     }
442    
443     private static void testConcurrentCollection(Collection<Integer> c) {
444     try {
445     c.add(1);
446     Iterator<Integer> it = c.iterator();
447     check(it.hasNext());
448     clear(c);
449     check(it.next() instanceof Integer); // No CME
450     check(c.isEmpty());
451     }
452     catch (Throwable t) { unexpected(t); }
453     }
454    
455     private static void testQueue(Queue<Integer> q) {
456     q.clear();
457 jsr166 1.4 for (int i = 0; i < 5; i++) {
458     testQueueAddRemove(q, null);
459     testQueueAddRemove(q, 537);
460 jsr166 1.1 q.add(i);
461 jsr166 1.4 }
462 jsr166 1.1 equal(q.size(), 5);
463     checkFunctionalInvariants(q);
464     q.poll();
465     equal(q.size(), 4);
466     checkFunctionalInvariants(q);
467 jsr166 1.2 if ((q instanceof LinkedBlockingQueue) ||
468     (q instanceof LinkedBlockingDeque) ||
469     (q instanceof ConcurrentLinkedDeque) ||
470 jsr166 1.1 (q instanceof ConcurrentLinkedQueue)) {
471     testQueueIteratorRemove(q);
472     }
473     }
474    
475 jsr166 1.4 private static void testQueueAddRemove(final Queue<Integer> q,
476     final Integer e) {
477     final List<Integer> originalContents = new ArrayList<Integer>(q);
478     final boolean isEmpty = q.isEmpty();
479     final boolean isList = (q instanceof List);
480     final List asList = isList ? (List) q : null;
481     check(!q.contains(e));
482     try {
483     q.add(e);
484     } catch (NullPointerException npe) {
485     check(e == null);
486     return; // Null elements not supported
487     }
488     check(q.contains(e));
489     check(q.remove(e));
490     check(!q.contains(e));
491     equal(new ArrayList<Integer>(q), originalContents);
492    
493     if (q instanceof Deque<?>) {
494     final Deque<Integer> deq = (Deque<Integer>) q;
495     final List<Integer> singleton = Collections.singletonList(e);
496    
497     // insert, query, remove element at head
498     if (isEmpty) {
499     THROWS(NoSuchElementException.class,
500 jsr166 1.8 () -> deq.getFirst(),
501     () -> deq.element(),
502     () -> deq.iterator().next());
503 jsr166 1.4 check(deq.peekFirst() == null);
504     check(deq.peek() == null);
505     } else {
506     check(deq.getFirst() != e);
507     check(deq.element() != e);
508     check(deq.iterator().next() != e);
509     check(deq.peekFirst() != e);
510     check(deq.peek() != e);
511     }
512     check(!deq.contains(e));
513     check(!deq.removeFirstOccurrence(e));
514     check(!deq.removeLastOccurrence(e));
515     if (isList) {
516     check(asList.indexOf(e) == -1);
517     check(asList.lastIndexOf(e) == -1);
518     }
519     switch (rnd.nextInt(isList ? 4 : 3)) {
520     case 0: deq.addFirst(e); break;
521     case 1: check(deq.offerFirst(e)); break;
522     case 2: deq.push(e); break;
523     case 3: asList.add(0, e); break;
524     default: throw new AssertionError();
525     }
526     check(deq.peekFirst() == e);
527     check(deq.getFirst() == e);
528     check(deq.element() == e);
529     check(deq.peek() == e);
530     check(deq.iterator().next() == e);
531     check(deq.contains(e));
532     if (isList) {
533     check(asList.get(0) == e);
534     check(asList.indexOf(e) == 0);
535     check(asList.lastIndexOf(e) == 0);
536     check(asList.subList(0, 1).equals(singleton));
537     }
538     switch (rnd.nextInt(isList ? 11 : 9)) {
539     case 0: check(deq.pollFirst() == e); break;
540     case 1: check(deq.removeFirst() == e); break;
541     case 2: check(deq.remove() == e); break;
542     case 3: check(deq.pop() == e); break;
543     case 4: check(deq.removeFirstOccurrence(e)); break;
544     case 5: check(deq.removeLastOccurrence(e)); break;
545     case 6: check(deq.remove(e)); break;
546     case 7: check(deq.removeAll(singleton)); break;
547     case 8: Iterator it = deq.iterator(); it.next(); it.remove(); break;
548     case 9: asList.remove(0); break;
549     case 10: asList.subList(0, 1).clear(); break;
550     default: throw new AssertionError();
551     }
552     if (isEmpty) {
553     THROWS(NoSuchElementException.class,
554 jsr166 1.8 () -> deq.getFirst(),
555     () -> deq.element(),
556     () -> deq.iterator().next());
557 jsr166 1.4 check(deq.peekFirst() == null);
558     check(deq.peek() == null);
559     } else {
560     check(deq.getFirst() != e);
561     check(deq.element() != e);
562     check(deq.iterator().next() != e);
563     check(deq.peekFirst() != e);
564     check(deq.peek() != e);
565     }
566     check(!deq.contains(e));
567     check(!deq.removeFirstOccurrence(e));
568     check(!deq.removeLastOccurrence(e));
569     if (isList) {
570     check(isEmpty || asList.get(0) != e);
571     check(asList.indexOf(e) == -1);
572     check(asList.lastIndexOf(e) == -1);
573     }
574     equal(new ArrayList<Integer>(deq), originalContents);
575    
576     // insert, query, remove element at tail
577     if (isEmpty) {
578     check(deq.peekLast() == null);
579 jsr166 1.8 THROWS(NoSuchElementException.class, () -> deq.getLast());
580 jsr166 1.4 } else {
581     check(deq.peekLast() != e);
582     check(deq.getLast() != e);
583     }
584     switch (rnd.nextInt(isList ? 6 : 4)) {
585     case 0: deq.addLast(e); break;
586     case 1: check(deq.offerLast(e)); break;
587     case 2: check(deq.add(e)); break;
588     case 3: deq.addAll(singleton); break;
589     case 4: asList.addAll(deq.size(), singleton); break;
590     case 5: asList.add(deq.size(), e); break;
591     default: throw new AssertionError();
592     }
593     check(deq.peekLast() == e);
594     check(deq.getLast() == e);
595     check(deq.contains(e));
596     if (isList) {
597     ListIterator it = asList.listIterator(asList.size());
598     check(it.previous() == e);
599     check(asList.get(asList.size() - 1) == e);
600     check(asList.indexOf(e) == asList.size() - 1);
601     check(asList.lastIndexOf(e) == asList.size() - 1);
602     int size = asList.size();
603     check(asList.subList(size - 1, size).equals(singleton));
604     }
605     switch (rnd.nextInt(isList ? 8 : 6)) {
606     case 0: check(deq.pollLast() == e); break;
607     case 1: check(deq.removeLast() == e); break;
608     case 2: check(deq.removeFirstOccurrence(e)); break;
609     case 3: check(deq.removeLastOccurrence(e)); break;
610     case 4: check(deq.remove(e)); break;
611     case 5: check(deq.removeAll(singleton)); break;
612     case 6: asList.remove(asList.size() - 1); break;
613     case 7:
614     ListIterator it = asList.listIterator(asList.size());
615     it.previous();
616     it.remove();
617     break;
618     default: throw new AssertionError();
619     }
620     if (isEmpty) {
621     check(deq.peekLast() == null);
622 jsr166 1.8 THROWS(NoSuchElementException.class, () -> deq.getLast());
623 jsr166 1.4 } else {
624     check(deq.peekLast() != e);
625     check(deq.getLast() != e);
626     }
627     check(!deq.contains(e));
628     equal(new ArrayList<Integer>(deq), originalContents);
629    
630     // Test operations on empty deque
631     switch (rnd.nextInt(isList ? 4 : 2)) {
632     case 0: deq.clear(); break;
633     case 1:
634     Iterator it = deq.iterator();
635     while (it.hasNext()) {
636     it.next();
637     it.remove();
638     }
639     break;
640     case 2: asList.subList(0, asList.size()).clear(); break;
641     case 3:
642     ListIterator lit = asList.listIterator(asList.size());
643     while (lit.hasPrevious()) {
644     lit.previous();
645     lit.remove();
646     }
647     break;
648     default: throw new AssertionError();
649     }
650     testEmptyCollection(deq);
651     check(!deq.iterator().hasNext());
652     if (isList) {
653     check(!asList.listIterator().hasPrevious());
654     THROWS(NoSuchElementException.class,
655 jsr166 1.8 () -> asList.listIterator().previous());
656 jsr166 1.4 }
657     THROWS(NoSuchElementException.class,
658 jsr166 1.8 () -> deq.iterator().next(),
659     () -> deq.element(),
660     () -> deq.getFirst(),
661     () -> deq.getLast(),
662     () -> deq.pop(),
663     () -> deq.remove(),
664     () -> deq.removeFirst(),
665     () -> deq.removeLast());
666 jsr166 1.4
667     check(deq.poll() == null);
668     check(deq.pollFirst() == null);
669     check(deq.pollLast() == null);
670     check(deq.peek() == null);
671     check(deq.peekFirst() == null);
672     check(deq.peekLast() == null);
673     check(!deq.removeFirstOccurrence(e));
674     check(!deq.removeLastOccurrence(e));
675    
676     check(deq.addAll(originalContents) == !isEmpty);
677     equal(new ArrayList<Integer>(deq), originalContents);
678     check(!deq.addAll(Collections.<Integer>emptyList()));
679     equal(new ArrayList<Integer>(deq), originalContents);
680     }
681     }
682    
683 jsr166 1.1 private static void testQueueIteratorRemove(Queue<Integer> q) {
684     System.err.printf("testQueueIteratorRemove %s%n",
685     q.getClass().getSimpleName());
686     q.clear();
687     for (int i = 0; i < 5; i++)
688     q.add(i);
689     Iterator<Integer> it = q.iterator();
690     check(it.hasNext());
691     for (int i = 3; i >= 0; i--)
692     q.remove(i);
693     equal(it.next(), 0);
694     equal(it.next(), 4);
695    
696     q.clear();
697     for (int i = 0; i < 5; i++)
698     q.add(i);
699     it = q.iterator();
700     equal(it.next(), 0);
701     check(it.hasNext());
702     for (int i = 1; i < 4; i++)
703     q.remove(i);
704     equal(it.next(), 1);
705     equal(it.next(), 4);
706     }
707    
708     private static void testList(final List<Integer> l) {
709     //----------------------------------------------------------------
710     // 4802633: (coll) AbstractList.addAll(-1,emptyCollection)
711     // doesn't throw IndexOutOfBoundsException
712     //----------------------------------------------------------------
713     try {
714     l.addAll(-1, Collections.<Integer>emptyList());
715     fail("Expected IndexOutOfBoundsException not thrown");
716     }
717 jsr166 1.6 catch (UnsupportedOperationException ignored) {/* OK */}
718     catch (IndexOutOfBoundsException ignored) {/* OK */}
719 jsr166 1.1 catch (Throwable t) { unexpected(t); }
720    
721     // equal(l instanceof Serializable,
722     // l.subList(0,0) instanceof Serializable);
723     if (l.subList(0,0) instanceof Serializable)
724     check(l instanceof Serializable);
725    
726     equal(l instanceof RandomAccess,
727     l.subList(0,0) instanceof RandomAccess);
728 jsr166 1.8
729     l.iterator();
730     l.listIterator();
731     l.listIterator(0);
732     l.listIterator(l.size());
733     THROWS(IndexOutOfBoundsException.class,
734     () -> l.listIterator(-1),
735     () -> l.listIterator(l.size() + 1));
736    
737     if (l instanceof AbstractList) {
738     try {
739     int size = l.size();
740     AbstractList<Integer> abList = (AbstractList<Integer>) l;
741     Method m = AbstractList.class.getDeclaredMethod("removeRange", new Class[] { int.class, int.class });
742     m.setAccessible(true);
743     m.invoke(abList, new Object[] { 0, 0 });
744     m.invoke(abList, new Object[] { size, size });
745     equal(size, l.size());
746     }
747     catch (UnsupportedOperationException ignored) {/* OK */}
748     catch (Throwable t) { unexpected(t); }
749     }
750 jsr166 1.1 }
751    
752     private static void testCollection(Collection<Integer> c) {
753     try { testCollection1(c); }
754     catch (Throwable t) { unexpected(t); }
755     }
756    
757     private static void testCollection1(Collection<Integer> c) {
758    
759     System.out.println("\n==> " + c.getClass().getName());
760    
761     checkFunctionalInvariants(c);
762    
763     if (! supportsAdd(c)) return;
764     //System.out.println("add() supported");
765    
766     if (c instanceof NavigableSet) {
767     System.out.println("NavigableSet tests...");
768    
769     NavigableSet<Integer> ns = (NavigableSet<Integer>)c;
770     testNavigableSet(ns);
771     testNavigableSet(ns.headSet(6, false));
772     testNavigableSet(ns.headSet(5, true));
773     testNavigableSet(ns.tailSet(0, false));
774     testNavigableSet(ns.tailSet(1, true));
775     testNavigableSet(ns.subSet(0, false, 5, true));
776     testNavigableSet(ns.subSet(1, true, 6, false));
777     }
778    
779     if (c instanceof Queue)
780     testQueue((Queue<Integer>)c);
781    
782     if (c instanceof List)
783     testList((List<Integer>)c);
784    
785     check(supportsRemove(c));
786    
787     try {
788     oneElement(c);
789     checkFunctionalInvariants(c);
790     }
791     catch (Throwable t) { unexpected(t); }
792    
793     clear(c); testNullElement(c);
794     oneElement(c); testNullElement(c);
795    
796     clear(c); testStringElement(c);
797     oneElement(c); testStringElement(c);
798    
799     if (c.getClass().getName().matches(".*concurrent.*"))
800     testConcurrentCollection(c);
801    
802     //----------------------------------------------------------------
803     // The "all" operations should throw NPE when passed null
804     //----------------------------------------------------------------
805     {
806 jsr166 1.8 clear(c);
807     try {
808     c.removeAll(null);
809     fail("Expected NullPointerException");
810     }
811     catch (NullPointerException e) { pass(); }
812     catch (Throwable t) { unexpected(t); }
813    
814 jsr166 1.1 oneElement(c);
815     try {
816     c.removeAll(null);
817     fail("Expected NullPointerException");
818     }
819     catch (NullPointerException e) { pass(); }
820     catch (Throwable t) { unexpected(t); }
821    
822 jsr166 1.8 clear(c);
823     try {
824     c.retainAll(null);
825     fail("Expected NullPointerException");
826     }
827     catch (NullPointerException e) { pass(); }
828     catch (Throwable t) { unexpected(t); }
829    
830 jsr166 1.1 oneElement(c);
831     try {
832     c.retainAll(null);
833     fail("Expected NullPointerException");
834     }
835     catch (NullPointerException e) { pass(); }
836     catch (Throwable t) { unexpected(t); }
837    
838     oneElement(c);
839     try {
840     c.addAll(null);
841     fail("Expected NullPointerException");
842     }
843     catch (NullPointerException e) { pass(); }
844     catch (Throwable t) { unexpected(t); }
845    
846     oneElement(c);
847     try {
848     c.containsAll(null);
849     fail("Expected NullPointerException");
850     }
851     catch (NullPointerException e) { pass(); }
852     catch (Throwable t) { unexpected(t); }
853     }
854     }
855    
856     //----------------------------------------------------------------
857     // Map
858     //----------------------------------------------------------------
859     private static void checkFunctionalInvariants(Map<Integer,Integer> m) {
860     check(m.keySet().size() == m.entrySet().size());
861     check(m.keySet().size() == m.size());
862     checkFunctionalInvariants(m.keySet());
863     checkFunctionalInvariants(m.values());
864     check(m.size() != 0 ^ m.isEmpty());
865     }
866    
867     private static void testMap(Map<Integer,Integer> m) {
868     System.out.println("\n==> " + m.getClass().getName());
869    
870     if (m instanceof ConcurrentMap)
871     testConcurrentMap((ConcurrentMap<Integer,Integer>) m);
872    
873     if (m instanceof NavigableMap) {
874     System.out.println("NavigableMap tests...");
875    
876     NavigableMap<Integer,Integer> nm =
877     (NavigableMap<Integer,Integer>) m;
878     testNavigableMapRemovers(nm);
879     testNavigableMap(nm);
880     testNavigableMap(nm.headMap(6, false));
881     testNavigableMap(nm.headMap(5, true));
882     testNavigableMap(nm.tailMap(0, false));
883     testNavigableMap(nm.tailMap(1, true));
884     testNavigableMap(nm.subMap(1, true, 6, false));
885     testNavigableMap(nm.subMap(0, false, 5, true));
886     }
887    
888     checkFunctionalInvariants(m);
889    
890     if (supportsClear(m)) {
891     try { clear(m); }
892     catch (Throwable t) { unexpected(t); }
893     }
894    
895     if (supportsPut(m)) {
896     try {
897     check(m.put(3333, 77777) == null);
898     check(m.put(9134, 74982) == null);
899     check(m.get(9134) == 74982);
900     check(m.put(9134, 1382) == 74982);
901     check(m.get(9134) == 1382);
902     check(m.size() == 2);
903     checkFunctionalInvariants(m);
904     checkNPEConsistency(m);
905     }
906     catch (Throwable t) { unexpected(t); }
907     }
908     }
909    
910     private static boolean supportsPut(Map<Integer,Integer> m) {
911     // We're asking for .equals(...) semantics
912     if (m instanceof IdentityHashMap) return false;
913    
914     try { check(m.put(778347983,12735) == null); }
915     catch (UnsupportedOperationException t) { return false; }
916     catch (Throwable t) { unexpected(t); }
917    
918     try {
919     check(m.containsKey(778347983));
920     check(m.remove(778347983) != null);
921     } catch (Throwable t) { unexpected(t); }
922     return true;
923     }
924    
925     private static boolean supportsClear(Map<?,?> m) {
926     try { m.clear(); }
927     catch (UnsupportedOperationException t) { return false; }
928     catch (Throwable t) { unexpected(t); }
929     return true;
930     }
931    
932     //----------------------------------------------------------------
933     // ConcurrentMap
934     //----------------------------------------------------------------
935     private static void testConcurrentMap(ConcurrentMap<Integer,Integer> m) {
936     System.out.println("ConcurrentMap tests...");
937    
938     try {
939     clear(m);
940    
941     check(m.putIfAbsent(18357,7346) == null);
942     check(m.containsKey(18357));
943     check(m.putIfAbsent(18357,8263) == 7346);
944     try { m.putIfAbsent(18357,null); fail("NPE"); }
945     catch (NullPointerException t) { }
946     check(m.containsKey(18357));
947    
948     check(! m.replace(18357,8888,7777));
949     check(m.containsKey(18357));
950     try { m.replace(18357,null,7777); fail("NPE"); }
951     catch (NullPointerException t) { }
952     check(m.containsKey(18357));
953     check(m.get(18357) == 7346);
954     check(m.replace(18357,7346,5555));
955     check(m.replace(18357,5555,7346));
956     check(m.get(18357) == 7346);
957    
958     check(m.replace(92347,7834) == null);
959     try { m.replace(18357,null); fail("NPE"); }
960     catch (NullPointerException t) { }
961     check(m.replace(18357,7346) == 7346);
962     check(m.replace(18357,5555) == 7346);
963     check(m.get(18357) == 5555);
964     check(m.replace(18357,7346) == 5555);
965     check(m.get(18357) == 7346);
966    
967     check(! m.remove(18357,9999));
968     check(m.get(18357) == 7346);
969     check(m.containsKey(18357));
970     check(! m.remove(18357,null)); // 6272521
971     check(m.get(18357) == 7346);
972     check(m.remove(18357,7346));
973     check(m.get(18357) == null);
974     check(! m.containsKey(18357));
975     check(m.isEmpty());
976    
977     m.putIfAbsent(1,2);
978     check(m.size() == 1);
979     check(! m.remove(1,null));
980     check(! m.remove(1,null));
981     check(! m.remove(1,1));
982     check(m.remove(1,2));
983     check(m.isEmpty());
984    
985     testEmptyMap(m);
986     }
987     catch (Throwable t) { unexpected(t); }
988     }
989    
990     private static void throwsConsistently(Class<? extends Throwable> k,
991     Iterable<Fun> fs) {
992     List<Class<? extends Throwable>> threw
993     = new ArrayList<Class<? extends Throwable>>();
994     for (Fun f : fs)
995     try { f.f(); threw.add(null); }
996     catch (Throwable t) {
997     check(k.isAssignableFrom(t.getClass()));
998     threw.add(t.getClass());
999     }
1000     if (new HashSet<Object>(threw).size() != 1)
1001     fail(threw.toString());
1002     }
1003    
1004     private static <T> void checkNPEConsistency(final Map<T,Integer> m) {
1005     m.clear();
1006     final ConcurrentMap<T,Integer> cm = (m instanceof ConcurrentMap)
1007     ? (ConcurrentMap<T,Integer>) m
1008     : null;
1009     List<Fun> fs = new ArrayList<Fun>();
1010 jsr166 1.8 fs.add(() -> check(! m.containsKey(null)));
1011     fs.add(() -> equal(m.remove(null), null));
1012     fs.add(() -> equal(m.get(null), null));
1013     if (cm != null)
1014     fs.add(() -> check(! cm.remove(null,null)));
1015 jsr166 1.1 throwsConsistently(NullPointerException.class, fs);
1016    
1017     fs.clear();
1018     final Map<T,Integer> sm = singletonMap(null,1);
1019 jsr166 1.8 fs.add(() -> { equal(m.put(null,1), null); m.clear();});
1020     fs.add(() -> { m.putAll(sm); m.clear();});
1021 jsr166 1.1 if (cm != null) {
1022 jsr166 1.8 fs.add(() -> check(! cm.remove(null,null)));
1023     fs.add(() -> equal(cm.putIfAbsent(null,1), 1));
1024     fs.add(() -> equal(cm.replace(null,1), null));
1025     fs.add(() -> equal(cm.replace(null,1, 1), 1));
1026 jsr166 1.1 }
1027     throwsConsistently(NullPointerException.class, fs);
1028     }
1029    
1030     //----------------------------------------------------------------
1031     // NavigableMap
1032     //----------------------------------------------------------------
1033     private static void
1034     checkNavigableMapKeys(NavigableMap<Integer,Integer> m,
1035     Integer i,
1036     Integer lower,
1037     Integer floor,
1038     Integer ceiling,
1039     Integer higher) {
1040     equal(m.lowerKey(i), lower);
1041     equal(m.floorKey(i), floor);
1042     equal(m.ceilingKey(i), ceiling);
1043     equal(m.higherKey(i), higher);
1044     }
1045    
1046     private static void
1047     checkNavigableSetKeys(NavigableSet<Integer> m,
1048     Integer i,
1049     Integer lower,
1050     Integer floor,
1051     Integer ceiling,
1052     Integer higher) {
1053     equal(m.lower(i), lower);
1054     equal(m.floor(i), floor);
1055     equal(m.ceiling(i), ceiling);
1056     equal(m.higher(i), higher);
1057     }
1058    
1059     static final Random rnd = new Random();
1060     static void equalNext(final Iterator<?> it, Object expected) {
1061     if (rnd.nextBoolean())
1062     check(it.hasNext());
1063     equal(it.next(), expected);
1064     }
1065    
1066     static void equalMaps(Map m1, Map m2) {
1067     equal(m1, m2);
1068     equal(m2, m1);
1069     equal(m1.size(), m2.size());
1070     equal(m1.isEmpty(), m2.isEmpty());
1071     equal(m1.toString(), m2.toString());
1072     check(Arrays.equals(m1.entrySet().toArray(), m2.entrySet().toArray()));
1073     }
1074    
1075     @SuppressWarnings({"unchecked", "rawtypes"})
1076     static void testNavigableMapRemovers(NavigableMap m)
1077     {
1078     final Map emptyMap = new HashMap();
1079    
1080     final Map singletonMap = new HashMap();
1081     singletonMap.put(1, 2);
1082    
1083     abstract class NavigableMapView {
1084     abstract NavigableMap view(NavigableMap m);
1085     }
1086    
1087     NavigableMapView[] views = {
1088     new NavigableMapView() { NavigableMap view(NavigableMap m) {
1089     return m; }},
1090     new NavigableMapView() { NavigableMap view(NavigableMap m) {
1091     return m.headMap(99, true); }},
1092     new NavigableMapView() { NavigableMap view(NavigableMap m) {
1093     return m.tailMap(-99, false); }},
1094     new NavigableMapView() { NavigableMap view(NavigableMap m) {
1095     return m.subMap(-99, true, 99, false); }},
1096     };
1097    
1098     abstract class Remover {
1099     abstract void remove(NavigableMap m, Object k, Object v);
1100     }
1101    
1102     Remover[] removers = {
1103     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1104     equal(m.remove(k), v); }},
1105    
1106     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1107     equal(m.descendingMap().remove(k), v); }},
1108     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1109     equal(m.descendingMap().headMap(-86, false).remove(k), v); }},
1110     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1111     equal(m.descendingMap().tailMap(86, true).remove(k), v); }},
1112    
1113     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1114     equal(m.headMap(86, true).remove(k), v); }},
1115     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1116     equal(m.tailMap(-86, true).remove(k), v); }},
1117     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1118     equal(m.subMap(-86, false, 86, true).remove(k), v); }},
1119    
1120     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1121     check(m.keySet().remove(k)); }},
1122     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1123     check(m.navigableKeySet().remove(k)); }},
1124    
1125     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1126     check(m.navigableKeySet().headSet(86, true).remove(k)); }},
1127     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1128     check(m.navigableKeySet().tailSet(-86, false).remove(k)); }},
1129     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1130     check(m.navigableKeySet().subSet(-86, true, 86, false)
1131     .remove(k)); }},
1132    
1133     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1134     check(m.descendingKeySet().headSet(-86, false).remove(k)); }},
1135     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1136     check(m.descendingKeySet().tailSet(86, true).remove(k)); }},
1137     new Remover() { void remove(NavigableMap m, Object k, Object v) {
1138     check(m.descendingKeySet().subSet(86, true, -86, false)
1139     .remove(k)); }},
1140     };
1141    
1142     for (NavigableMapView view : views) {
1143     for (Remover remover : removers) {
1144     try {
1145     m.clear();
1146     equalMaps(m, emptyMap);
1147     equal(m.put(1, 2), null);
1148     equalMaps(m, singletonMap);
1149     NavigableMap v = view.view(m);
1150     remover.remove(v, 1, 2);
1151     equalMaps(m, emptyMap);
1152     } catch (Throwable t) { unexpected(t); }
1153     }
1154     }
1155     }
1156    
1157     private static void testNavigableMap(NavigableMap<Integer,Integer> m)
1158     {
1159     clear(m);
1160     checkNavigableMapKeys(m, 1, null, null, null, null);
1161    
1162     equal(m.put(1, 2), null);
1163     equal(m.put(3, 4), null);
1164     equal(m.put(5, 9), null);
1165    
1166     equal(m.put(1, 2), 2);
1167     equal(m.put(3, 4), 4);
1168     equal(m.put(5, 6), 9);
1169    
1170     checkNavigableMapKeys(m, 0, null, null, 1, 1);
1171     checkNavigableMapKeys(m, 1, null, 1, 1, 3);
1172     checkNavigableMapKeys(m, 2, 1, 1, 3, 3);
1173     checkNavigableMapKeys(m, 3, 1, 3, 3, 5);
1174     checkNavigableMapKeys(m, 5, 3, 5, 5, null);
1175     checkNavigableMapKeys(m, 6, 5, 5, null, null);
1176    
1177     for (final Iterator<Integer> it :
1178     (Iterator<Integer>[])
1179     new Iterator<?>[] {
1180     m.descendingKeySet().iterator(),
1181     m.navigableKeySet().descendingIterator()}) {
1182     equalNext(it, 5);
1183     equalNext(it, 3);
1184     equalNext(it, 1);
1185     check(! it.hasNext());
1186 jsr166 1.8 THROWS(NoSuchElementException.class, () -> it.next());
1187 jsr166 1.1 }
1188    
1189     {
1190     final Iterator<Map.Entry<Integer,Integer>> it
1191     = m.descendingMap().entrySet().iterator();
1192     check(it.hasNext()); equal(it.next().getKey(), 5);
1193     check(it.hasNext()); equal(it.next().getKey(), 3);
1194     check(it.hasNext()); equal(it.next().getKey(), 1);
1195     check(! it.hasNext());
1196 jsr166 1.8 THROWS(NoSuchElementException.class, () -> it.next());
1197 jsr166 1.1 }
1198 jsr166 1.8
1199     prepMapForDescItrTests(m);
1200     checkDescItrRmFirst(m.keySet(), m.navigableKeySet().descendingIterator());
1201     prepMapForDescItrTests(m);
1202     checkDescItrRmMid(m.keySet(), m.navigableKeySet().descendingIterator());
1203     prepMapForDescItrTests(m);
1204     checkDescItrRmLast(m.keySet(), m.navigableKeySet().descendingIterator());
1205    
1206     prepMapForDescItrTests(m);
1207     checkDescItrRmFirst(m.keySet(), m.descendingMap().keySet().iterator());
1208     prepMapForDescItrTests(m);
1209     checkDescItrRmMid(m.keySet(), m.descendingMap().keySet().iterator());
1210     prepMapForDescItrTests(m);
1211     checkDescItrRmLast(m.keySet(), m.descendingMap().keySet().iterator());
1212    
1213     prepMapForDescItrTests(m);
1214     checkDescItrRmFirst(m.keySet(), m.descendingKeySet().iterator());
1215     prepMapForDescItrTests(m);
1216     checkDescItrRmMid(m.keySet(), m.descendingKeySet().iterator());
1217     prepMapForDescItrTests(m);
1218     checkDescItrRmLast(m.keySet(), m.descendingKeySet().iterator());
1219    
1220     prepMapForDescItrTests(m);
1221     checkDescItrRmFirst(m.values(), m.descendingMap().values().iterator());
1222     prepMapForDescItrTests(m);
1223     checkDescItrRmMid(m.values(), m.descendingMap().values().iterator());
1224     prepMapForDescItrTests(m);
1225     checkDescItrRmLast(m.values(), m.descendingMap().values().iterator());
1226    
1227     prepMapForDescItrTests(m);
1228     checkDescItrRmFirst((Collection)m.entrySet(),
1229     m.descendingMap().entrySet().iterator());
1230     prepMapForDescItrTests(m);
1231     checkDescItrRmMid((Collection)m.entrySet(),
1232     m.descendingMap().entrySet().iterator());
1233     prepMapForDescItrTests(m);
1234     checkDescItrRmLast((Collection)m.entrySet(),
1235     m.descendingMap().entrySet().iterator());
1236 jsr166 1.1 }
1237    
1238     private static void testNavigableSet(NavigableSet<Integer> s) {
1239     clear(s);
1240     checkNavigableSetKeys(s, 1, null, null, null, null);
1241    
1242     check(s.add(1));
1243     check(s.add(3));
1244     check(s.add(5));
1245    
1246     check(! s.add(1));
1247     check(! s.add(3));
1248     check(! s.add(5));
1249    
1250     checkNavigableSetKeys(s, 0, null, null, 1, 1);
1251     checkNavigableSetKeys(s, 1, null, 1, 1, 3);
1252     checkNavigableSetKeys(s, 2, 1, 1, 3, 3);
1253     checkNavigableSetKeys(s, 3, 1, 3, 3, 5);
1254     checkNavigableSetKeys(s, 5, 3, 5, 5, null);
1255     checkNavigableSetKeys(s, 6, 5, 5, null, null);
1256    
1257     for (final Iterator<Integer> it :
1258     (Iterator<Integer>[])
1259     new Iterator<?>[] {
1260     s.descendingIterator(),
1261     s.descendingSet().iterator()}) {
1262     equalNext(it, 5);
1263     equalNext(it, 3);
1264     equalNext(it, 1);
1265     check(! it.hasNext());
1266 jsr166 1.8 THROWS(NoSuchElementException.class, () -> it.next());
1267 jsr166 1.1 }
1268 jsr166 1.8
1269     prepSetForDescItrTests(s);
1270     checkDescItrRmFirst(s, s.descendingIterator());
1271     prepSetForDescItrTests(s);
1272     checkDescItrRmMid(s, s.descendingIterator());
1273     prepSetForDescItrTests(s);
1274     checkDescItrRmLast(s, s.descendingIterator());
1275    
1276     prepSetForDescItrTests(s);
1277     checkDescItrRmFirst(s, s.descendingSet().iterator());
1278     prepSetForDescItrTests(s);
1279     checkDescItrRmMid(s, s.descendingSet().iterator());
1280     prepSetForDescItrTests(s);
1281     checkDescItrRmLast(s, s.descendingSet().iterator());
1282     }
1283    
1284     private static void prepSetForDescItrTests(Set s) {
1285     clear(s);
1286     check(s.add(1));
1287     check(s.add(3));
1288     check(s.add(5));
1289     }
1290    
1291     private static void prepMapForDescItrTests(Map m) {
1292     clear(m);
1293     equal(m.put(1, 2), null);
1294     equal(m.put(3, 4), null);
1295     equal(m.put(5, 9), null);
1296     }
1297    
1298     //--------------------------------------------------------------------
1299     // Check behavior of descending iterator when first element is removed
1300     //--------------------------------------------------------------------
1301     private static <T> void checkDescItrRmFirst(Collection<T> ascColl,
1302     Iterator<T> descItr) {
1303     T[] expected = (T[]) ascColl.toArray();
1304     int idx = expected.length -1;
1305    
1306     equalNext(descItr, expected[idx--]);
1307     descItr.remove();
1308 jsr166 1.9 while (idx >= 0 && descItr.hasNext()) {
1309 jsr166 1.8 equalNext(descItr, expected[idx--]);
1310     }
1311     equal(descItr.hasNext(), false);
1312     equal(idx, -1);
1313     }
1314    
1315     //-----------------------------------------------------------------------
1316     // Check behavior of descending iterator when a middle element is removed
1317     //-----------------------------------------------------------------------
1318     private static <T> void checkDescItrRmMid(Collection<T> ascColl,
1319     Iterator<T> descItr) {
1320     T[] expected = (T[]) ascColl.toArray();
1321     int idx = expected.length -1;
1322    
1323     while (idx >= expected.length / 2) {
1324     equalNext(descItr, expected[idx--]);
1325     }
1326     descItr.remove();
1327     while (idx >= 0 && descItr.hasNext()) {
1328     equalNext(descItr, expected[idx--]);
1329     }
1330     equal(descItr.hasNext(), false);
1331     equal(idx, -1);
1332     }
1333    
1334     //-----------------------------------------------------------------------
1335     // Check behavior of descending iterator when the last element is removed
1336     //-----------------------------------------------------------------------
1337     private static <T> void checkDescItrRmLast(Collection<T> ascColl,
1338     Iterator<T> descItr) {
1339     T[] expected = (T[]) ascColl.toArray();
1340     int idx = expected.length -1;
1341    
1342     while (idx >= 0 && descItr.hasNext()) {
1343     equalNext(descItr, expected[idx--]);
1344     }
1345     equal(idx, -1);
1346     equal(descItr.hasNext(), false);
1347     descItr.remove();
1348     equal(ascColl.contains(expected[0]), false);
1349 jsr166 1.1 }
1350    
1351     //--------------------- Infrastructure ---------------------------
1352     static volatile int passed = 0, failed = 0;
1353     static void pass() { passed++; }
1354     static void fail() { failed++; Thread.dumpStack(); }
1355     static void fail(String msg) { System.out.println(msg); fail(); }
1356     static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
1357     static void check(boolean cond) { if (cond) pass(); else fail(); }
1358     static void equal(Object x, Object y) {
1359     if (x == null ? y == null : x.equals(y)) pass();
1360     else {System.out.println(x + " not equal to " + y); fail();}}
1361     static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
1362     public static void main(String[] args) throws Throwable {
1363     try { realMain(args); } catch (Throwable t) { unexpected(t); }
1364    
1365     System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
1366     if (failed > 0) throw new Exception("Some tests failed");
1367     }
1368 jsr166 1.8 interface Fun {void f() throws Throwable;}
1369 jsr166 1.1 private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
1370 jsr166 1.8 for (Fun f : fs)
1371     try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
1372     catch (Throwable t) {
1373     if (k.isAssignableFrom(t.getClass())) pass();
1374     else unexpected(t);}}
1375 jsr166 1.1 static byte[] serializedForm(Object obj) {
1376     try {
1377     ByteArrayOutputStream baos = new ByteArrayOutputStream();
1378     new ObjectOutputStream(baos).writeObject(obj);
1379     return baos.toByteArray();
1380     } catch (IOException e) { throw new Error(e); }}
1381     static Object readObject(byte[] bytes)
1382     throws IOException, ClassNotFoundException {
1383     InputStream is = new ByteArrayInputStream(bytes);
1384     return new ObjectInputStream(is).readObject();}
1385     @SuppressWarnings("unchecked")
1386     static <T> T serialClone(T obj) {
1387     try { return (T) readObject(serializedForm(obj)); }
1388     catch (Exception e) { throw new Error(e); }}
1389 jsr166 1.8 private static class NewAbstractCollection<E> extends AbstractCollection<E> {
1390     ArrayList<E> list = new ArrayList<>();
1391     public boolean remove(Object obj) {
1392     return list.remove(obj);
1393     }
1394     public boolean add(E e) {
1395     return list.add(e);
1396     }
1397     public Iterator<E> iterator() {
1398     return list.iterator();
1399     }
1400     public int size() {
1401     return list.size();
1402     }
1403     }
1404     private static class NewAbstractSet<E> extends AbstractSet<E> {
1405     HashSet<E> set = new HashSet<>();
1406     public boolean remove(Object obj) {
1407     return set.remove(obj);
1408     }
1409     public boolean add(E e) {
1410     return set.add(e);
1411     }
1412     public Iterator<E> iterator() {
1413     return set.iterator();
1414     }
1415     public int size() {
1416     return set.size();
1417     }
1418     }
1419    
1420 jsr166 1.1 }