blob: 35d8cca4bea3f836af8a29defbc473ba332fa51a [file] [log] [blame]
// CHECKSTYLE_OFF: Copyrighted to members of JCP JSR-166 Expert Group.
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/licenses/publicdomain
* Other contributors include Andrew Wright, Jeffrey Hayes,
* Pat Fisher, Mike Judd.
*/
// CHECKSTYLE_ON
package com.google.gwt.emultest.java.util.concurrent;
import com.google.gwt.emultest.java.util.EmulTestBase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Tests for {@link java.util.concurrent.ConcurrentHashMap}.
* It's adopted from tests from {@code
* http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/ConcurrentHashMapTest.java?view=markup}
*/
// TODO(hhchan): Fix the type parameters (missing from the original test).
@SuppressWarnings({"unchecked", "MismatchedQueryAndUpdateOfCollection"})
public class ConcurrentHashMapTest extends EmulTestBase {
private static final int ZERO = 0;
private static final int ONE = 1;
private static final int TWO = 2;
private static final int THREE = 3;
private static final int FOUR = 4;
private static final int FIVE = 5;
private static final int SIX = 6;
/** Create a map from Integers 1-5 to Strings "A"-"E". */
private static ConcurrentHashMap map5() {
ConcurrentHashMap map = new ConcurrentHashMap(5);
assertTrue(map.isEmpty());
map.put(ONE, "A");
map.put(TWO, "B");
map.put(THREE, "C");
map.put(FOUR, "D");
map.put(FIVE, "E");
assertFalse(map.isEmpty());
assertEquals(5, map.size());
return map;
}
/** clear removes all pairs */
public void testClear() {
ConcurrentHashMap map = map5();
map.clear();
assertEquals(0, map.size());
}
/** Maps with same contents are equal */
public void testEquals() {
ConcurrentHashMap map1 = map5();
ConcurrentHashMap map2 = map5();
assertEquals(map1, map2);
assertEquals(map2, map1);
map1.clear();
assertFalse(map1.equals(map2));
assertFalse(map2.equals(map1));
}
/** contains returns true for contained value */
public void testContains() {
ConcurrentHashMap map = map5();
assertTrue(map.containsValue("A"));
assertFalse(map.containsValue("Z"));
}
/** containsKey returns true for contained key */
public void testContainsKey() {
ConcurrentHashMap map = map5();
assertTrue(map.containsKey(ONE));
assertFalse(map.containsKey(ZERO));
}
/** containsValue returns true for held values */
public void testContainsValue() {
ConcurrentHashMap map = map5();
assertTrue(map.containsValue("A"));
assertFalse(map.containsValue("Z"));
}
/** enumeration returns an enumeration containing the correct elements */
public void testEnumeration() {
ConcurrentHashMap map = map5();
Enumeration e = map.elements();
int count = 0;
while (e.hasMoreElements()) {
count++;
e.nextElement();
}
assertEquals(5, count);
}
/** get returns the correct element at the given key, or null if not present */
public void testGet() {
ConcurrentHashMap map = map5();
assertEquals("A", (String) map.get(ONE));
assertNull(map.get("anything"));
}
/** isEmpty is true of empty map and false for non-empty */
public void testIsEmpty() {
ConcurrentHashMap empty = new ConcurrentHashMap();
ConcurrentHashMap map = map5();
assertTrue(empty.isEmpty());
assertFalse(map.isEmpty());
}
/** keys returns an enumeration containing all the keys from the map */
public void testKeys() {
ConcurrentHashMap map = map5();
Enumeration e = map.keys();
int count = 0;
while (e.hasMoreElements()) {
count++;
e.nextElement();
}
assertEquals(5, count);
}
/** keySet returns a Set containing all the keys */
public void testKeySet() {
ConcurrentHashMap map = map5();
Set s = map.keySet();
assertEquals(5, s.size());
assertTrue(s.contains(ONE));
assertTrue(s.contains(TWO));
assertTrue(s.contains(THREE));
assertTrue(s.contains(FOUR));
assertTrue(s.contains(FIVE));
}
/** keySet.toArray returns contains all keys */
public void testKeySetToArray() {
ConcurrentHashMap map = map5();
Set s = map.keySet();
Object[] ar = s.toArray();
assertTrue(s.containsAll(Arrays.asList(ar)));
assertEquals(5, ar.length);
ar[0] = 10;
assertFalse(s.containsAll(Arrays.asList(ar)));
}
/** Values.toArray contains all values */
public void testValuesToArray() {
ConcurrentHashMap map = map5();
Collection v = map.values();
Object[] ar = v.toArray();
ArrayList s = new ArrayList(Arrays.asList(ar));
assertEquals(5, ar.length);
assertTrue(s.contains("A"));
assertTrue(s.contains("B"));
assertTrue(s.contains("C"));
assertTrue(s.contains("D"));
assertTrue(s.contains("E"));
}
/** entrySet.toArray contains all entries */
public void testEntrySetToArray() {
ConcurrentHashMap map = map5();
Set s = map.entrySet();
Object[] ar = s.toArray();
assertEquals(5, ar.length);
for (int i = 0; i < 5; ++i) {
assertTrue(map.containsKey(((Map.Entry) (ar[i])).getKey()));
assertTrue(map.containsValue(((Map.Entry) (ar[i])).getValue()));
}
}
/** values collection contains all values */
public void testValues() {
ConcurrentHashMap map = map5();
Collection s = map.values();
assertEquals(5, s.size());
assertTrue(s.contains("A"));
assertTrue(s.contains("B"));
assertTrue(s.contains("C"));
assertTrue(s.contains("D"));
assertTrue(s.contains("E"));
}
/** entrySet contains all pairs */
public void testEntrySet() {
ConcurrentHashMap map = map5();
Set s = map.entrySet();
assertEquals(5, s.size());
for (Object value : s) {
Entry e = (Entry) value;
assertTrue(
(e.getKey().equals(ONE) && e.getValue().equals("A"))
|| (e.getKey().equals(TWO) && e.getValue().equals("B"))
|| (e.getKey().equals(THREE) && e.getValue().equals("C"))
|| (e.getKey().equals(FOUR) && e.getValue().equals("D"))
|| (e.getKey().equals(FIVE) && e.getValue().equals("E")));
}
}
/** putAll adds all key-value pairs from the given map */
public void testPutAll() {
ConcurrentHashMap empty = new ConcurrentHashMap();
ConcurrentHashMap map = map5();
empty.putAll(map);
assertEquals(5, empty.size());
assertTrue(empty.containsKey(ONE));
assertTrue(empty.containsKey(TWO));
assertTrue(empty.containsKey(THREE));
assertTrue(empty.containsKey(FOUR));
assertTrue(empty.containsKey(FIVE));
}
/** putIfAbsent works when the given key is not present */
public void testPutIfAbsent() {
ConcurrentHashMap map = map5();
map.putIfAbsent(SIX, "Z");
assertTrue(map.containsKey(SIX));
}
/** putIfAbsent does not add the pair if the key is already present */
public void testPutIfAbsent2() {
ConcurrentHashMap map = map5();
assertEquals("A", map.putIfAbsent(ONE, "Z"));
}
/** replace fails when the given key is not present */
public void testReplace() {
ConcurrentHashMap map = map5();
assertNull(map.replace(SIX, "Z"));
assertFalse(map.containsKey(SIX));
}
/** replace succeeds if the key is already present */
public void testReplace2() {
ConcurrentHashMap map = map5();
assertNotNull(map.replace(ONE, "Z"));
assertEquals("Z", map.get(ONE));
}
/** replace value fails when the given key not mapped to expected value */
public void testReplaceValue() {
ConcurrentHashMap map = map5();
assertEquals("A", map.get(ONE));
assertFalse(map.replace(ONE, "Z", "Z"));
assertEquals("A", map.get(ONE));
}
/** replace value succeeds when the given key mapped to expected value */
public void testReplaceValue2() {
ConcurrentHashMap map = map5();
assertEquals("A", map.get(ONE));
assertTrue(map.replace(ONE, "A", "Z"));
assertEquals("Z", map.get(ONE));
}
/** remove removes the correct key-value pair from the map */
public void testRemove() {
ConcurrentHashMap map = map5();
map.remove(FIVE);
assertEquals(4, map.size());
assertFalse(map.containsKey(FIVE));
}
/** remove(key,value) removes only if pair present */
public void testRemove2() {
ConcurrentHashMap map = map5();
map.remove(FIVE, "E");
assertEquals(4, map.size());
assertFalse(map.containsKey(FIVE));
map.remove(FOUR, "A");
assertEquals(4, map.size());
assertTrue(map.containsKey(FOUR));
}
/** size returns the correct values */
public void testSize() {
ConcurrentHashMap map = map5();
ConcurrentHashMap empty = new ConcurrentHashMap();
assertEquals(0, empty.size());
assertEquals(5, map.size());
}
/** toString contains toString of elements */
public void testToString() {
ConcurrentHashMap map = map5();
String s = map.toString();
for (int i = 1; i <= 5; ++i) {
assertTrue(s.indexOf(String.valueOf(i)) >= 0);
}
}
// Exception tests
/** Cannot create with only negative capacity */
public void testConstructor() {
try {
new ConcurrentHashMap(-1);
fail("Exception expected");
} catch (IllegalArgumentException expected) {
}
}
/** get(null) throws NPE */
public void testGet_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.get(null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** containsKey(null) throws NPE */
public void testContainsKey_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.containsKey(null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** containsValue(null) throws NPE */
public void testContainsValue_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.containsValue(null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** contains(null) throws NPE */
public void testContains_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.containsValue(null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** put(null,x) throws NPE */
public void testPut1_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.put(null, "whatever");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** put(x, null) throws NPE */
public void testPut2_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.put("whatever", null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** putIfAbsent(null, x) throws NPE */
public void testPutIfAbsent1_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.putIfAbsent(null, "whatever");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** replace(null, x) throws NPE */
public void testReplace_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.replace(null, "whatever");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** replace(null, x, y) throws NPE */
public void testReplaceValue_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.replace(null, ONE, "whatever");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** putIfAbsent(x, null) throws NPE */
public void testPutIfAbsent2_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.putIfAbsent("whatever", null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** replace(x, null) throws NPE */
public void testReplace2_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.replace("whatever", null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** replace(x, null, y) throws NPE */
public void testReplaceValue2_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.replace("whatever", null, "A");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** replace(x, y, null) throws NPE */
public void testReplaceValue3_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.replace("whatever", ONE, null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** remove(null) throws NPE */
public void testRemove1_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.put("sadsdf", "asdads");
c.remove(null);
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** remove(null, x) throws NPE */
public void testRemove2_NullPointerException() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.put("sadsdf", "asdads");
c.remove(null, "whatever");
fail("Exception expected");
} catch (NullPointerException expected) {
}
}
/** remove(x, null) returns false */
public void testRemove3() {
try {
ConcurrentHashMap c = new ConcurrentHashMap(5);
c.put("sadsdf", "asdads");
assertFalse(c.remove("sadsdf", null));
} catch (NullPointerException e) {
fail();
}
}
/** SetValue of an EntrySet entry sets value in the map. */
public void testSetValueWriteThrough() {
// Adapted from a bug report by Eric Zoerner
ConcurrentHashMap map = new ConcurrentHashMap(2);
assertTrue(map.isEmpty());
for (int i = 0; i < 20; i++) {
map.put(new Integer(i), new Integer(i));
}
assertFalse(map.isEmpty());
Map.Entry entry1 = (Map.Entry) map.entrySet().iterator().next();
if (entry1.getKey().equals(new Integer(16))) {
// can't perform the test this time
// TODO(cpovirk): Could we just pick a different key?
return;
}
// remove 16 (a different key) from map
// which just happens to cause entry1 to be cloned in map
map.remove(new Integer(16));
entry1.setValue("XYZ");
assertTrue(map.containsValue("XYZ")); // fails
}
}