001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 019 package org.apache.commons.logging.impl; 020 021 import java.lang.ref.*; 022 import junit.framework.*; 023 import java.util.*; 024 025 public class WeakHashtableTest extends TestCase { 026 027 028 /** Maximum number of iterations before our test fails */ 029 private static final int MAX_GC_ITERATIONS = 50; 030 031 private WeakHashtable weakHashtable; 032 private Long keyOne; 033 private Long keyTwo; 034 private Long keyThree; 035 private Long valueOne; 036 private Long valueTwo; 037 private Long valueThree; 038 039 public WeakHashtableTest(String testName) { 040 super(testName); 041 } 042 043 044 protected void setUp() throws Exception { 045 super.setUp(); 046 weakHashtable = new WeakHashtable(); 047 048 keyOne = new Long(1); 049 keyTwo = new Long(2); 050 keyThree = new Long(3); 051 valueOne = new Long(100); 052 valueTwo = new Long(200); 053 valueThree = new Long(300); 054 055 weakHashtable.put(keyOne, valueOne); 056 weakHashtable.put(keyTwo, valueTwo); 057 weakHashtable.put(keyThree, valueThree); 058 } 059 060 /** Tests public boolean contains(Object value) */ 061 public void testContains() throws Exception { 062 assertFalse(weakHashtable.contains(new Long(1))); 063 assertFalse(weakHashtable.contains(new Long(2))); 064 assertFalse(weakHashtable.contains(new Long(3))); 065 assertTrue(weakHashtable.contains(new Long(100))); 066 assertTrue(weakHashtable.contains(new Long(200))); 067 assertTrue(weakHashtable.contains(new Long(300))); 068 assertFalse(weakHashtable.contains(new Long(400))); 069 } 070 071 /** Tests public boolean containsKey(Object key) */ 072 public void testContainsKey() throws Exception { 073 assertTrue(weakHashtable.containsKey(new Long(1))); 074 assertTrue(weakHashtable.containsKey(new Long(2))); 075 assertTrue(weakHashtable.containsKey(new Long(3))); 076 assertFalse(weakHashtable.containsKey(new Long(100))); 077 assertFalse(weakHashtable.containsKey(new Long(200))); 078 assertFalse(weakHashtable.containsKey(new Long(300))); 079 assertFalse(weakHashtable.containsKey(new Long(400))); 080 } 081 082 /** Tests public boolean containsValue(Object value) */ 083 public void testContainsValue() throws Exception { 084 assertFalse(weakHashtable.containsValue(new Long(1))); 085 assertFalse(weakHashtable.containsValue(new Long(2))); 086 assertFalse(weakHashtable.containsValue(new Long(3))); 087 assertTrue(weakHashtable.containsValue(new Long(100))); 088 assertTrue(weakHashtable.containsValue(new Long(200))); 089 assertTrue(weakHashtable.containsValue(new Long(300))); 090 assertFalse(weakHashtable.containsValue(new Long(400))); 091 } 092 093 /** Tests public Enumeration elements() */ 094 public void testElements() throws Exception { 095 ArrayList elements = new ArrayList(); 096 for (Enumeration e = weakHashtable.elements(); e.hasMoreElements();) { 097 elements.add(e.nextElement()); 098 } 099 assertEquals(3, elements.size()); 100 assertTrue(elements.contains(valueOne)); 101 assertTrue(elements.contains(valueTwo)); 102 assertTrue(elements.contains(valueThree)); 103 } 104 105 /** Tests public Set entrySet() */ 106 public void testEntrySet() throws Exception { 107 Set entrySet = weakHashtable.entrySet(); 108 for (Iterator it = entrySet.iterator(); it.hasNext();) { 109 Map.Entry entry = (Map.Entry) it.next(); 110 Object key = entry.getKey(); 111 if (keyOne.equals(key)) { 112 assertEquals(valueOne, entry.getValue()); 113 } else if (keyTwo.equals(key)) { 114 assertEquals(valueTwo, entry.getValue()); 115 } else if (keyThree.equals(key)) { 116 assertEquals(valueThree, entry.getValue()); 117 } else { 118 fail("Unexpected key"); 119 } 120 } 121 } 122 123 /** Tests public Object get(Object???key) */ 124 public void testGet() throws Exception { 125 assertEquals(valueOne, weakHashtable.get(keyOne)); 126 assertEquals(valueTwo, weakHashtable.get(keyTwo)); 127 assertEquals(valueThree, weakHashtable.get(keyThree)); 128 assertNull(weakHashtable.get(new Long(50))); 129 } 130 131 /** Tests public Enumeration keys() */ 132 public void testKeys() throws Exception { 133 ArrayList keys = new ArrayList(); 134 for (Enumeration e = weakHashtable.keys(); e.hasMoreElements();) { 135 keys.add(e.nextElement()); 136 } 137 assertEquals(3, keys.size()); 138 assertTrue(keys.contains(keyOne)); 139 assertTrue(keys.contains(keyTwo)); 140 assertTrue(keys.contains(keyThree)); 141 } 142 143 /** Tests public Set keySet() */ 144 public void testKeySet() throws Exception { 145 Set keySet = weakHashtable.keySet(); 146 assertEquals(3, keySet.size()); 147 assertTrue(keySet.contains(keyOne)); 148 assertTrue(keySet.contains(keyTwo)); 149 assertTrue(keySet.contains(keyThree)); 150 } 151 152 /** Tests public Object put(Object key, Object value) */ 153 public void testPut() throws Exception { 154 Long anotherKey = new Long(2004); 155 weakHashtable.put(anotherKey, new Long(1066)); 156 157 assertEquals(new Long(1066), weakHashtable.get(anotherKey)); 158 159 // Test compliance with the hashtable API re nulls 160 Exception caught = null; 161 try { 162 weakHashtable.put(null, new Object()); 163 } 164 catch (Exception e) { 165 caught = e; 166 } 167 assertNotNull("did not throw an exception adding a null key", caught); 168 caught = null; 169 try { 170 weakHashtable.put(new Object(), null); 171 } 172 catch (Exception e) { 173 caught = e; 174 } 175 assertNotNull("did not throw an exception adding a null value", caught); 176 } 177 178 /** Tests public void putAll(Map t) */ 179 public void testPutAll() throws Exception { 180 Map newValues = new HashMap(); 181 Long newKey = new Long(1066); 182 Long newValue = new Long(1415); 183 newValues.put(newKey, newValue); 184 Long anotherNewKey = new Long(1645); 185 Long anotherNewValue = new Long(1815); 186 newValues.put(anotherNewKey, anotherNewValue); 187 weakHashtable.putAll(newValues); 188 189 assertEquals(5, weakHashtable.size()); 190 assertEquals(newValue, weakHashtable.get(newKey)); 191 assertEquals(anotherNewValue, weakHashtable.get(anotherNewKey)); 192 } 193 194 /** Tests public Object remove(Object???key) */ 195 public void testRemove() throws Exception { 196 weakHashtable.remove(keyOne); 197 assertEquals(2, weakHashtable.size()); 198 assertNull(weakHashtable.get(keyOne)); 199 } 200 201 /** Tests public Collection values() */ 202 public void testValues() throws Exception { 203 Collection values = weakHashtable.values(); 204 assertEquals(3, values.size()); 205 assertTrue(values.contains(valueOne)); 206 assertTrue(values.contains(valueTwo)); 207 assertTrue(values.contains(valueThree)); 208 } 209 210 public void testRelease() throws Exception { 211 assertNotNull(weakHashtable.get(new Long(1))); 212 ReferenceQueue testQueue = new ReferenceQueue(); 213 WeakReference weakKeyOne = new WeakReference(keyOne, testQueue); 214 215 // lose our references 216 keyOne = null; 217 keyTwo = null; 218 keyThree = null; 219 valueOne = null; 220 valueTwo = null; 221 valueThree = null; 222 223 int iterations = 0; 224 int bytz = 2; 225 while(true) { 226 System.gc(); 227 if(iterations++ > MAX_GC_ITERATIONS){ 228 fail("Max iterations reached before resource released."); 229 } 230 231 if(weakHashtable.get(new Long(1)) == null) { 232 break; 233 234 } else { 235 // create garbage: 236 byte[] b = new byte[bytz]; 237 bytz = bytz * 2; 238 } 239 } 240 241 // some JVMs seem to take a little time to put references on 242 // the reference queue once the reference has been collected 243 // need to think about whether this is enough to justify 244 // stepping through the collection each time... 245 while(testQueue.poll() == null) {} 246 247 // Test that the released objects are not taking space in the table 248 assertEquals("underlying table not emptied", 0, weakHashtable.size()); 249 } 250 }