Initial load
diff --git a/test/java/util/Collection/BiggernYours.java b/test/java/util/Collection/BiggernYours.java
new file mode 100644
index 0000000..de3a417
--- /dev/null
+++ b/test/java/util/Collection/BiggernYours.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6415641 6377302
+ * @summary Concurrent collections are permitted to lie about their size
+ * @author Martin Buchholz
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+@SuppressWarnings("unchecked")
+public class BiggernYours {
+ static final Random rnd = new Random();
+
+ static void compareCollections(Collection c1, Collection c2) {
+ arrayEqual(c1.toArray(),
+ c2.toArray());
+ arrayEqual(c1.toArray(new Object[0]),
+ c2.toArray(new Object[0]));
+ arrayEqual(c1.toArray(new Object[5]),
+ c2.toArray(new Object[5]));
+ }
+
+ static void compareMaps(Map m1, Map m2) {
+ compareCollections(m1.keySet(),
+ m2.keySet());
+ compareCollections(m1.values(),
+ m2.values());
+ compareCollections(m1.entrySet(),
+ m2.entrySet());
+ }
+
+ static void compareNavigableMaps(NavigableMap m1, NavigableMap m2) {
+ compareMaps(m1, m2);
+ compareMaps(m1.descendingMap(),
+ m2.descendingMap());
+ compareMaps(m1.tailMap(Integer.MIN_VALUE),
+ m2.tailMap(Integer.MIN_VALUE));
+ compareMaps(m1.headMap(Integer.MAX_VALUE),
+ m2.headMap(Integer.MAX_VALUE));
+ }
+
+ static void compareNavigableSets(NavigableSet s1, NavigableSet s2) {
+ compareCollections(s1, s2);
+ compareCollections(s1.descendingSet(),
+ s2.descendingSet());
+ compareCollections(s1.tailSet(Integer.MIN_VALUE),
+ s2.tailSet(Integer.MIN_VALUE));
+ }
+
+ static abstract class MapFrobber { abstract void frob(Map m); }
+ static abstract class SetFrobber { abstract void frob(Set s); }
+ static abstract class ColFrobber { abstract void frob(Collection c); }
+
+ static ColFrobber adder(final int i) {
+ return new ColFrobber() {void frob(Collection c) { c.add(i); }};
+ }
+
+ static final ColFrobber[] adders =
+ { adder(1), adder(3), adder(2) };
+
+ static MapFrobber putter(final int k, final int v) {
+ return new MapFrobber() {void frob(Map m) { m.put(k,v); }};
+ }
+
+ static final MapFrobber[] putters =
+ { putter(1, -2), putter(3, -6), putter(2, -4) };
+
+ static void unexpected(Throwable t, Object suspect) {
+ System.out.println(suspect.getClass());
+ unexpected(t);
+ }
+
+ static void testCollections(Collection c1, Collection c2) {
+ try {
+ compareCollections(c1, c2);
+ for (ColFrobber adder : adders) {
+ for (Collection c : new Collection[]{c1, c2})
+ adder.frob(c);
+ compareCollections(c1, c2);
+ }
+ } catch (Throwable t) { unexpected(t, c1); }
+ }
+
+ static void testNavigableSets(NavigableSet s1, NavigableSet s2) {
+ try {
+ compareNavigableSets(s1, s2);
+ for (ColFrobber adder : adders) {
+ for (Set s : new Set[]{s1, s2})
+ adder.frob(s);
+ compareNavigableSets(s1, s2);
+ }
+ } catch (Throwable t) { unexpected(t, s1); }
+ }
+
+ static void testMaps(Map m1, Map m2) {
+ try {
+ compareMaps(m1, m2);
+ for (MapFrobber putter : putters) {
+ for (Map m : new Map[]{m1, m2})
+ putter.frob(m);
+ compareMaps(m1, m2);
+ }
+ } catch (Throwable t) { unexpected(t, m1); }
+ }
+
+ static void testNavigableMaps(NavigableMap m1, NavigableMap m2) {
+ try {
+ compareNavigableMaps(m1, m2);
+ for (MapFrobber putter : putters) {
+ for (Map m : new Map[]{m1, m2})
+ putter.frob(m);
+ compareNavigableMaps(m1, m2);
+ }
+ } catch (Throwable t) { unexpected(t, m1); }
+ }
+
+ static int randomize(int size) { return rnd.nextInt(size + 2); }
+
+ @SuppressWarnings("serial")
+ private static void realMain(String[] args) throws Throwable {
+ testNavigableMaps(
+ new ConcurrentSkipListMap(),
+ new ConcurrentSkipListMap() {
+ public int size() {return randomize(super.size());}});
+
+ testNavigableSets(
+ new ConcurrentSkipListSet(),
+ new ConcurrentSkipListSet() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new CopyOnWriteArraySet(),
+ new CopyOnWriteArraySet() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new CopyOnWriteArrayList(),
+ new CopyOnWriteArrayList() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new TreeSet(),
+ new TreeSet() {
+ public int size() {return randomize(super.size());}});
+
+ testMaps(
+ new ConcurrentHashMap(),
+ new ConcurrentHashMap() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new ConcurrentLinkedQueue(),
+ new ConcurrentLinkedQueue() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new LinkedBlockingQueue(),
+ new LinkedBlockingQueue() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new LinkedBlockingDeque(),
+ new LinkedBlockingDeque() {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new ArrayBlockingQueue(5),
+ new ArrayBlockingQueue(5) {
+ public int size() {return randomize(super.size());}});
+
+ testCollections(
+ new PriorityBlockingQueue(5),
+ new PriorityBlockingQueue(5) {
+ public int size() {return randomize(super.size());}});
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ static void arrayEqual(Object[] x, Object[] y) {
+ if (x == null ? y == null : Arrays.equals(x, y)) pass();
+ else fail(Arrays.toString(x) + " not equal to " + Arrays.toString(y));}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ private static abstract class Fun {abstract void f() throws Throwable;}
+ static void THROWS(Class<? extends Throwable> k, Fun... fs) {
+ for (Fun f : fs)
+ try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+ private static abstract class CheckedThread extends Thread {
+ abstract void realRun() throws Throwable;
+ public void run() {
+ try {realRun();} catch (Throwable t) {unexpected(t);}}}
+}