test/java/util/NavigableMap/LockStep.java

Print this page
rev 7461 : 7129185: Add Collections.{checked|empty|unmodifiable}Navigable{Map|Set}
Reviewed-by: dmocek, martin, smarks


  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 }