blob: 1732dd3dcb92d03c7155581cb7982710f7ae23a2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.tests.java.util;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import libcore.java.lang.ref.FinalizationTester;
import tests.support.Support_MapTest2;
public class WeakHashMapTest extends junit.framework.TestCase {
class MockMap extends AbstractMap {
public Set entrySet() {
return null;
}
public int size() {
return 0;
}
}
Object[] keyArray = new Object[100];
Object[] valueArray = new Object[100];
WeakHashMap whm;
/**
* java.util.WeakHashMap#WeakHashMap()
*/
public void test_Constructor() {
// Test for method java.util.WeakHashMap()
new Support_MapTest2(new WeakHashMap()).runTest();
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
for (int i = 0; i < 100; i++)
assertTrue("Incorrect value retrieved", whm.get(keyArray[i]) == valueArray[i]);
}
/**
* java.util.WeakHashMap#WeakHashMap(int)
*/
public void test_ConstructorI() {
// Test for method java.util.WeakHashMap(int)
whm = new WeakHashMap(50);
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
for (int i = 0; i < 100; i++)
assertTrue("Incorrect value retrieved", whm.get(keyArray[i]) == valueArray[i]);
WeakHashMap empty = new WeakHashMap(0);
assertNull("Empty weakhashmap access", empty.get("nothing"));
empty.put("something", "here");
assertTrue("cannot get element", empty.get("something") == "here");
try {
new WeakHashMap(-50);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
//expected
}
}
/**
* java.util.WeakHashMap#WeakHashMap(int, float)
*/
public void test_ConstructorIF() {
// Test for method java.util.WeakHashMap(int, float)
whm = new WeakHashMap(50, 0.5f);
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
for (int i = 0; i < 100; i++)
assertTrue("Incorrect value retrieved", whm.get(keyArray[i]) == valueArray[i]);
WeakHashMap empty = new WeakHashMap(0, 0.75f);
assertNull("Empty hashtable access", empty.get("nothing"));
empty.put("something", "here");
assertTrue("cannot get element", empty.get("something") == "here");
try {
new WeakHashMap(50, -0.5f);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
//expected
}
}
/**
* java.util.WeakHashMap#WeakHashMap(java.util.Map)
*/
public void test_ConstructorLjava_util_Map() {
Map mockMap = new MockMap();
WeakHashMap map = new WeakHashMap(mockMap);
assertEquals("Size should be 0", 0, map.size());
try {
new WeakHashMap(null);
fail("NullPointerException expected");
} catch (NullPointerException e) {
//expected
}
}
/**
* java.util.WeakHashMap#clear()
*/
public void test_clear() {
// Test for method boolean java.util.WeakHashMap.clear()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
whm.clear();
assertTrue("Cleared map should be empty", whm.isEmpty());
for (int i = 0; i < 100; i++)
assertNull("Cleared map should only return null", whm.get(keyArray[i]));
}
/**
* java.util.WeakHashMap#containsKey(java.lang.Object)
*/
public void test_containsKeyLjava_lang_Object() {
// Test for method boolean java.util.WeakHashMap.containsKey()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
for (int i = 0; i < 100; i++)
assertTrue("Should contain referenced key", whm.containsKey(keyArray[i]));
keyArray[25] = null;
keyArray[50] = null;
}
/**
* java.util.WeakHashMap#containsValue(java.lang.Object)
*/
public void test_containsValueLjava_lang_Object() {
// Test for method boolean java.util.WeakHashMap.containsValue()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
for (int i = 0; i < 100; i++)
assertTrue("Should contain referenced value", whm.containsValue(valueArray[i]));
keyArray[25] = null;
keyArray[50] = null;
}
/**
* java.util.WeakHashMap#entrySet()
*/
public void test_entrySet() {
// Test for method java.util.Set java.util.WeakHashMap.entrySet()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
List keys = Arrays.asList(keyArray);
List values = Arrays.asList(valueArray);
Set entrySet = whm.entrySet();
assertTrue("Incorrect number of entries returned--wanted 100, got: " + entrySet.size(),
entrySet.size() == 100);
Iterator it = entrySet.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
assertTrue("Invalid map entry returned--bad key", keys.contains(entry.getKey()));
assertTrue("Invalid map entry returned--bad key", values.contains(entry.getValue()));
}
keys = null;
values = null;
keyArray[50] = null;
FinalizationTester.induceFinalization();
long startTime = System.currentTimeMillis();
// We use a busy wait loop here since we cannot know when the ReferenceQueue
// daemon will enqueue the cleared references on their internal reference
// queues. The current timeout is 5 seconds.
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
} while (entrySet.size() != 99 &&
System.currentTimeMillis() - startTime < 5000);
assertEquals("Incorrect number of keys returned after gc,", 99, entrySet.size());
}
/**
* java.util.WeakHashMap#isEmpty()
*/
public void test_isEmpty() {
// Test for method boolean java.util.WeakHashMap.isEmpty()
whm = new WeakHashMap();
assertTrue("New map should be empty", whm.isEmpty());
Object myObject = new Object();
whm.put(myObject, myObject);
assertTrue("Map should not be empty", !whm.isEmpty());
whm.remove(myObject);
assertTrue("Map with elements removed should be empty", whm.isEmpty());
}
/**
* java.util.WeakHashMap#put(java.lang.Object, java.lang.Object)
*/
public void test_putLjava_lang_ObjectLjava_lang_Object() {
// Test for method java.lang.Object
// java.util.WeakHashMap.put(java.lang.Object, java.lang.Object)
WeakHashMap map = new WeakHashMap();
map.put(null, "value"); // add null key
System.gc();
System.gc();
FinalizationTester.induceFinalization();
map.remove("nothing"); // Cause objects in queue to be removed
assertEquals("null key was removed", 1, map.size());
}
/**
* java.util.WeakHashMap#putAll(java.util.Map)
*/
public void test_putAllLjava_util_Map() {
Map mockMap = new MockMap();
WeakHashMap map = new WeakHashMap();
map.putAll(mockMap);
assertEquals("Size should be 0", 0, map.size());
try {
map.putAll(null);
fail("NullPointerException exected");
} catch (NullPointerException e) {
//expected
}
}
/**
* java.util.WeakHashMap#remove(java.lang.Object)
*/
public void test_removeLjava_lang_Object() {
// Test for method java.lang.Object
// java.util.WeakHashMap.remove(java.lang.Object)
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
assertTrue("Remove returned incorrect value", whm.remove(keyArray[25]) == valueArray[25]);
assertNull("Remove returned incorrect value", whm.remove(keyArray[25]));
assertEquals("Size should be 99 after remove", 99, whm.size());
}
/**
* java.util.WeakHashMap#size()
*/
public void test_size() {
whm = new WeakHashMap();
assertEquals(0, whm.size());
}
/**
* java.util.WeakHashMap#keySet()
*/
public void test_keySet() {
// Test for method java.util.Set java.util.WeakHashMap.keySet()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
List keys = Arrays.asList(keyArray);
List values = Arrays.asList(valueArray);
Set keySet = whm.keySet();
assertEquals("Incorrect number of keys returned,", 100, keySet.size());
Iterator it = keySet.iterator();
while (it.hasNext()) {
Object key = it.next();
assertTrue("Invalid map entry returned--bad key", keys.contains(key));
}
keys = null;
values = null;
keyArray[50] = null;
FinalizationTester.induceFinalization();
long startTime = System.currentTimeMillis();
// We use a busy wait loop here since we cannot know when the ReferenceQueue
// daemon will enqueue the cleared references on their internal reference
// queues. The current timeout is 5 seconds.
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
} while (keySet.size() != 99 &&
System.currentTimeMillis() - startTime < 5000);
assertEquals("Incorrect number of keys returned after gc,", 99, keySet.size());
}
/**
* Regression test for HARMONY-3883
*
* java.util.WeakHashMap#keySet()
*/
public void test_keySet_hasNext() {
WeakHashMap map = new WeakHashMap();
ConstantHashClass cl = new ConstantHashClass(2);
map.put(new ConstantHashClass(1), null);
map.put(cl, null);
map.put(new ConstantHashClass(3), null);
Iterator iter = map.keySet().iterator();
iter.next();
iter.next();
int count = 0;
do {
System.gc();
System.gc();
FinalizationTester.induceFinalization();
count++;
} while (count <= 5);
assertFalse("Wrong hasNext() value", iter.hasNext());
}
static class ConstantHashClass {
private int id = 0;
public ConstantHashClass(int id) {
this.id = id;
}
public int hashCode() {
return 0;
}
public String toString() {
return "ConstantHashClass[id=" + id + "]";
}
}
/**
* java.util.WeakHashMap#values()
*/
public void test_values() {
// Test for method java.util.Set java.util.WeakHashMap.values()
whm = new WeakHashMap();
for (int i = 0; i < 100; i++)
whm.put(keyArray[i], valueArray[i]);
List keys = Arrays.asList(keyArray);
List values = Arrays.asList(valueArray);
Collection valuesCollection = whm.values();
assertEquals("Incorrect number of keys returned,", 100, valuesCollection.size());
Iterator it = valuesCollection.iterator();
while (it.hasNext()) {
Object value = it.next();
assertTrue("Invalid map entry returned--bad value", values.contains(value));
}
keys = null;
values = null;
keyArray[50] = null;
FinalizationTester.induceFinalization();
long startTime = System.currentTimeMillis();
// We use a busy wait loop here since we cannot know when the ReferenceQueue
// daemon will enqueue the cleared references on their internal reference
// queues. The current timeout is 5 seconds.
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
} while (valuesCollection.size() != 99 &&
System.currentTimeMillis() - startTime < 5000);
assertEquals("Incorrect number of keys returned after gc,", 99, valuesCollection.size());
}
public void test_forEach() throws Exception {
WeakHashMap map = new WeakHashMap();
for (int i = 0; i < 100; i++)
map.put(keyArray[i], valueArray[i]);
WeakHashMap output = new WeakHashMap();
map.forEach((k, v) -> output.put(k,v));
assertEquals(map, output);
HashSet setOutput = new HashSet();
map.keySet().forEach((k) -> setOutput.add(k));
assertEquals(map.keySet(), setOutput);
setOutput.clear();
map.values().forEach((v) -> setOutput.add(v));
assertEquals(new HashSet(map.values()), setOutput);
HashSet entrySetOutput = new HashSet();
map.entrySet().forEach((v) -> entrySetOutput.add(v));
assertEquals(map.entrySet(), entrySetOutput);
}
public void test_forEach_NPE() throws Exception {
WeakHashMap map = new WeakHashMap();
try {
map.forEach(null);
fail();
} catch(NullPointerException expected) {}
try {
map.keySet().forEach(null);
fail();
} catch(NullPointerException expected) {}
try {
map.values().forEach(null);
fail();
} catch(NullPointerException expected) {}
try {
map.entrySet().forEach(null);
fail();
} catch(NullPointerException expected) {}
}
public void test_forEach_CME() throws Exception {
WeakHashMap map = new WeakHashMap();
for (int i = 0; i < 100; i++)
map.put(keyArray[i], valueArray[i]);
ArrayList<Object> processed = new ArrayList<>();
try {
map.forEach(new java.util.function.BiConsumer<Object, Object>() {
@Override
public void accept(Object k, Object v) {
processed.add(k);
map.put("foo", v);
}
});
fail();
} catch(ConcurrentModificationException expected) {}
// We should get a CME and DO NOT continue forEach evaluation
assertEquals(1, processed.size());
processed.clear();
try {
map.keySet().forEach(new java.util.function.Consumer<Object>() {
@Override
public void accept(Object k) {
processed.add(k);
map.put("foo2", "boo");
}
});
fail();
} catch(ConcurrentModificationException expected) {}
// We should get a CME and DO NOT continue forEach evaluation
assertEquals(1, processed.size());
processed.clear();
try {
map.values().forEach(new java.util.function.Consumer<Object>() {
@Override
public void accept(Object k) {
processed.add(k);
map.put("foo3", "boo");
}
});
fail();
} catch(ConcurrentModificationException expected) {}
// We should get a CME and DO NOT continue forEach evaluation
assertEquals(1, processed.size());
processed.clear();
try {
map.entrySet().forEach(new java.util.function.Consumer<Map.Entry<Object, Object>>() {
@Override
public void accept(Map.Entry<Object, Object> k) {
processed.add(k.getKey());
map.put("foo4", "boo");
}
});
fail();
} catch(ConcurrentModificationException expected) {}
// We should get a CME and DO NOT continue forEach evaluation
assertEquals(1, processed.size());
}
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
protected void setUp() {
for (int i = 0; i < 100; i++) {
keyArray[i] = new Object();
valueArray[i] = new Object();
}
}
/**
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
*/
protected void tearDown() {
}
}