ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMapTest.java
Revision: 1.60
Committed: Fri Oct 5 22:12:45 2018 UTC (5 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.59: +1 -3 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.56 * 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 jsr166 1.23 * http://creativecommons.org/publicdomain/zero/1.0/
6 jsr166 1.14 * Other contributors include Andrew Wright, Jeffrey Hayes,
7     * Pat Fisher, Mike Judd.
8 dl 1.1 */
9    
10 jsr166 1.40 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.util.Iterator;
16     import java.util.Map;
17     import java.util.Random;
18     import java.util.Set;
19 jsr166 1.25 import java.util.concurrent.ConcurrentHashMap;
20 dl 1.1
21 jsr166 1.40 import junit.framework.Test;
22    
23 jsr166 1.16 public class ConcurrentHashMapTest extends JSR166TestCase {
24 dl 1.1 public static void main(String[] args) {
25 jsr166 1.45 main(suite(), args);
26 dl 1.1 }
27     public static Test suite() {
28 jsr166 1.56 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 dl 1.1 }
42    
43 dl 1.5 /**
44 jsr166 1.28 * Returns a new map from Integers 1-5 to Strings "A"-"E".
45 dl 1.5 */
46 dl 1.36 private static ConcurrentHashMap<Integer, String> map5() {
47 jsr166 1.52 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
48 dl 1.1 assertTrue(map.isEmpty());
49 jsr166 1.17 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 dl 1.1 assertFalse(map.isEmpty());
55     assertEquals(5, map.size());
56 jsr166 1.17 return map;
57 dl 1.1 }
58    
59 jsr166 1.30 // 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 jsr166 1.58 return Integer.compare(value, other.value);
65 jsr166 1.30 }
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 jsr166 1.58 r = Integer.compare(size(), other.size());
99 jsr166 1.30 return r;
100     }
101     private static final long serialVersionUID = 0;
102     }
103    
104 dl 1.34 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 jsr166 1.30 /**
121     * Inserted elements that are subclasses of the same Comparable
122     * class are found.
123     */
124     public void testComparableFamily() {
125 jsr166 1.39 int size = 500; // makes measured test run time -> 60ms
126 jsr166 1.57 ConcurrentHashMap<BI, Boolean> m = new ConcurrentHashMap<>();
127 jsr166 1.39 for (int i = 0; i < size; i++) {
128 jsr166 1.54 assertNull(m.put(new CI(i), true));
129 jsr166 1.30 }
130 jsr166 1.39 for (int i = 0; i < size; i++) {
131 jsr166 1.30 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 jsr166 1.39 int size = 120; // makes measured test run time -> 60ms
142 jsr166 1.57 ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
143 jsr166 1.39 for (int i = 0; i < size; i++) {
144 jsr166 1.30 BI bi = new BI(i);
145     BS bs = new BS(String.valueOf(i));
146 jsr166 1.57 LexicographicList<BI> bis = new LexicographicList<>(bi);
147     LexicographicList<BS> bss = new LexicographicList<>(bs);
148 jsr166 1.54 assertNull(m.putIfAbsent(bis, true));
149 jsr166 1.30 assertTrue(m.containsKey(bis));
150     if (m.putIfAbsent(bss, true) == null)
151     assertTrue(m.containsKey(bss));
152     assertTrue(m.containsKey(bis));
153     }
154 jsr166 1.39 for (int i = 0; i < size; i++) {
155     assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
156 jsr166 1.30 }
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 jsr166 1.39 int size = 500; // makes measured test run time -> 60ms
166 jsr166 1.57 ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
167 jsr166 1.39 for (int i = 0; i < size; i++) {
168     m.put(Collections.singletonList(new BI(i)), true);
169 jsr166 1.30 }
170    
171 jsr166 1.39 for (int i = 0; i < size; i++) {
172 jsr166 1.57 LexicographicList<BI> bis = new LexicographicList<>(new BI(i));
173 jsr166 1.30 assertTrue(m.containsKey(bis));
174     }
175     }
176    
177 dl 1.1 /**
178 dl 1.34 * Mixtures of instances of comparable and non-comparable classes
179     * can be inserted and found.
180     */
181     public void testMixedComparable() {
182 jsr166 1.38 int size = 1200; // makes measured test run time -> 35ms
183 jsr166 1.57 ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
184 jsr166 1.38 Random rng = new Random();
185 jsr166 1.35 for (int i = 0; i < size; i++) {
186 dl 1.34 Object x;
187 jsr166 1.35 switch (rng.nextInt(4)) {
188 dl 1.34 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 jsr166 1.22 * clear removes all pairs
213 dl 1.1 */
214 dl 1.5 public void testClear() {
215 dl 1.1 ConcurrentHashMap map = map5();
216 jsr166 1.17 map.clear();
217 jsr166 1.26 assertEquals(0, map.size());
218 dl 1.1 }
219    
220     /**
221 jsr166 1.22 * Maps with same contents are equal
222 dl 1.5 */
223     public void testEquals() {
224     ConcurrentHashMap map1 = map5();
225     ConcurrentHashMap map2 = map5();
226     assertEquals(map1, map2);
227     assertEquals(map2, map1);
228 jsr166 1.17 map1.clear();
229 dl 1.5 assertFalse(map1.equals(map2));
230     assertFalse(map2.equals(map1));
231     }
232    
233 dl 1.36 /**
234 jsr166 1.37 * hashCode() equals sum of each key.hashCode ^ value.hashCode
235     */
236 dl 1.36 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 dl 1.5 /**
245 jsr166 1.22 * contains returns true for contained value
246 dl 1.1 */
247 dl 1.5 public void testContains() {
248 dl 1.1 ConcurrentHashMap map = map5();
249 jsr166 1.17 assertTrue(map.contains("A"));
250 dl 1.1 assertFalse(map.contains("Z"));
251     }
252 jsr166 1.14
253 dl 1.1 /**
254 jsr166 1.22 * containsKey returns true for contained key
255 dl 1.1 */
256 dl 1.5 public void testContainsKey() {
257 dl 1.1 ConcurrentHashMap map = map5();
258 jsr166 1.17 assertTrue(map.containsKey(one));
259 dl 1.5 assertFalse(map.containsKey(zero));
260 dl 1.1 }
261    
262     /**
263 jsr166 1.22 * containsValue returns true for held values
264 dl 1.1 */
265 dl 1.5 public void testContainsValue() {
266 dl 1.1 ConcurrentHashMap map = map5();
267 jsr166 1.17 assertTrue(map.containsValue("A"));
268 dl 1.11 assertFalse(map.containsValue("Z"));
269 dl 1.1 }
270    
271     /**
272 jsr166 1.22 * enumeration returns an enumeration containing the correct
273     * elements
274 dl 1.1 */
275 dl 1.5 public void testEnumeration() {
276 dl 1.1 ConcurrentHashMap map = map5();
277 jsr166 1.17 Enumeration e = map.elements();
278     int count = 0;
279     while (e.hasMoreElements()) {
280     count++;
281     e.nextElement();
282     }
283     assertEquals(5, count);
284 dl 1.4 }
285    
286     /**
287 jsr166 1.22 * get returns the correct element at the given key,
288     * or null if not present
289 dl 1.1 */
290 dl 1.5 public void testGet() {
291 dl 1.1 ConcurrentHashMap map = map5();
292 jsr166 1.17 assertEquals("A", (String)map.get(one));
293 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
294 dl 1.5 assertNull(map.get("anything"));
295 jsr166 1.42 assertNull(empty.get("anything"));
296 dl 1.1 }
297    
298     /**
299 jsr166 1.22 * isEmpty is true of empty map and false for non-empty
300 dl 1.1 */
301 dl 1.5 public void testIsEmpty() {
302 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
303     ConcurrentHashMap map = map5();
304 jsr166 1.17 assertTrue(empty.isEmpty());
305 dl 1.1 assertFalse(map.isEmpty());
306     }
307    
308     /**
309 jsr166 1.22 * keys returns an enumeration containing all the keys from the map
310 dl 1.1 */
311 dl 1.5 public void testKeys() {
312 dl 1.1 ConcurrentHashMap map = map5();
313 jsr166 1.17 Enumeration e = map.keys();
314     int count = 0;
315     while (e.hasMoreElements()) {
316     count++;
317     e.nextElement();
318     }
319     assertEquals(5, count);
320 dl 1.1 }
321    
322     /**
323 jsr166 1.22 * keySet returns a Set containing all the keys
324 dl 1.1 */
325 dl 1.5 public void testKeySet() {
326 dl 1.1 ConcurrentHashMap map = map5();
327 jsr166 1.17 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 dl 1.1 }
335    
336 dl 1.5 /**
337 jsr166 1.50 * 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 jsr166 1.22 * keySet.toArray returns contains all keys
353 dl 1.13 */
354     public void testKeySetToArray() {
355     ConcurrentHashMap map = map5();
356 jsr166 1.17 Set s = map.keySet();
357 dl 1.13 Object[] ar = s.toArray();
358     assertTrue(s.containsAll(Arrays.asList(ar)));
359 jsr166 1.17 assertEquals(5, ar.length);
360 dl 1.13 ar[0] = m10;
361     assertFalse(s.containsAll(Arrays.asList(ar)));
362     }
363    
364     /**
365 jsr166 1.22 * Values.toArray contains all values
366 dl 1.13 */
367     public void testValuesToArray() {
368     ConcurrentHashMap map = map5();
369 jsr166 1.17 Collection v = map.values();
370 dl 1.13 Object[] ar = v.toArray();
371     ArrayList s = new ArrayList(Arrays.asList(ar));
372 jsr166 1.17 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 dl 1.13 }
379    
380     /**
381 jsr166 1.22 * entrySet.toArray contains all entries
382 dl 1.13 */
383     public void testEntrySetToArray() {
384     ConcurrentHashMap map = map5();
385 jsr166 1.17 Set s = map.entrySet();
386 dl 1.13 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     /**
395 dl 1.5 * values collection contains all values
396     */
397     public void testValues() {
398 dl 1.1 ConcurrentHashMap map = map5();
399 jsr166 1.17 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 dl 1.1 }
407    
408 dl 1.5 /**
409     * entrySet contains all pairs
410     */
411     public void testEntrySet() {
412 dl 1.1 ConcurrentHashMap map = map5();
413 jsr166 1.17 Set s = map.entrySet();
414     assertEquals(5, s.size());
415 dl 1.1 Iterator it = s.iterator();
416     while (it.hasNext()) {
417     Map.Entry e = (Map.Entry) it.next();
418 jsr166 1.14 assertTrue(
419 dl 1.1 (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")) ||
422     (e.getKey().equals(four) && e.getValue().equals("D")) ||
423     (e.getKey().equals(five) && e.getValue().equals("E")));
424     }
425     }
426    
427     /**
428 jsr166 1.22 * putAll adds all key-value pairs from the given map
429 dl 1.1 */
430 dl 1.5 public void testPutAll() {
431 dl 1.1 ConcurrentHashMap empty = new ConcurrentHashMap();
432     ConcurrentHashMap map = map5();
433 jsr166 1.17 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 dl 1.1 }
441    
442     /**
443 jsr166 1.22 * putIfAbsent works when the given key is not present
444 dl 1.1 */
445 dl 1.5 public void testPutIfAbsent() {
446 dl 1.1 ConcurrentHashMap map = map5();
447 jsr166 1.17 map.putIfAbsent(six, "Z");
448 dl 1.7 assertTrue(map.containsKey(six));
449 dl 1.1 }
450    
451     /**
452 jsr166 1.22 * putIfAbsent does not add the pair if the key is already present
453 dl 1.1 */
454 dl 1.5 public void testPutIfAbsent2() {
455 dl 1.1 ConcurrentHashMap map = map5();
456     assertEquals("A", map.putIfAbsent(one, "Z"));
457     }
458    
459     /**
460 jsr166 1.22 * replace fails when the given key is not present
461 dl 1.7 */
462     public void testReplace() {
463     ConcurrentHashMap map = map5();
464 jsr166 1.17 assertNull(map.replace(six, "Z"));
465 dl 1.7 assertFalse(map.containsKey(six));
466     }
467    
468     /**
469 jsr166 1.22 * replace succeeds if the key is already present
470 dl 1.7 */
471     public void testReplace2() {
472     ConcurrentHashMap map = map5();
473 dl 1.8 assertNotNull(map.replace(one, "Z"));
474 dl 1.7 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 jsr166 1.17 assertFalse(map.replace(one, "Z", "Z"));
484 dl 1.7 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 jsr166 1.17 assertTrue(map.replace(one, "A", "Z"));
494 dl 1.7 assertEquals("Z", map.get(one));
495     }
496    
497     /**
498 jsr166 1.22 * remove removes the correct key-value pair from the map
499 dl 1.1 */
500 dl 1.5 public void testRemove() {
501 dl 1.1 ConcurrentHashMap map = map5();
502 jsr166 1.17 map.remove(five);
503     assertEquals(4, map.size());
504     assertFalse(map.containsKey(five));
505 dl 1.1 }
506    
507 dl 1.5 /**
508     * remove(key,value) removes only if pair present
509     */
510     public void testRemove2() {
511 dl 1.1 ConcurrentHashMap map = map5();
512 jsr166 1.17 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 dl 1.1 }
519    
520     /**
521 jsr166 1.22 * size returns the correct values
522 dl 1.1 */
523 dl 1.5 public void testSize() {
524 dl 1.1 ConcurrentHashMap map = map5();
525     ConcurrentHashMap empty = new ConcurrentHashMap();
526 jsr166 1.17 assertEquals(0, empty.size());
527     assertEquals(5, map.size());
528 dl 1.1 }
529    
530 dl 1.5 /**
531     * toString contains toString of elements
532     */
533     public void testToString() {
534 dl 1.1 ConcurrentHashMap map = map5();
535     String s = map.toString();
536     for (int i = 1; i <= 5; ++i) {
537 jsr166 1.24 assertTrue(s.contains(String.valueOf(i)));
538 dl 1.1 }
539 jsr166 1.14 }
540 dl 1.1
541     // Exception tests
542 jsr166 1.14
543 dl 1.5 /**
544 dl 1.36 * Cannot create with only negative capacity
545 dl 1.5 */
546     public void testConstructor1() {
547     try {
548 dl 1.36 new ConcurrentHashMap(-1);
549 dl 1.5 shouldThrow();
550 jsr166 1.19 } catch (IllegalArgumentException success) {}
551 dl 1.1 }
552    
553 dl 1.5 /**
554 dl 1.36 * Constructor (initialCapacity, loadFactor) throws
555     * IllegalArgumentException if either argument is negative
556 jsr166 1.47 */
557 dl 1.5 public void testConstructor2() {
558     try {
559 dl 1.36 new ConcurrentHashMap(-1, .75f);
560 dl 1.5 shouldThrow();
561 jsr166 1.43 } catch (IllegalArgumentException success) {}
562 jsr166 1.37
563 dl 1.36 try {
564     new ConcurrentHashMap(16, -1);
565     shouldThrow();
566 jsr166 1.43 } catch (IllegalArgumentException success) {}
567 dl 1.1 }
568 jsr166 1.37
569     /**
570     * Constructor (initialCapacity, loadFactor, concurrencyLevel)
571     * throws IllegalArgumentException if any argument is negative
572     */
573 dl 1.36 public void testConstructor3() {
574 jsr166 1.37 try {
575     new ConcurrentHashMap(-1, .75f, 1);
576     shouldThrow();
577 jsr166 1.43 } catch (IllegalArgumentException success) {}
578 jsr166 1.37
579     try {
580     new ConcurrentHashMap(16, -1, 1);
581     shouldThrow();
582 jsr166 1.43 } catch (IllegalArgumentException success) {}
583 jsr166 1.37
584     try {
585     new ConcurrentHashMap(16, .75f, -1);
586     shouldThrow();
587 jsr166 1.43 } catch (IllegalArgumentException success) {}
588 jsr166 1.37 }
589 dl 1.1
590 dl 1.5 /**
591 dl 1.36 * ConcurrentHashMap(map) throws NullPointerException if the given
592     * map is null
593 dl 1.5 */
594 dl 1.36 public void testConstructor4() {
595 dl 1.5 try {
596 dl 1.36 new ConcurrentHashMap(null);
597 dl 1.5 shouldThrow();
598 jsr166 1.43 } catch (NullPointerException success) {}
599 dl 1.36 }
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 dl 1.1 }
612    
613 dl 1.5 /**
614     * get(null) throws NPE
615     */
616     public void testGet_NullPointerException() {
617 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
618 dl 1.5 try {
619 dl 1.1 c.get(null);
620 dl 1.5 shouldThrow();
621 jsr166 1.19 } catch (NullPointerException success) {}
622 dl 1.1 }
623    
624 dl 1.5 /**
625     * containsKey(null) throws NPE
626     */
627     public void testContainsKey_NullPointerException() {
628 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
629 dl 1.5 try {
630 dl 1.1 c.containsKey(null);
631 dl 1.5 shouldThrow();
632 jsr166 1.19 } catch (NullPointerException success) {}
633 dl 1.1 }
634    
635 dl 1.5 /**
636     * containsValue(null) throws NPE
637     */
638     public void testContainsValue_NullPointerException() {
639 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
640 dl 1.5 try {
641 dl 1.1 c.containsValue(null);
642 dl 1.5 shouldThrow();
643 jsr166 1.19 } catch (NullPointerException success) {}
644 dl 1.1 }
645    
646 dl 1.5 /**
647     * contains(null) throws NPE
648     */
649     public void testContains_NullPointerException() {
650 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
651 dl 1.5 try {
652 dl 1.1 c.contains(null);
653 dl 1.5 shouldThrow();
654 jsr166 1.19 } catch (NullPointerException success) {}
655 dl 1.1 }
656    
657 dl 1.5 /**
658     * put(null,x) throws NPE
659     */
660     public void testPut1_NullPointerException() {
661 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
662 dl 1.5 try {
663 dl 1.1 c.put(null, "whatever");
664 dl 1.5 shouldThrow();
665 jsr166 1.19 } catch (NullPointerException success) {}
666 dl 1.1 }
667    
668 dl 1.5 /**
669     * put(x, null) throws NPE
670     */
671     public void testPut2_NullPointerException() {
672 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
673 dl 1.5 try {
674 dl 1.1 c.put("whatever", null);
675 dl 1.5 shouldThrow();
676 jsr166 1.19 } catch (NullPointerException success) {}
677 dl 1.1 }
678    
679 dl 1.5 /**
680     * putIfAbsent(null, x) throws NPE
681     */
682     public void testPutIfAbsent1_NullPointerException() {
683 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
684 dl 1.5 try {
685 dl 1.1 c.putIfAbsent(null, "whatever");
686 dl 1.5 shouldThrow();
687 jsr166 1.19 } catch (NullPointerException success) {}
688 dl 1.1 }
689    
690 dl 1.5 /**
691 dl 1.7 * replace(null, x) throws NPE
692     */
693     public void testReplace_NullPointerException() {
694 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
695 dl 1.7 try {
696     c.replace(null, "whatever");
697     shouldThrow();
698 jsr166 1.19 } catch (NullPointerException success) {}
699 dl 1.7 }
700    
701     /**
702     * replace(null, x, y) throws NPE
703     */
704     public void testReplaceValue_NullPointerException() {
705 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
706 dl 1.7 try {
707     c.replace(null, one, "whatever");
708     shouldThrow();
709 jsr166 1.19 } catch (NullPointerException success) {}
710 dl 1.7 }
711    
712     /**
713 dl 1.5 * putIfAbsent(x, null) throws NPE
714     */
715     public void testPutIfAbsent2_NullPointerException() {
716 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
717 dl 1.5 try {
718 dl 1.1 c.putIfAbsent("whatever", null);
719 dl 1.7 shouldThrow();
720 jsr166 1.19 } catch (NullPointerException success) {}
721 dl 1.7 }
722    
723     /**
724     * replace(x, null) throws NPE
725     */
726     public void testReplace2_NullPointerException() {
727 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
728 dl 1.7 try {
729     c.replace("whatever", null);
730     shouldThrow();
731 jsr166 1.19 } catch (NullPointerException success) {}
732 dl 1.7 }
733    
734     /**
735     * replace(x, null, y) throws NPE
736     */
737     public void testReplaceValue2_NullPointerException() {
738 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
739 dl 1.7 try {
740     c.replace("whatever", null, "A");
741     shouldThrow();
742 jsr166 1.19 } catch (NullPointerException success) {}
743 dl 1.7 }
744    
745     /**
746     * replace(x, y, null) throws NPE
747     */
748     public void testReplaceValue3_NullPointerException() {
749 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
750 dl 1.7 try {
751     c.replace("whatever", one, null);
752 dl 1.5 shouldThrow();
753 jsr166 1.19 } catch (NullPointerException success) {}
754 dl 1.1 }
755    
756 dl 1.5 /**
757     * remove(null) throws NPE
758     */
759     public void testRemove1_NullPointerException() {
760 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
761     c.put("sadsdf", "asdads");
762 dl 1.5 try {
763 dl 1.1 c.remove(null);
764 dl 1.5 shouldThrow();
765 jsr166 1.19 } catch (NullPointerException success) {}
766 dl 1.1 }
767    
768 dl 1.5 /**
769     * remove(null, x) throws NPE
770     */
771     public void testRemove2_NullPointerException() {
772 jsr166 1.44 ConcurrentHashMap c = new ConcurrentHashMap(5);
773     c.put("sadsdf", "asdads");
774 dl 1.5 try {
775 dl 1.1 c.remove(null, "whatever");
776 dl 1.5 shouldThrow();
777 jsr166 1.19 } catch (NullPointerException success) {}
778 dl 1.1 }
779 dl 1.2
780 dl 1.5 /**
781 dl 1.12 * remove(x, null) returns false
782     */
783     public void testRemove3() {
784 jsr166 1.19 ConcurrentHashMap c = new ConcurrentHashMap(5);
785     c.put("sadsdf", "asdads");
786     assertFalse(c.remove("sadsdf", null));
787 dl 1.12 }
788    
789     /**
790 jsr166 1.55 * A deserialized/reserialized map equals original
791 dl 1.5 */
792 jsr166 1.18 public void testSerialization() throws Exception {
793 jsr166 1.25 Map x = map5();
794     Map y = serialClone(x);
795 dl 1.2
796 jsr166 1.31 assertNotSame(x, y);
797 jsr166 1.25 assertEquals(x.size(), y.size());
798     assertEquals(x, y);
799     assertEquals(y, x);
800 dl 1.2 }
801 dl 1.6
802     /**
803     * SetValue of an EntrySet entry sets value in the map.
804     */
805     public void testSetValueWriteThrough() {
806 jsr166 1.14 // Adapted from a bug report by Eric Zoerner
807 dl 1.6 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 dl 1.29 // 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 dl 1.6 }
823 jsr166 1.14
824 jsr166 1.48 /**
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 jsr166 1.49 final int mapSize = expensiveTests ? 1_000_000 : 100;
830     final int iterations = expensiveTests ? 500 : 2;
831     final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
832 jsr166 1.48 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 jsr166 1.49
841 dl 1.59 public void testReentrantComputeIfAbsent() {
842     ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(16);
843     try {
844     for (int i = 0; i < 100; i++) { // force a resize
845     map.computeIfAbsent(i, key -> findValue(map, key));
846     }
847     fail("recursive computeIfAbsent");
848     } catch (IllegalStateException ex) {
849     }
850     }
851    
852     private Integer findValue(ConcurrentHashMap<Integer, Integer> map,
853     Integer key) {
854     return (key % 5 == 0) ? key :
855     map.computeIfAbsent(key + 1, k -> findValue(map, k));
856     }
857 jsr166 1.60
858 dl 1.1 }