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 org.apache.harmony.logging.tests.java.util.logging;
19
20import dalvik.annotation.TestTargetClass;
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestTargetNew;
23import dalvik.annotation.TestLevel;
24
25import java.io.Serializable;
26import java.util.ResourceBundle;
27import java.util.logging.Handler;
28import java.util.logging.Level;
29
30import junit.framework.TestCase;
31
32import org.apache.harmony.testframework.serialization.SerializationTest;
33import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
34
35/*
36 * This class implements Serializable, so that the non-static inner class
37 * MockLevel can be Serializable.
38 */
39@TestTargetClass(Level.class)
40public class LevelTest extends TestCase implements Serializable {
41
42    private static final long serialVersionUID = 1L;
43
44    /**
45     * Test the constructor without resource bundle parameter using normal
46     * values. As byproducts, getName & intValue are also tested.
47     */
48    @TestTargets({
49        @TestTargetNew(
50            level = TestLevel.PARTIAL_COMPLETE,
51            notes = "Checks  the constructor without resource bundle parameter using normal values.",
52            method = "Level",
53            args = {java.lang.String.class, int.class}
54        ),
55        @TestTargetNew(
56            level = TestLevel.PARTIAL_COMPLETE,
57            notes = "Checks  the constructor without resource bundle parameter using normal values.",
58            method = "getName",
59            args = {}
60        )
61    })
62    public void testConstructorNoResBundle_Normal() {
63        MockLevel l = new MockLevel("level1", 1);
64        assertEquals("level1", l.getName());
65        assertEquals(1, l.intValue());
66        assertNull(l.getResourceBundleName());
67    }
68
69    /**
70     * Test the constructor without resource bundle parameter using null name.
71     * As byproducts, getName & intValue are also tested.
72     */
73    @TestTargets({
74        @TestTargetNew(
75            level = TestLevel.PARTIAL_COMPLETE,
76            notes = "Checks the constructor without resource bundle parameter using null name.",
77            method = "Level",
78            args = {java.lang.String.class, int.class}
79        ),
80        @TestTargetNew(
81            level = TestLevel.PARTIAL_COMPLETE,
82            notes = "Checks the constructor without resource bundle parameter using null name.",
83            method = "getName",
84            args = {}
85        )
86    })
87    public void testConstructorNoResBundle_NullName() {
88        try {
89            new MockLevel(null, -2);
90            fail("No expected NullPointerException");
91        } catch (NullPointerException ignore) {
92            // expected
93        }
94    }
95
96    /*
97     * Test the constructor without resource bundle parameter using empty name.
98     * As byproducts, getName & intValue are also tested.
99     */
100    @TestTargets({
101        @TestTargetNew(
102            level = TestLevel.PARTIAL_COMPLETE,
103            notes = "Checks the constructor without resource bundle parameter using empty name.",
104            method = "Level",
105            args = {java.lang.String.class, int.class}
106        ),
107        @TestTargetNew(
108            level = TestLevel.PARTIAL_COMPLETE,
109            notes = "Checks the constructor without resource bundle parameter using empty name.",
110            method = "getName",
111            args = {}
112        )
113    })
114     public void testConstructorNoResBundle_EmptyName() {
115        MockLevel l = new MockLevel("", -3);
116        assertEquals("", l.getName());
117        assertEquals(-3, l.intValue());
118        assertNull(l.getResourceBundleName());
119    }
120
121    /*
122     * Test the constructor having resource bundle parameter using normal
123     * values. As byproducts, getName & intValue are also tested.
124     */
125    @TestTargets({
126        @TestTargetNew(
127            level = TestLevel.PARTIAL_COMPLETE,
128            notes = "",
129            method = "Level",
130            args = {java.lang.String.class, int.class, java.lang.String.class}
131        ),
132        @TestTargetNew(
133            level = TestLevel.PARTIAL_COMPLETE,
134            notes = "",
135            method = "getName",
136            args = {}
137        )
138    })
139    public void testConstructorHavingResBundle_Normal() {
140        MockLevel l = new MockLevel("level1", 1, "resourceBundle");
141        assertEquals("level1", l.getName());
142        assertEquals(1, l.intValue());
143        assertEquals("resourceBundle", l.getResourceBundleName());
144    }
145
146    /*
147     * Test the constructor having resource bundle parameter using null names.
148     * As byproducts, getName & intValue are also tested.
149     */
150    @TestTargetNew(
151        level = TestLevel.PARTIAL_COMPLETE,
152        notes = "Checks NullPointerException.",
153        method = "Level",
154        args = {java.lang.String.class, int.class, java.lang.String.class}
155    )
156    public void testConstructorHavingResBundle_NullName() {
157        try {
158            new MockLevel(null, -123, "qwe");
159            fail("No expected NullPointerException");
160        } catch (NullPointerException ignore) {
161            // expected
162        }
163    }
164
165     /*
166     * Test the constructor having resource bundle parameter using empty
167     names.
168     * As byproducts, getName & intValue are also tested.
169     */
170    @TestTargetNew(
171        level = TestLevel.PARTIAL_COMPLETE,
172        notes = "Verifies the constructor having resource bundle parameter using empty names.",
173        method = "Level",
174        args = {java.lang.String.class, int.class, java.lang.String.class}
175    )
176     public void testConstructorHavingResBundle_EmptyName() {
177     MockLevel l = new MockLevel("", -1000, "");
178     assertEquals("", l.getName());
179     assertEquals(-1000, l.intValue());
180     assertEquals("", l.getResourceBundleName());
181     }
182
183    /*
184     * Test method parse, with the pre-defined string consts.
185     */
186    @TestTargetNew(
187        level = TestLevel.PARTIAL_COMPLETE,
188        notes = "Verifies parse, with the pre-defined string consts.",
189        method = "parse",
190        args = {java.lang.String.class}
191    )
192    public void testParse_PredefinedConstStrings() {
193        assertSame(Level.SEVERE, Level.parse("SEVERE"));
194        assertSame(Level.WARNING, Level.parse("WARNING"));
195        assertSame(Level.INFO, Level.parse("INFO"));
196        assertSame(Level.CONFIG, Level.parse("CONFIG"));
197        assertSame(Level.FINE, Level.parse("FINE"));
198        assertSame(Level.FINER, Level.parse("FINER"));
199        assertSame(Level.FINEST, Level.parse("FINEST"));
200        assertSame(Level.OFF, Level.parse("OFF"));
201        assertSame(Level.ALL, Level.parse("ALL"));
202    }
203
204    /*
205     * Test method parse, with an undefined string.
206     */
207    @TestTargetNew(
208        level = TestLevel.PARTIAL_COMPLETE,
209        notes = "IllegalArgumentException is verified.",
210        method = "parse",
211        args = {java.lang.String.class}
212    )
213    public void testParse_IllegalConstString() {
214        try {
215            Level.parse("SEVERe");
216            fail("Should throw IllegalArgumentException if undefined string.");
217        } catch (IllegalArgumentException e) {
218            // expected
219        }
220    }
221
222    /*
223     * Test method parse, with a null string.
224     */
225    @TestTargetNew(
226        level = TestLevel.PARTIAL_COMPLETE,
227        notes = "Verifies null as a parameter.",
228        method = "parse",
229        args = {java.lang.String.class}
230    )
231    public void testParse_NullString() {
232        try {
233            Level.parse(null);
234            fail("Should throw NullPointerException.");
235        } catch (NullPointerException e) {
236            // expected
237        }
238    }
239
240    /*
241     * Test method parse, with pre-defined valid number strings.
242     */
243    @TestTargetNew(
244        level = TestLevel.PARTIAL_COMPLETE,
245        notes = "Verifies parse, with pre-defined valid number strings.",
246        method = "parse",
247        args = {java.lang.String.class}
248    )
249    public void testParse_PredefinedNumber() {
250        assertSame(Level.SEVERE, Level.parse("SEVERE"));
251        assertSame(Level.WARNING, Level.parse("WARNING"));
252        assertSame(Level.INFO, Level.parse("INFO"));
253        assertSame(Level.CONFIG, Level.parse("CONFIG"));
254        assertSame(Level.FINE, Level.parse("FINE"));
255        assertSame(Level.FINER, Level.parse("FINER"));
256        assertSame(Level.FINEST, Level.parse("FINEST"));
257        assertSame(Level.OFF, Level.parse("OFF"));
258        assertSame(Level.ALL, Level.parse("ALL"));
259        assertSame(Level.SEVERE, Level.parse("1000"));
260        assertSame(Level.WARNING, Level.parse("900"));
261        assertSame(Level.INFO, Level.parse("800"));
262        assertSame(Level.CONFIG, Level.parse("700"));
263        assertSame(Level.FINE, Level.parse("500"));
264        assertSame(Level.FINER, Level.parse("400"));
265        assertSame(Level.FINEST, Level.parse("300"));
266        assertSame(Level.OFF, Level.parse(String.valueOf(Integer.MAX_VALUE)));
267        assertSame(Level.ALL, Level.parse(String.valueOf(Integer.MIN_VALUE)));
268    }
269
270    /*
271     * Test method parse, with an undefined valid number strings.
272     */
273    @TestTargetNew(
274        level = TestLevel.PARTIAL_COMPLETE,
275        notes = "Verifies parse, with an undefined valid number strings.",
276        method = "parse",
277        args = {java.lang.String.class}
278    )
279    public void testParse_UndefinedNumber() {
280        Level l = Level.parse("0");
281        assertEquals(0, l.intValue());
282        assertEquals("0", l.getName());
283        assertNull(l.getResourceBundleName());
284    }
285
286    /*
287     * Test method parse, with an undefined valid number strings with spaces.
288     */
289    @TestTargetNew(
290        level = TestLevel.PARTIAL_COMPLETE,
291        notes = "Verifies parse, with an undefined valid number strings with spaces.",
292        method = "parse",
293        args = {java.lang.String.class}
294    )
295    public void testParse_UndefinedNumberWithSpaces() {
296        try {
297            Level.parse(" 0");
298        } catch (IllegalArgumentException e) {
299            // expected
300        }
301    }
302    @TestTargetNew(
303        level = TestLevel.PARTIAL_COMPLETE,
304        notes = "Verifies negative number.",
305        method = "parse",
306        args = {java.lang.String.class}
307    )
308    public void testParse_NegativeNumber() {
309        Level l = Level.parse("-4");
310        assertEquals(-4, l.intValue());
311        assertEquals("-4", l.getName());
312        assertNull(l.getResourceBundleName());
313    }
314
315    /*
316     * Test method parse, expecting the same objects will be returned given the
317     * same name, even for non-predefined levels.
318     */
319    @TestTargetNew(
320        level = TestLevel.PARTIAL_COMPLETE,
321        notes = "Verifies parse, expecting the same objects will be returned given the same name, even for non-predefined levels.",
322        method = "parse",
323        args = {java.lang.String.class}
324    )
325    public void testParse_SameObject() {
326        Level l = Level.parse("-100");
327        assertSame(l, Level.parse("-100"));
328    }
329
330    /*
331     * Test method hashCode, with normal fields.
332     */
333    @TestTargetNew(
334        level = TestLevel.COMPLETE,
335        notes = "",
336        method = "hashCode",
337        args = {}
338    )
339    public void testHashCode_Normal() {
340        assertEquals(100, Level.parse("100").hashCode());
341        assertEquals(-1, Level.parse("-1").hashCode());
342        assertEquals(0, Level.parse("0").hashCode());
343        assertEquals(Integer.MIN_VALUE, Level.parse("ALL").hashCode());
344    }
345
346    /*
347     * Test equals when two objects are equal.
348     */
349    @TestTargetNew(
350        level = TestLevel.PARTIAL_COMPLETE,
351        notes = "Doesn't check negative case.",
352        method = "equals",
353        args = {java.lang.Object.class}
354    )
355    public void testEquals_Equal() {
356        MockLevel l1 = new MockLevel("level1", 1);
357        MockLevel l2 = new MockLevel("level2", 1);
358        assertEquals(l1, l2);
359        assertEquals(l2, l1);
360    }
361
362    /*
363     * Test equals when two objects are not equal.
364     */
365    @TestTargetNew(
366        level = TestLevel.PARTIAL_COMPLETE,
367        notes = "Checks negative case.",
368        method = "equals",
369        args = {java.lang.Object.class}
370    )
371    public void testEquals_NotEqual() {
372        MockLevel l1 = new MockLevel("level1", 1);
373        MockLevel l2 = new MockLevel("level1", 2);
374        assertFalse(l1.equals(l2));
375        assertFalse(l2.equals(l1));
376    }
377
378    /*
379     * Test equals when the other object is null.
380     */
381    @TestTargetNew(
382        level = TestLevel.PARTIAL_COMPLETE,
383        notes = "Checks null as a parameter.",
384        method = "equals",
385        args = {java.lang.Object.class}
386    )
387    public void testEquals_Null() {
388        assertFalse(Level.ALL.equals(null));
389    }
390
391    /*
392     * Test equals when the other object is not an instance of Level.
393     */
394    @TestTargetNew(
395        level = TestLevel.PARTIAL_COMPLETE,
396        notes = "Checks negative case.",
397        method = "equals",
398        args = {java.lang.Object.class}
399    )
400    public void testEquals_NotLevel() {
401        assertFalse(Level.ALL.equals(new Object()));
402    }
403
404    /*
405     * Test equals when the other object is itself.
406     */
407    @TestTargetNew(
408        level = TestLevel.PARTIAL_COMPLETE,
409        notes = "Checks equals when the other object is itself.",
410        method = "equals",
411        args = {java.lang.Object.class}
412    )
413    public void testEquals_Itself() {
414        assertTrue(Level.ALL.equals(Level.ALL));
415    }
416
417    /*
418     * Test toString of a normal Level.
419     */
420    @TestTargetNew(
421        level = TestLevel.COMPLETE,
422        notes = "",
423        method = "toString",
424        args = {}
425    )
426    public void testToString_Normal() {
427        assertEquals("ALL", Level.ALL.toString());
428
429        MockLevel l = new MockLevel("name", 2);
430        assertEquals("name", l.toString());
431
432        MockLevel emptyLevel = new MockLevel("", 3);
433        assertEquals("", emptyLevel.toString());
434    }
435
436    // comparator for Level objects:
437    // is used because Level.equals() method only takes into account
438    // 'level' value but ignores 'name' and 'resourceBundleName' values
439    private static final SerializableAssert LEVEL_COMPARATOR = new SerializableAssert() {
440        public void assertDeserialized(Serializable initial,
441                Serializable deserialized) {
442
443            Level init = (Level) initial;
444            Level dser = (Level) deserialized;
445
446            assertEquals("Class", init.getClass(), dser.getClass());
447            assertEquals("Name", init.getName(), dser.getName());
448            assertEquals("Value", init.intValue(), dser.intValue());
449            assertEquals("ResourceBundleName", init.getResourceBundleName(),
450                    dser.getResourceBundleName());
451        }
452    };
453
454    /**
455     * @tests serialization/deserialization compatibility.
456     *
457     * Test serialization of pre-defined const levels. It is expected that the
458     * deserialized cost level should be the same instance as the existing one.
459     */
460    @TestTargetNew(
461        level = TestLevel.COMPLETE,
462        notes = "Serialization of pre-defined const levels. ",
463        method = "!SerializationSelf",
464        args = {}
465    )
466    public void testSerialization_ConstLevel() throws Exception {
467
468        SerializationTest.verifySelf(Level.ALL,
469                SerializationTest.SAME_COMPARATOR);
470    }
471
472    /**
473     * @tests serialization/deserialization compatibility.
474     *
475     * Test serialization of normal instance of Level. It is expected that the
476     * deserialized level object should be equal to the original one.
477     */
478    @TestTargetNew(
479        level = TestLevel.COMPLETE,
480        notes = "Test serialization of normal instance of Level.",
481        method = "!SerializationSelf",
482        args = {}
483    )
484    public void testSerialization_InstanceLevel() throws Exception {
485
486        // tests that objects are the same
487        Level[] objectsToTest = new Level[] { Level.parse("550")};
488
489        SerializationTest.verifySelf(objectsToTest,
490                SerializationTest.SAME_COMPARATOR);
491
492        // tests that objects are the equals
493        objectsToTest = new Level[] {
494                new MockLevel("123", 123, "bundle"),
495                new MockLevel("123", 123, null) };
496
497        SerializationTest.verifySelf(objectsToTest, LEVEL_COMPARATOR);
498    }
499
500    /**
501     * @tests serialization/deserialization compatibility with RI.
502     */
503    @TestTargetNew(
504        level = TestLevel.COMPLETE,
505        notes = "Serialization/deserialization compatibility",
506        method = "!SerializationGolden",
507        args = {}
508    )
509    public void testSerializationCompatibility() throws Exception {
510
511        SerializationTest.verifyGolden(this,
512                new MockLevel("123", 123, "bundle"), LEVEL_COMPARATOR);
513    }
514    @TestTargetNew(
515        level = TestLevel.COMPLETE,
516        notes = "",
517        method = "getLocalizedName",
518        args = {}
519    )
520    public void testGetLocalName() {
521        ResourceBundle rb = ResourceBundle.getBundle("bundles/java/util/logging/res");
522        Level l = new MockLevel("level1", 120,
523                "bundles/java/util/logging/res");
524        assertEquals(rb.getString("level1"), l.getLocalizedName());
525
526        // regression test for HARMONY-2415
527        rb = ResourceBundle.getBundle(
528                "org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
529        l = new MockLevel("Level_error", 120,
530                "org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
531        assertEquals(rb.getString("Level_error"), l.getLocalizedName());
532
533        l = new MockLevel("bad name", 120, "res");
534        assertEquals("bad name", l.getLocalizedName());
535
536        l = new MockLevel("level1", 11120, "bad name");
537        assertEquals("level1", l.getLocalizedName());
538
539        l = new MockLevel("level1", 1120);
540        assertEquals("level1", l.getLocalizedName());
541    }
542
543    /*
544     * test for method public String getResourceBundleName()
545     */
546    @TestTargetNew(
547        level = TestLevel.COMPLETE,
548        notes = "",
549        method = "getResourceBundleName",
550        args = {}
551    )
552     public void testGetResourceBundleName() {
553        String bundleName = "bundles/java/util/logging/res";
554        Level l = new MockLevel("level1", 120);
555        assertNull("level's localization resource bundle name is not null", l
556                .getResourceBundleName());
557        l = new MockLevel("level1", 120, bundleName);
558        assertEquals("bundleName is non equal to actual value", bundleName, l
559                .getResourceBundleName());
560        l = new MockLevel("level1", 120, bundleName + "+abcdef");
561        assertEquals("bundleName is non equal to actual value", bundleName
562                + "+abcdef", l.getResourceBundleName());
563    }
564
565     /*
566     * test for method public final int intValue()
567     */
568    @TestTargetNew(
569        level = TestLevel.COMPLETE,
570        notes = "",
571        method = "intValue",
572        args = {}
573    )
574    public void testIntValue() {
575        int value1 = 120;
576        Level l = new MockLevel("level1", value1);
577        assertEquals(
578                "integer value for this level is non equal to actual value",
579                value1, l.intValue());
580    }
581
582    /*
583     * Test defining new levels in subclasses of Level
584     */
585    @TestTargetNew(
586        level = TestLevel.COMPLETE,
587        notes = "Test defining new levels in subclasses of Level",
588        method = "parse",
589        args = {java.lang.String.class}
590    )
591    public void testSubclassNewLevel() {
592        MyLevel.DUPLICATENAME.getName();// just to load MyLevel class
593
594        // test duplicated name and num
595        assertEquals("INFO", MyLevel.parse("800").getName());
596        assertEquals(800, MyLevel.parse("INFO").intValue());
597        // test duplicated name
598        assertEquals("FINE", MyLevel.parse("499").getName());
599        assertEquals("FINE", MyLevel.parse("500").getName());
600        assertEquals(500, MyLevel.parse("FINE").intValue());
601        // test duplicated number
602        assertEquals("FINEST", MyLevel.parse("300").getName());
603        assertEquals(300, MyLevel.parse("FINEST").intValue());
604        assertEquals(300, MyLevel.parse("MYLEVEL1").intValue());
605        // test a normal new level, without duplicated elements
606        assertEquals("MYLEVEL2", MyLevel.parse("299").getName());
607        assertEquals(299, MyLevel.parse("MYLEVEL2").intValue());
608    }
609
610    /*
611     * This subclass is to test whether subclasses of Level can add new defined
612     * levels.
613     */
614    static class MyLevel extends Level implements Serializable {
615        private static final long serialVersionUID = 1L;
616
617        public MyLevel(String name, int value) {
618            super(name, value);
619        }
620
621        public static final Level DUPLICATENAMENUM = new MyLevel("INFO", 800);
622
623        public static final Level DUPLICATENAME = new MyLevel("FINE", 499);
624
625        public static final Level DUPLICATENUM = new MyLevel("MYLEVEL1", 300);
626
627        public static final Level NORMAL = new MyLevel("MYLEVEL2", 299);
628    }
629
630    /*
631     * This Mock is used to expose the protected constructors.
632     */
633    public class MockLevel extends Level implements Serializable {
634
635        private static final long serialVersionUID = 1L;
636
637        public MockLevel(String name, int value) {
638            super(name, value);
639        }
640
641        public MockLevel(String name, int value, String resourceBundleName) {
642            super(name, value, resourceBundleName);
643        }
644    }
645}
646