1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.logging.impl;
19
20 import java.lang.ref.ReferenceQueue;
21 import java.lang.ref.WeakReference;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Set;
28
29 import junit.framework.TestCase;
30
31 public class WeakHashtableTestCase extends TestCase {
32
33 public static class StupidThread extends Thread {
34
35 public StupidThread(final String name) {
36 super(name);
37 }
38
39 @Override
40 public void run() {
41 for (int i = 0; i < RUN_LOOPS; i++) {
42 hashtable.put("key" + ":" + i % 10, Boolean.TRUE);
43 if (i % 50 == 0) {
44 yield();
45 }
46 }
47 }
48 }
49 private static final int WAIT_FOR_THREAD_COMPLETION = 5000;
50 private static final int RUN_LOOPS = 3000;
51 private static final int OUTER_LOOP = 400;
52
53 private static final int THREAD_COUNT = 10;
54
55 private static WeakHashtable hashtable;
56
57
58 private static final int MAX_GC_ITERATIONS = 50;
59 private WeakHashtable weakHashtable;
60 private Long keyOne;
61 private Long keyTwo;
62 private Long keyThree;
63 private Long valueOne;
64 private Long valueTwo;
65
66 private Long valueThree;
67
68 public WeakHashtableTestCase(final String testName) {
69 super(testName);
70 }
71
72 @Override
73 protected void setUp() throws Exception {
74 super.setUp();
75 weakHashtable = new WeakHashtable();
76
77 keyOne = Long.valueOf(1);
78 keyTwo = Long.valueOf(2);
79 keyThree = Long.valueOf(3);
80 valueOne = Long.valueOf(100);
81 valueTwo = Long.valueOf(200);
82 valueThree = Long.valueOf(300);
83
84 weakHashtable.put(keyOne, valueOne);
85 weakHashtable.put(keyTwo, valueTwo);
86 weakHashtable.put(keyThree, valueThree);
87 }
88
89
90 public void testContains() throws Exception {
91 assertFalse(weakHashtable.contains(Long.valueOf(1)));
92 assertFalse(weakHashtable.contains(Long.valueOf(2)));
93 assertFalse(weakHashtable.contains(Long.valueOf(3)));
94 assertTrue(weakHashtable.contains(Long.valueOf(100)));
95 assertTrue(weakHashtable.contains(Long.valueOf(200)));
96 assertTrue(weakHashtable.contains(Long.valueOf(300)));
97 assertFalse(weakHashtable.contains(Long.valueOf(400)));
98 }
99
100
101 public void testContainsKey() throws Exception {
102 assertTrue(weakHashtable.containsKey(Long.valueOf(1)));
103 assertTrue(weakHashtable.containsKey(Long.valueOf(2)));
104 assertTrue(weakHashtable.containsKey(Long.valueOf(3)));
105 assertFalse(weakHashtable.containsKey(Long.valueOf(100)));
106 assertFalse(weakHashtable.containsKey(Long.valueOf(200)));
107 assertFalse(weakHashtable.containsKey(Long.valueOf(300)));
108 assertFalse(weakHashtable.containsKey(Long.valueOf(400)));
109 }
110
111
112 public void testContainsValue() throws Exception {
113 assertFalse(weakHashtable.containsValue(Long.valueOf(1)));
114 assertFalse(weakHashtable.containsValue(Long.valueOf(2)));
115 assertFalse(weakHashtable.containsValue(Long.valueOf(3)));
116 assertTrue(weakHashtable.containsValue(Long.valueOf(100)));
117 assertTrue(weakHashtable.containsValue(Long.valueOf(200)));
118 assertTrue(weakHashtable.containsValue(Long.valueOf(300)));
119 assertFalse(weakHashtable.containsValue(Long.valueOf(400)));
120 }
121
122
123 public void testElements() throws Exception {
124 final ArrayList elements = new ArrayList();
125 for (final Enumeration e = weakHashtable.elements(); e.hasMoreElements();) {
126 elements.add(e.nextElement());
127 }
128 assertEquals(3, elements.size());
129 assertTrue(elements.contains(valueOne));
130 assertTrue(elements.contains(valueTwo));
131 assertTrue(elements.contains(valueThree));
132 }
133
134
135 public void testEntrySet() throws Exception {
136 final Set entrySet = weakHashtable.entrySet();
137 for (final Object element : entrySet) {
138 final Map.Entry entry = (Map.Entry) element;
139 final Object key = entry.getKey();
140 if (keyOne.equals(key)) {
141 assertEquals(valueOne, entry.getValue());
142 } else if (keyTwo.equals(key)) {
143 assertEquals(valueTwo, entry.getValue());
144 } else if (keyThree.equals(key)) {
145 assertEquals(valueThree, entry.getValue());
146 } else {
147 fail("Unexpected key");
148 }
149 }
150 }
151
152
153 public void testGet() throws Exception {
154 assertEquals(valueOne, weakHashtable.get(keyOne));
155 assertEquals(valueTwo, weakHashtable.get(keyTwo));
156 assertEquals(valueThree, weakHashtable.get(keyThree));
157 assertNull(weakHashtable.get(Long.valueOf(50)));
158 }
159
160
161 public void testKeys() throws Exception {
162 final ArrayList keys = new ArrayList();
163 for (final Enumeration e = weakHashtable.keys(); e.hasMoreElements();) {
164 keys.add(e.nextElement());
165 }
166 assertEquals(3, keys.size());
167 assertTrue(keys.contains(keyOne));
168 assertTrue(keys.contains(keyTwo));
169 assertTrue(keys.contains(keyThree));
170 }
171
172
173 public void testKeySet() throws Exception {
174 final Set keySet = weakHashtable.keySet();
175 assertEquals(3, keySet.size());
176 assertTrue(keySet.contains(keyOne));
177 assertTrue(keySet.contains(keyTwo));
178 assertTrue(keySet.contains(keyThree));
179 }
180
181 public void testLOGGING_119() throws Exception {
182 final Thread [] t = new Thread[THREAD_COUNT];
183 for (int j=1; j <= OUTER_LOOP; j++) {
184 hashtable = new WeakHashtable();
185 for (int i = 0; i < t.length; i++) {
186 t[i] = new StupidThread("Thread:" + i);
187 t[i].setDaemon(true);
188 t[i].start();
189 }
190 for (final Thread element : t) {
191 element.join(WAIT_FOR_THREAD_COMPLETION);
192 if (element.isAlive()) {
193 break;
194 }
195 }
196 int active=0;
197 for (final Thread element : t) {
198 if (element.isAlive()) {
199 active++;
200 }
201 }
202 if (active > 0) {
203 fail("Attempt: " + j + " Stuck threads: " + active);
204 }
205 }
206 }
207
208
209 public void testPut() throws Exception {
210 final Long anotherKey = Long.valueOf(2004);
211 weakHashtable.put(anotherKey, Long.valueOf(1066));
212
213 assertEquals(Long.valueOf(1066), weakHashtable.get(anotherKey));
214
215
216 Exception caught = null;
217 try {
218 weakHashtable.put(null, new Object());
219 }
220 catch (final Exception e) {
221 caught = e;
222 }
223 assertNotNull("did not throw an exception adding a null key", caught);
224 caught = null;
225 try {
226 weakHashtable.put(new Object(), null);
227 }
228 catch (final Exception e) {
229 caught = e;
230 }
231 assertNotNull("did not throw an exception adding a null value", caught);
232 }
233
234
235 public void testPutAll() throws Exception {
236 final Map newValues = new HashMap();
237 final Long newKey = Long.valueOf(1066);
238 final Long newValue = Long.valueOf(1415);
239 newValues.put(newKey, newValue);
240 final Long anotherNewKey = Long.valueOf(1645);
241 final Long anotherNewValue = Long.valueOf(1815);
242 newValues.put(anotherNewKey, anotherNewValue);
243 weakHashtable.putAll(newValues);
244
245 assertEquals(5, weakHashtable.size());
246 assertEquals(newValue, weakHashtable.get(newKey));
247 assertEquals(anotherNewValue, weakHashtable.get(anotherNewKey));
248 }
249
250
251 public void testRemove() throws Exception {
252 weakHashtable.remove(keyOne);
253 assertEquals(2, weakHashtable.size());
254 assertNull(weakHashtable.get(keyOne));
255 }
256
257
258 public void testValues() throws Exception {
259 final Collection values = weakHashtable.values();
260 assertEquals(3, values.size());
261 assertTrue(values.contains(valueOne));
262 assertTrue(values.contains(valueTwo));
263 assertTrue(values.contains(valueThree));
264 }
265
266
267
268
269
270
271
272
273 public void xxxIgnoretestRelease() throws Exception {
274 assertNotNull(weakHashtable.get(Long.valueOf(1)));
275 final ReferenceQueue testQueue = new ReferenceQueue();
276 final WeakReference weakKeyOne = new WeakReference(keyOne, testQueue);
277
278
279 keyOne = null;
280 keyTwo = null;
281 keyThree = null;
282 valueOne = null;
283 valueTwo = null;
284 valueThree = null;
285
286 int iterations = 0;
287 int bytz = 2;
288 while(true) {
289 System.gc();
290 if (iterations++ > MAX_GC_ITERATIONS) {
291 fail("Max iterations reached before resource released.");
292 }
293
294 if (weakHashtable.get(Long.valueOf(1)) == null) {
295 break;
296
297 }
298
299 final byte[] b = new byte[bytz];
300 bytz *= 2;
301 }
302
303
304
305
306
307 while(testQueue.poll() == null) {}
308
309
310 assertEquals("underlying table not emptied", 0, weakHashtable.size());
311 }
312 }