ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMapTest.java
Revision: 1.62
Committed: Sun Sep 29 20:40:48 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.61: +0 -2 lines
Log Message:
add MapTest.testConcurrentAccess

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