38
39 @SuppressWarnings("unchecked")
40 public class LockStep {
41 static final int DEFAULT_SIZE = 5;
42 static int size; // Running time is O(size**2)
43
44 static int intArg(String[] args, int i, int defaultValue) {
45 return args.length > i ? Integer.parseInt(args[i]) : defaultValue;
46 }
47
48 // Pass -Dthorough=true for more exhaustive testing
49 static final boolean thorough = Boolean.getBoolean("thorough");
50
51 static boolean maybe(int n) { return rnd.nextInt(n) == 0; }
52
53 static void realMain(String[] args) {
54 size = intArg(args, 0, DEFAULT_SIZE);
55
56 lockSteps(new TreeMap(),
57 new ConcurrentSkipListMap());
58 lockSteps(new TreeMap(reverseOrder()),
59 new ConcurrentSkipListMap(reverseOrder()));
60
61 lockSteps(new TreeSet(),
62 new ConcurrentSkipListSet());
63 lockSteps(new TreeSet(reverseOrder()),
64 new ConcurrentSkipListSet(reverseOrder()));
65 }
66
67 static void lockSteps(NavigableMap m1, NavigableMap m2) {
68 if (maybe(4)) m1 = serialClone(m1);
69 if (maybe(4)) m2 = serialClone(m2);
70 lockStep(m1,
71 m2);
72 lockStep(m1.descendingMap(),
73 m2.descendingMap());
74 lockStep(fullSubMap(m1),
75 fullSubMap(m2));
76 lockStep(fullSubMap(m1.descendingMap()),
77 fullSubMap(m2.descendingMap()));
78 lockStep(fullHeadMap(m1),
79 fullHeadMap(m2));
80 lockStep(fullHeadMap(m1.descendingMap()),
81 fullHeadMap(m2.descendingMap()));
82 lockStep(fullTailMap(m1),
164 equal(a[0], null);
165 check(! c.iterator().hasNext());
166 }
167
168 static void testEmptySet(Set<?> c) {
169 testEmptyCollection(c);
170 equal(c.hashCode(), 0);
171 equal2(c, Collections.<Integer>emptySet());
172 }
173
174 static void testEmptyMap(final Map<?,?> m) {
175 check(m.isEmpty());
176 equal(m.size(), 0);
177 equal(m.toString(),"{}");
178 equal(m.hashCode(), 0);
179 testEmptySet(m.keySet());
180 testEmptySet(m.entrySet());
181 testEmptyCollection(m.values());
182 }
183
184 static final Random rnd = new Random();
185
186 static void equalNext(final Iterator<?> it, Object expected) {
187 if (maybe(2))
188 check(it.hasNext());
189 equal(it.next(), expected);
190 }
191
192 static Comparator comparator(NavigableSet s) {
193 Comparator cmp = s.comparator();
194 return cmp != null ? cmp : new Comparator() {
195 public int compare(Object o1, Object o2) {
196 return ((Comparable) o1).compareTo(o2); }};
197 }
198
199 static Comparator comparator(NavigableMap m) {
200 Comparator cmp = m.comparator();
201 return cmp != null ? cmp : new Comparator() {
202 public int compare(Object o1, Object o2) {
203 return ((Comparable) o1).compareTo(o2); }};
204 }
205
206 static void checkNavigableSet(final NavigableSet s) {
207 if (s.comparator() == null)
208 check(s.descendingSet().descendingSet().comparator() == null);
209 equal(s.isEmpty(), s.size() == 0);
210 equal2(s, s.descendingSet());
211 if (maybe(4) && s instanceof Serializable)
212 equal2(s, serialClone(s));
213 Comparator cmp = comparator(s);
214 if (s.isEmpty()) {
215 THROWS(NoSuchElementException.class,
216 new Fun(){void f(){ s.first(); }},
217 new Fun(){void f(){ s.last(); }});
218 equal(null, s.lower(1));
219 equal(null, s.floor(1));
220 equal(null, s.ceiling(1));
221 equal(null, s.higher(1));
222 } else {
223 Object a = s.first();
224 Object z = s.last();
225 equal(s.lower(a), null);
226 equal(s.higher(z), null);
227 equal2(s, s.tailSet(a));
228 equal2(s, s.headSet(z, true));
229 equal2(s, s.subSet(a, true, z, true));
230
231 testEmptySet(s.subSet(a, true, a, false));
232 testEmptySet(s.subSet(z, true, z, false));
259 prev = e;
260 }
261 for (final Iterator it : its) {
262 if (maybe(2))
263 check(! it.hasNext());
264 Fun fun = new Fun(){void f(){ it.next(); }};
265 THROWS(NoSuchElementException.class, fun, fun, fun);
266 }
267 }
268
269 static void equalIterators(final Iterator<?> it1,
270 final Iterator<?> it2) {
271 while (it1.hasNext()) {
272 if (maybe(2))
273 check(it2.hasNext());
274 equal(it1.next(), it2.next());
275 }
276 check(! it2.hasNext());
277 }
278
279 static void equalNavigableSetsLeaf(final NavigableSet s1,
280 final NavigableSet s2) {
281 equal2(s1, s2);
282 equal( s1.size(), s2.size());
283 equal( s1.isEmpty(), s2.isEmpty());
284 equal( s1.hashCode(), s2.hashCode());
285 equal( s1.toString(), s2.toString());
286 if (! s1.isEmpty()) {
287 equal(s1.first(), s2.first());
288 equal(s1.last(), s2.last());
289 }
290 equalIterators(s1.iterator(), s2.iterator());
291 equalIterators(s1.descendingIterator(), s2.descendingIterator());
292 checkNavigableSet(s1);
293 checkNavigableSet(s2);
294 }
295
296 static void equalNavigableSets(final NavigableSet s1,
297 final NavigableSet s2) {
298 equalNavigableSetsLeaf(s1, s2);
431 THROWS(NoSuchElementException.class, fun, fun, fun);
432 }
433 }
434
435 static void equalNavigableMapsLeaf(final NavigableMap m1,
436 final NavigableMap m2) {
437 equal2(m1, m2);
438 equal( m1.size(), m2.size());
439 equal( m1.isEmpty(), m2.isEmpty());
440 equal( m1.hashCode(), m2.hashCode());
441 equal( m1.toString(), m2.toString());
442 equal2(m1.firstEntry(), m2.firstEntry());
443 equal2(m1.lastEntry(), m2.lastEntry());
444 checkNavigableMap(m1);
445 checkNavigableMap(m2);
446 }
447
448 static void equalNavigableMaps(NavigableMap m1,
449 NavigableMap m2) {
450 equalNavigableMapsLeaf(m1, m2);
451 equalNavigableSetsLeaf((NavigableSet) m1.keySet(),
452 (NavigableSet) m2.keySet());
453 equalNavigableSets(m1.navigableKeySet(),
454 m2.navigableKeySet());
455 equalNavigableSets(m1.descendingKeySet(),
456 m2.descendingKeySet());
457 equal2(m1.entrySet(),
458 m2.entrySet());
459 equalNavigableMapsLeaf(m1.descendingMap(),
460 m2.descendingMap());
461 equalNavigableMapsLeaf(m1.descendingMap().descendingMap(),
462 m2);
463 equalNavigableSetsLeaf((NavigableSet) m1.descendingMap().keySet(),
464 (NavigableSet) m2.descendingMap().keySet());
465 equalNavigableSetsLeaf(m1.descendingMap().descendingKeySet(),
466 m2.descendingMap().descendingKeySet());
467 equal2(m1.descendingMap().entrySet(),
468 m2.descendingMap().entrySet());
469
470 //----------------------------------------------------------------
471 // submaps
472 //----------------------------------------------------------------
819 static abstract class Fun {abstract void f() throws Throwable;}
820 static void THROWS(Class<? extends Throwable> k, Fun... fs) {
821 for (Fun f : fs)
822 try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
823 catch (Throwable t) {
824 if (k.isAssignableFrom(t.getClass())) pass();
825 else unexpected(t);}}
826 static byte[] serializedForm(Object obj) {
827 try {
828 ByteArrayOutputStream baos = new ByteArrayOutputStream();
829 new ObjectOutputStream(baos).writeObject(obj);
830 return baos.toByteArray();
831 } catch (IOException e) { throw new RuntimeException(e); }}
832 static Object readObject(byte[] bytes)
833 throws IOException, ClassNotFoundException {
834 InputStream is = new ByteArrayInputStream(bytes);
835 return new ObjectInputStream(is).readObject();}
836 @SuppressWarnings("unchecked")
837 static <T> T serialClone(T obj) {
838 try { return (T) readObject(serializedForm(obj)); }
839 catch (Exception e) { throw new RuntimeException(e); }}
840 }
|
38
39 @SuppressWarnings("unchecked")
40 public class LockStep {
41 static final int DEFAULT_SIZE = 5;
42 static int size; // Running time is O(size**2)
43
44 static int intArg(String[] args, int i, int defaultValue) {
45 return args.length > i ? Integer.parseInt(args[i]) : defaultValue;
46 }
47
48 // Pass -Dthorough=true for more exhaustive testing
49 static final boolean thorough = Boolean.getBoolean("thorough");
50
51 static boolean maybe(int n) { return rnd.nextInt(n) == 0; }
52
53 static void realMain(String[] args) {
54 size = intArg(args, 0, DEFAULT_SIZE);
55
56 lockSteps(new TreeMap(),
57 new ConcurrentSkipListMap());
58 lockSteps(new TreeMap(),
59 Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class));
60 lockSteps(new TreeMap(),
61 Collections.synchronizedNavigableMap(new TreeMap()));
62 lockSteps(new TreeMap(reverseOrder()),
63 new ConcurrentSkipListMap(reverseOrder()));
64
65 lockSteps(new TreeSet(),
66 new ConcurrentSkipListSet());
67 lockSteps(new TreeSet(),
68 Collections.checkedNavigableSet(new TreeSet(), Integer.class));
69 lockSteps(new TreeSet(),
70 Collections.synchronizedNavigableSet(new TreeSet()));
71 lockSteps(new TreeSet(reverseOrder()),
72 new ConcurrentSkipListSet(reverseOrder()));
73 }
74
75 static void lockSteps(NavigableMap m1, NavigableMap m2) {
76 if (maybe(4)) m1 = serialClone(m1);
77 if (maybe(4)) m2 = serialClone(m2);
78 lockStep(m1,
79 m2);
80 lockStep(m1.descendingMap(),
81 m2.descendingMap());
82 lockStep(fullSubMap(m1),
83 fullSubMap(m2));
84 lockStep(fullSubMap(m1.descendingMap()),
85 fullSubMap(m2.descendingMap()));
86 lockStep(fullHeadMap(m1),
87 fullHeadMap(m2));
88 lockStep(fullHeadMap(m1.descendingMap()),
89 fullHeadMap(m2.descendingMap()));
90 lockStep(fullTailMap(m1),
172 equal(a[0], null);
173 check(! c.iterator().hasNext());
174 }
175
176 static void testEmptySet(Set<?> c) {
177 testEmptyCollection(c);
178 equal(c.hashCode(), 0);
179 equal2(c, Collections.<Integer>emptySet());
180 }
181
182 static void testEmptyMap(final Map<?,?> m) {
183 check(m.isEmpty());
184 equal(m.size(), 0);
185 equal(m.toString(),"{}");
186 equal(m.hashCode(), 0);
187 testEmptySet(m.keySet());
188 testEmptySet(m.entrySet());
189 testEmptyCollection(m.values());
190 }
191
192 static final Random rnd;
193
194 static {
195 // sufficiently random for this test
196 long seed = System.nanoTime();
197 System.out.println(LockStep.class.getCanonicalName() + ": Trial random seed: " + seed );
198
199 rnd = new Random(seed);
200 }
201
202 static void equalNext(final Iterator<?> it, Object expected) {
203 if (maybe(2))
204 check(it.hasNext());
205 equal(it.next(), expected);
206 }
207
208 static Comparator comparator(NavigableSet s) {
209 Comparator cmp = s.comparator();
210 return cmp != null ? cmp : new Comparator() {
211 public int compare(Object o1, Object o2) {
212 return ((Comparable) o1).compareTo(o2); }};
213 }
214
215 static Comparator comparator(NavigableMap m) {
216 Comparator cmp = m.comparator();
217 return cmp != null ? cmp : new Comparator() {
218 public int compare(Object o1, Object o2) {
219 return ((Comparable) o1).compareTo(o2); }};
220 }
221
222 static void checkNavigableSet(final NavigableSet s) {
223 if (s.comparator() == null)
224 check(s.descendingSet().descendingSet().comparator() == null);
225 equal(s.isEmpty(), s.size() == 0);
226 equal2(s, s.descendingSet());
227 if (maybe(4) && s instanceof Serializable) {
228 try {
229 equal2(s, serialClone(s));
230 } catch(RuntimeException uhoh) {
231 if(!(uhoh.getCause() instanceof NotSerializableException)) {
232 throw uhoh;
233 }
234 }
235 }
236 Comparator cmp = comparator(s);
237 if (s.isEmpty()) {
238 THROWS(NoSuchElementException.class,
239 new Fun(){void f(){ s.first(); }},
240 new Fun(){void f(){ s.last(); }});
241 equal(null, s.lower(1));
242 equal(null, s.floor(1));
243 equal(null, s.ceiling(1));
244 equal(null, s.higher(1));
245 } else {
246 Object a = s.first();
247 Object z = s.last();
248 equal(s.lower(a), null);
249 equal(s.higher(z), null);
250 equal2(s, s.tailSet(a));
251 equal2(s, s.headSet(z, true));
252 equal2(s, s.subSet(a, true, z, true));
253
254 testEmptySet(s.subSet(a, true, a, false));
255 testEmptySet(s.subSet(z, true, z, false));
282 prev = e;
283 }
284 for (final Iterator it : its) {
285 if (maybe(2))
286 check(! it.hasNext());
287 Fun fun = new Fun(){void f(){ it.next(); }};
288 THROWS(NoSuchElementException.class, fun, fun, fun);
289 }
290 }
291
292 static void equalIterators(final Iterator<?> it1,
293 final Iterator<?> it2) {
294 while (it1.hasNext()) {
295 if (maybe(2))
296 check(it2.hasNext());
297 equal(it1.next(), it2.next());
298 }
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);
314 equal( s1.size(), s2.size());
315 equal( s1.isEmpty(), s2.isEmpty());
316 equal( s1.hashCode(), s2.hashCode());
317 equal( s1.toString(), s2.toString());
318 if (! s1.isEmpty()) {
319 equal(s1.first(), s2.first());
320 equal(s1.last(), s2.last());
321 }
322 equalIterators(s1.iterator(), s2.iterator());
323 equalIterators(s1.descendingIterator(), s2.descendingIterator());
324 checkNavigableSet(s1);
325 checkNavigableSet(s2);
326 }
327
328 static void equalNavigableSets(final NavigableSet s1,
329 final NavigableSet s2) {
330 equalNavigableSetsLeaf(s1, s2);
463 THROWS(NoSuchElementException.class, fun, fun, fun);
464 }
465 }
466
467 static void equalNavigableMapsLeaf(final NavigableMap m1,
468 final NavigableMap m2) {
469 equal2(m1, m2);
470 equal( m1.size(), m2.size());
471 equal( m1.isEmpty(), m2.isEmpty());
472 equal( m1.hashCode(), m2.hashCode());
473 equal( m1.toString(), m2.toString());
474 equal2(m1.firstEntry(), m2.firstEntry());
475 equal2(m1.lastEntry(), m2.lastEntry());
476 checkNavigableMap(m1);
477 checkNavigableMap(m2);
478 }
479
480 static void equalNavigableMaps(NavigableMap m1,
481 NavigableMap m2) {
482 equalNavigableMapsLeaf(m1, m2);
483 equalSetsLeaf(m1.keySet(), m2.keySet());
484 equalNavigableSets(m1.navigableKeySet(),
485 m2.navigableKeySet());
486 equalNavigableSets(m1.descendingKeySet(),
487 m2.descendingKeySet());
488 equal2(m1.entrySet(),
489 m2.entrySet());
490 equalNavigableMapsLeaf(m1.descendingMap(),
491 m2.descendingMap());
492 equalNavigableMapsLeaf(m1.descendingMap().descendingMap(),
493 m2);
494 equalNavigableSetsLeaf((NavigableSet) m1.descendingMap().keySet(),
495 (NavigableSet) m2.descendingMap().keySet());
496 equalNavigableSetsLeaf(m1.descendingMap().descendingKeySet(),
497 m2.descendingMap().descendingKeySet());
498 equal2(m1.descendingMap().entrySet(),
499 m2.descendingMap().entrySet());
500
501 //----------------------------------------------------------------
502 // submaps
503 //----------------------------------------------------------------
850 static abstract class Fun {abstract void f() throws Throwable;}
851 static void THROWS(Class<? extends Throwable> k, Fun... fs) {
852 for (Fun f : fs)
853 try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
854 catch (Throwable t) {
855 if (k.isAssignableFrom(t.getClass())) pass();
856 else unexpected(t);}}
857 static byte[] serializedForm(Object obj) {
858 try {
859 ByteArrayOutputStream baos = new ByteArrayOutputStream();
860 new ObjectOutputStream(baos).writeObject(obj);
861 return baos.toByteArray();
862 } catch (IOException e) { throw new RuntimeException(e); }}
863 static Object readObject(byte[] bytes)
864 throws IOException, ClassNotFoundException {
865 InputStream is = new ByteArrayInputStream(bytes);
866 return new ObjectInputStream(is).readObject();}
867 @SuppressWarnings("unchecked")
868 static <T> T serialClone(T obj) {
869 try { return (T) readObject(serializedForm(obj)); }
870 catch (Throwable e) {
871 if (e instanceof Error) {
872 throw (Error) e;
873 } else if (e instanceof RuntimeException) {
874 throw (RuntimeException) e;
875 } else {
876 throw new RuntimeException(e);
877 }
878 }}
879 }
|