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