HashtableTest.java revision cc05ad238516f1303687aba4a978e24e57c0c07a
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
18package tests.api.java.util;
19
20import dalvik.annotation.TestTargetNew;
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestLevel;
23import dalvik.annotation.TestTargetClass;
24
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Collection;
28import java.util.ConcurrentModificationException;
29import java.util.Enumeration;
30import java.util.HashSet;
31import java.util.Hashtable;
32import java.util.Iterator;
33import java.util.Map;
34import java.util.NoSuchElementException;
35import java.util.Set;
36import java.util.TreeMap;
37import java.util.Vector;
38
39import tests.api.java.util.HashMapTest.ReusableKey;
40import tests.support.Support_MapTest2;
41import tests.support.Support_UnmodifiableCollectionTest;
42
43@TestTargetClass(Hashtable.class)
44public class HashtableTest extends junit.framework.TestCase {
45
46    private Hashtable ht10;
47
48    private Hashtable ht100;
49
50    private Hashtable htfull;
51
52    private Vector keyVector;
53
54    private Vector elmVector;
55
56    private String h10sVal;
57
58    /**
59     * @tests java.util.Hashtable#Hashtable()
60     */
61    @TestTargetNew(
62        level = TestLevel.COMPLETE,
63        notes = "",
64        method = "Hashtable",
65        args = {}
66    )
67    public void test_Constructor() {
68        // Test for method java.util.Hashtable()
69        new Support_MapTest2(new Hashtable()).runTest();
70
71        Hashtable h = new Hashtable();
72
73        assertEquals("Created incorrect hashtable", 0, h.size());
74    }
75
76    /**
77     * @tests java.util.Hashtable#Hashtable(int)
78     */
79    @TestTargetNew(
80        level = TestLevel.COMPLETE,
81        notes = "",
82        method = "Hashtable",
83        args = {int.class}
84    )
85    public void test_ConstructorI() {
86        // Test for method java.util.Hashtable(int)
87        Hashtable h = new Hashtable(9);
88
89        assertEquals("Created incorrect hashtable", 0, h.size());
90
91        Hashtable empty = new Hashtable(0);
92        assertNull("Empty hashtable access", empty.get("nothing"));
93        empty.put("something", "here");
94        assertTrue("cannot get element", empty.get("something") == "here");
95
96        try {
97            new Hashtable(-1);
98            fail("IllegalArgumentException expected");
99        } catch (IllegalArgumentException e) {
100            //expected
101        }
102    }
103
104    /**
105     * @tests java.util.Hashtable#Hashtable(int, float)
106     */
107    @TestTargetNew(
108        level = TestLevel.COMPLETE,
109        notes = "",
110        method = "Hashtable",
111        args = {int.class, float.class}
112    )
113    public void test_ConstructorIF() {
114        // Test for method java.util.Hashtable(int, float)
115        Hashtable h = new java.util.Hashtable(10, 0.5f);
116        assertEquals("Created incorrect hashtable", 0, h.size());
117
118        Hashtable empty = new Hashtable(0, 0.75f);
119        assertNull("Empty hashtable access", empty.get("nothing"));
120        empty.put("something", "here");
121        assertTrue("cannot get element", empty.get("something") == "here");
122
123        try {
124            new Hashtable(-1, 0.75f);
125            fail("IllegalArgumentException expected");
126        } catch (IllegalArgumentException e) {
127            //expected
128        }
129
130        try {
131            new Hashtable(0, -0.75f);
132            fail("IllegalArgumentException expected");
133        } catch (IllegalArgumentException e) {
134            //expected
135        }
136    }
137
138    /**
139     * @tests java.util.Hashtable#Hashtable(java.util.Map)
140     */
141    @TestTargetNew(
142        level = TestLevel.COMPLETE,
143        notes = "",
144        method = "Hashtable",
145        args = {java.util.Map.class}
146    )
147    public void test_ConstructorLjava_util_Map() {
148        // Test for method java.util.Hashtable(java.util.Map)
149        Map map = new TreeMap();
150        Object firstVal = "Gabba";
151        Object secondVal = new Integer(5);
152        map.put("Gah", firstVal);
153        map.put("Ooga", secondVal);
154        Hashtable ht = new Hashtable(map);
155        assertTrue("a) Incorrect Hashtable constructed",
156                ht.get("Gah") == firstVal);
157        assertTrue("b) Incorrect Hashtable constructed",
158                ht.get("Ooga") == secondVal);
159
160        try {
161            new Hashtable(null);
162            fail("NullPointerException expected");
163        } catch (NullPointerException e) {
164            //expected
165        }
166    }
167
168    /**
169     * @tests java.util.Hashtable#clear()
170     */
171    @TestTargetNew(
172        level = TestLevel.COMPLETE,
173        notes = "",
174        method = "clear",
175        args = {}
176    )
177    public void test_clear() {
178        // Test for method void java.util.Hashtable.clear()
179        Hashtable h = hashtableClone(htfull);
180        h.clear();
181        assertEquals("Hashtable was not cleared", 0, h.size());
182        Enumeration el = h.elements();
183        Enumeration keys = h.keys();
184        assertTrue("Hashtable improperly cleared", !el.hasMoreElements()
185                && !(keys.hasMoreElements()));
186    }
187
188    /**
189     * @tests java.util.Hashtable#clone()
190     */
191    @TestTargetNew(
192        level = TestLevel.COMPLETE,
193        notes = "",
194        method = "clone",
195        args = {}
196    )
197    public void test_clone() {
198        // Test for method java.lang.Object java.util.Hashtable.clone()
199
200        Hashtable h = (Hashtable) htfull.clone();
201        assertTrue("Clone different size than original", h.size() == htfull
202                .size());
203
204        Enumeration org = htfull.keys();
205        Enumeration cpy = h.keys();
206
207        String okey, ckey;
208        while (org.hasMoreElements()) {
209            assertTrue("Key comparison failed", (okey = (String) org
210                    .nextElement()).equals(ckey = (String) cpy.nextElement()));
211            assertTrue("Value comparison failed", ((String) htfull.get(okey))
212                    .equals((String) h.get(ckey)));
213        }
214        assertTrue("Copy has more keys than original", !cpy.hasMoreElements());
215    }
216
217    /**
218     * @tests java.util.Hashtable#contains(java.lang.Object)
219     */
220    @TestTargetNew(
221        level = TestLevel.COMPLETE,
222        notes = "",
223        method = "contains",
224        args = {java.lang.Object.class}
225    )
226    public void test_containsLjava_lang_Object() {
227        // Test for method boolean
228        // java.util.Hashtable.contains(java.lang.Object)
229        assertTrue("Element not found", ht10.contains("Val 7"));
230        assertTrue("Invalid element found", !ht10.contains("ZZZZZZZZZZZZZZZZ"));
231
232        try {
233            ht10.contains(null);
234            fail("NullPointerException expected");
235        } catch (NullPointerException e) {
236            //expected
237        }
238    }
239
240    /**
241     * @tests java.util.Hashtable#containsKey(java.lang.Object)
242     */
243    @TestTargetNew(
244        level = TestLevel.COMPLETE,
245        notes = "",
246        method = "containsKey",
247        args = {java.lang.Object.class}
248    )
249    public void test_containsKeyLjava_lang_Object() {
250        // Test for method boolean
251        // java.util.Hashtable.containsKey(java.lang.Object)
252
253        assertTrue("Failed to find key", htfull.containsKey("FKey 4"));
254        assertTrue("Failed to find key", !htfull.containsKey("FKey 99"));
255
256        try {
257            htfull.containsKey(null);
258            fail("NullPointerException expected");
259        } catch (NullPointerException e) {
260            //expected
261        }
262    }
263
264    /**
265     * @tests java.util.Hashtable#containsValue(java.lang.Object)
266     */
267    @TestTargetNew(
268        level = TestLevel.COMPLETE,
269        notes = "",
270        method = "containsValue",
271        args = {java.lang.Object.class}
272    )
273    public void test_containsValueLjava_lang_Object() {
274        // Test for method boolean
275        // java.util.Hashtable.containsValue(java.lang.Object)
276        Enumeration e = elmVector.elements();
277        while (e.hasMoreElements())
278            assertTrue("Returned false for valid value", ht10.containsValue(e
279                    .nextElement()));
280        assertTrue("Returned true for invalid value", !ht10
281                .containsValue(new Object()));
282
283        try {
284            ht10.containsValue(null);
285            fail("NullPointerException expected");
286        } catch (NullPointerException ee) {
287            //expected
288        }
289    }
290
291    /**
292     * @tests java.util.Hashtable#elements()
293     */
294    @TestTargetNew(
295        level = TestLevel.COMPLETE,
296        notes = "",
297        method = "elements",
298        args = {}
299    )
300    public void test_elements() {
301        // Test for method java.util.Enumeration java.util.Hashtable.elements()
302        Enumeration elms = ht10.elements();
303        int i = 0;
304        while (elms.hasMoreElements()) {
305            String s = (String) elms.nextElement();
306            assertTrue("Missing key from enumeration", elmVector.contains(s));
307            ++i;
308        }
309
310        assertEquals("All keys not retrieved", 10, ht10.size());
311    }
312
313    /**
314     * @tests java.util.Hashtable#elements()
315     */
316    @TestTargetNew(
317        level = TestLevel.COMPLETE,
318        notes = "",
319        method = "elements",
320        args = {}
321    )
322    public void test_elements_subtest0() {
323        // this is the reference implementation behavior
324        final Hashtable ht = new Hashtable(7);
325        ht.put("1", "a");
326        // these three elements hash to the same bucket in a 7 element Hashtable
327        ht.put("2", "b");
328        ht.put("9", "c");
329        ht.put("12", "d");
330        // Hashtable looks like:
331        // 0: "1"
332        // 1: "12" -> "9" -> "2"
333        Enumeration en = ht.elements();
334        // cache the first entry
335        en.hasMoreElements();
336        ht.remove("12");
337        ht.remove("9");
338        boolean exception = false;
339        try {
340            // cached "12"
341            Object result = en.nextElement();
342            assertNull("unexpected: " + result, result);
343            // next is removed "9"
344            result = en.nextElement();
345            assertNull("unexpected: " + result, result);
346            result = en.nextElement();
347            assertTrue("unexpected: " + result, "b".equals(result));
348        } catch (NoSuchElementException e) {
349            exception = true;
350        }
351        assertTrue("unexpected NoSuchElementException", !exception);
352    }
353
354    /**
355     * @tests java.util.Hashtable#entrySet()
356     */
357    @TestTargetNew(
358        level = TestLevel.COMPLETE,
359        notes = "",
360        method = "entrySet",
361        args = {}
362    )
363    public void test_entrySet() {
364        // Test for method java.util.Set java.util.Hashtable.entrySet()
365        Set s = ht10.entrySet();
366        Set s2 = new HashSet();
367        Iterator i = s.iterator();
368        while (i.hasNext())
369            s2.add(((Map.Entry) i.next()).getValue());
370        Enumeration e = elmVector.elements();
371        while (e.hasMoreElements())
372            assertTrue("Returned incorrect entry set", s2.contains(e
373                    .nextElement()));
374
375        assertEquals("Not synchronized",
376                "java.util.Collections$SynchronizedSet", s.getClass().getName());
377
378        boolean exception = false;
379        try {
380            ((Map.Entry) ht10.entrySet().iterator().next()).setValue(null);
381        } catch (NullPointerException e1) {
382            exception = true;
383        }
384        assertTrue(
385                "Should not be able to assign null to a Hashtable entrySet() Map.Entry",
386                exception);
387    }
388
389    /**
390     * @tests java.util.Hashtable#equals(java.lang.Object)
391     */
392    @TestTargetNew(
393        level = TestLevel.COMPLETE,
394        notes = "",
395        method = "equals",
396        args = {java.lang.Object.class}
397    )
398    public void test_equalsLjava_lang_Object() {
399        // Test for method boolean java.util.Hashtable.equals(java.lang.Object)
400        Hashtable h = hashtableClone(ht10);
401        assertTrue("Returned false for equal tables", ht10.equals(h));
402        assertTrue("Returned true for unequal tables", !ht10.equals(htfull));
403    }
404
405    /**
406     * @tests java.util.Hashtable#get(java.lang.Object)
407     */
408    @TestTargetNew(
409        level = TestLevel.COMPLETE,
410        notes = "",
411        method = "get",
412        args = {java.lang.Object.class}
413    )
414    public void test_getLjava_lang_Object() {
415        // Test for method java.lang.Object
416        // java.util.Hashtable.get(java.lang.Object)
417        Hashtable h = hashtableClone(htfull);
418        assertEquals("Could not retrieve element", "FVal 2", ((String) h.get("FKey 2"))
419                );
420
421
422        // Regression for HARMONY-262
423        ReusableKey k = new ReusableKey();
424        Hashtable h2 = new Hashtable();
425        k.setKey(1);
426        h2.put(k, "value1");
427
428        k.setKey(13);
429        assertNull(h2.get(k));
430
431        k.setKey(12);
432        assertNull(h2.get(k));
433
434        try {
435            h2.get(null);
436            fail("NullPointerException expected");
437        } catch (NullPointerException e) {
438            //expected
439        }
440    }
441
442    /**
443     * @tests java.util.Hashtable#hashCode()
444     */
445    @TestTargetNew(
446        level = TestLevel.COMPLETE,
447        notes = "",
448        method = "hashCode",
449        args = {}
450    )
451    public void test_hashCode() {
452        // Test for method int java.util.Hashtable.hashCode()
453        Set entrySet = ht10.entrySet();
454        Iterator iterator = entrySet.iterator();
455        int expectedHash;
456        for (expectedHash = 0; iterator.hasNext(); expectedHash += iterator
457                .next().hashCode())
458            ;
459        assertTrue("Incorrect hashCode returned.  Wanted: " + expectedHash
460                + " got: " + ht10.hashCode(), expectedHash == ht10.hashCode());
461    }
462
463    /**
464     * @tests java.util.Hashtable#isEmpty()
465     */
466    @TestTargetNew(
467        level = TestLevel.COMPLETE,
468        notes = "",
469        method = "isEmpty",
470        args = {}
471    )
472    public void test_isEmpty() {
473        // Test for method boolean java.util.Hashtable.isEmpty()
474
475        assertTrue("isEmpty returned incorrect value", !ht10.isEmpty());
476        assertTrue("isEmpty returned incorrect value",
477                new java.util.Hashtable().isEmpty());
478
479        final Hashtable ht = new Hashtable();
480        ht.put("0", "");
481        Thread t1 = new Thread() {
482            public void run() {
483                while (!ht.isEmpty())
484                    ;
485                ht.put("final", "");
486            }
487        };
488        t1.start();
489        for (int i = 1; i < 10000; i++) {
490            synchronized (ht) {
491                ht.remove(String.valueOf(i - 1));
492                ht.put(String.valueOf(i), "");
493            }
494            int size;
495            if ((size = ht.size()) != 1) {
496                String result = "Size is not 1: " + size + " " + ht;
497                // terminate the thread
498                ht.clear();
499                fail(result);
500            }
501        }
502        // terminate the thread
503        ht.clear();
504    }
505
506    /**
507     * @tests java.util.Hashtable#keys()
508     */
509    @TestTargetNew(
510        level = TestLevel.COMPLETE,
511        notes = "",
512        method = "keys",
513        args = {}
514    )
515    public void test_keys() {
516        // Test for method java.util.Enumeration java.util.Hashtable.keys()
517
518        Enumeration keys = ht10.keys();
519        int i = 0;
520        while (keys.hasMoreElements()) {
521            String s = (String) keys.nextElement();
522            assertTrue("Missing key from enumeration", keyVector.contains(s));
523            ++i;
524        }
525
526        assertEquals("All keys not retrieved", 10, ht10.size());
527    }
528
529    /**
530     * @tests java.util.Hashtable#keys()
531     */
532    @TestTargetNew(
533        level = TestLevel.PARTIAL_COMPLETE,
534        notes = "",
535        method = "keys",
536        args = {}
537    )
538    public void test_keys_subtest0() {
539        // this is the reference implementation behavior
540        final Hashtable ht = new Hashtable(3);
541        ht.put("initial", "");
542        Enumeration en = ht.keys();
543        en.hasMoreElements();
544        ht.remove("initial");
545        boolean exception = false;
546        try {
547            Object result = en.nextElement();
548            assertTrue("unexpected: " + result, "initial".equals(result));
549        } catch (NoSuchElementException e) {
550            exception = true;
551        }
552        assertTrue("unexpected NoSuchElementException", !exception);
553    }
554
555    /**
556     * @tests java.util.Hashtable#keySet()
557     */
558    @TestTargetNew(
559        level = TestLevel.COMPLETE,
560        notes = "",
561        method = "keySet",
562        args = {}
563    )
564    public void test_keySet() {
565        // Test for method java.util.Set java.util.Hashtable.keySet()
566        Set s = ht10.keySet();
567        Enumeration e = keyVector.elements();
568        while (e.hasMoreElements())
569            assertTrue("Returned incorrect key set", s
570                    .contains(e.nextElement()));
571
572        assertEquals("Not synchronized",
573                "java.util.Collections$SynchronizedSet", s.getClass().getName());
574
575        Map map = new Hashtable(101);
576        map.put(new Integer(1), "1");
577        map.put(new Integer(102), "102");
578        map.put(new Integer(203), "203");
579        Iterator it = map.keySet().iterator();
580        Integer remove1 = (Integer) it.next();
581        it.remove();
582        Integer remove2 = (Integer) it.next();
583        it.remove();
584        ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
585                new Integer(1), new Integer(102), new Integer(203) }));
586        list.remove(remove1);
587        list.remove(remove2);
588        assertTrue("Wrong result", it.next().equals(list.get(0)));
589        assertEquals("Wrong size", 1, map.size());
590        assertTrue("Wrong contents", map.keySet().iterator().next().equals(
591                list.get(0)));
592
593        Map map2 = new Hashtable(101);
594        map2.put(new Integer(1), "1");
595        map2.put(new Integer(4), "4");
596        Iterator it2 = map2.keySet().iterator();
597        Integer remove3 = (Integer) it2.next();
598        Integer next;
599        if (remove3.intValue() == 1)
600            next = new Integer(4);
601        else
602            next = new Integer(1);
603        it2.hasNext();
604        it2.remove();
605        assertTrue("Wrong result 2", it2.next().equals(next));
606        assertEquals("Wrong size 2", 1, map2.size());
607        assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
608                next));
609    }
610
611    /**
612     * @tests java.util.Hashtable#keySet()
613     */
614    @TestTargetNew(
615        level = TestLevel.PARTIAL_COMPLETE,
616        notes = "",
617        method = "keySet",
618        args = {}
619    )
620    public void test_keySet_subtest0() {
621        Set s1 = ht10.keySet();
622        assertTrue("should contain key", s1.remove("Key 0"));
623        assertTrue("should not contain key", !s1.remove("Key 0"));
624
625        final int iterations = 10000;
626        final Hashtable ht = new Hashtable();
627        Thread t1 = new Thread() {
628            public void run() {
629                for (int i = 0; i < iterations; i++) {
630                    ht.put(String.valueOf(i), "");
631                    ht.remove(String.valueOf(i));
632                }
633            }
634        };
635        t1.start();
636        Set set = ht.keySet();
637        for (int i = 0; i < iterations; i++) {
638            Iterator it = set.iterator();
639            try {
640                it.next();
641                it.remove();
642                int size;
643                // ensure removing with the iterator doesn't corrupt the
644                // Hashtable
645                if ((size = ht.size()) < 0) {
646                    fail("invalid size: " + size);
647                }
648            } catch (NoSuchElementException e) {
649            } catch (ConcurrentModificationException e) {
650            }
651        }
652    }
653
654    /**
655     * @tests java.util.Hashtable#keySet()
656     */
657    @TestTargetNew(
658        level = TestLevel.PARTIAL_COMPLETE,
659        notes = "",
660        method = "keySet",
661        args = {}
662    )
663    public void test_keySet_subtest1() {
664        // this is the reference implementation behavior
665        final Hashtable ht = new Hashtable(7);
666        ht.put("1", "a");
667        // these three elements hash to the same bucket in a 7 element Hashtable
668        ht.put("2", "b");
669        ht.put("9", "c");
670        ht.put("12", "d");
671        // Hashtable looks like:
672        // 0: "1"
673        // 1: "12" -> "9" -> "2"
674        Enumeration en = ht.elements();
675        // cache the first entry
676        en.hasMoreElements();
677        Iterator it = ht.keySet().iterator();
678        // this is mostly a copy of the test in test_elements_subtest0()
679        // test removing with the iterator does not null the values
680        while (it.hasNext()) {
681            String key = (String) it.next();
682            if ("12".equals(key) || "9".equals(key)) {
683                it.remove();
684            }
685        }
686        it.remove();
687        boolean exception = false;
688        try {
689            // cached "12"
690            Object result = en.nextElement();
691            assertTrue("unexpected: " + result, "d".equals(result));
692            // next is removed "9"
693            result = en.nextElement();
694            assertTrue("unexpected: " + result, "c".equals(result));
695            result = en.nextElement();
696            assertTrue("unexpected: " + result, "b".equals(result));
697        } catch (NoSuchElementException e) {
698            exception = true;
699        }
700        assertTrue("unexpected NoSuchElementException", !exception);
701    }
702
703    /**
704     * @tests java.util.Hashtable#put(java.lang.Object, java.lang.Object)
705     */
706    @TestTargetNew(
707        level = TestLevel.COMPLETE,
708        notes = "",
709        method = "put",
710        args = {java.lang.Object.class, java.lang.Object.class}
711    )
712    public void test_putLjava_lang_ObjectLjava_lang_Object() {
713        // Test for method java.lang.Object
714        // java.util.Hashtable.put(java.lang.Object, java.lang.Object)
715        Hashtable h = hashtableClone(ht100);
716        Integer key = new Integer(100);
717        h.put("Value 100", key);
718        assertTrue("Key/Value not inserted", h.size() == 1 && (h.contains(key)));
719
720        // Put into "full" table
721        h = hashtableClone(htfull);
722        h.put("Value 100", key);
723        assertTrue("Key/Value not inserted into full table", h.size() == 8
724                && (h.contains(key)));
725
726        try {
727            h.put(null, key);
728            fail("NullPointerException expected");
729        } catch (NullPointerException e) {
730            //expected
731        }
732
733        try {
734            h.put("Value 100", null);
735            fail("NullPointerException expected");
736        } catch (NullPointerException e) {
737            //expected
738        }
739    }
740
741    /**
742     * @tests java.util.Hashtable#putAll(java.util.Map)
743     */
744    @TestTargetNew(
745        level = TestLevel.COMPLETE,
746        notes = "",
747        method = "putAll",
748        args = {java.util.Map.class}
749    )
750    public void test_putAllLjava_util_Map() {
751        // Test for method void java.util.Hashtable.putAll(java.util.Map)
752        Hashtable h = new Hashtable();
753        h.putAll(ht10);
754        Enumeration e = keyVector.elements();
755        while (e.hasMoreElements()) {
756            Object x = e.nextElement();
757            assertTrue("Failed to put all elements", h.get(x).equals(
758                    ht10.get(x)));
759        }
760
761        try {
762            h.putAll(null);
763            fail("NullPointerException expected");
764        } catch (NullPointerException ee) {
765            //expected
766        }
767    }
768
769    /**
770     * @tests java.util.Hashtable#remove(java.lang.Object)
771     */
772    @TestTargetNew(
773        level = TestLevel.COMPLETE,
774        notes = "",
775        method = "remove",
776        args = {java.lang.Object.class}
777    )
778    public void test_removeLjava_lang_Object() {
779        // Test for method java.lang.Object
780        // java.util.Hashtable.remove(java.lang.Object)
781        Hashtable h = hashtableClone(htfull);
782        Object k = h.remove("FKey 0");
783        assertTrue("Remove failed", !h.containsKey("FKey 0") || k == null);
784        assertNull(h.remove("FKey 0"));
785
786        try {
787            h.remove(null);
788            fail("NullPointerException expected");
789        } catch (NullPointerException e) {
790            //expected
791        }
792    }
793
794    /**
795     * @tests java.util.Hashtable#size()
796     */
797    @TestTargetNew(
798        level = TestLevel.COMPLETE,
799        notes = "",
800        method = "size",
801        args = {}
802    )
803    public void test_size() {
804        // Test for method int java.util.Hashtable.size()
805        assertTrue("Returned invalid size", ht10.size() == 10
806                && (ht100.size() == 0));
807
808        final Hashtable ht = new Hashtable();
809        ht.put("0", "");
810        Thread t1 = new Thread() {
811            public void run() {
812                while (ht.size() > 0)
813                    ;
814                ht.put("final", "");
815            }
816        };
817        t1.start();
818        for (int i = 1; i < 10000; i++) {
819            synchronized (ht) {
820                ht.remove(String.valueOf(i - 1));
821                ht.put(String.valueOf(i), "");
822            }
823            int size;
824            if ((size = ht.size()) != 1) {
825                String result = "Size is not 1: " + size + " " + ht;
826                // terminate the thread
827                ht.clear();
828                fail(result);
829            }
830        }
831        // terminate the thread
832        ht.clear();
833    }
834
835    /**
836     * @tests java.util.Hashtable#toString()
837     */
838    @TestTargetNew(
839        level = TestLevel.COMPLETE,
840        notes = "",
841        method = "toString",
842        args = {}
843    )
844    public void test_toString() {
845        // Test for method java.lang.String java.util.Hashtable.toString()
846        Hashtable h = new Hashtable();
847        assertEquals("Incorrect toString for Empty table",
848                "{}", h.toString());
849
850        h.put("one", "1");
851        h.put("two", h);
852        h.put(h, "3");
853        h.put(h, h);
854        String result = h.toString();
855        assertTrue("should contain self ref", result.indexOf("(this") > -1);
856    }
857
858    /**
859     * @tests java.util.Hashtable#values()
860     */
861    @TestTargetNew(
862        level = TestLevel.COMPLETE,
863        notes = "",
864        method = "values",
865        args = {}
866    )
867    public void test_values() {
868        // Test for method java.util.Collection java.util.Hashtable.values()
869        Collection c = ht10.values();
870        Enumeration e = elmVector.elements();
871        while (e.hasMoreElements())
872            assertTrue("Returned incorrect values", c.contains(e.nextElement()));
873
874        assertEquals("Not synchronized",
875                "java.util.Collections$SynchronizedCollection", c.getClass().getName());
876
877        Hashtable myHashtable = new Hashtable();
878        for (int i = 0; i < 100; i++)
879            myHashtable.put(new Integer(i), new Integer(i));
880        Collection values = myHashtable.values();
881        new Support_UnmodifiableCollectionTest(
882                "Test Returned Collection From Hashtable.values()", values)
883                .runTest();
884        values.remove(new Integer(0));
885        assertTrue(
886                "Removing from the values collection should remove from the original map",
887                !myHashtable.containsValue(new Integer(0)));
888    }
889
890    /**
891     * Regression Test for JIRA 2181
892     */
893    @TestTargets({
894        @TestTargetNew(
895            level = TestLevel.PARTIAL_COMPLETE,
896            notes = "",
897            method = "entrySet",
898            args = {}
899        ),
900        @TestTargetNew(
901            level = TestLevel.PARTIAL_COMPLETE,
902            notes = "",
903            method = "remove",
904            args = {java.lang.Object.class}
905        )
906    })
907    public void test_entrySet_remove()
908    {
909        Hashtable<String,String> hashtable = new Hashtable<String,String>();
910        hashtable.put("my.nonexistent.prop", "AAA");
911        hashtable.put( "parse.error", "BBB" );
912        Iterator<Map.Entry<String,String>> iterator =
913            hashtable.entrySet().iterator();
914        while(iterator.hasNext())
915        {
916            Map.Entry entry = iterator.next();
917            final Object value = entry.getValue();
918            if(value.equals("AAA"))
919            {
920               iterator.remove();
921            }
922        }
923        assertFalse(hashtable.containsKey("my.nonexistent.prop"));
924    }
925
926    class Mock_Hashtable extends Hashtable {
927        boolean flag = false;
928
929        public Mock_Hashtable(int i) {
930            super(i);
931        }
932
933        @Override
934        protected void rehash() {
935            flag = true;
936            super.rehash();
937        }
938
939        public boolean isRehashed() {
940            return flag;
941        }
942    }
943
944    @TestTargetNew(
945        level = TestLevel.COMPLETE,
946        notes = "",
947        method = "rehash",
948        args = {}
949    )
950    public void test_rehash() {
951        Mock_Hashtable mht = new Mock_Hashtable(5);
952
953        assertFalse(mht.isRehashed());
954        for(int i = 0; i < 10; i++) {
955            mht.put(i, "New value");
956        }
957        assertTrue(mht.isRehashed());
958    }
959
960    protected Hashtable hashtableClone(Hashtable s) {
961        return (Hashtable) s.clone();
962    }
963
964    /**
965     * Sets up the fixture, for example, open a network connection. This method
966     * is called before a test is executed.
967     */
968    protected void setUp() {
969
970        ht10 = new Hashtable(10);
971        ht100 = new Hashtable(100);
972        htfull = new Hashtable(10);
973        keyVector = new Vector(10);
974        elmVector = new Vector(10);
975
976        for (int i = 0; i < 10; i++) {
977            ht10.put("Key " + i, "Val " + i);
978            keyVector.addElement("Key " + i);
979            elmVector.addElement("Val " + i);
980        }
981
982        for (int i = 0; i < 7; i++)
983            htfull.put("FKey " + i, "FVal " + i);
984    }
985
986    /**
987     * Tears down the fixture, for example, close a network connection. This
988     * method is called after a test is executed.
989     */
990    protected void tearDown() {
991    }
992}
993