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