| /* |
| * 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() { |
| } |
| } |