ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMapTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ConcurrentHashMapTest.java (file contents):
Revision 1.12 by dl, Fri May 20 14:31:06 2005 UTC vs.
Revision 1.58 by jsr166, Mon Jan 8 03:37:59 2018 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
5 < * Other contributors include Andrew Wright, Jeffrey Hayes,
6 < * Pat Fisher, Mike Judd.
2 > * Written by Doug Lea and Martin Buchholz with assistance from
3 > * members of JCP JSR-166 Expert Group and released to the public
4 > * domain, as explained at
5 > * http://creativecommons.org/publicdomain/zero/1.0/
6 > * Other contributors include Andrew Wright, Jeffrey Hayes,
7 > * Pat Fisher, Mike Judd.
8   */
9  
10 < import junit.framework.*;
11 < import java.util.*;
12 < import java.util.concurrent.*;
10 > import java.util.ArrayList;
11 > import java.util.Arrays;
12 > import java.util.Collection;
13 > import java.util.Collections;
14   import java.util.Enumeration;
15 < import java.io.*;
15 > import java.util.Iterator;
16 > import java.util.Map;
17 > import java.util.Random;
18 > import java.util.Set;
19 > import java.util.concurrent.ConcurrentHashMap;
20  
21 < public class ConcurrentHashMapTest extends JSR166TestCase{
21 > import junit.framework.Test;
22 >
23 > public class ConcurrentHashMapTest extends JSR166TestCase {
24      public static void main(String[] args) {
25 <        junit.textui.TestRunner.run (suite());  
25 >        main(suite(), args);
26      }
27      public static Test suite() {
28 <        return new TestSuite(ConcurrentHashMapTest.class);
28 >        class Implementation implements MapImplementation {
29 >            public Class<?> klazz() { return ConcurrentHashMap.class; }
30 >            public Map emptyMap() { return new ConcurrentHashMap(); }
31 >            public Object makeKey(int i) { return i; }
32 >            public Object makeValue(int i) { return i; }
33 >            public boolean isConcurrent() { return true; }
34 >            public boolean permitsNullKeys() { return false; }
35 >            public boolean permitsNullValues() { return false; }
36 >            public boolean supportsSetValue() { return true; }
37 >        }
38 >        return newTestSuite(
39 >            ConcurrentHashMapTest.class,
40 >            MapTest.testSuite(new Implementation()));
41      }
42  
43      /**
44 <     * Create a map from Integers 1-5 to Strings "A"-"E".
44 >     * Returns a new map from Integers 1-5 to Strings "A"-"E".
45       */
46 <    private static ConcurrentHashMap map5() {  
47 <        ConcurrentHashMap map = new ConcurrentHashMap(5);
46 >    private static ConcurrentHashMap<Integer, String> map5() {
47 >        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
48          assertTrue(map.isEmpty());
49 <        map.put(one, "A");
50 <        map.put(two, "B");
51 <        map.put(three, "C");
52 <        map.put(four, "D");
53 <        map.put(five, "E");
49 >        map.put(one, "A");
50 >        map.put(two, "B");
51 >        map.put(three, "C");
52 >        map.put(four, "D");
53 >        map.put(five, "E");
54          assertFalse(map.isEmpty());
55          assertEquals(5, map.size());
56 <        return map;
56 >        return map;
57 >    }
58 >
59 >    // classes for testing Comparable fallbacks
60 >    static class BI implements Comparable<BI> {
61 >        private final int value;
62 >        BI(int value) { this.value = value; }
63 >        public int compareTo(BI other) {
64 >            return Integer.compare(value, other.value);
65 >        }
66 >        public boolean equals(Object x) {
67 >            return (x instanceof BI) && ((BI)x).value == value;
68 >        }
69 >        public int hashCode() { return 42; }
70 >    }
71 >    static class CI extends BI { CI(int value) { super(value); } }
72 >    static class DI extends BI { DI(int value) { super(value); } }
73 >
74 >    static class BS implements Comparable<BS> {
75 >        private final String value;
76 >        BS(String value) { this.value = value; }
77 >        public int compareTo(BS other) {
78 >            return value.compareTo(other.value);
79 >        }
80 >        public boolean equals(Object x) {
81 >            return (x instanceof BS) && value.equals(((BS)x).value);
82 >        }
83 >        public int hashCode() { return 42; }
84 >    }
85 >
86 >    static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
87 >        implements Comparable<LexicographicList<E>> {
88 >        LexicographicList(Collection<E> c) { super(c); }
89 >        LexicographicList(E e) { super(Collections.singleton(e)); }
90 >        public int compareTo(LexicographicList<E> other) {
91 >            int common = Math.min(size(), other.size());
92 >            int r = 0;
93 >            for (int i = 0; i < common; i++) {
94 >                if ((r = get(i).compareTo(other.get(i))) != 0)
95 >                    break;
96 >            }
97 >            if (r == 0)
98 >                r = Integer.compare(size(), other.size());
99 >            return r;
100 >        }
101 >        private static final long serialVersionUID = 0;
102 >    }
103 >
104 >    static class CollidingObject {
105 >        final String value;
106 >        CollidingObject(final String value) { this.value = value; }
107 >        public int hashCode() { return this.value.hashCode() & 1; }
108 >        public boolean equals(final Object obj) {
109 >            return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value);
110 >        }
111 >    }
112 >
113 >    static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> {
114 >        ComparableCollidingObject(final String value) { super(value); }
115 >        public int compareTo(final ComparableCollidingObject o) {
116 >            return value.compareTo(o.value);
117 >        }
118      }
119  
120      /**
121 <     *  clear removes all pairs
121 >     * Inserted elements that are subclasses of the same Comparable
122 >     * class are found.
123 >     */
124 >    public void testComparableFamily() {
125 >        int size = 500;         // makes measured test run time -> 60ms
126 >        ConcurrentHashMap<BI, Boolean> m = new ConcurrentHashMap<>();
127 >        for (int i = 0; i < size; i++) {
128 >            assertNull(m.put(new CI(i), true));
129 >        }
130 >        for (int i = 0; i < size; i++) {
131 >            assertTrue(m.containsKey(new CI(i)));
132 >            assertTrue(m.containsKey(new DI(i)));
133 >        }
134 >    }
135 >
136 >    /**
137 >     * Elements of classes with erased generic type parameters based
138 >     * on Comparable can be inserted and found.
139 >     */
140 >    public void testGenericComparable() {
141 >        int size = 120;         // makes measured test run time -> 60ms
142 >        ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
143 >        for (int i = 0; i < size; i++) {
144 >            BI bi = new BI(i);
145 >            BS bs = new BS(String.valueOf(i));
146 >            LexicographicList<BI> bis = new LexicographicList<>(bi);
147 >            LexicographicList<BS> bss = new LexicographicList<>(bs);
148 >            assertNull(m.putIfAbsent(bis, true));
149 >            assertTrue(m.containsKey(bis));
150 >            if (m.putIfAbsent(bss, true) == null)
151 >                assertTrue(m.containsKey(bss));
152 >            assertTrue(m.containsKey(bis));
153 >        }
154 >        for (int i = 0; i < size; i++) {
155 >            assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
156 >        }
157 >    }
158 >
159 >    /**
160 >     * Elements of non-comparable classes equal to those of classes
161 >     * with erased generic type parameters based on Comparable can be
162 >     * inserted and found.
163 >     */
164 >    public void testGenericComparable2() {
165 >        int size = 500;         // makes measured test run time -> 60ms
166 >        ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
167 >        for (int i = 0; i < size; i++) {
168 >            m.put(Collections.singletonList(new BI(i)), true);
169 >        }
170 >
171 >        for (int i = 0; i < size; i++) {
172 >            LexicographicList<BI> bis = new LexicographicList<>(new BI(i));
173 >            assertTrue(m.containsKey(bis));
174 >        }
175 >    }
176 >
177 >    /**
178 >     * Mixtures of instances of comparable and non-comparable classes
179 >     * can be inserted and found.
180 >     */
181 >    public void testMixedComparable() {
182 >        int size = 1200;        // makes measured test run time -> 35ms
183 >        ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
184 >        Random rng = new Random();
185 >        for (int i = 0; i < size; i++) {
186 >            Object x;
187 >            switch (rng.nextInt(4)) {
188 >            case 0:
189 >                x = new Object();
190 >                break;
191 >            case 1:
192 >                x = new CollidingObject(Integer.toString(i));
193 >                break;
194 >            default:
195 >                x = new ComparableCollidingObject(Integer.toString(i));
196 >            }
197 >            assertNull(map.put(x, x));
198 >        }
199 >        int count = 0;
200 >        for (Object k : map.keySet()) {
201 >            assertEquals(map.get(k), k);
202 >            ++count;
203 >        }
204 >        assertEquals(count, size);
205 >        assertEquals(map.size(), size);
206 >        for (Object k : map.keySet()) {
207 >            assertEquals(map.put(k, k), k);
208 >        }
209 >    }
210 >
211 >    /**
212 >     * clear removes all pairs
213       */
214      public void testClear() {
215          ConcurrentHashMap map = map5();
216 <        map.clear();
217 <        assertEquals(map.size(), 0);
216 >        map.clear();
217 >        assertEquals(0, map.size());
218      }
219  
220      /**
221 <     *  Maps with same contents are equal
221 >     * Maps with same contents are equal
222       */
223      public void testEquals() {
224          ConcurrentHashMap map1 = map5();
225          ConcurrentHashMap map2 = map5();
226          assertEquals(map1, map2);
227          assertEquals(map2, map1);
228 <        map1.clear();
228 >        map1.clear();
229          assertFalse(map1.equals(map2));
230          assertFalse(map2.equals(map1));
231      }
232  
233      /**
234 <     *  contains returns true for contained value
234 >     * hashCode() equals sum of each key.hashCode ^ value.hashCode
235 >     */
236 >    public void testHashCode() {
237 >        ConcurrentHashMap<Integer,String> map = map5();
238 >        int sum = 0;
239 >        for (Map.Entry<Integer,String> e : map.entrySet())
240 >            sum += e.getKey().hashCode() ^ e.getValue().hashCode();
241 >        assertEquals(sum, map.hashCode());
242 >    }
243 >
244 >    /**
245 >     * contains returns true for contained value
246       */
247      public void testContains() {
248          ConcurrentHashMap map = map5();
249 <        assertTrue(map.contains("A"));
249 >        assertTrue(map.contains("A"));
250          assertFalse(map.contains("Z"));
251      }
252 <    
252 >
253      /**
254 <     *  containsKey returns true for contained key
254 >     * containsKey returns true for contained key
255       */
256      public void testContainsKey() {
257          ConcurrentHashMap map = map5();
258 <        assertTrue(map.containsKey(one));
258 >        assertTrue(map.containsKey(one));
259          assertFalse(map.containsKey(zero));
260      }
261  
262      /**
263 <     *  containsValue returns true for held values
263 >     * containsValue returns true for held values
264       */
265      public void testContainsValue() {
266          ConcurrentHashMap map = map5();
267 <        assertTrue(map.containsValue("A"));
267 >        assertTrue(map.containsValue("A"));
268          assertFalse(map.containsValue("Z"));
269      }
270  
271      /**
272 <     *   enumeration returns an enumeration containing the correct
273 <     *   elements
272 >     * enumeration returns an enumeration containing the correct
273 >     * elements
274       */
275      public void testEnumeration() {
276          ConcurrentHashMap map = map5();
277 <        Enumeration e = map.elements();
278 <        int count = 0;
279 <        while(e.hasMoreElements()){
280 <            count++;
281 <            e.nextElement();
282 <        }
283 <        assertEquals(5, count);
277 >        Enumeration e = map.elements();
278 >        int count = 0;
279 >        while (e.hasMoreElements()) {
280 >            count++;
281 >            e.nextElement();
282 >        }
283 >        assertEquals(5, count);
284      }
285  
286      /**
287 <     *  get returns the correct element at the given key,
288 <     *  or null if not present
287 >     * get returns the correct element at the given key,
288 >     * or null if not present
289       */
290      public void testGet() {
291          ConcurrentHashMap map = map5();
292 <        assertEquals("A", (String)map.get(one));
292 >        assertEquals("A", (String)map.get(one));
293          ConcurrentHashMap empty = new ConcurrentHashMap();
294          assertNull(map.get("anything"));
295 +        assertNull(empty.get("anything"));
296      }
297  
298      /**
299 <     *  isEmpty is true of empty map and false for non-empty
299 >     * isEmpty is true of empty map and false for non-empty
300       */
301      public void testIsEmpty() {
302          ConcurrentHashMap empty = new ConcurrentHashMap();
303          ConcurrentHashMap map = map5();
304 <        assertTrue(empty.isEmpty());
304 >        assertTrue(empty.isEmpty());
305          assertFalse(map.isEmpty());
306      }
307  
308      /**
309 <     *   keys returns an enumeration containing all the keys from the map
309 >     * keys returns an enumeration containing all the keys from the map
310       */
311      public void testKeys() {
312          ConcurrentHashMap map = map5();
313 <        Enumeration e = map.keys();
314 <        int count = 0;
315 <        while(e.hasMoreElements()){
316 <            count++;
317 <            e.nextElement();
318 <        }
319 <        assertEquals(5, count);
313 >        Enumeration e = map.keys();
314 >        int count = 0;
315 >        while (e.hasMoreElements()) {
316 >            count++;
317 >            e.nextElement();
318 >        }
319 >        assertEquals(5, count);
320      }
321  
322      /**
323 <     *   keySet returns a Set containing all the keys
323 >     * keySet returns a Set containing all the keys
324       */
325      public void testKeySet() {
326          ConcurrentHashMap map = map5();
327 <        Set s = map.keySet();
328 <        assertEquals(5, s.size());
329 <        assertTrue(s.contains(one));
330 <        assertTrue(s.contains(two));
331 <        assertTrue(s.contains(three));
332 <        assertTrue(s.contains(four));
333 <        assertTrue(s.contains(five));
327 >        Set s = map.keySet();
328 >        assertEquals(5, s.size());
329 >        assertTrue(s.contains(one));
330 >        assertTrue(s.contains(two));
331 >        assertTrue(s.contains(three));
332 >        assertTrue(s.contains(four));
333 >        assertTrue(s.contains(five));
334 >    }
335 >
336 >    /**
337 >     * Test keySet().removeAll on empty map
338 >     */
339 >    public void testKeySet_empty_removeAll() {
340 >        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
341 >        Set<Integer> set = map.keySet();
342 >        set.removeAll(Collections.emptyList());
343 >        assertTrue(map.isEmpty());
344 >        assertTrue(set.isEmpty());
345 >        // following is test for JDK-8163353
346 >        set.removeAll(Collections.emptySet());
347 >        assertTrue(map.isEmpty());
348 >        assertTrue(set.isEmpty());
349 >    }
350 >
351 >    /**
352 >     * keySet.toArray returns contains all keys
353 >     */
354 >    public void testKeySetToArray() {
355 >        ConcurrentHashMap map = map5();
356 >        Set s = map.keySet();
357 >        Object[] ar = s.toArray();
358 >        assertTrue(s.containsAll(Arrays.asList(ar)));
359 >        assertEquals(5, ar.length);
360 >        ar[0] = m10;
361 >        assertFalse(s.containsAll(Arrays.asList(ar)));
362 >    }
363 >
364 >    /**
365 >     * Values.toArray contains all values
366 >     */
367 >    public void testValuesToArray() {
368 >        ConcurrentHashMap map = map5();
369 >        Collection v = map.values();
370 >        Object[] ar = v.toArray();
371 >        ArrayList s = new ArrayList(Arrays.asList(ar));
372 >        assertEquals(5, ar.length);
373 >        assertTrue(s.contains("A"));
374 >        assertTrue(s.contains("B"));
375 >        assertTrue(s.contains("C"));
376 >        assertTrue(s.contains("D"));
377 >        assertTrue(s.contains("E"));
378 >    }
379 >
380 >    /**
381 >     * entrySet.toArray contains all entries
382 >     */
383 >    public void testEntrySetToArray() {
384 >        ConcurrentHashMap map = map5();
385 >        Set s = map.entrySet();
386 >        Object[] ar = s.toArray();
387 >        assertEquals(5, ar.length);
388 >        for (int i = 0; i < 5; ++i) {
389 >            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
390 >            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
391 >        }
392      }
393  
394      /**
# Line 154 | Line 396 | public class ConcurrentHashMapTest exten
396       */
397      public void testValues() {
398          ConcurrentHashMap map = map5();
399 <        Collection s = map.values();
400 <        assertEquals(5, s.size());
401 <        assertTrue(s.contains("A"));
402 <        assertTrue(s.contains("B"));
403 <        assertTrue(s.contains("C"));
404 <        assertTrue(s.contains("D"));
405 <        assertTrue(s.contains("E"));
399 >        Collection s = map.values();
400 >        assertEquals(5, s.size());
401 >        assertTrue(s.contains("A"));
402 >        assertTrue(s.contains("B"));
403 >        assertTrue(s.contains("C"));
404 >        assertTrue(s.contains("D"));
405 >        assertTrue(s.contains("E"));
406      }
407  
408      /**
# Line 168 | Line 410 | public class ConcurrentHashMapTest exten
410       */
411      public void testEntrySet() {
412          ConcurrentHashMap map = map5();
413 <        Set s = map.entrySet();
414 <        assertEquals(5, s.size());
413 >        Set s = map.entrySet();
414 >        assertEquals(5, s.size());
415          Iterator it = s.iterator();
416          while (it.hasNext()) {
417              Map.Entry e = (Map.Entry) it.next();
418 <            assertTrue(
418 >            assertTrue(
419                         (e.getKey().equals(one) && e.getValue().equals("A")) ||
420                         (e.getKey().equals(two) && e.getValue().equals("B")) ||
421                         (e.getKey().equals(three) && e.getValue().equals("C")) ||
# Line 183 | Line 425 | public class ConcurrentHashMapTest exten
425      }
426  
427      /**
428 <     *   putAll  adds all key-value pairs from the given map
428 >     * putAll adds all key-value pairs from the given map
429       */
430      public void testPutAll() {
431          ConcurrentHashMap empty = new ConcurrentHashMap();
432          ConcurrentHashMap map = map5();
433 <        empty.putAll(map);
434 <        assertEquals(5, empty.size());
435 <        assertTrue(empty.containsKey(one));
436 <        assertTrue(empty.containsKey(two));
437 <        assertTrue(empty.containsKey(three));
438 <        assertTrue(empty.containsKey(four));
439 <        assertTrue(empty.containsKey(five));
433 >        empty.putAll(map);
434 >        assertEquals(5, empty.size());
435 >        assertTrue(empty.containsKey(one));
436 >        assertTrue(empty.containsKey(two));
437 >        assertTrue(empty.containsKey(three));
438 >        assertTrue(empty.containsKey(four));
439 >        assertTrue(empty.containsKey(five));
440      }
441  
442      /**
443 <     *   putIfAbsent works when the given key is not present
443 >     * putIfAbsent works when the given key is not present
444       */
445      public void testPutIfAbsent() {
446          ConcurrentHashMap map = map5();
447 <        map.putIfAbsent(six, "Z");
447 >        map.putIfAbsent(six, "Z");
448          assertTrue(map.containsKey(six));
449      }
450  
451      /**
452 <     *   putIfAbsent does not add the pair if the key is already present
452 >     * putIfAbsent does not add the pair if the key is already present
453       */
454      public void testPutIfAbsent2() {
455          ConcurrentHashMap map = map5();
# Line 215 | Line 457 | public class ConcurrentHashMapTest exten
457      }
458  
459      /**
460 <     *   replace fails when the given key is not present
460 >     * replace fails when the given key is not present
461       */
462      public void testReplace() {
463          ConcurrentHashMap map = map5();
464 <        assertNull(map.replace(six, "Z"));
464 >        assertNull(map.replace(six, "Z"));
465          assertFalse(map.containsKey(six));
466      }
467  
468      /**
469 <     *   replace succeeds if the key is already present
469 >     * replace succeeds if the key is already present
470       */
471      public void testReplace2() {
472          ConcurrentHashMap map = map5();
# Line 232 | Line 474 | public class ConcurrentHashMapTest exten
474          assertEquals("Z", map.get(one));
475      }
476  
235
477      /**
478       * replace value fails when the given key not mapped to expected value
479       */
480      public void testReplaceValue() {
481          ConcurrentHashMap map = map5();
482          assertEquals("A", map.get(one));
483 <        assertFalse(map.replace(one, "Z", "Z"));
483 >        assertFalse(map.replace(one, "Z", "Z"));
484          assertEquals("A", map.get(one));
485      }
486  
# Line 249 | Line 490 | public class ConcurrentHashMapTest exten
490      public void testReplaceValue2() {
491          ConcurrentHashMap map = map5();
492          assertEquals("A", map.get(one));
493 <        assertTrue(map.replace(one, "A", "Z"));
493 >        assertTrue(map.replace(one, "A", "Z"));
494          assertEquals("Z", map.get(one));
495      }
496  
256
497      /**
498 <     *   remove removes the correct key-value pair from the map
498 >     * remove removes the correct key-value pair from the map
499       */
500      public void testRemove() {
501          ConcurrentHashMap map = map5();
502 <        map.remove(five);
503 <        assertEquals(4, map.size());
504 <        assertFalse(map.containsKey(five));
502 >        map.remove(five);
503 >        assertEquals(4, map.size());
504 >        assertFalse(map.containsKey(five));
505      }
506  
507      /**
# Line 269 | Line 509 | public class ConcurrentHashMapTest exten
509       */
510      public void testRemove2() {
511          ConcurrentHashMap map = map5();
512 <        map.remove(five, "E");
513 <        assertEquals(4, map.size());
514 <        assertFalse(map.containsKey(five));
515 <        map.remove(four, "A");
516 <        assertEquals(4, map.size());
517 <        assertTrue(map.containsKey(four));
278 <
512 >        map.remove(five, "E");
513 >        assertEquals(4, map.size());
514 >        assertFalse(map.containsKey(five));
515 >        map.remove(four, "A");
516 >        assertEquals(4, map.size());
517 >        assertTrue(map.containsKey(four));
518      }
519  
520      /**
521 <     *   size returns the correct values
521 >     * size returns the correct values
522       */
523      public void testSize() {
524          ConcurrentHashMap map = map5();
525          ConcurrentHashMap empty = new ConcurrentHashMap();
526 <        assertEquals(0, empty.size());
527 <        assertEquals(5, map.size());
526 >        assertEquals(0, empty.size());
527 >        assertEquals(5, map.size());
528      }
529  
530      /**
# Line 295 | Line 534 | public class ConcurrentHashMapTest exten
534          ConcurrentHashMap map = map5();
535          String s = map.toString();
536          for (int i = 1; i <= 5; ++i) {
537 <            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
537 >            assertTrue(s.contains(String.valueOf(i)));
538          }
539 <    }        
539 >    }
540  
541      // Exception tests
542 <    
542 >
543      /**
544 <     * Cannot create with negative capacity
544 >     * Cannot create with only negative capacity
545       */
546      public void testConstructor1() {
547          try {
548 <            new ConcurrentHashMap(-1,0,1);
548 >            new ConcurrentHashMap(-1);
549              shouldThrow();
550 <        } catch(IllegalArgumentException e){}
550 >        } catch (IllegalArgumentException success) {}
551      }
552  
553      /**
554 <     * Cannot create with negative concurrency level
554 >     * Constructor (initialCapacity, loadFactor) throws
555 >     * IllegalArgumentException if either argument is negative
556       */
557      public void testConstructor2() {
558          try {
559 <            new ConcurrentHashMap(1,0,-1);
559 >            new ConcurrentHashMap(-1, .75f);
560 >            shouldThrow();
561 >        } catch (IllegalArgumentException success) {}
562 >
563 >        try {
564 >            new ConcurrentHashMap(16, -1);
565              shouldThrow();
566 <        } catch(IllegalArgumentException e){}
566 >        } catch (IllegalArgumentException success) {}
567      }
568  
569      /**
570 <     * Cannot create with only negative capacity
570 >     * Constructor (initialCapacity, loadFactor, concurrencyLevel)
571 >     * throws IllegalArgumentException if any argument is negative
572       */
573      public void testConstructor3() {
574          try {
575 <            new ConcurrentHashMap(-1);
575 >            new ConcurrentHashMap(-1, .75f, 1);
576 >            shouldThrow();
577 >        } catch (IllegalArgumentException success) {}
578 >
579 >        try {
580 >            new ConcurrentHashMap(16, -1, 1);
581              shouldThrow();
582 <        } catch(IllegalArgumentException e){}
582 >        } catch (IllegalArgumentException success) {}
583 >
584 >        try {
585 >            new ConcurrentHashMap(16, .75f, -1);
586 >            shouldThrow();
587 >        } catch (IllegalArgumentException success) {}
588 >    }
589 >
590 >    /**
591 >     * ConcurrentHashMap(map) throws NullPointerException if the given
592 >     * map is null
593 >     */
594 >    public void testConstructor4() {
595 >        try {
596 >            new ConcurrentHashMap(null);
597 >            shouldThrow();
598 >        } catch (NullPointerException success) {}
599 >    }
600 >
601 >    /**
602 >     * ConcurrentHashMap(map) creates a new map with the same mappings
603 >     * as the given map
604 >     */
605 >    public void testConstructor5() {
606 >        ConcurrentHashMap map1 = map5();
607 >        ConcurrentHashMap map2 = new ConcurrentHashMap(map5());
608 >        assertTrue(map2.equals(map1));
609 >        map2.put(one, "F");
610 >        assertFalse(map2.equals(map1));
611      }
612  
613      /**
614       * get(null) throws NPE
615       */
616      public void testGet_NullPointerException() {
617 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
618          try {
339            ConcurrentHashMap c = new ConcurrentHashMap(5);
619              c.get(null);
620              shouldThrow();
621 <        } catch(NullPointerException e){}
621 >        } catch (NullPointerException success) {}
622      }
623  
624      /**
625       * containsKey(null) throws NPE
626       */
627      public void testContainsKey_NullPointerException() {
628 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
629          try {
350            ConcurrentHashMap c = new ConcurrentHashMap(5);
630              c.containsKey(null);
631              shouldThrow();
632 <        } catch(NullPointerException e){}
632 >        } catch (NullPointerException success) {}
633      }
634  
635      /**
636       * containsValue(null) throws NPE
637       */
638      public void testContainsValue_NullPointerException() {
639 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
640          try {
361            ConcurrentHashMap c = new ConcurrentHashMap(5);
641              c.containsValue(null);
642              shouldThrow();
643 <        } catch(NullPointerException e){}
643 >        } catch (NullPointerException success) {}
644      }
645  
646      /**
647       * contains(null) throws NPE
648       */
649      public void testContains_NullPointerException() {
650 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
651          try {
372            ConcurrentHashMap c = new ConcurrentHashMap(5);
652              c.contains(null);
653              shouldThrow();
654 <        } catch(NullPointerException e){}
654 >        } catch (NullPointerException success) {}
655      }
656  
657      /**
658       * put(null,x) throws NPE
659       */
660      public void testPut1_NullPointerException() {
661 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
662          try {
383            ConcurrentHashMap c = new ConcurrentHashMap(5);
663              c.put(null, "whatever");
664              shouldThrow();
665 <        } catch(NullPointerException e){}
665 >        } catch (NullPointerException success) {}
666      }
667  
668      /**
669       * put(x, null) throws NPE
670       */
671      public void testPut2_NullPointerException() {
672 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
673          try {
394            ConcurrentHashMap c = new ConcurrentHashMap(5);
674              c.put("whatever", null);
675              shouldThrow();
676 <        } catch(NullPointerException e){}
676 >        } catch (NullPointerException success) {}
677      }
678  
679      /**
680       * putIfAbsent(null, x) throws NPE
681       */
682      public void testPutIfAbsent1_NullPointerException() {
683 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
684          try {
405            ConcurrentHashMap c = new ConcurrentHashMap(5);
685              c.putIfAbsent(null, "whatever");
686              shouldThrow();
687 <        } catch(NullPointerException e){}
687 >        } catch (NullPointerException success) {}
688      }
689  
690      /**
691       * replace(null, x) throws NPE
692       */
693      public void testReplace_NullPointerException() {
694 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
695          try {
416            ConcurrentHashMap c = new ConcurrentHashMap(5);
696              c.replace(null, "whatever");
697              shouldThrow();
698 <        } catch(NullPointerException e){}
698 >        } catch (NullPointerException success) {}
699      }
700  
701      /**
702       * replace(null, x, y) throws NPE
703       */
704      public void testReplaceValue_NullPointerException() {
705 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
706          try {
427            ConcurrentHashMap c = new ConcurrentHashMap(5);
707              c.replace(null, one, "whatever");
708              shouldThrow();
709 <        } catch(NullPointerException e){}
709 >        } catch (NullPointerException success) {}
710      }
711  
712      /**
713       * putIfAbsent(x, null) throws NPE
714       */
715      public void testPutIfAbsent2_NullPointerException() {
716 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
717          try {
438            ConcurrentHashMap c = new ConcurrentHashMap(5);
718              c.putIfAbsent("whatever", null);
719              shouldThrow();
720 <        } catch(NullPointerException e){}
720 >        } catch (NullPointerException success) {}
721      }
722  
444
723      /**
724       * replace(x, null) throws NPE
725       */
726      public void testReplace2_NullPointerException() {
727 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
728          try {
450            ConcurrentHashMap c = new ConcurrentHashMap(5);
729              c.replace("whatever", null);
730              shouldThrow();
731 <        } catch(NullPointerException e){}
731 >        } catch (NullPointerException success) {}
732      }
733  
734      /**
735       * replace(x, null, y) throws NPE
736       */
737      public void testReplaceValue2_NullPointerException() {
738 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
739          try {
461            ConcurrentHashMap c = new ConcurrentHashMap(5);
740              c.replace("whatever", null, "A");
741              shouldThrow();
742 <        } catch(NullPointerException e){}
742 >        } catch (NullPointerException success) {}
743      }
744  
745      /**
746       * replace(x, y, null) throws NPE
747       */
748      public void testReplaceValue3_NullPointerException() {
749 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
750          try {
472            ConcurrentHashMap c = new ConcurrentHashMap(5);
751              c.replace("whatever", one, null);
752              shouldThrow();
753 <        } catch(NullPointerException e){}
753 >        } catch (NullPointerException success) {}
754      }
755  
478
756      /**
757       * remove(null) throws NPE
758       */
759      public void testRemove1_NullPointerException() {
760 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
761 +        c.put("sadsdf", "asdads");
762          try {
484            ConcurrentHashMap c = new ConcurrentHashMap(5);
485            c.put("sadsdf", "asdads");
763              c.remove(null);
764              shouldThrow();
765 <        } catch(NullPointerException e){}
765 >        } catch (NullPointerException success) {}
766      }
767  
768      /**
769       * remove(null, x) throws NPE
770       */
771      public void testRemove2_NullPointerException() {
772 +        ConcurrentHashMap c = new ConcurrentHashMap(5);
773 +        c.put("sadsdf", "asdads");
774          try {
496            ConcurrentHashMap c = new ConcurrentHashMap(5);
497            c.put("sadsdf", "asdads");
775              c.remove(null, "whatever");
776              shouldThrow();
777 <        } catch(NullPointerException e){}
777 >        } catch (NullPointerException success) {}
778      }
779  
780      /**
781       * remove(x, null) returns false
782       */
783      public void testRemove3() {
784 <        try {
785 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
786 <            c.put("sadsdf", "asdads");
510 <            assertFalse(c.remove("sadsdf", null));
511 <        } catch(NullPointerException e){
512 <            fail();
513 <        }
784 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
785 >        c.put("sadsdf", "asdads");
786 >        assertFalse(c.remove("sadsdf", null));
787      }
788  
789      /**
790 <     * A deserialized map equals original
790 >     * A deserialized/reserialized map equals original
791       */
792 <    public void testSerialization() {
793 <        ConcurrentHashMap q = map5();
792 >    public void testSerialization() throws Exception {
793 >        Map x = map5();
794 >        Map y = serialClone(x);
795  
796 <        try {
797 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
798 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
799 <            out.writeObject(q);
526 <            out.close();
527 <
528 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
529 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
530 <            ConcurrentHashMap r = (ConcurrentHashMap)in.readObject();
531 <            assertEquals(q.size(), r.size());
532 <            assertTrue(q.equals(r));
533 <            assertTrue(r.equals(q));
534 <        } catch(Exception e){
535 <            e.printStackTrace();
536 <            unexpectedException();
537 <        }
796 >        assertNotSame(x, y);
797 >        assertEquals(x.size(), y.size());
798 >        assertEquals(x, y);
799 >        assertEquals(y, x);
800      }
801  
540
802      /**
803       * SetValue of an EntrySet entry sets value in the map.
804       */
805      public void testSetValueWriteThrough() {
806 <        // Adapted from a bug report by Eric Zoerner
806 >        // Adapted from a bug report by Eric Zoerner
807          ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
808          assertTrue(map.isEmpty());
809          for (int i = 0; i < 20; i++)
810              map.put(new Integer(i), new Integer(i));
811          assertFalse(map.isEmpty());
812          Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
813 <        
814 <        // assert that entry1 is not 16
815 <        assertTrue("entry is 16, test not valid",
816 <                   !entry1.getKey().equals(new Integer(16)));
817 <        
818 <        // remove 16 (a different key) from map
819 <        // which just happens to cause entry1 to be cloned in map
820 <        map.remove(new Integer(16));
821 <        entry1.setValue("XYZ");
561 <        assertTrue(map.containsValue("XYZ")); // fails
813 >        // Unless it happens to be first (in which case remainder of
814 >        // test is skipped), remove a possibly-colliding key from map
815 >        // which, under some implementations, may cause entry1 to be
816 >        // cloned in map
817 >        if (!entry1.getKey().equals(new Integer(16))) {
818 >            map.remove(new Integer(16));
819 >            entry1.setValue("XYZ");
820 >            assertTrue(map.containsValue("XYZ")); // fails if write-through broken
821 >        }
822      }
823 <    
823 >
824 >    /**
825 >     * Tests performance of removeAll when the other collection is much smaller.
826 >     * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testRemoveAll_performance -Djsr166.expensiveTests=true tck
827 >     */
828 >    public void testRemoveAll_performance() {
829 >        final int mapSize = expensiveTests ? 1_000_000 : 100;
830 >        final int iterations = expensiveTests ? 500 : 2;
831 >        final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
832 >        for (int i = 0; i < mapSize; i++)
833 >            map.put(i, i);
834 >        Set<Integer> keySet = map.keySet();
835 >        Collection<Integer> removeMe = Arrays.asList(new Integer[] { -99, -86 });
836 >        for (int i = 0; i < iterations; i++)
837 >            assertFalse(keySet.removeAll(removeMe));
838 >        assertEquals(mapSize, map.size());
839 >    }
840 >
841   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines