1 |
|
/* |
2 |
< |
* Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. |
2 |
> |
* Copyright (c) 2006, 2014, 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 |
25 |
|
* @test |
26 |
|
* @bug 6420753 6242436 6691185 |
27 |
|
* @summary Compare NavigableMap implementations for identical behavior |
28 |
+ |
* @run main LockStep |
29 |
+ |
* @run main/othervm -XX:+AggressiveOpts LockStep |
30 |
+ |
* @run main/othervm -XX:+AggressiveOpts -Dthorough=true LockStep |
31 |
|
* @author Martin Buchholz |
32 |
+ |
* @key randomness |
33 |
|
*/ |
34 |
|
|
35 |
|
import java.io.*; |
56 |
|
|
57 |
|
lockSteps(new TreeMap(), |
58 |
|
new ConcurrentSkipListMap()); |
59 |
+ |
lockSteps(new TreeMap(), |
60 |
+ |
Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)); |
61 |
+ |
lockSteps(new TreeMap(), |
62 |
+ |
Collections.synchronizedNavigableMap(new TreeMap())); |
63 |
|
lockSteps(new TreeMap(reverseOrder()), |
64 |
|
new ConcurrentSkipListMap(reverseOrder())); |
65 |
|
|
66 |
|
lockSteps(new TreeSet(), |
67 |
|
new ConcurrentSkipListSet()); |
68 |
+ |
lockSteps(new TreeSet(), |
69 |
+ |
Collections.checkedNavigableSet(new TreeSet(), Integer.class)); |
70 |
+ |
lockSteps(new TreeSet(), |
71 |
+ |
Collections.synchronizedNavigableSet(new TreeSet())); |
72 |
|
lockSteps(new TreeSet(reverseOrder()), |
73 |
|
new ConcurrentSkipListSet(reverseOrder())); |
74 |
|
} |
190 |
|
testEmptyCollection(m.values()); |
191 |
|
} |
192 |
|
|
193 |
< |
static final Random rnd = new Random(); |
193 |
> |
static final Random rnd; |
194 |
> |
|
195 |
> |
static { |
196 |
> |
// sufficiently random for this test |
197 |
> |
long seed = System.nanoTime(); |
198 |
> |
System.out.println(LockStep.class.getCanonicalName() + ": Trial random seed: " + seed ); |
199 |
> |
|
200 |
> |
rnd = new Random(seed); |
201 |
> |
} |
202 |
|
|
203 |
|
static void equalNext(final Iterator<?> it, Object expected) { |
204 |
|
if (maybe(2)) |
225 |
|
check(s.descendingSet().descendingSet().comparator() == null); |
226 |
|
equal(s.isEmpty(), s.size() == 0); |
227 |
|
equal2(s, s.descendingSet()); |
228 |
< |
if (maybe(4) && s instanceof Serializable) |
229 |
< |
equal2(s, serialClone(s)); |
228 |
> |
if (maybe(4) && s instanceof Serializable) { |
229 |
> |
try { |
230 |
> |
equal2(s, serialClone(s)); |
231 |
> |
} catch (RuntimeException uhoh) { |
232 |
> |
if (!(uhoh.getCause() instanceof NotSerializableException)) { |
233 |
> |
throw uhoh; |
234 |
> |
} |
235 |
> |
} |
236 |
> |
} |
237 |
|
Comparator cmp = comparator(s); |
238 |
|
if (s.isEmpty()) { |
239 |
|
THROWS(NoSuchElementException.class, |
240 |
< |
new Fun(){void f(){ s.first(); }}, |
241 |
< |
new Fun(){void f(){ s.last(); }}); |
240 |
> |
() -> s.first(), |
241 |
> |
() -> s.last()); |
242 |
|
equal(null, s.lower(1)); |
243 |
|
equal(null, s.floor(1)); |
244 |
|
equal(null, s.ceiling(1)); |
266 |
|
}; |
267 |
|
for (final Iterator it : its) |
268 |
|
if (maybe(4)) |
269 |
< |
THROWS(IllegalStateException.class, |
243 |
< |
new Fun(){void f(){ it.remove(); }}); |
269 |
> |
THROWS(IllegalStateException.class, () -> it.remove()); |
270 |
|
Object prev = null; |
271 |
|
for (Object e : s) { |
272 |
|
check(s.contains(e)); |
284 |
|
for (final Iterator it : its) { |
285 |
|
if (maybe(2)) |
286 |
|
check(! it.hasNext()); |
287 |
< |
Fun fun = new Fun(){void f(){ it.next(); }}; |
287 |
> |
Fun fun = () -> it.next(); |
288 |
|
THROWS(NoSuchElementException.class, fun, fun, fun); |
289 |
|
} |
290 |
|
} |
299 |
|
check(! it2.hasNext()); |
300 |
|
} |
301 |
|
|
302 |
+ |
static void equalSetsLeaf(final Set s1, final Set s2) { |
303 |
+ |
equal2(s1, s2); |
304 |
+ |
equal( s1.size(), s2.size()); |
305 |
+ |
equal( s1.isEmpty(), s2.isEmpty()); |
306 |
+ |
equal( s1.hashCode(), s2.hashCode()); |
307 |
+ |
equal( s1.toString(), s2.toString()); |
308 |
+ |
equal( s1.containsAll(s2), s2.containsAll(s1)); |
309 |
+ |
} |
310 |
+ |
|
311 |
|
static void equalNavigableSetsLeaf(final NavigableSet s1, |
312 |
|
final NavigableSet s2) { |
313 |
|
equal2(s1, s2); |
380 |
|
Comparator cmp = comparator(m); |
381 |
|
if (m.isEmpty()) { |
382 |
|
THROWS(NoSuchElementException.class, |
383 |
< |
new Fun(){void f(){ m.firstKey(); }}, |
384 |
< |
new Fun(){void f(){ m.lastKey(); }}); |
383 |
> |
() -> m.firstKey(), |
384 |
> |
() -> m.lastKey()); |
385 |
|
equal(null, m.firstEntry()); |
386 |
|
equal(null, m.lastEntry()); |
387 |
|
equal(null, m.pollFirstEntry()); |
430 |
|
Iterator[] its = concat(kits, vits, eits); |
431 |
|
for (final Iterator it : its) |
432 |
|
if (maybe(4)) |
433 |
< |
THROWS(IllegalStateException.class, |
399 |
< |
new Fun(){void f(){ it.remove(); }}); |
433 |
> |
THROWS(IllegalStateException.class, () -> it.remove()); |
434 |
|
Map.Entry prev = null; |
435 |
|
for (Map.Entry e : (Set<Map.Entry>) m.entrySet()) { |
436 |
|
Object k = e.getKey(); |
458 |
|
for (final Iterator it : its) { |
459 |
|
if (maybe(2)) |
460 |
|
check(! it.hasNext()); |
461 |
< |
Fun fun = new Fun(){void f(){ it.next(); }}; |
461 |
> |
Fun fun = () -> it.next(); |
462 |
|
THROWS(NoSuchElementException.class, fun, fun, fun); |
463 |
|
} |
464 |
|
} |
479 |
|
static void equalNavigableMaps(NavigableMap m1, |
480 |
|
NavigableMap m2) { |
481 |
|
equalNavigableMapsLeaf(m1, m2); |
482 |
< |
equalNavigableSetsLeaf((NavigableSet) m1.keySet(), |
449 |
< |
(NavigableSet) m2.keySet()); |
482 |
> |
equalSetsLeaf(m1.keySet(), m2.keySet()); |
483 |
|
equalNavigableSets(m1.navigableKeySet(), |
484 |
|
m2.navigableKeySet()); |
485 |
|
equalNavigableSets(m1.descendingKeySet(), |
632 |
|
} |
633 |
|
|
634 |
|
static Fun remover(final Iterator it) { |
635 |
< |
return new Fun(){void f(){ it.remove(); }}; |
635 |
> |
return () -> it.remove(); |
636 |
|
} |
637 |
|
|
638 |
|
static MapFrobber randomRemover(NavigableMap m) { |
662 |
|
it.remove(); |
663 |
|
if (maybe(2)) |
664 |
|
THROWS(IllegalStateException.class, |
665 |
< |
new Fun(){void f(){ it.remove(); }}); |
665 |
> |
() -> it.remove()); |
666 |
|
} |
667 |
|
checkUnusedKey(m, k);}}, |
668 |
|
new MapFrobber() {void frob(NavigableMap m) { |
672 |
|
it.remove(); |
673 |
|
if (maybe(2)) |
674 |
|
THROWS(IllegalStateException.class, |
675 |
< |
new Fun(){void f(){ it.remove(); }}); |
675 |
> |
() -> it.remove()); |
676 |
|
} |
677 |
|
checkUnusedKey(m, k);}}, |
678 |
|
new MapFrobber() {void frob(NavigableMap m) { |
717 |
|
it.remove(); |
718 |
|
if (maybe(2)) |
719 |
|
THROWS(IllegalStateException.class, |
720 |
< |
new Fun(){void f(){ it.remove(); }}); |
720 |
> |
() -> it.remove()); |
721 |
|
} |
722 |
|
checkUnusedElt(s, e);}}, |
723 |
|
new SetFrobber() {void frob(NavigableSet s) { |
727 |
|
it.remove(); |
728 |
|
if (maybe(2)) |
729 |
|
THROWS(IllegalStateException.class, |
730 |
< |
new Fun(){void f(){ it.remove(); }}); |
730 |
> |
() -> it.remove()); |
731 |
|
} |
732 |
|
checkUnusedElt(s, e);}}, |
733 |
|
new SetFrobber() {void frob(NavigableSet s) { |
737 |
|
it.remove(); |
738 |
|
if (maybe(2)) |
739 |
|
THROWS(IllegalStateException.class, |
740 |
< |
new Fun(){void f(){ it.remove(); }}); |
740 |
> |
() -> it.remove()); |
741 |
|
} |
742 |
|
checkUnusedElt(s, e);}} |
743 |
|
}; |
768 |
|
for (final NavigableMap m : maps) { |
769 |
|
final Object e = usedKey(m); |
770 |
|
THROWS(IllegalArgumentException.class, |
771 |
< |
new Fun(){void f(){m.subMap(e,true,e,false) |
772 |
< |
.subMap(e,true,e,true);}}, |
773 |
< |
new Fun(){void f(){m.subMap(e,false,e,true) |
774 |
< |
.subMap(e,true,e,true);}}, |
775 |
< |
new Fun(){void f(){m.tailMap(e,false).tailMap(e,true);}}, |
776 |
< |
new Fun(){void f(){m.headMap(e,false).headMap(e,true);}}); |
771 |
> |
() -> {m.subMap(e,true,e,false) |
772 |
> |
.subMap(e,true,e,true);}, |
773 |
> |
() -> {m.subMap(e,false,e,true) |
774 |
> |
.subMap(e,true,e,true);}, |
775 |
> |
() -> m.tailMap(e,false).tailMap(e,true), |
776 |
> |
() -> m.headMap(e,false).headMap(e,true)); |
777 |
|
} |
778 |
|
//System.out.printf("%s%n", m1); |
779 |
|
for (int i = size; i > 0; i--) { |
810 |
|
for (final NavigableSet s : sets) { |
811 |
|
final Object e = usedElt(s); |
812 |
|
THROWS(IllegalArgumentException.class, |
813 |
< |
new Fun(){void f(){s.subSet(e,true,e,false) |
814 |
< |
.subSet(e,true,e,true);}}, |
815 |
< |
new Fun(){void f(){s.subSet(e,false,e,true) |
816 |
< |
.subSet(e,true,e,true);}}, |
817 |
< |
new Fun(){void f(){s.tailSet(e,false).tailSet(e,true);}}, |
818 |
< |
new Fun(){void f(){s.headSet(e,false).headSet(e,true);}}); |
813 |
> |
() -> {s.subSet(e,true,e,false) |
814 |
> |
.subSet(e,true,e,true);}, |
815 |
> |
() -> {s.subSet(e,false,e,true) |
816 |
> |
.subSet(e,true,e,true);}, |
817 |
> |
() -> s.tailSet(e,false).tailSet(e,true), |
818 |
> |
() -> s.headSet(e,false).headSet(e,true)); |
819 |
|
} |
820 |
|
//System.out.printf("%s%n", s1); |
821 |
|
for (int i = size; i > 0; i--) { |
846 |
|
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
847 |
|
if (failed > 0) throw new Exception("Some tests failed"); |
848 |
|
} |
849 |
< |
abstract static class Fun {abstract void f() throws Throwable;} |
849 |
> |
interface Fun {void f() throws Throwable;} |
850 |
|
static void THROWS(Class<? extends Throwable> k, Fun... fs) { |
851 |
< |
for (Fun f : fs) |
852 |
< |
try { f.f(); fail("Expected " + k.getName() + " not thrown"); } |
853 |
< |
catch (Throwable t) { |
854 |
< |
if (k.isAssignableFrom(t.getClass())) pass(); |
855 |
< |
else unexpected(t);}} |
851 |
> |
for (Fun f : fs) |
852 |
> |
try { f.f(); fail("Expected " + k.getName() + " not thrown"); } |
853 |
> |
catch (Throwable t) { |
854 |
> |
if (k.isAssignableFrom(t.getClass())) pass(); |
855 |
> |
else unexpected(t);}} |
856 |
|
static byte[] serializedForm(Object obj) { |
857 |
|
try { |
858 |
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
866 |
|
@SuppressWarnings("unchecked") |
867 |
|
static <T> T serialClone(T obj) { |
868 |
|
try { return (T) readObject(serializedForm(obj)); } |
869 |
< |
catch (Exception e) { throw new RuntimeException(e); }} |
869 |
> |
catch (Error|RuntimeException e) { throw e; } |
870 |
> |
catch (Throwable e) { throw new RuntimeException(e); } |
871 |
> |
} |
872 |
|
} |