    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18
    19  package org.apache.commons.logging.impl;
    20
    21  import java.lang.ref.*;
    22  import junit.framework.*;
    23  import java.util.*;
    24
    25  public class WeakHashtableTest extends TestCase {
    26
    27
    28      /** Maximum number of iterations before our test fails */
    29      private static final int MAX_GC_ITERATIONS = 50;
    30
    31      private WeakHashtable weakHashtable;
    32      private Long keyOne;
    33      private Long keyTwo;
    34      private Long keyThree;
    35      private Long valueOne;
    36      private Long valueTwo;
    37      private Long valueThree;
    38
    39      public WeakHashtableTest(String testName) {
    40          super(testName);
    41      }
    42
    43
    44      protected void setUp() throws Exception {
    45          super.setUp();
    46          weakHashtable = new WeakHashtable();
    47
    48          keyOne = new Long(1);
    49          keyTwo = new Long(2);
    50          keyThree = new Long(3);
    51          valueOne = new Long(100);
    52          valueTwo = new Long(200);
    53          valueThree = new Long(300);
    54
    55          weakHashtable.put(keyOne, valueOne);
    56          weakHashtable.put(keyTwo, valueTwo);
    57          weakHashtable.put(keyThree, valueThree);
    58      }
    59
    60      /** Tests public boolean contains(Object value) */
    61      public void testContains() throws Exception {
    62          assertFalse(weakHashtable.contains(new Long(1)));
    63          assertFalse(weakHashtable.contains(new Long(2)));
    64          assertFalse(weakHashtable.contains(new Long(3)));
    65          assertTrue(weakHashtable.contains(new Long(100)));
    66          assertTrue(weakHashtable.contains(new Long(200)));
    67          assertTrue(weakHashtable.contains(new Long(300)));
    68          assertFalse(weakHashtable.contains(new Long(400)));
    69      }
    70
    71      /** Tests public boolean containsKey(Object key) */
    72      public void testContainsKey() throws Exception {
    73          assertTrue(weakHashtable.containsKey(new Long(1)));
    74          assertTrue(weakHashtable.containsKey(new Long(2)));
    75          assertTrue(weakHashtable.containsKey(new Long(3)));
    76          assertFalse(weakHashtable.containsKey(new Long(100)));
    77          assertFalse(weakHashtable.containsKey(new Long(200)));
    78          assertFalse(weakHashtable.containsKey(new Long(300)));
    79          assertFalse(weakHashtable.containsKey(new Long(400)));
    80      }
    81
    82      /** Tests public boolean containsValue(Object value) */
    83      public void testContainsValue() throws Exception {
    84          assertFalse(weakHashtable.containsValue(new Long(1)));
    85          assertFalse(weakHashtable.containsValue(new Long(2)));
    86          assertFalse(weakHashtable.containsValue(new Long(3)));
    87          assertTrue(weakHashtable.containsValue(new Long(100)));
    88          assertTrue(weakHashtable.containsValue(new Long(200)));
    89          assertTrue(weakHashtable.containsValue(new Long(300)));
    90          assertFalse(weakHashtable.containsValue(new Long(400)));
    91      }
    92
    93      /** Tests public Enumeration elements() */
    94      public void testElements() throws Exception {
    95          ArrayList elements = new ArrayList();
    96          for (Enumeration e = weakHashtable.elements(); e.hasMoreElements();) {
    97              elements.add(e.nextElement());
    98          }
    99          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 }