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