ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jtreg/util/Collection/MOAT.java
Revision: 1.23
Committed: Mon May 28 19:21:02 2018 UTC (6 years ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +1 -1 lines
Log Message:
fix @param mismatch

File Contents

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