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 }