• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect.testing;
18 
19 import java.util.concurrent.ConcurrentMap;
20 
21 /**
22  * Tests representing the contract of {@link ConcurrentMap}. Concrete
23  * subclasses of this base class test conformance of concrete
24  * {@link ConcurrentMap} subclasses to that contract.
25  *
26  * <p>This class is GWT compatible.
27  *
28  * <p>The tests in this class for null keys and values only check maps for
29  * which null keys and values are not allowed. There are currently no
30  * {@link ConcurrentMap} implementations that support nulls.
31  *
32  * @author Jared Levy
33  */
34 public abstract class ConcurrentMapInterfaceTest<K, V>
35     extends MapInterfaceTest<K, V> {
36 
ConcurrentMapInterfaceTest(boolean allowsNullKeys, boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, boolean supportsClear)37   protected ConcurrentMapInterfaceTest(boolean allowsNullKeys,
38       boolean allowsNullValues, boolean supportsPut, boolean supportsRemove,
39       boolean supportsClear) {
40     super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove,
41         supportsClear);
42   }
43 
44   /**
45    * Creates a new value that is not expected to be found in
46    * {@link #makePopulatedMap()} and differs from the value returned by
47    * {@link #getValueNotInPopulatedMap()}.
48    *
49    * @return a value
50    * @throws UnsupportedOperationException if it's not possible to make a value
51    * that will not be found in the map
52    */
getSecondValueNotInPopulatedMap()53   protected abstract V getSecondValueNotInPopulatedMap()
54       throws UnsupportedOperationException;
55 
makeEmptyMap()56   @Override protected abstract ConcurrentMap<K, V> makeEmptyMap()
57       throws UnsupportedOperationException;
58 
makePopulatedMap()59   @Override protected abstract ConcurrentMap<K, V> makePopulatedMap()
60       throws UnsupportedOperationException;
61 
makeEitherMap()62   @Override protected ConcurrentMap<K, V> makeEitherMap() {
63     try {
64       return makePopulatedMap();
65     } catch (UnsupportedOperationException e) {
66       return makeEmptyMap();
67     }
68   }
69 
testPutIfAbsentNewKey()70   public void testPutIfAbsentNewKey() {
71     final ConcurrentMap<K, V> map;
72     final K keyToPut;
73     final V valueToPut;
74     try {
75       map = makeEitherMap();
76       keyToPut = getKeyNotInPopulatedMap();
77       valueToPut = getValueNotInPopulatedMap();
78     } catch (UnsupportedOperationException e) {
79       return;
80     }
81     if (supportsPut) {
82       int initialSize = map.size();
83       V oldValue = map.putIfAbsent(keyToPut, valueToPut);
84       assertEquals(valueToPut, map.get(keyToPut));
85       assertTrue(map.containsKey(keyToPut));
86       assertTrue(map.containsValue(valueToPut));
87       assertEquals(initialSize + 1, map.size());
88       assertNull(oldValue);
89     } else {
90       try {
91         map.putIfAbsent(keyToPut, valueToPut);
92         fail("Expected UnsupportedOperationException.");
93       } catch (UnsupportedOperationException e) {
94         // Expected.
95       }
96     }
97     assertInvariants(map);
98   }
99 
testPutIfAbsentExistingKey()100   public void testPutIfAbsentExistingKey() {
101     final ConcurrentMap<K, V> map;
102     final K keyToPut;
103     final V valueToPut;
104     try {
105       map = makePopulatedMap();
106       valueToPut = getValueNotInPopulatedMap();
107     } catch (UnsupportedOperationException e) {
108       return;
109     }
110     keyToPut = map.keySet().iterator().next();
111     if (supportsPut) {
112       V oldValue = map.get(keyToPut);
113       int initialSize = map.size();
114       assertEquals(oldValue, map.putIfAbsent(keyToPut, valueToPut));
115       assertEquals(oldValue, map.get(keyToPut));
116       assertTrue(map.containsKey(keyToPut));
117       assertTrue(map.containsValue(oldValue));
118       assertFalse(map.containsValue(valueToPut));
119       assertEquals(initialSize, map.size());
120     } else {
121       try {
122         map.putIfAbsent(keyToPut, valueToPut);
123         fail("Expected UnsupportedOperationException.");
124       } catch (UnsupportedOperationException e) {
125         // Expected.
126       }
127     }
128     assertInvariants(map);
129   }
130 
testPutIfAbsentNullKey()131   public void testPutIfAbsentNullKey() {
132     if (allowsNullKeys) {
133       return;   // Not yet implemented
134     }
135     final ConcurrentMap<K, V> map;
136     final V valueToPut;
137     try {
138       map = makeEitherMap();
139       valueToPut = getValueNotInPopulatedMap();
140     } catch (UnsupportedOperationException e) {
141       return;
142     }
143     int initialSize = map.size();
144     if (supportsPut) {
145       try {
146         map.putIfAbsent(null, valueToPut);
147         fail("Expected NullPointerException");
148       } catch (NullPointerException e) {
149         // Expected.
150       }
151     } else {
152       try {
153         map.putIfAbsent(null, valueToPut);
154         fail("Expected UnsupportedOperationException or NullPointerException");
155       } catch (UnsupportedOperationException e) {
156         // Expected.
157       } catch (NullPointerException e) {
158         // Expected.
159       }
160     }
161     assertEquals(initialSize, map.size());
162     assertInvariants(map);
163   }
164 
testPutIfAbsentNewKeyNullValue()165   public void testPutIfAbsentNewKeyNullValue() {
166     if (allowsNullValues) {
167       return;   // Not yet implemented
168     }
169     final ConcurrentMap<K, V> map;
170     final K keyToPut;
171     try {
172       map = makeEitherMap();
173       keyToPut = getKeyNotInPopulatedMap();
174     } catch (UnsupportedOperationException e) {
175       return;
176     }
177     int initialSize = map.size();
178     if (supportsPut) {
179       try {
180         map.putIfAbsent(keyToPut, null);
181         fail("Expected NullPointerException");
182       } catch (NullPointerException e) {
183         // Expected.
184       }
185     } else {
186       try {
187         map.putIfAbsent(keyToPut, null);
188         fail("Expected UnsupportedOperationException or NullPointerException");
189       } catch (UnsupportedOperationException e) {
190         // Expected.
191       } catch (NullPointerException e) {
192         // Expected.
193       }
194     }
195     assertEquals(initialSize, map.size());
196     assertInvariants(map);
197   }
198 
testPutIfAbsentExistingKeyNullValue()199   public void testPutIfAbsentExistingKeyNullValue() {
200     if (allowsNullValues) {
201       return;   // Not yet implemented
202     }
203     final ConcurrentMap<K, V> map;
204     final K keyToPut;
205     try {
206       map = makePopulatedMap();
207     } catch (UnsupportedOperationException e) {
208       return;
209     }
210     keyToPut = map.keySet().iterator().next();
211     int initialSize = map.size();
212     if (supportsPut) {
213       try {
214         assertNull(map.putIfAbsent(keyToPut, null));
215       } catch (NullPointerException e) {
216         // Optional.
217       }
218     } else {
219       try {
220         map.putIfAbsent(keyToPut, null);
221         fail("Expected UnsupportedOperationException or NullPointerException");
222       } catch (UnsupportedOperationException e) {
223         // Expected.
224       } catch (NullPointerException e) {
225         // Expected.
226       }
227     }
228     assertEquals(initialSize, map.size());
229     assertInvariants(map);
230   }
231 
testRemoveKeyValueExisting()232   public void testRemoveKeyValueExisting() {
233     final ConcurrentMap<K, V> map;
234     final K keyToRemove;
235     try {
236       map = makePopulatedMap();
237     } catch (UnsupportedOperationException e) {
238       return;
239     }
240     keyToRemove = map.keySet().iterator().next();
241     V oldValue = map.get(keyToRemove);
242     if (supportsRemove) {
243       int initialSize = map.size();
244       assertTrue(map.remove(keyToRemove, oldValue));
245       assertFalse(map.containsKey(keyToRemove));
246       assertEquals(initialSize - 1, map.size());
247     } else {
248       try {
249         map.remove(keyToRemove, oldValue);
250         fail("Expected UnsupportedOperationException.");
251       } catch (UnsupportedOperationException e) {
252         // Expected.
253       }
254     }
255     assertInvariants(map);
256   }
257 
testRemoveKeyValueMissingKey()258   public void testRemoveKeyValueMissingKey() {
259     final ConcurrentMap<K, V> map;
260     final K keyToRemove;
261     final V valueToRemove;
262     try {
263       map = makePopulatedMap();
264       keyToRemove = getKeyNotInPopulatedMap();
265       valueToRemove = getValueNotInPopulatedMap();
266     } catch (UnsupportedOperationException e) {
267       return;
268     }
269     if (supportsRemove) {
270       int initialSize = map.size();
271       assertFalse(map.remove(keyToRemove, valueToRemove));
272       assertEquals(initialSize, map.size());
273     } else {
274       try {
275         map.remove(keyToRemove, valueToRemove);
276         fail("Expected UnsupportedOperationException.");
277       } catch (UnsupportedOperationException e) {
278         // Expected.
279       }
280     }
281     assertInvariants(map);
282   }
283 
testRemoveKeyValueDifferentValue()284   public void testRemoveKeyValueDifferentValue() {
285     final ConcurrentMap<K, V> map;
286     final K keyToRemove;
287     final V valueToRemove;
288     try {
289       map = makePopulatedMap();
290       valueToRemove = getValueNotInPopulatedMap();
291     } catch (UnsupportedOperationException e) {
292       return;
293     }
294     keyToRemove = map.keySet().iterator().next();
295     if (supportsRemove) {
296       int initialSize = map.size();
297       V oldValue = map.get(keyToRemove);
298       assertFalse(map.remove(keyToRemove, valueToRemove));
299       assertEquals(oldValue, map.get(keyToRemove));
300       assertTrue(map.containsKey(keyToRemove));
301       assertEquals(initialSize, map.size());
302     } else {
303       try {
304         map.remove(keyToRemove, valueToRemove);
305         fail("Expected UnsupportedOperationException.");
306       } catch (UnsupportedOperationException e) {
307         // Expected.
308       }
309     }
310     assertInvariants(map);
311   }
312 
testRemoveKeyValueNullKey()313   public void testRemoveKeyValueNullKey() {
314     if (allowsNullKeys) {
315       return;   // Not yet implemented
316     }
317     final ConcurrentMap<K, V> map;
318     final V valueToRemove;
319     try {
320       map = makeEitherMap();
321       valueToRemove = getValueNotInPopulatedMap();
322     } catch (UnsupportedOperationException e) {
323       return;
324     }
325     int initialSize = map.size();
326     if (supportsRemove) {
327       try {
328         assertFalse(map.remove(null, valueToRemove));
329       } catch (NullPointerException e) {
330         // Optional.
331       }
332     } else {
333       try {
334         assertFalse(map.remove(null, valueToRemove));
335       } catch (UnsupportedOperationException e) {
336         // Optional.
337       } catch (NullPointerException e) {
338         // Optional.
339       }
340     }
341     assertEquals(initialSize, map.size());
342     assertInvariants(map);
343   }
344 
testRemoveKeyValueExistingKeyNullValue()345   public void testRemoveKeyValueExistingKeyNullValue() {
346     if (allowsNullValues) {
347       return;   // Not yet implemented
348     }
349     final ConcurrentMap<K, V> map;
350     final K keyToRemove;
351     try {
352       map = makePopulatedMap();
353     } catch (UnsupportedOperationException e) {
354       return;
355     }
356     keyToRemove = map.keySet().iterator().next();
357     int initialSize = map.size();
358     if (supportsRemove) {
359       try {
360         assertFalse(map.remove(keyToRemove, null));
361       } catch (NullPointerException e) {
362         // Optional.
363       }
364     } else {
365       try {
366         assertFalse(map.remove(keyToRemove, null));
367       } catch (UnsupportedOperationException e) {
368         // Optional.
369       } catch (NullPointerException e) {
370         // Optional.
371       }
372     }
373     assertEquals(initialSize, map.size());
374     assertInvariants(map);
375   }
376 
testRemoveKeyValueMissingKeyNullValue()377   public void testRemoveKeyValueMissingKeyNullValue() {
378     if (allowsNullValues) {
379       return;   // Not yet implemented
380     }
381     final ConcurrentMap<K, V> map;
382     final K keyToRemove;
383     try {
384       map = makeEitherMap();
385       keyToRemove = getKeyNotInPopulatedMap();
386     } catch (UnsupportedOperationException e) {
387       return;
388     }
389     int initialSize = map.size();
390     if (supportsRemove) {
391       try {
392         assertFalse(map.remove(keyToRemove, null));
393       } catch (NullPointerException e) {
394         // Optional.
395       }
396     } else {
397       try {
398         assertFalse(map.remove(keyToRemove, null));
399       } catch (UnsupportedOperationException e) {
400         // Optional.
401       } catch (NullPointerException e) {
402         // Optional.
403       }
404     }
405     assertEquals(initialSize, map.size());
406     assertInvariants(map);
407   }
408 
409   /* Replace2 tests call 2-parameter replace(key, value) */
410 
testReplace2ExistingKey()411   public void testReplace2ExistingKey() {
412     final ConcurrentMap<K, V> map;
413     final K keyToReplace;
414     final V newValue;
415     try {
416       map = makePopulatedMap();
417       newValue = getValueNotInPopulatedMap();
418     } catch (UnsupportedOperationException e) {
419       return;
420     }
421     keyToReplace = map.keySet().iterator().next();
422     if (supportsPut) {
423       V oldValue = map.get(keyToReplace);
424       int initialSize = map.size();
425       assertEquals(oldValue, map.replace(keyToReplace, newValue));
426       assertEquals(newValue, map.get(keyToReplace));
427       assertTrue(map.containsKey(keyToReplace));
428       assertTrue(map.containsValue(newValue));
429       assertEquals(initialSize, map.size());
430     } else {
431       try {
432         map.replace(keyToReplace, newValue);
433         fail("Expected UnsupportedOperationException.");
434       } catch (UnsupportedOperationException e) {
435         // Expected.
436       }
437     }
438     assertInvariants(map);
439   }
440 
testReplace2MissingKey()441   public void testReplace2MissingKey() {
442     final ConcurrentMap<K, V> map;
443     final K keyToReplace;
444     final V newValue;
445     try {
446       map = makeEitherMap();
447       keyToReplace = getKeyNotInPopulatedMap();
448       newValue = getValueNotInPopulatedMap();
449     } catch (UnsupportedOperationException e) {
450       return;
451     }
452     if (supportsPut) {
453       int initialSize = map.size();
454       assertNull(map.replace(keyToReplace, newValue));
455       assertNull(map.get(keyToReplace));
456       assertFalse(map.containsKey(keyToReplace));
457       assertFalse(map.containsValue(newValue));
458       assertEquals(initialSize, map.size());
459     } else {
460       try {
461         map.replace(keyToReplace, newValue);
462         fail("Expected UnsupportedOperationException.");
463       } catch (UnsupportedOperationException e) {
464         // Expected.
465       }
466     }
467     assertInvariants(map);
468   }
469 
testReplace2NullKey()470   public void testReplace2NullKey() {
471     if (allowsNullKeys) {
472       return;   // Not yet implemented
473     }
474     final ConcurrentMap<K, V> map;
475     final V valueToReplace;
476     try {
477       map = makeEitherMap();
478       valueToReplace = getValueNotInPopulatedMap();
479     } catch (UnsupportedOperationException e) {
480       return;
481     }
482     int initialSize = map.size();
483     if (supportsPut) {
484       try {
485         assertNull(map.replace(null, valueToReplace));
486       } catch (NullPointerException e) {
487         // Optional.
488       }
489     } else {
490       try {
491         assertNull(map.replace(null, valueToReplace));
492       } catch (UnsupportedOperationException e) {
493         // Optional.
494       } catch (NullPointerException e) {
495         // Optional.
496       }
497     }
498     assertEquals(initialSize, map.size());
499     assertInvariants(map);
500   }
501 
testReplace2ExistingKeyNullValue()502   public void testReplace2ExistingKeyNullValue() {
503     if (allowsNullValues) {
504       return;   // Not yet implemented
505     }
506     final ConcurrentMap<K, V> map;
507     final K keyToReplace;
508     try {
509       map = makePopulatedMap();
510     } catch (UnsupportedOperationException e) {
511       return;
512     }
513     keyToReplace = map.keySet().iterator().next();
514     int initialSize = map.size();
515     if (supportsPut) {
516       try {
517         map.replace(keyToReplace, null);
518         fail("Expected NullPointerException");
519       } catch (NullPointerException e) {
520         // Expected.
521       }
522     } else {
523       try {
524         map.replace(keyToReplace, null);
525         fail("Expected UnsupportedOperationException or NullPointerException");
526       } catch (UnsupportedOperationException e) {
527         // Expected.
528       } catch (NullPointerException e) {
529         // Expected.
530       }
531     }
532     assertEquals(initialSize, map.size());
533     assertInvariants(map);
534   }
535 
testReplace2MissingKeyNullValue()536   public void testReplace2MissingKeyNullValue() {
537     if (allowsNullValues) {
538       return;   // Not yet implemented
539     }
540     final ConcurrentMap<K, V> map;
541     final K keyToReplace;
542     try {
543       map = makeEitherMap();
544       keyToReplace = getKeyNotInPopulatedMap();
545     } catch (UnsupportedOperationException e) {
546       return;
547     }
548     int initialSize = map.size();
549     if (supportsPut) {
550       try {
551         assertNull(map.replace(keyToReplace, null));
552       } catch (NullPointerException e) {
553         // Optional.
554       }
555     } else {
556       try {
557         assertNull(map.replace(keyToReplace, null));
558       } catch (UnsupportedOperationException e) {
559         // Optional.
560       } catch (NullPointerException e) {
561         // Optional.
562       }
563     }
564     assertEquals(initialSize, map.size());
565     assertInvariants(map);
566   }
567 
568   /*
569    * Replace3 tests call 3-parameter replace(key, oldValue, newValue)
570    */
571 
testReplace3ExistingKeyValue()572   public void testReplace3ExistingKeyValue() {
573     final ConcurrentMap<K, V> map;
574     final K keyToReplace;
575     final V oldValue;
576     final V newValue;
577     try {
578       map = makePopulatedMap();
579       newValue = getValueNotInPopulatedMap();
580     } catch (UnsupportedOperationException e) {
581       return;
582     }
583     keyToReplace = map.keySet().iterator().next();
584     oldValue = map.get(keyToReplace);
585     if (supportsPut) {
586       int initialSize = map.size();
587       assertTrue(map.replace(keyToReplace, oldValue, newValue));
588       assertEquals(newValue, map.get(keyToReplace));
589       assertTrue(map.containsKey(keyToReplace));
590       assertTrue(map.containsValue(newValue));
591       assertFalse(map.containsValue(oldValue));
592       assertEquals(initialSize, map.size());
593     } else {
594       try {
595         map.replace(keyToReplace, oldValue, newValue);
596         fail("Expected UnsupportedOperationException.");
597       } catch (UnsupportedOperationException e) {
598         // Expected.
599       }
600     }
601     assertInvariants(map);
602   }
603 
testReplace3ExistingKeyDifferentValue()604   public void testReplace3ExistingKeyDifferentValue() {
605     final ConcurrentMap<K, V> map;
606     final K keyToReplace;
607     final V oldValue;
608     final V newValue;
609     try {
610       map = makePopulatedMap();
611       oldValue = getValueNotInPopulatedMap();
612       newValue = getSecondValueNotInPopulatedMap();
613     } catch (UnsupportedOperationException e) {
614       return;
615     }
616     keyToReplace = map.keySet().iterator().next();
617     final V originalValue = map.get(keyToReplace);
618     int initialSize = map.size();
619     if (supportsPut) {
620       assertFalse(map.replace(keyToReplace, oldValue, newValue));
621     } else {
622       try {
623         map.replace(keyToReplace, oldValue, newValue);
624         fail("Expected UnsupportedOperationException.");
625       } catch (UnsupportedOperationException e) {
626         // Expected.
627       }
628     }
629     assertTrue(map.containsKey(keyToReplace));
630     assertFalse(map.containsValue(newValue));
631     assertFalse(map.containsValue(oldValue));
632     assertEquals(originalValue, map.get(keyToReplace));
633     assertEquals(initialSize, map.size());
634     assertInvariants(map);
635   }
636 
testReplace3MissingKey()637   public void testReplace3MissingKey() {
638     final ConcurrentMap<K, V> map;
639     final K keyToReplace;
640     final V oldValue;
641     final V newValue;
642     try {
643       map = makeEitherMap();
644       keyToReplace = getKeyNotInPopulatedMap();
645       oldValue = getValueNotInPopulatedMap();
646       newValue = getSecondValueNotInPopulatedMap();
647     } catch (UnsupportedOperationException e) {
648       return;
649     }
650     int initialSize = map.size();
651     if (supportsPut) {
652       assertFalse(map.replace(keyToReplace, oldValue, newValue));
653     } else {
654       try {
655         map.replace(keyToReplace, oldValue, newValue);
656         fail("Expected UnsupportedOperationException.");
657       } catch (UnsupportedOperationException e) {
658         // Expected.
659       }
660     }
661     assertFalse(map.containsKey(keyToReplace));
662     assertFalse(map.containsValue(newValue));
663     assertFalse(map.containsValue(oldValue));
664     assertEquals(initialSize, map.size());
665     assertInvariants(map);
666   }
667 
testReplace3NullKey()668   public void testReplace3NullKey() {
669     if (allowsNullKeys) {
670       return;   // Not yet implemented
671     }
672     final ConcurrentMap<K, V> map;
673     final V oldValue;
674     final V newValue;
675     try {
676       map = makeEitherMap();
677       oldValue = getValueNotInPopulatedMap();
678       newValue = getSecondValueNotInPopulatedMap();
679     } catch (UnsupportedOperationException e) {
680       return;
681     }
682     int initialSize = map.size();
683     if (supportsPut) {
684       try {
685         assertFalse(map.replace(null, oldValue, newValue));
686       } catch (NullPointerException e) {
687         // Optional.
688       }
689     } else {
690       try {
691         assertFalse(map.replace(null, oldValue, newValue));
692       } catch (UnsupportedOperationException e) {
693         // Optional.
694       } catch (NullPointerException e) {
695         // Optional.
696       }
697     }
698     assertEquals(initialSize, map.size());
699     assertInvariants(map);
700   }
701 
testReplace3ExistingKeyNullOldValue()702   public void testReplace3ExistingKeyNullOldValue() {
703     if (allowsNullValues) {
704       return;   // Not yet implemented
705     }
706     final ConcurrentMap<K, V> map;
707     final K keyToReplace;
708     final V newValue;
709     try {
710       map = makePopulatedMap();
711       newValue = getValueNotInPopulatedMap();
712     } catch (UnsupportedOperationException e) {
713       return;
714     }
715     keyToReplace = map.keySet().iterator().next();
716     final V originalValue = map.get(keyToReplace);
717     int initialSize = map.size();
718     if (supportsPut) {
719       try {
720         assertFalse(map.replace(keyToReplace, null, newValue));
721       } catch (NullPointerException e) {
722         // Optional.
723       }
724     } else {
725       try {
726         assertFalse(map.replace(keyToReplace, null, newValue));
727       } catch (UnsupportedOperationException e) {
728         // Optional.
729       } catch (NullPointerException e) {
730         // Optional.
731       }
732     }
733     assertEquals(initialSize, map.size());
734     assertEquals(originalValue, map.get(keyToReplace));
735     assertInvariants(map);
736   }
737 
testReplace3MissingKeyNullOldValue()738   public void testReplace3MissingKeyNullOldValue() {
739     if (allowsNullValues) {
740       return;   // Not yet implemented
741     }
742     final ConcurrentMap<K, V> map;
743     final K keyToReplace;
744     final V newValue;
745     try {
746       map = makeEitherMap();
747       keyToReplace = getKeyNotInPopulatedMap();
748       newValue = getValueNotInPopulatedMap();
749     } catch (UnsupportedOperationException e) {
750       return;
751     }
752     int initialSize = map.size();
753     if (supportsPut) {
754       try {
755         assertFalse(map.replace(keyToReplace, null, newValue));
756       } catch (NullPointerException e) {
757         // Optional.
758       }
759     } else {
760       try {
761         assertFalse(map.replace(keyToReplace, null, newValue));
762       } catch (UnsupportedOperationException e) {
763         // Optional.
764       } catch (NullPointerException e) {
765         // Optional.
766       }
767     }
768     assertEquals(initialSize, map.size());
769     assertInvariants(map);
770   }
771 
testReplace3MissingKeyNullNewValue()772   public void testReplace3MissingKeyNullNewValue() {
773     if (allowsNullValues) {
774       return;   // Not yet implemented
775     }
776     final ConcurrentMap<K, V> map;
777     final K keyToReplace;
778     final V oldValue;
779     try {
780       map = makeEitherMap();
781       keyToReplace = getKeyNotInPopulatedMap();
782       oldValue = getValueNotInPopulatedMap();
783     } catch (UnsupportedOperationException e) {
784       return;
785     }
786     int initialSize = map.size();
787     if (supportsPut) {
788       try {
789         map.replace(keyToReplace, oldValue, null);
790       } catch (NullPointerException e) {
791         // Optional.
792       }
793     } else {
794       try {
795         map.replace(keyToReplace, oldValue, null);
796       } catch (UnsupportedOperationException e) {
797         // Optional.
798       } catch (NullPointerException e) {
799         // Optional.
800       }
801     }
802     assertEquals(initialSize, map.size());
803     assertInvariants(map);
804   }
805 
testReplace3ExistingKeyValueNullNewValue()806   public void testReplace3ExistingKeyValueNullNewValue() {
807     if (allowsNullValues) {
808       return;   // Not yet implemented
809     }
810     final ConcurrentMap<K, V> map;
811     final K keyToReplace;
812     final V oldValue;
813     try {
814       map = makePopulatedMap();
815     } catch (UnsupportedOperationException e) {
816       return;
817     }
818     keyToReplace = map.keySet().iterator().next();
819     oldValue = map.get(keyToReplace);
820     int initialSize = map.size();
821     if (supportsPut) {
822       try {
823         map.replace(keyToReplace, oldValue, null);
824         fail("Expected NullPointerException");
825       } catch (NullPointerException e) {
826         // Expected.
827       }
828     } else {
829       try {
830         map.replace(keyToReplace, oldValue, null);
831         fail("Expected UnsupportedOperationException or NullPointerException");
832       } catch (UnsupportedOperationException e) {
833         // Expected.
834       } catch (NullPointerException e) {
835         // Expected.
836       }
837     }
838     assertEquals(initialSize, map.size());
839     assertEquals(oldValue, map.get(keyToReplace));
840     assertInvariants(map);
841   }
842 }
843