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.4 by dl, Sat Sep 20 00:31:57 2003 UTC vs.
Revision 1.58 by jsr166, Mon Jan 8 03:37:59 2018 UTC

# Line 1 | Line 1
1   /*
2 < * Written by members of JCP JSR-166 Expert Group and released to the
3 < * public domain. Use, modify, and redistribute this code in any way
4 < * without acknowledgement. Other contributors include Andrew Wright,
5 < * Jeffrey Hayes, Pat Fischer, 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 <    private static ConcurrentHashMap map5() {  
44 <        ConcurrentHashMap map = new ConcurrentHashMap(5);
43 >    /**
44 >     * Returns a new map from Integers 1-5 to Strings "A"-"E".
45 >     */
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 key-element pairs from the map
121 >     * Inserted elements that are subclasses of the same Comparable
122 >     * class are found.
123       */
124 <    public void testClear(){
125 <        ConcurrentHashMap map = map5();
126 <        map.clear();
127 <        assertEquals(map.size(), 0);
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 <     *   contains gives the appropriate value
137 >     * Elements of classes with erased generic type parameters based
138 >     * on Comparable can be inserted and found.
139       */
140 <    public void testContains(){
141 <        ConcurrentHashMap map = map5();
142 <        assertTrue(map.contains("A"));
143 <        assertFalse(map.contains("Z"));
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 <    
158 >
159      /**
160 <     *   containsKey gives the appropriate value
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 testContainsKey(){
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 <        assertTrue(map.containsKey(one));
217 <        assertFalse(map.containsKey(new Integer(100)));
216 >        map.clear();
217 >        assertEquals(0, map.size());
218 >    }
219 >
220 >    /**
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();
229 >        assertFalse(map1.equals(map2));
230 >        assertFalse(map2.equals(map1));
231 >    }
232 >
233 >    /**
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 <     *  Identical to normal contains
245 >     * contains returns true for contained value
246       */
247 <    public void testContainsValue(){
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  
253      /**
254 <     *   enumeration returns an enumeration containing the correct
73 <     *   elements
254 >     * containsKey returns true for contained key
255       */
256 <    public void testEnumeration(){
256 >    public void testContainsKey() {
257          ConcurrentHashMap map = map5();
258 <        Enumeration e = map.elements();
259 <        int count = 0;
79 <        while(e.hasMoreElements()){
80 <            count++;
81 <            e.nextElement();
82 <        }
83 <        assertEquals(5, count);
258 >        assertTrue(map.containsKey(one));
259 >        assertFalse(map.containsKey(zero));
260      }
261  
262      /**
263 <     *   Clone creates an equal map
263 >     * containsValue returns true for held values
264       */
265 <    public void testClone(){
265 >    public void testContainsValue() {
266          ConcurrentHashMap map = map5();
267 <        ConcurrentHashMap m2 = (ConcurrentHashMap)(map.clone());
268 <        assertEquals(map, m2);
267 >        assertTrue(map.containsValue("A"));
268 >        assertFalse(map.containsValue("Z"));
269      }
270  
271      /**
272 <     *   get returns the correct element at the given index
272 >     * enumeration returns an enumeration containing the correct
273 >     * elements
274       */
275 <    public void testGet(){
275 >    public void testEnumeration() {
276          ConcurrentHashMap map = map5();
277 <        assertEquals("A", (String)map.get(one));
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 on a nonexistant key returns null
287 >     * get returns the correct element at the given key,
288 >     * or null if not present
289       */
290 <    public void testGet2(){
290 >    public void testGet() {
291 >        ConcurrentHashMap map = map5();
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 <     *  Simple test to verify isEmpty returns the correct value
299 >     * isEmpty is true of empty map and false for non-empty
300       */
301 <    public void testIsEmpty(){
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);
320 >    }
321 >
322 >    /**
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));
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 testKeys(){
354 >    public void testKeySetToArray() {
355          ConcurrentHashMap map = map5();
356 <        Enumeration e = map.keys();
357 <        int count = 0;
358 <        while(e.hasMoreElements()){
359 <            count++;
360 <            e.nextElement();
361 <        }
132 <        assertEquals(5, count);
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 <     *   keySet returns a Set containing all the keys
365 >     * Values.toArray contains all values
366       */
367 <    public void testKeySet(){
367 >    public void testValuesToArray() {
368          ConcurrentHashMap map = map5();
369 <        Set s = map.keySet();
370 <        assertEquals(5, s.size());
371 <        assertTrue(s.contains(one));
372 <        assertTrue(s.contains(two));
373 <        assertTrue(s.contains(three));
374 <        assertTrue(s.contains(four));
375 <        assertTrue(s.contains(five));
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 <    public void testValues(){
380 >    /**
381 >     * entrySet.toArray contains all entries
382 >     */
383 >    public void testEntrySetToArray() {
384          ConcurrentHashMap map = map5();
385 <        Collection s = map.values();
386 <        assertEquals(5, s.size());
387 <        assertTrue(s.contains("A"));
388 <        assertTrue(s.contains("B"));
389 <        assertTrue(s.contains("C"));
390 <        assertTrue(s.contains("D"));
391 <        assertTrue(s.contains("E"));
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 <    public void testEntrySet(){
394 >    /**
395 >     * values collection contains all values
396 >     */
397 >    public void testValues() {
398          ConcurrentHashMap map = map5();
399 <        Set s = map.entrySet();
400 <        assertEquals(5, s.size());
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 >    /**
409 >     * entrySet contains all pairs
410 >     */
411 >    public void testEntrySet() {
412 >        ConcurrentHashMap map = map5();
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 174 | 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(){
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(){
445 >    public void testPutIfAbsent() {
446          ConcurrentHashMap map = map5();
447 <        map.putIfAbsent(new Integer(6), "Z");
448 <        assertTrue(map.containsKey(new Integer(6)));
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(){
454 >    public void testPutIfAbsent2() {
455          ConcurrentHashMap map = map5();
456          assertEquals("A", map.putIfAbsent(one, "Z"));
457      }
458  
459      /**
460 <     *   remove removes the correct key-value pair from the map
460 >     * replace fails when the given key is not present
461       */
462 <    public void testRemove(){
462 >    public void testReplace() {
463          ConcurrentHashMap map = map5();
464 <        map.remove(five);
465 <        assertEquals(4, map.size());
215 <        assertFalse(map.containsKey(five));
464 >        assertNull(map.replace(six, "Z"));
465 >        assertFalse(map.containsKey(six));
466      }
467  
468 <    public void testRemove2(){
468 >    /**
469 >     * replace succeeds if the key is already present
470 >     */
471 >    public void testReplace2() {
472          ConcurrentHashMap map = map5();
473 <        map.remove(five, "E");
474 <        assertEquals(4, map.size());
475 <        assertFalse(map.containsKey(five));
223 <        map.remove(four, "A");
224 <        assertEquals(4, map.size());
225 <        assertTrue(map.containsKey(four));
473 >        assertNotNull(map.replace(one, "Z"));
474 >        assertEquals("Z", map.get(one));
475 >    }
476  
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"));
484 +        assertEquals("A", map.get(one));
485 +    }
486 +
487 +    /**
488 +     * replace value succeeds when the given key mapped to expected value
489 +     */
490 +    public void testReplaceValue2() {
491 +        ConcurrentHashMap map = map5();
492 +        assertEquals("A", map.get(one));
493 +        assertTrue(map.replace(one, "A", "Z"));
494 +        assertEquals("Z", map.get(one));
495      }
496  
497      /**
498 <     *   size returns the correct values
498 >     * remove removes the correct key-value pair from the map
499       */
500 <    public void testSize(){
500 >    public void testRemove() {
501 >        ConcurrentHashMap map = map5();
502 >        map.remove(five);
503 >        assertEquals(4, map.size());
504 >        assertFalse(map.containsKey(five));
505 >    }
506 >
507 >    /**
508 >     * remove(key,value) removes only if pair present
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));
518 >    }
519 >
520 >    /**
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 <    public void testToString(){
530 >    /**
531 >     * toString contains toString of elements
532 >     */
533 >    public void testToString() {
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
248    
249    public void testConstructor1(){
250        try{
251            new ConcurrentHashMap(-1,0,1);
252            fail("ConcurrentHashMap(int, float, int) should throw Illegal Argument Exception");
253        }catch(IllegalArgumentException e){}
254    }
255
256    public void testConstructor2(){
257        try{
258            new ConcurrentHashMap(1,0,-1);
259            fail("ConcurrentHashMap(int, float, int) should throw Illegal Argument Exception");
260        }catch(IllegalArgumentException e){}
261    }
542  
543 <    public void testConstructor3(){
544 <        try{
543 >    /**
544 >     * Cannot create with only negative capacity
545 >     */
546 >    public void testConstructor1() {
547 >        try {
548              new ConcurrentHashMap(-1);
549 <            fail("ConcurrentHashMap(int) should throw Illegal Argument Exception");
550 <        }catch(IllegalArgumentException e){}
549 >            shouldThrow();
550 >        } catch (IllegalArgumentException success) {}
551 >    }
552 >
553 >    /**
554 >     * Constructor (initialCapacity, loadFactor) throws
555 >     * IllegalArgumentException if either argument is negative
556 >     */
557 >    public void testConstructor2() {
558 >        try {
559 >            new ConcurrentHashMap(-1, .75f);
560 >            shouldThrow();
561 >        } catch (IllegalArgumentException success) {}
562 >
563 >        try {
564 >            new ConcurrentHashMap(16, -1);
565 >            shouldThrow();
566 >        } catch (IllegalArgumentException success) {}
567      }
568  
569 <    public void testGet_NullPointerException(){
570 <        try{
571 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
569 >    /**
570 >     * Constructor (initialCapacity, loadFactor, concurrencyLevel)
571 >     * throws IllegalArgumentException if any argument is negative
572 >     */
573 >    public void testConstructor3() {
574 >        try {
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 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 {
619              c.get(null);
620 <            fail("ConcurrentHashMap - Object get(Object) should throw Null Pointer exception");
621 <        }catch(NullPointerException e){}
620 >            shouldThrow();
621 >        } catch (NullPointerException success) {}
622      }
623  
624 <    public void testContainsKey_NullPointerException(){
625 <        try{
626 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
624 >    /**
625 >     * containsKey(null) throws NPE
626 >     */
627 >    public void testContainsKey_NullPointerException() {
628 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
629 >        try {
630              c.containsKey(null);
631 <            fail("ConcurrenthashMap - boolean containsKey(Object) should throw Null Pointer exception");
632 <        }catch(NullPointerException e){}
631 >            shouldThrow();
632 >        } catch (NullPointerException success) {}
633      }
634  
635 <    public void testContainsValue_NullPointerException(){
636 <        try{
637 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
635 >    /**
636 >     * containsValue(null) throws NPE
637 >     */
638 >    public void testContainsValue_NullPointerException() {
639 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
640 >        try {
641              c.containsValue(null);
642 <            fail("ConcurrentHashMap - boolean containsValue(Object) should throw Null Pointer exception");
643 <        }catch(NullPointerException e){}
642 >            shouldThrow();
643 >        } catch (NullPointerException success) {}
644      }
645  
646 <    public void testContains_NullPointerException(){
647 <        try{
648 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
646 >    /**
647 >     * contains(null) throws NPE
648 >     */
649 >    public void testContains_NullPointerException() {
650 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
651 >        try {
652              c.contains(null);
653 <            fail("ConcurrentHashMap - boolean contains(Object) should throw Null Pointer exception");
654 <        }catch(NullPointerException e){}
653 >            shouldThrow();
654 >        } catch (NullPointerException success) {}
655      }
656  
657 <    public void testPut1_NullPointerException(){
658 <        try{
659 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
657 >    /**
658 >     * put(null,x) throws NPE
659 >     */
660 >    public void testPut1_NullPointerException() {
661 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
662 >        try {
663              c.put(null, "whatever");
664 <            fail("ConcurrentHashMap - Object put(Object, Object) should throw Null Pointer exception");
665 <        }catch(NullPointerException e){}
664 >            shouldThrow();
665 >        } catch (NullPointerException success) {}
666      }
667  
668 <    public void testPut2_NullPointerException(){
669 <        try{
670 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
668 >    /**
669 >     * put(x, null) throws NPE
670 >     */
671 >    public void testPut2_NullPointerException() {
672 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
673 >        try {
674              c.put("whatever", null);
675 <            fail("ConcurrentHashMap - Object put(Object, Object) should throw Null Pointer exception");
676 <        }catch(NullPointerException e){}
675 >            shouldThrow();
676 >        } catch (NullPointerException success) {}
677      }
678  
679 <    public void testPutIfAbsent1_NullPointerException(){
680 <        try{
681 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
679 >    /**
680 >     * putIfAbsent(null, x) throws NPE
681 >     */
682 >    public void testPutIfAbsent1_NullPointerException() {
683 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
684 >        try {
685              c.putIfAbsent(null, "whatever");
686 <            fail("ConcurrentHashMap - Object putIfAbsent(Object, Object) should throw Null Pointer exception");
687 <        }catch(NullPointerException e){}
686 >            shouldThrow();
687 >        } catch (NullPointerException success) {}
688      }
689  
690 <    public void testPutIfAbsent2_NullPointerException(){
691 <        try{
692 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
690 >    /**
691 >     * replace(null, x) throws NPE
692 >     */
693 >    public void testReplace_NullPointerException() {
694 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
695 >        try {
696 >            c.replace(null, "whatever");
697 >            shouldThrow();
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 {
707 >            c.replace(null, one, "whatever");
708 >            shouldThrow();
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 {
718              c.putIfAbsent("whatever", null);
719 <            fail("COncurrentHashMap - Object putIfAbsent(Object, Object) should throw Null Pointer exception");
720 <        }catch(NullPointerException e){}
719 >            shouldThrow();
720 >        } catch (NullPointerException success) {}
721 >    }
722 >
723 >    /**
724 >     * replace(x, null) throws NPE
725 >     */
726 >    public void testReplace2_NullPointerException() {
727 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
728 >        try {
729 >            c.replace("whatever", null);
730 >            shouldThrow();
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 {
740 +            c.replace("whatever", null, "A");
741 +            shouldThrow();
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 {
751 +            c.replace("whatever", one, null);
752 +            shouldThrow();
753 +        } catch (NullPointerException success) {}
754 +    }
755  
756 <    public void testRemove1_NullPointerException(){
757 <        try{
758 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
759 <            c.put("sadsdf", "asdads");
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 {
763              c.remove(null);
764 <            fail("ConcurrentHashMap - Object remove(Object) should throw Null pointer exceptione");
765 <        }catch(NullPointerException e){}
764 >            shouldThrow();
765 >        } catch (NullPointerException success) {}
766      }
767  
768 <    public void testRemove2_NullPointerException(){
769 <        try{
770 <            ConcurrentHashMap c = new ConcurrentHashMap(5);
771 <            c.put("sadsdf", "asdads");
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 {
775              c.remove(null, "whatever");
776 <            fail("ConcurrentHashMap - Object remove(Object, Object) should throw Null pointer exceptione");
777 <        }catch(NullPointerException e){}
776 >            shouldThrow();
777 >        } catch (NullPointerException success) {}
778      }
779  
780 <    public void testSerialization() {
781 <        ConcurrentHashMap q = map5();
780 >    /**
781 >     * remove(x, null) returns false
782 >     */
783 >    public void testRemove3() {
784 >        ConcurrentHashMap c = new ConcurrentHashMap(5);
785 >        c.put("sadsdf", "asdads");
786 >        assertFalse(c.remove("sadsdf", null));
787 >    }
788  
789 <        try {
790 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
791 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
792 <            out.writeObject(q);
793 <            out.close();
789 >    /**
790 >     * A deserialized/reserialized map equals original
791 >     */
792 >    public void testSerialization() throws Exception {
793 >        Map x = map5();
794 >        Map y = serialClone(x);
795 >
796 >        assertNotSame(x, y);
797 >        assertEquals(x.size(), y.size());
798 >        assertEquals(x, y);
799 >        assertEquals(y, x);
800 >    }
801  
802 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
803 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
804 <            ConcurrentHashMap r = (ConcurrentHashMap)in.readObject();
805 <            assertEquals(q.size(), r.size());
806 <            assertTrue(q.equals(r));
807 <            assertTrue(r.equals(q));
808 <        } catch(Exception e){
809 <            e.printStackTrace();
810 <            fail("unexpected exception");
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
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 >        // 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  
824 <    
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