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 (5 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +1 -1 lines
Log Message:
fix @param mismatch

File Contents

# Content
1 /*
2 * Copyright (c) 2005, 2015, 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
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
55 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
124 public class MOAT {
125 // 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 public static void realMain(String[] args) {
141
142 testCollection(new NewAbstractCollection<Integer>());
143 testCollection(new NewAbstractSet<Integer>());
144 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 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
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 testCollection(new ConcurrentLinkedDeque<Integer>());
172 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
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 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 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
200 // 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 // Empty collections
215 final List<Integer> emptyArray = Arrays.asList(new Integer[]{});
216 testCollection(emptyArray);
217 testEmptyList(emptyArray);
218 THROWS(IndexOutOfBoundsException.class, () -> emptyArray.set(0,1));
219 THROWS(UnsupportedOperationException.class, () -> emptyArray.add(0,1));
220
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 testEmptySet(Collections.emptySet());
231 testEmptySet(Collections.emptySortedSet());
232 testEmptySet(Collections.emptyNavigableSet());
233 testImmutableSet(emptySet);
234
235 List<Integer> emptyList = emptyList();
236 testCollection(emptyList);
237 testEmptyList(emptyList);
238 testEmptyList(EMPTY_LIST);
239 testEmptyList(Collections.emptyList());
240 testImmutableList(emptyList);
241
242 Map<Integer,Integer> emptyMap = emptyMap();
243 testMap(emptyMap);
244 testEmptyMap(emptyMap);
245 testEmptyMap(EMPTY_MAP);
246 testEmptyMap(Collections.emptyMap());
247 testEmptyMap(Collections.emptySortedMap());
248 testEmptyMap(Collections.emptyNavigableMap());
249 testImmutableMap(emptyMap);
250 testImmutableMap(Collections.emptyMap());
251 testImmutableMap(Collections.emptySortedMap());
252 testImmutableMap(Collections.emptyNavigableMap());
253
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
274 // Immutable List
275 testEmptyList(List.of());
276 testListMutatorsAlwaysThrow(List.of());
277 testEmptyListMutatorsAlwaysThrow(List.of());
278 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 testListMutatorsAlwaysThrow(list);
294 }
295
296 // Immutable Set
297 testEmptySet(Set.of());
298 testCollMutatorsAlwaysThrow(Set.of());
299 testEmptyCollMutatorsAlwaysThrow(Set.of());
300 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 testCollMutatorsAlwaysThrow(set);
316 }
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 testMapMutatorsAlwaysThrow(Map.of());
328 testEmptyMapMutatorsAlwaysThrow(Map.of());
329 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 testMapMutatorsAlwaysThrow(map);
345 }
346 }
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 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 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 THROWS(NoSuchElementException.class, () -> it.next());
388
389 try { it.remove(); }
390 catch (IllegalStateException ignored) { pass(); }
391 catch (UnsupportedOperationException ignored) { pass(); }
392 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 () -> c.add(99),
415 () -> c.addAll(singleton(99)));
416 if (! c.isEmpty()) {
417 final Integer first = c.iterator().next();
418 THROWS(UnsupportedOperationException.class,
419 () -> c.clear(),
420 () -> c.remove(first),
421 () -> c.removeAll(singleton(first)),
422 () -> c.retainAll(emptyList()));
423 }
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 () -> c.set(0,42),
435 () -> c.add(0,42),
436 () -> c.addAll(0,singleton(86)));
437 if (! c.isEmpty())
438 THROWS(UnsupportedOperationException.class,
439 () -> { Iterator<Integer> it = c.iterator();
440 it.next();
441 it.remove(); },
442 () -> { ListIterator<Integer> it = c.listIterator();
443 it.next();
444 it.remove(); });
445 }
446
447 /**
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 * @param m the map instance to test, must be empty
524 */
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 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 catch (NullPointerException ignored) { /* OK */ }
550 try { check(! m.containsKey(null)); }
551 catch (NullPointerException ignored) { /* OK */ }
552 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 () -> m.put(1,1),
559 () -> m.putAll(singletonMap(1,1)));
560 if (! m.isEmpty()) {
561 final Integer first = m.keySet().iterator().next();
562 THROWS(UnsupportedOperationException.class,
563 () -> m.remove(first),
564 () -> m.clear());
565 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 () -> me.setValue(3));
571 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 try { check(c.add(ABSENT_VALUE)); }
597 catch (UnsupportedOperationException t) { return false; }
598 catch (Throwable t) { unexpected(t); }
599
600 try {
601 check(c.contains(ABSENT_VALUE));
602 check(c.remove(ABSENT_VALUE));
603 } catch (Throwable t) { unexpected(t); }
604 return true;
605 }
606
607 private static boolean supportsRemove(Collection<Integer> c) {
608 try { check(! c.remove(ABSENT_VALUE)); }
609 catch (UnsupportedOperationException t) { return false; }
610 catch (Throwable t) { unexpected(t); }
611 return true;
612 }
613
614 // 6260652: (coll) Arrays.asList(x).toArray().getClass()
615 // should be Object[].class
616 // Fixed in jdk9, but not jdk8 ...
617 static final boolean needToWorkAround6260652 =
618 Arrays.asList("").toArray().getClass() != Object[].class;
619
620 private static void checkFunctionalInvariants(Collection<Integer> c) {
621 try {
622 checkContainsSelf(c);
623 checkContainsEmpty(c);
624 check(c.size() != 0 ^ c.isEmpty());
625 check(! c.contains(ABSENT_VALUE));
626
627 {
628 int size = 0;
629 for (Integer i : c) size++;
630 check(c.size() == size);
631 }
632
633 if (c instanceof Set) {
634 checkUnique((Set<Integer>)c);
635 }
636
637 check(c.toArray().length == c.size());
638 check(c.toArray().getClass() == Object[].class
639 ||
640 (needToWorkAround6260652 &&
641 c.getClass().getName().equals("java.util.Arrays$ArrayList")));
642 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 for (int i = 0; i < 5; i++) {
725 testQueueAddRemove(q, null);
726 testQueueAddRemove(q, 537);
727 q.add(i);
728 }
729 equal(q.size(), 5);
730 checkFunctionalInvariants(q);
731 q.poll();
732 equal(q.size(), 4);
733 checkFunctionalInvariants(q);
734 if ((q instanceof LinkedBlockingQueue) ||
735 (q instanceof LinkedBlockingDeque) ||
736 (q instanceof ConcurrentLinkedDeque) ||
737 (q instanceof ConcurrentLinkedQueue)) {
738 testQueueIteratorRemove(q);
739 }
740 }
741
742 private static void testQueueAddRemove(final Queue<Integer> q,
743 final Integer e) {
744 final List<Integer> originalContents = new ArrayList<>(q);
745 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 () -> deq.getFirst(),
768 () -> deq.element(),
769 () -> deq.iterator().next());
770 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 () -> deq.getFirst(),
822 () -> deq.element(),
823 () -> deq.iterator().next());
824 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 THROWS(NoSuchElementException.class, () -> deq.getLast());
847 } 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 THROWS(NoSuchElementException.class, () -> deq.getLast());
890 } 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 () -> asList.listIterator().previous());
923 }
924 THROWS(NoSuchElementException.class,
925 () -> 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
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 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 catch (UnsupportedOperationException ignored) {/* OK */}
985 catch (IndexOutOfBoundsException ignored) {/* OK */}
986 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
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 Method m = AbstractList.class.getDeclaredMethod("removeRange", int.class, int.class);
1009 m.setAccessible(true);
1010 m.invoke(abList, 0, 0);
1011 m.invoke(abList, size, size);
1012 equal(size, l.size());
1013 }
1014 catch (UnsupportedOperationException ignored) {/* OK */}
1015 catch (Throwable t) { unexpected(t); }
1016 }
1017 }
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 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 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 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 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 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 check(clone instanceof Serializable);
1139 equal(m, clone);
1140 } catch (Error xxx) {
1141 if (! (xxx.getCause() instanceof NotSerializableException))
1142 throw xxx;
1143 }
1144 }
1145 }
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 try { check(m.put(ABSENT_VALUE,12735) == null); }
1195 catch (UnsupportedOperationException t) { return false; }
1196 catch (Throwable t) { unexpected(t); }
1197
1198 try {
1199 check(m.containsKey(ABSENT_VALUE));
1200 check(m.remove(ABSENT_VALUE) != null);
1201 } 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 List<Class<? extends Throwable>> threw = new ArrayList<>();
1273 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 List<Fun> fs = new ArrayList<>();
1289 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 throwsConsistently(NullPointerException.class, fs);
1295
1296 fs.clear();
1297 final Map<T,Integer> sm = singletonMap(null,1);
1298 fs.add(() -> { equal(m.put(null,1), null); m.clear();});
1299 fs.add(() -> { m.putAll(sm); m.clear();});
1300 if (cm != null) {
1301 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 }
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 THROWS(NoSuchElementException.class, () -> it.next());
1466 }
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 THROWS(NoSuchElementException.class, () -> it.next());
1476 }
1477
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 }
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 THROWS(NoSuchElementException.class, () -> it.next());
1546 }
1547
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 while (idx >= 0 && descItr.hasNext()) {
1588 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 }
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 interface Fun {void f() throws Throwable;}
1648 private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
1649 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 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 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 }