blob: 4650f4140b5860066f77977e16f1007fa2ef7efb [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010011import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.Enumeration;
16import java.util.Iterator;
17import java.util.Map;
18import java.util.Random;
19import java.util.Set;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010020import java.util.concurrent.ConcurrentHashMap;
21
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010022import junit.framework.Test;
23import junit.framework.TestSuite;
24
Calin Juravle8f0d92b2013-08-01 17:26:00 +010025public class ConcurrentHashMapTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010026 // android-note: Removed because the CTS runner does a bad job of
27 // retrying tests that have suite() declarations.
28 //
29 // public static void main(String[] args) {
30 // main(suite(), args);
31 // }
32 // public static Test suite() {
33 // return new TestSuite(...);
34 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010035
36 /**
37 * Returns a new map from Integers 1-5 to Strings "A"-"E".
38 */
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010039 private static ConcurrentHashMap<Integer, String> map5() {
40 ConcurrentHashMap map = new ConcurrentHashMap<Integer, String>(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010041 assertTrue(map.isEmpty());
42 map.put(one, "A");
43 map.put(two, "B");
44 map.put(three, "C");
45 map.put(four, "D");
46 map.put(five, "E");
47 assertFalse(map.isEmpty());
48 assertEquals(5, map.size());
49 return map;
50 }
51
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010052 /** Re-implement Integer.compare for old java versions */
53 static int compare(int x, int y) { return x < y ? -1 : x > y ? 1 : 0; }
54
Calin Juravle8f0d92b2013-08-01 17:26:00 +010055 // classes for testing Comparable fallbacks
56 static class BI implements Comparable<BI> {
57 private final int value;
58 BI(int value) { this.value = value; }
59 public int compareTo(BI other) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010060 return compare(value, other.value);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010061 }
62 public boolean equals(Object x) {
63 return (x instanceof BI) && ((BI)x).value == value;
64 }
65 public int hashCode() { return 42; }
66 }
67 static class CI extends BI { CI(int value) { super(value); } }
68 static class DI extends BI { DI(int value) { super(value); } }
69
70 static class BS implements Comparable<BS> {
71 private final String value;
72 BS(String value) { this.value = value; }
73 public int compareTo(BS other) {
74 return value.compareTo(other.value);
75 }
76 public boolean equals(Object x) {
77 return (x instanceof BS) && value.equals(((BS)x).value);
78 }
79 public int hashCode() { return 42; }
80 }
81
82 static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
83 implements Comparable<LexicographicList<E>> {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010084 LexicographicList(Collection<E> c) { super(c); }
85 LexicographicList(E e) { super(Collections.singleton(e)); }
86 public int compareTo(LexicographicList<E> other) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010087 int common = Math.min(size(), other.size());
88 int r = 0;
89 for (int i = 0; i < common; i++) {
90 if ((r = get(i).compareTo(other.get(i))) != 0)
91 break;
92 }
93 if (r == 0)
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010094 r = compare(size(), other.size());
Calin Juravle8f0d92b2013-08-01 17:26:00 +010095 return r;
96 }
97 private static final long serialVersionUID = 0;
98 }
99
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100100 static class CollidingObject {
101 final String value;
102 CollidingObject(final String value) { this.value = value; }
103 public int hashCode() { return this.value.hashCode() & 1; }
104 public boolean equals(final Object obj) {
105 return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value);
106 }
107 }
108
109 static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> {
110 ComparableCollidingObject(final String value) { super(value); }
111 public int compareTo(final ComparableCollidingObject o) {
112 return value.compareTo(o.value);
113 }
114 }
115
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100116 /**
117 * Inserted elements that are subclasses of the same Comparable
118 * class are found.
119 */
120 public void testComparableFamily() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100121 int size = 500; // makes measured test run time -> 60ms
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100122 ConcurrentHashMap<BI, Boolean> m =
123 new ConcurrentHashMap<BI, Boolean>();
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100124 for (int i = 0; i < size; i++) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100125 assertTrue(m.put(new CI(i), true) == null);
126 }
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100127 for (int i = 0; i < size; i++) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100128 assertTrue(m.containsKey(new CI(i)));
129 assertTrue(m.containsKey(new DI(i)));
130 }
131 }
132
133 /**
134 * Elements of classes with erased generic type parameters based
135 * on Comparable can be inserted and found.
136 */
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100137 public void testGenericComparable() {
138 int size = 120; // makes measured test run time -> 60ms
139 ConcurrentHashMap<Object, Boolean> m =
140 new ConcurrentHashMap<Object, Boolean>();
141 for (int i = 0; i < size; i++) {
142 BI bi = new BI(i);
143 BS bs = new BS(String.valueOf(i));
144 LexicographicList<BI> bis = new LexicographicList<BI>(bi);
145 LexicographicList<BS> bss = new LexicographicList<BS>(bs);
146 assertTrue(m.putIfAbsent(bis, true) == null);
147 assertTrue(m.containsKey(bis));
148 if (m.putIfAbsent(bss, true) == null)
149 assertTrue(m.containsKey(bss));
150 assertTrue(m.containsKey(bis));
151 }
152 for (int i = 0; i < size; i++) {
153 assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
154 }
155 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100156
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() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100163 int size = 500; // makes measured test run time -> 60ms
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100164 ConcurrentHashMap<Object, Boolean> m =
165 new ConcurrentHashMap<Object, Boolean>();
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100166 for (int i = 0; i < size; i++) {
167 m.put(Collections.singletonList(new BI(i)), true);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100168 }
169
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100170 for (int i = 0; i < size; i++) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100171 LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i));
172 assertTrue(m.containsKey(bis));
173 }
174 }
175
176 /**
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100177 * Mixtures of instances of comparable and non-comparable classes
178 * can be inserted and found.
179 */
180 public void testMixedComparable() {
181 int size = 1200; // makes measured test run time -> 35ms
182 ConcurrentHashMap<Object, Object> map =
183 new ConcurrentHashMap<Object, Object>();
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 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100212 * clear removes all pairs
213 */
214 public void testClear() {
215 ConcurrentHashMap map = map5();
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 /**
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100234 * 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 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100245 * contains returns true for contained value
246 */
247 public void testContains() {
248 ConcurrentHashMap map = map5();
249 assertTrue(map.contains("A"));
250 assertFalse(map.contains("Z"));
251 }
252
253 /**
254 * containsKey returns true for contained key
255 */
256 public void testContainsKey() {
257 ConcurrentHashMap map = map5();
258 assertTrue(map.containsKey(one));
259 assertFalse(map.containsKey(zero));
260 }
261
262 /**
263 * containsValue returns true for held values
264 */
265 public void testContainsValue() {
266 ConcurrentHashMap map = map5();
267 assertTrue(map.containsValue("A"));
268 assertFalse(map.containsValue("Z"));
269 }
270
271 /**
272 * enumeration returns an enumeration containing the correct
273 * elements
274 */
275 public void testEnumeration() {
276 ConcurrentHashMap map = map5();
277 Enumeration e = map.elements();
278 int count = 0;
279 while (e.hasMoreElements()) {
280 count++;
281 e.nextElement();
282 }
283 assertEquals(5, count);
284 }
285
286 /**
287 * get returns the correct element at the given key,
288 * or null if not present
289 */
290 public void testGet() {
291 ConcurrentHashMap map = map5();
292 assertEquals("A", (String)map.get(one));
293 ConcurrentHashMap empty = new ConcurrentHashMap();
294 assertNull(map.get("anything"));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100295 assertNull(empty.get("anything"));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100296 }
297
298 /**
299 * isEmpty is true of empty map and false for non-empty
300 */
301 public void testIsEmpty() {
302 ConcurrentHashMap empty = new ConcurrentHashMap();
303 ConcurrentHashMap map = map5();
304 assertTrue(empty.isEmpty());
305 assertFalse(map.isEmpty());
306 }
307
308 /**
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 * keySet.toArray returns contains all keys
338 */
339 public void testKeySetToArray() {
340 ConcurrentHashMap map = map5();
341 Set s = map.keySet();
342 Object[] ar = s.toArray();
343 assertTrue(s.containsAll(Arrays.asList(ar)));
344 assertEquals(5, ar.length);
345 ar[0] = m10;
346 assertFalse(s.containsAll(Arrays.asList(ar)));
347 }
348
349 /**
350 * Values.toArray contains all values
351 */
352 public void testValuesToArray() {
353 ConcurrentHashMap map = map5();
354 Collection v = map.values();
355 Object[] ar = v.toArray();
356 ArrayList s = new ArrayList(Arrays.asList(ar));
357 assertEquals(5, ar.length);
358 assertTrue(s.contains("A"));
359 assertTrue(s.contains("B"));
360 assertTrue(s.contains("C"));
361 assertTrue(s.contains("D"));
362 assertTrue(s.contains("E"));
363 }
364
365 /**
366 * entrySet.toArray contains all entries
367 */
368 public void testEntrySetToArray() {
369 ConcurrentHashMap map = map5();
370 Set s = map.entrySet();
371 Object[] ar = s.toArray();
372 assertEquals(5, ar.length);
373 for (int i = 0; i < 5; ++i) {
374 assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
375 assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
376 }
377 }
378
379 /**
380 * values collection contains all values
381 */
382 public void testValues() {
383 ConcurrentHashMap map = map5();
384 Collection s = map.values();
385 assertEquals(5, s.size());
386 assertTrue(s.contains("A"));
387 assertTrue(s.contains("B"));
388 assertTrue(s.contains("C"));
389 assertTrue(s.contains("D"));
390 assertTrue(s.contains("E"));
391 }
392
393 /**
394 * entrySet contains all pairs
395 */
396 public void testEntrySet() {
397 ConcurrentHashMap map = map5();
398 Set s = map.entrySet();
399 assertEquals(5, s.size());
400 Iterator it = s.iterator();
401 while (it.hasNext()) {
402 Map.Entry e = (Map.Entry) it.next();
403 assertTrue(
404 (e.getKey().equals(one) && e.getValue().equals("A")) ||
405 (e.getKey().equals(two) && e.getValue().equals("B")) ||
406 (e.getKey().equals(three) && e.getValue().equals("C")) ||
407 (e.getKey().equals(four) && e.getValue().equals("D")) ||
408 (e.getKey().equals(five) && e.getValue().equals("E")));
409 }
410 }
411
412 /**
413 * putAll adds all key-value pairs from the given map
414 */
415 public void testPutAll() {
416 ConcurrentHashMap empty = new ConcurrentHashMap();
417 ConcurrentHashMap map = map5();
418 empty.putAll(map);
419 assertEquals(5, empty.size());
420 assertTrue(empty.containsKey(one));
421 assertTrue(empty.containsKey(two));
422 assertTrue(empty.containsKey(three));
423 assertTrue(empty.containsKey(four));
424 assertTrue(empty.containsKey(five));
425 }
426
427 /**
428 * putIfAbsent works when the given key is not present
429 */
430 public void testPutIfAbsent() {
431 ConcurrentHashMap map = map5();
432 map.putIfAbsent(six, "Z");
433 assertTrue(map.containsKey(six));
434 }
435
436 /**
437 * putIfAbsent does not add the pair if the key is already present
438 */
439 public void testPutIfAbsent2() {
440 ConcurrentHashMap map = map5();
441 assertEquals("A", map.putIfAbsent(one, "Z"));
442 }
443
444 /**
445 * replace fails when the given key is not present
446 */
447 public void testReplace() {
448 ConcurrentHashMap map = map5();
449 assertNull(map.replace(six, "Z"));
450 assertFalse(map.containsKey(six));
451 }
452
453 /**
454 * replace succeeds if the key is already present
455 */
456 public void testReplace2() {
457 ConcurrentHashMap map = map5();
458 assertNotNull(map.replace(one, "Z"));
459 assertEquals("Z", map.get(one));
460 }
461
462 /**
463 * replace value fails when the given key not mapped to expected value
464 */
465 public void testReplaceValue() {
466 ConcurrentHashMap map = map5();
467 assertEquals("A", map.get(one));
468 assertFalse(map.replace(one, "Z", "Z"));
469 assertEquals("A", map.get(one));
470 }
471
472 /**
473 * replace value succeeds when the given key mapped to expected value
474 */
475 public void testReplaceValue2() {
476 ConcurrentHashMap map = map5();
477 assertEquals("A", map.get(one));
478 assertTrue(map.replace(one, "A", "Z"));
479 assertEquals("Z", map.get(one));
480 }
481
482 /**
483 * remove removes the correct key-value pair from the map
484 */
485 public void testRemove() {
486 ConcurrentHashMap map = map5();
487 map.remove(five);
488 assertEquals(4, map.size());
489 assertFalse(map.containsKey(five));
490 }
491
492 /**
493 * remove(key,value) removes only if pair present
494 */
495 public void testRemove2() {
496 ConcurrentHashMap map = map5();
497 map.remove(five, "E");
498 assertEquals(4, map.size());
499 assertFalse(map.containsKey(five));
500 map.remove(four, "A");
501 assertEquals(4, map.size());
502 assertTrue(map.containsKey(four));
503 }
504
505 /**
506 * size returns the correct values
507 */
508 public void testSize() {
509 ConcurrentHashMap map = map5();
510 ConcurrentHashMap empty = new ConcurrentHashMap();
511 assertEquals(0, empty.size());
512 assertEquals(5, map.size());
513 }
514
515 /**
516 * toString contains toString of elements
517 */
518 public void testToString() {
519 ConcurrentHashMap map = map5();
520 String s = map.toString();
521 for (int i = 1; i <= 5; ++i) {
522 assertTrue(s.contains(String.valueOf(i)));
523 }
524 }
525
526 // Exception tests
527
528 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100529 * Cannot create with only negative capacity
530 */
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100531 public void testConstructor1() {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100532 try {
533 new ConcurrentHashMap(-1);
534 shouldThrow();
535 } catch (IllegalArgumentException success) {}
536 }
537
538 /**
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100539 * Constructor (initialCapacity, loadFactor) throws
540 * IllegalArgumentException if either argument is negative
541 */
542 public void testConstructor2() {
543 try {
544 new ConcurrentHashMap(-1, .75f);
545 shouldThrow();
546 } catch (IllegalArgumentException success) {}
547
548 try {
549 new ConcurrentHashMap(16, -1);
550 shouldThrow();
551 } catch (IllegalArgumentException success) {}
552 }
553
554 /**
555 * Constructor (initialCapacity, loadFactor, concurrencyLevel)
556 * throws IllegalArgumentException if any argument is negative
557 */
558 public void testConstructor3() {
559 try {
560 new ConcurrentHashMap(-1, .75f, 1);
561 shouldThrow();
562 } catch (IllegalArgumentException success) {}
563
564 try {
565 new ConcurrentHashMap(16, -1, 1);
566 shouldThrow();
567 } catch (IllegalArgumentException success) {}
568
569 try {
570 new ConcurrentHashMap(16, .75f, -1);
571 shouldThrow();
572 } catch (IllegalArgumentException success) {}
573 }
574
575 /**
576 * ConcurrentHashMap(map) throws NullPointerException if the given
577 * map is null
578 */
579 public void testConstructor4() {
580 try {
581 new ConcurrentHashMap(null);
582 shouldThrow();
583 } catch (NullPointerException success) {}
584 }
585
586 /**
587 * ConcurrentHashMap(map) creates a new map with the same mappings
588 * as the given map
589 */
590 public void testConstructor5() {
591 ConcurrentHashMap map1 = map5();
592 ConcurrentHashMap map2 = new ConcurrentHashMap(map5());
593 assertTrue(map2.equals(map1));
594 map2.put(one, "F");
595 assertFalse(map2.equals(map1));
596 }
597
598 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100599 * get(null) throws NPE
600 */
601 public void testGet_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100602 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100603 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100604 c.get(null);
605 shouldThrow();
606 } catch (NullPointerException success) {}
607 }
608
609 /**
610 * containsKey(null) throws NPE
611 */
612 public void testContainsKey_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100613 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100614 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100615 c.containsKey(null);
616 shouldThrow();
617 } catch (NullPointerException success) {}
618 }
619
620 /**
621 * containsValue(null) throws NPE
622 */
623 public void testContainsValue_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100624 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100625 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100626 c.containsValue(null);
627 shouldThrow();
628 } catch (NullPointerException success) {}
629 }
630
631 /**
632 * contains(null) throws NPE
633 */
634 public void testContains_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100635 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100636 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100637 c.contains(null);
638 shouldThrow();
639 } catch (NullPointerException success) {}
640 }
641
642 /**
643 * put(null,x) throws NPE
644 */
645 public void testPut1_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100646 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100647 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100648 c.put(null, "whatever");
649 shouldThrow();
650 } catch (NullPointerException success) {}
651 }
652
653 /**
654 * put(x, null) throws NPE
655 */
656 public void testPut2_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100657 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100658 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100659 c.put("whatever", null);
660 shouldThrow();
661 } catch (NullPointerException success) {}
662 }
663
664 /**
665 * putIfAbsent(null, x) throws NPE
666 */
667 public void testPutIfAbsent1_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100668 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100669 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100670 c.putIfAbsent(null, "whatever");
671 shouldThrow();
672 } catch (NullPointerException success) {}
673 }
674
675 /**
676 * replace(null, x) throws NPE
677 */
678 public void testReplace_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100679 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100680 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100681 c.replace(null, "whatever");
682 shouldThrow();
683 } catch (NullPointerException success) {}
684 }
685
686 /**
687 * replace(null, x, y) throws NPE
688 */
689 public void testReplaceValue_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100690 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100691 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100692 c.replace(null, one, "whatever");
693 shouldThrow();
694 } catch (NullPointerException success) {}
695 }
696
697 /**
698 * putIfAbsent(x, null) throws NPE
699 */
700 public void testPutIfAbsent2_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100701 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100702 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100703 c.putIfAbsent("whatever", null);
704 shouldThrow();
705 } catch (NullPointerException success) {}
706 }
707
708 /**
709 * replace(x, null) throws NPE
710 */
711 public void testReplace2_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100712 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100713 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100714 c.replace("whatever", null);
715 shouldThrow();
716 } catch (NullPointerException success) {}
717 }
718
719 /**
720 * replace(x, null, y) throws NPE
721 */
722 public void testReplaceValue2_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100723 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100724 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100725 c.replace("whatever", null, "A");
726 shouldThrow();
727 } catch (NullPointerException success) {}
728 }
729
730 /**
731 * replace(x, y, null) throws NPE
732 */
733 public void testReplaceValue3_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100734 ConcurrentHashMap c = new ConcurrentHashMap(5);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100735 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100736 c.replace("whatever", one, null);
737 shouldThrow();
738 } catch (NullPointerException success) {}
739 }
740
741 /**
742 * remove(null) throws NPE
743 */
744 public void testRemove1_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100745 ConcurrentHashMap c = new ConcurrentHashMap(5);
746 c.put("sadsdf", "asdads");
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100747 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100748 c.remove(null);
749 shouldThrow();
750 } catch (NullPointerException success) {}
751 }
752
753 /**
754 * remove(null, x) throws NPE
755 */
756 public void testRemove2_NullPointerException() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100757 ConcurrentHashMap c = new ConcurrentHashMap(5);
758 c.put("sadsdf", "asdads");
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100759 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100760 c.remove(null, "whatever");
761 shouldThrow();
762 } catch (NullPointerException success) {}
763 }
764
765 /**
766 * remove(x, null) returns false
767 */
768 public void testRemove3() {
769 ConcurrentHashMap c = new ConcurrentHashMap(5);
770 c.put("sadsdf", "asdads");
771 assertFalse(c.remove("sadsdf", null));
772 }
773
774 /**
775 * A deserialized map equals original
776 */
777 public void testSerialization() throws Exception {
778 Map x = map5();
779 Map y = serialClone(x);
780
781 assertNotSame(x, y);
782 assertEquals(x.size(), y.size());
783 assertEquals(x, y);
784 assertEquals(y, x);
785 }
786
787 /**
788 * SetValue of an EntrySet entry sets value in the map.
789 */
790 public void testSetValueWriteThrough() {
791 // Adapted from a bug report by Eric Zoerner
792 ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
793 assertTrue(map.isEmpty());
794 for (int i = 0; i < 20; i++)
795 map.put(new Integer(i), new Integer(i));
796 assertFalse(map.isEmpty());
797 Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
798 // Unless it happens to be first (in which case remainder of
799 // test is skipped), remove a possibly-colliding key from map
800 // which, under some implementations, may cause entry1 to be
801 // cloned in map
802 if (!entry1.getKey().equals(new Integer(16))) {
803 map.remove(new Integer(16));
804 entry1.setValue("XYZ");
805 assertTrue(map.containsValue("XYZ")); // fails if write-through broken
806 }
807 }
808
809}