Home | History | Annotate | Download | only in logging
      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 package org.apache.harmony.logging.tests.java.util.logging;
     19 
     20 import java.beans.PropertyChangeEvent;
     21 import java.beans.PropertyChangeListener;
     22 import java.io.FileNotFoundException;
     23 import java.io.IOException;
     24 import java.io.InputStream;
     25 import java.io.PrintStream;
     26 import java.security.Permission;
     27 import java.util.Enumeration;
     28 import java.util.Properties;
     29 import java.util.logging.ConsoleHandler;
     30 import java.util.logging.Handler;
     31 import java.util.logging.Level;
     32 import java.util.logging.LogManager;
     33 import java.util.logging.LogRecord;
     34 import java.util.logging.Logger;
     35 import java.util.logging.LoggingPermission;
     36 
     37 import junit.framework.TestCase;
     38 
     39 import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
     40 import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
     41 
     42 /**
     43  * add/get logger(dot)
     44  */
     45 public class LogManagerTest extends TestCase {
     46 
     47     private static final String FOO = "LogManagerTestFoo";
     48 
     49     LogManager mockManager;
     50 
     51     LogManager manager = LogManager.getLogManager();
     52 
     53     MockPropertyChangeListener listener;
     54 
     55     Properties props;
     56 
     57     private static String className = LogManagerTest.class.getName();
     58 
     59     static Handler handler = null;
     60 
     61     static final String CONFIG_CLASS = "java.util.logging.config.class";
     62 
     63     static final String CONFIG_FILE = "java.util.logging.config.file";
     64 
     65     static final String MANAGER_CLASS = "java.util.logging.config.manager";
     66 
     67     static final String clearPath = System.getProperty("clearpath");
     68 
     69 
     70     /*
     71       * @see TestCase#setUp()
     72       */
     73     protected void setUp() throws Exception {
     74         super.setUp();
     75         mockManager = new MockLogManager();
     76         listener = new MockPropertyChangeListener();
     77         handler = new MockHandler();
     78         props = initProps();
     79     }
     80 
     81     static Properties initProps() throws Exception {
     82         Properties props = new Properties();
     83         props.put("handlers", className + "$MockHandler " + className
     84                 + "$MockHandler");
     85         props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
     86         props.put("java.util.logging.FileHandler.limit", "50000");
     87         props.put("java.util.logging.FileHandler.count", "5");
     88         props.put("java.util.logging.FileHandler.formatter",
     89                 "java.util.logging.XMLFormatter");
     90         props.put(".level", "FINE");
     91         props.put("java.util.logging.ConsoleHandler.level", "OFF");
     92         props.put("java.util.logging.ConsoleHandler.formatter",
     93                 "java.util.logging.SimpleFormatter");
     94         props.put("LogManagerTestFoo.handlers", "java.util.logging.ConsoleHandler");
     95         props.put("LogManagerTestFoo.level", "WARNING");
     96         return props;
     97     }
     98 
     99     /*
    100       * @see TestCase#tearDown()
    101       */
    102     protected void tearDown() throws Exception {
    103         super.tearDown();
    104         handler = null;
    105     }
    106 
    107     public void testAddGetLogger() {
    108         Logger log = new MockLogger(FOO, null);
    109         Logger foo = mockManager.getLogger(FOO);
    110         assertNull(foo);
    111         assertTrue(mockManager.addLogger(log));
    112         foo = mockManager.getLogger(FOO);
    113         assertSame(foo, log);
    114         assertNull(foo.getParent());
    115 
    116         try {
    117             mockManager.addLogger(null);
    118             fail("add null should throw NullPointerException");
    119         } catch (NullPointerException e) {
    120         }
    121 
    122         try {
    123             mockManager.getLogger(null);
    124             fail("get null should throw NullPointerException");
    125         } catch (NullPointerException e) {
    126         }
    127 
    128         assertNull(mockManager.getLogger("bad name"));
    129 
    130         Enumeration<String> enumar = mockManager.getLoggerNames();
    131         int i = 0;
    132         while (enumar.hasMoreElements()) {
    133             String name = (String) enumar.nextElement();
    134             i++;
    135             assertEquals(FOO, name);
    136         }
    137         assertEquals(i, 1);
    138     }
    139 
    140     public void testAddGetLogger_duplicateName() {
    141         // add logger with duplicate name has no effect
    142         Logger foo = new MockLogger(FOO, null);
    143         Logger foo2 = new MockLogger(FOO, null);
    144         assertTrue(mockManager.addLogger(foo));
    145         assertSame(foo, mockManager.getLogger(FOO));
    146         assertFalse(mockManager.addLogger(foo2));
    147         assertSame(foo, mockManager.getLogger(FOO));
    148         Enumeration<String> enumar = mockManager.getLoggerNames();
    149         int i = 0;
    150         while (enumar.hasMoreElements()) {
    151             enumar.nextElement();
    152             i++;
    153         }
    154         assertEquals(1, i);
    155     }
    156 
    157     public void testAddGetLogger_Hierachy() {
    158         Logger foo = new MockLogger("testAddGetLogger_Hierachy.foo", null);
    159         Logger child = new MockLogger("testAddGetLogger_Hierachy.foo.child",
    160                 null);
    161         Logger fakeChild = new MockLogger(
    162                 "testAddGetLogger_Hierachy.foo2.child", null);
    163         Logger grandson = new MockLogger(
    164                 "testAddGetLogger_Hierachy.foo.child.grandson", null);
    165         Logger otherChild = new MockLogger(
    166                 "testAddGetLogger_Hierachy.foo.child", null);
    167         assertNull(foo.getParent());
    168         assertNull(child.getParent());
    169         assertNull(grandson.getParent());
    170         assertNull(otherChild.getParent());
    171 
    172         // whenever a logger is added to a LogManager, hierarchy will be updated
    173         // accordingly
    174         assertTrue(mockManager.addLogger(child));
    175         assertNull(child.getParent());
    176 
    177         assertTrue(mockManager.addLogger(fakeChild));
    178         assertNull(fakeChild.getParent());
    179 
    180         assertTrue(mockManager.addLogger(grandson));
    181         assertSame(child, grandson.getParent());
    182 
    183         assertTrue(mockManager.addLogger(foo));
    184         assertSame(foo, child.getParent());
    185         assertNull(foo.getParent());
    186         assertNull(fakeChild.getParent());
    187 
    188         // but for non-mock LogManager, foo's parent should be root
    189         assertTrue(manager.addLogger(foo));
    190         assertSame(manager.getLogger(""), manager.getLogger(
    191                 "testAddGetLogger_Hierachy.foo").getParent());
    192 
    193         // if we add one logger to two LogManager, parent will changed
    194         assertTrue(manager.addLogger(otherChild));
    195         assertTrue(manager.addLogger(grandson));
    196         assertSame(foo, otherChild.getParent());
    197         assertSame(otherChild, grandson.getParent());
    198     }
    199 
    200     public void testAddLoggerReverseOrder() {
    201         Logger root = new MockLogger("testAddLoggerReverseOrder", null);
    202         Logger foo = new MockLogger("testAddLoggerReverseOrder.foo", null);
    203         Logger fooChild = new MockLogger("testAddLoggerReverseOrder.foo.child",
    204                 null);
    205         Logger fooGrandChild = new MockLogger(
    206                 "testAddLoggerReverseOrder.foo.child.grand", null);
    207         Logger fooGrandChild2 = new MockLogger(
    208                 "testAddLoggerReverseOrder.foo.child.grand2", null);
    209 
    210         Logger realRoot = manager.getLogger("");
    211 
    212         manager.addLogger(fooGrandChild);
    213         assertEquals(realRoot, fooGrandChild.getParent());
    214 
    215         manager.addLogger(root);
    216         assertSame(root, fooGrandChild.getParent());
    217         assertSame(realRoot, root.getParent());
    218 
    219         manager.addLogger(foo);
    220         assertSame(root, foo.getParent());
    221         assertSame(foo, fooGrandChild.getParent());
    222 
    223         manager.addLogger(fooGrandChild2);
    224         assertSame(foo, fooGrandChild2.getParent());
    225         assertSame(foo, fooGrandChild.getParent());
    226 
    227         manager.addLogger(fooChild);
    228         assertSame(fooChild, fooGrandChild2.getParent());
    229         assertSame(fooChild, fooGrandChild.getParent());
    230         assertSame(foo, fooChild.getParent());
    231         assertSame(root, foo.getParent());
    232         assertSame(realRoot, root.getParent());
    233     }
    234 
    235     public void testAddSimiliarLogger() {
    236         Logger root = new MockLogger("testAddSimiliarLogger", null);
    237         Logger foo = new MockLogger("testAddSimiliarLogger.foo", null);
    238         Logger similiarFoo = new MockLogger("testAddSimiliarLogger.fop", null);
    239         Logger fooo = new MockLogger("testAddSimiliarLogger.fooo", null);
    240         Logger fooChild = new MockLogger("testAddSimiliarLogger.foo.child",
    241                 null);
    242         Logger similiarFooChild = new MockLogger(
    243                 "testAddSimiliarLogger.fop.child", null);
    244         Logger foooChild = new MockLogger("testAddSimiliarLogger.fooo.child",
    245                 null);
    246 
    247         manager.addLogger(root);
    248         manager.addLogger(fooChild);
    249         manager.addLogger(similiarFooChild);
    250         manager.addLogger(foooChild);
    251         assertSame(root, fooChild.getParent());
    252         assertSame(root, similiarFooChild.getParent());
    253         assertSame(root, foooChild.getParent());
    254 
    255         manager.addLogger(foo);
    256         assertSame(foo, fooChild.getParent());
    257         assertSame(root, similiarFooChild.getParent());
    258         assertSame(root, foooChild.getParent());
    259 
    260         manager.addLogger(similiarFoo);
    261         assertSame(foo, fooChild.getParent());
    262         assertSame(similiarFoo, similiarFooChild.getParent());
    263         assertSame(root, foooChild.getParent());
    264 
    265         manager.addLogger(fooo);
    266         assertSame(fooo, foooChild.getParent());
    267     }
    268 
    269     public void testAddGetLogger_nameWithSpace() {
    270         Logger foo = new MockLogger(FOO, null);
    271         Logger fooBeforeSpace = new MockLogger(FOO + " ", null);
    272         Logger fooAfterSpace = new MockLogger(" " + FOO, null);
    273         Logger fooWithBothSpace = new MockLogger(" " + FOO + " ", null);
    274         assertTrue(mockManager.addLogger(foo));
    275         assertTrue(mockManager.addLogger(fooBeforeSpace));
    276         assertTrue(mockManager.addLogger(fooAfterSpace));
    277         assertTrue(mockManager.addLogger(fooWithBothSpace));
    278 
    279         assertSame(foo, mockManager.getLogger(FOO));
    280         assertSame(fooBeforeSpace, mockManager.getLogger(FOO + " "));
    281         assertSame(fooAfterSpace, mockManager.getLogger(" " + FOO));
    282         assertSame(fooWithBothSpace, mockManager.getLogger(" " + FOO + " "));
    283     }
    284 
    285     public void testAddGetLogger_addRoot() throws IOException {
    286         Logger foo = new MockLogger(FOO, null);
    287         Logger fooChild = new MockLogger(FOO + ".child", null);
    288         Logger other = new MockLogger("other", null);
    289         Logger root = new MockLogger("", null);
    290         assertNull(foo.getParent());
    291         assertNull(root.getParent());
    292         assertNull(other.getParent());
    293 
    294         // add root to mock logmanager and it works as "root" logger
    295         assertTrue(mockManager.addLogger(foo));
    296         assertTrue(mockManager.addLogger(other));
    297         assertTrue(mockManager.addLogger(fooChild));
    298         assertNull(foo.getParent());
    299         assertNull(other.getParent());
    300         assertSame(foo, fooChild.getParent());
    301 
    302         assertTrue(mockManager.addLogger(root));
    303         assertSame(root, foo.getParent());
    304         assertSame(root, other.getParent());
    305         assertNull(root.getParent());
    306 
    307         // try to add root logger to non-mock LogManager, no effect
    308         assertFalse(manager.addLogger(root));
    309         assertNotSame(root, manager.getLogger(""));
    310     }
    311 
    312     public void testDefaultLoggerProperties() throws Exception {
    313         // mock LogManager has no default logger
    314         assertNull(mockManager.getLogger(""));
    315         assertNull(mockManager.getLogger("global"));
    316 
    317         // non-mock LogManager has two default logger
    318         Logger global = manager.getLogger("global");
    319         Logger root = manager.getLogger("");
    320 
    321         assertSame(global, Logger.global);
    322         assertSame(root, global.getParent());
    323 
    324         // root properties
    325         manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    326         assertNull(root.getFilter());
    327         assertEquals(2, root.getHandlers().length);
    328         assertEquals(Level.FINE, root.getLevel());
    329         assertEquals("", root.getName());
    330         assertSame(root.getParent(), null);
    331         assertNull(root.getResourceBundle());
    332         assertNull(root.getResourceBundleName());
    333         assertTrue(root.getUseParentHandlers());
    334 
    335     }
    336 
    337     public void testMockGetProperty() throws Exception {
    338         // mock manager doesn't read configuration until you call
    339         // readConfiguration()
    340         Logger root = new MockLogger("", null);
    341         assertTrue(mockManager.addLogger(root));
    342         root = mockManager.getLogger("");
    343         checkPropertyNull(mockManager);
    344         assertEquals(0, root.getHandlers().length);
    345         assertNull(root.getLevel());
    346         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    347         assertEquals(Level.FINE, root.getLevel());
    348         checkProperty(mockManager);
    349         mockManager.reset();
    350         checkPropertyNull(mockManager);
    351         assertEquals(Level.INFO, root.getLevel());
    352         assertEquals(0, mockManager.getLogger("").getHandlers().length);
    353     }
    354 
    355     public void testGetProperty() throws SecurityException, IOException {
    356 //      //FIXME: move it to exec
    357         //        manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    358 //		Logger root = manager.getLogger("");
    359 ////		checkProperty(manager);
    360 //		assertEquals(Level.FINE, root.getLevel());
    361 //		assertEquals(2, root.getHandlers().length);
    362 
    363         // but non-mock manager DO read it from the very beginning
    364         Logger root = manager.getLogger("");
    365         manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    366         checkProperty(manager);
    367         assertEquals(2, root.getHandlers().length);
    368         assertEquals(Level.FINE, root.getLevel());
    369 
    370         manager.reset();
    371         checkPropertyNull(manager);
    372         assertEquals(0, root.getHandlers().length);
    373         assertEquals(Level.INFO, root.getLevel());
    374         manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    375     }
    376 
    377     public void testReadConfiguration_null() throws SecurityException,
    378             IOException {
    379         try {
    380             manager.readConfiguration(null);
    381             fail("should throw null pointer exception");
    382         } catch (NullPointerException e) {
    383         }
    384 
    385     }
    386 
    387     public void testReadConfiguration() throws SecurityException,
    388             IOException {
    389 
    390         MockConfigLogManager lm = new MockConfigLogManager();
    391         assertFalse(lm.isCalled);
    392 
    393         lm.readConfiguration();
    394         assertTrue(lm.isCalled);
    395     }
    396 
    397     private static void checkPropertyNull(LogManager m) {
    398         // assertNull(m.getProperty(".level"));
    399         assertNull(m.getProperty("java.util.logging.FileHandler.limit"));
    400         assertNull(m.getProperty("java.util.logging.ConsoleHandler.formatter"));
    401         // assertNull(m.getProperty("handlers"));
    402         assertNull(m.getProperty("java.util.logging.FileHandler.count"));
    403         assertNull(m.getProperty("com.xyz.foo.level"));
    404         assertNull(m.getProperty("java.util.logging.FileHandler.formatter"));
    405         assertNull(m.getProperty("java.util.logging.ConsoleHandler.level"));
    406         assertNull(m.getProperty("java.util.logging.FileHandler.pattern"));
    407     }
    408 
    409     private static void checkProperty(LogManager m) {
    410         // assertEquals(m.getProperty(".level"), "INFO");
    411         assertEquals(m.getProperty("java.util.logging.FileHandler.limit"),
    412                 "50000");
    413         assertEquals(m
    414                 .getProperty("java.util.logging.ConsoleHandler.formatter"),
    415                 "java.util.logging.SimpleFormatter");
    416         // assertEquals(m.getProperty("handlers"),
    417         // "java.util.logging.ConsoleHandler");
    418         assertEquals(m.getProperty("java.util.logging.FileHandler.count"), "5");
    419         assertEquals(m.getProperty("LogManagerTestFoo.level"), "WARNING");
    420         assertEquals(m.getProperty("java.util.logging.FileHandler.formatter"),
    421                 "java.util.logging.XMLFormatter");
    422         assertEquals(m.getProperty("java.util.logging.ConsoleHandler.level"),
    423                 "OFF");
    424         assertEquals(m.getProperty("java.util.logging.FileHandler.pattern"),
    425                 "%h/java%u.log");
    426     }
    427 
    428 //	public void testReadConfiguration() throws SecurityException, IOException {
    429 //          FIXME: move the support_exec
    430 //			Logger foo = new MockLogger("foo", null);
    431 //			assertNull(foo.getLevel());
    432 //			assertTrue(mockManager.addLogger(foo));
    433 //
    434 //			Logger fo = new MockLogger("foo2", null);
    435 //			fo.setLevel(Level.ALL);
    436 //			assertTrue(mockManager.addLogger(fo));
    437 //
    438 //			Handler h = new ConsoleHandler();
    439 //			Level l = h.getLevel();
    440 //			assertNotSame(Level.OFF, h.getLevel());
    441 //
    442 //			// read configuration
    443 //			mockManager.readConfiguration();
    444 //			// level DO has effect
    445 //			assertEquals(Level.WARNING, foo.getLevel());
    446 //			// for non specified logger, level is reset to null
    447 //			assertNull(fo.getLevel());
    448 //
    449 //			// read properties don't affect handler
    450 //			assertNotSame(Level.OFF, h.getLevel());
    451 //			assertSame(l, h.getLevel());
    452 //
    453 //	}
    454 
    455     /*
    456       * Class under test for void readConfiguration(InputStream)
    457       */
    458     public void testReadConfigurationInputStream() throws IOException {
    459         // mock LogManager
    460         InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
    461 
    462         Logger foo = new MockLogger(FOO, null);
    463         assertNull(foo.getLevel());
    464         assertTrue(mockManager.addLogger(foo));
    465 
    466         Logger fo = new MockLogger("LogManagerTestFoo2", null);
    467         fo.setLevel(Level.ALL);
    468         assertTrue(mockManager.addLogger(fo));
    469 
    470         Handler h = new ConsoleHandler();
    471         Level l = h.getLevel();
    472         assertNotSame(Level.OFF, h.getLevel());
    473 
    474         // read configuration from stream
    475         mockManager.readConfiguration(stream);
    476         stream.close();
    477 
    478         // level DO has effect
    479         assertEquals(Level.WARNING, foo.getLevel());
    480 
    481         // for non specified logger, level is reset to null
    482         assertNull(fo.getLevel());
    483 
    484         // read properties don't affect handler
    485         assertNotSame(Level.OFF, h.getLevel());
    486         assertSame(l, h.getLevel());
    487     }
    488 
    489     public void testReadConfigurationInputStream_null()
    490             throws SecurityException, IOException {
    491         try {
    492             mockManager.readConfiguration(null);
    493             fail("should throw null pointer exception");
    494         } catch (NullPointerException e) {
    495         }
    496 
    497     }
    498 
    499     public void testReadConfigurationInputStream_root() throws IOException {
    500         InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
    501         manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    502 
    503         Logger logger = new MockLogger(
    504                 "testReadConfigurationInputStream_root.foo", null);
    505         Logger root = manager.getLogger("");
    506         Logger logger2 = Logger
    507                 .getLogger("testReadConfigurationInputStream_root.foo2");
    508 
    509         manager.addLogger(logger);
    510         assertNull(logger.getLevel());
    511         assertEquals(0, logger.getHandlers().length);
    512         assertSame(root, logger.getParent());
    513 
    514         assertNull(logger2.getLevel());
    515         assertEquals(0, logger2.getHandlers().length);
    516         assertSame(root, logger2.getParent());
    517         // if (!hasConfigClass) {
    518         assertEquals(Level.FINE, root.getLevel());
    519         assertEquals(2, root.getHandlers().length);
    520         // }
    521 
    522         // after read stream
    523         manager.readConfiguration(stream);
    524         assertEquals(Level.FINE, root.getLevel());
    525         assertEquals(2, root.getHandlers().length);
    526         assertNull(logger.getLevel());
    527         assertEquals(0, logger.getHandlers().length);
    528         stream.close();
    529     }
    530 
    531     public void testReadConfigurationUpdatesRootLoggersHandlers()
    532             throws IOException {
    533         Properties properties = new Properties();
    534         LogManager.getLogManager().readConfiguration(
    535                 EnvironmentHelper.PropertiesToInputStream(properties));
    536 
    537         Logger root = Logger.getLogger("");
    538         assertEquals(0, root.getHandlers().length);
    539 
    540         properties.put("handlers", "java.util.logging.ConsoleHandler");
    541         LogManager.getLogManager().readConfiguration(
    542                 EnvironmentHelper.PropertiesToInputStream(properties));
    543 
    544         assertEquals(1, root.getHandlers().length);
    545     }
    546 
    547     public void testReadConfigurationDoesNotUpdateOtherLoggers()
    548             throws IOException {
    549         Properties properties = new Properties();
    550         LogManager.getLogManager().readConfiguration(
    551                 EnvironmentHelper.PropertiesToInputStream(properties));
    552 
    553         Logger logger = Logger.getLogger("testReadConfigurationDoesNotUpdateOtherLoggers");
    554         assertEquals(0, logger.getHandlers().length);
    555 
    556         properties.put("testReadConfigurationDoesNotUpdateOtherLoggers.handlers",
    557                 "java.util.logging.ConsoleHandler");
    558         LogManager.getLogManager().readConfiguration(
    559                 EnvironmentHelper.PropertiesToInputStream(properties));
    560 
    561         assertEquals(0, logger.getHandlers().length);
    562     }
    563 
    564     public void testAddRemovePropertyChangeListener() throws Exception {
    565         MockPropertyChangeListener listener1 = new MockPropertyChangeListener();
    566         MockPropertyChangeListener listener2 = new MockPropertyChangeListener();
    567         // add same listener1 two times
    568         mockManager.addPropertyChangeListener(listener1);
    569         mockManager.addPropertyChangeListener(listener1);
    570         mockManager.addPropertyChangeListener(listener2);
    571 
    572         assertNull(listener1.getEvent());
    573         assertNull(listener2.getEvent());
    574         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    575         // if (!hasConfigClass) {
    576         assertNotNull(listener1.getEvent());
    577         assertNotNull(listener2.getEvent());
    578         // }
    579 
    580         listener1.reset();
    581         listener2.reset();
    582 
    583         // remove listener1, no effect
    584         mockManager.removePropertyChangeListener(listener1);
    585         mockManager.readConfiguration(EnvironmentHelper
    586                 .PropertiesToInputStream(props));
    587         assertNotNull(listener1.getEvent());
    588         assertNotNull(listener2.getEvent());
    589         listener1.reset();
    590         listener2.reset();
    591 
    592         // remove listener1 again and it works
    593         mockManager.removePropertyChangeListener(listener1);
    594         mockManager.readConfiguration(EnvironmentHelper
    595                 .PropertiesToInputStream(props));
    596         assertNull(listener1.getEvent());
    597         assertNotNull(listener2.getEvent());
    598         listener2.reset();
    599 
    600         // reset don't produce event
    601         mockManager.reset();
    602         assertNull(listener2.getEvent());
    603 
    604         mockManager.removePropertyChangeListener(listener2);
    605         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    606         assertNull(listener1.getEvent());
    607         assertNull(listener2.getEvent());
    608     }
    609 
    610     public void testAddRemovePropertyChangeListener_null() {
    611         // seems nothing happened
    612         try {
    613             mockManager.addPropertyChangeListener(null);
    614             fail("Should throw NPE");
    615         } catch (NullPointerException e) {
    616         }
    617         mockManager.removePropertyChangeListener(null);
    618     }
    619 
    620     public void testLoggerLevelInitialized_explicit() throws SecurityException, IOException {
    621         // mock LogManager
    622         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    623         assertNotNull(mockManager.getProperty("handlers"));
    624 
    625         // Before the Android O (and before the openJdk8) the logger level
    626         // value was  unconditionally overwritten by a value taken from properties.
    627         // Starting from Android O, the value is only set from properties if it wasn't
    628         // initialized before.
    629         Logger foo = new MockLogger(FOO, null);
    630         assertNull(foo.getLevel());
    631         assertEquals(0, foo.getHandlers().length);
    632         // Explicit set before the .addLogger
    633         foo.setLevel(Level.ALL);
    634         foo.addHandler(new ConsoleHandler());
    635         assertTrue(mockManager.addLogger(foo));
    636         assertEquals(Level.ALL, foo.getLevel());
    637     }
    638 
    639     public void testLoggerLevelInitialized() throws SecurityException, IOException {
    640         // mock LogManager
    641         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    642         assertNotNull(mockManager.getProperty("handlers"));
    643 
    644         // Before the Android O (and before the openJdk8) the logger level
    645         // value was  unconditionally overwritten by a value taken from properties.
    646         // Starting from Android O, the value is only set from properties if it wasn't
    647         // initialized before.
    648         Logger foo = new MockLogger(FOO, null);
    649         assertNull(foo.getLevel());
    650         assertEquals(0, foo.getHandlers().length);
    651         foo.addHandler(new ConsoleHandler());
    652         assertTrue(mockManager.addLogger(foo));
    653         assertEquals(Level.WARNING, foo.getLevel());
    654     }
    655 
    656     public void testReset() throws SecurityException, IOException {
    657         // mock LogManager
    658         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
    659         assertNotNull(mockManager.getProperty("handlers"));
    660         Logger foo = new MockLogger(FOO, null);
    661         assertNull(foo.getLevel());
    662         assertEquals(0, foo.getHandlers().length);
    663         foo.addHandler(new ConsoleHandler());
    664         assertTrue(mockManager.addLogger(foo));
    665         assertEquals(Level.WARNING, foo.getLevel());
    666         assertEquals(2, foo.getHandlers().length);
    667 
    668         // reset
    669         mockManager.reset();
    670 
    671         // properties is cleared
    672         assertNull(mockManager.getProperty("handlers"));
    673 
    674         // level is null
    675         assertNull(foo.getLevel());
    676         // handlers are all closed
    677         assertEquals(0, foo.getHandlers().length);
    678 
    679         // for root logger
    680         manager.reset();
    681         assertNull(manager.getProperty("handlers"));
    682         Logger root = manager.getLogger("");
    683         // level reset to info
    684         assertEquals(Level.INFO, root.getLevel());
    685         // also close root's handler
    686         assertEquals(0, root.getHandlers().length);
    687     }
    688 
    689     public void testGlobalPropertyConfig() throws Exception {
    690         PrintStream err = System.err;
    691         try {
    692             System.setErr(new PrintStream(new NullOutputStream()));
    693             // before add config property, root has two handler
    694             manager.readConfiguration(EnvironmentHelper
    695                     .PropertiesToInputStream(props));
    696             assertEquals(2, manager.getLogger("").getHandlers().length);
    697 
    698             // one valid config class
    699             props.setProperty("config", className + "$MockValidConfig");
    700             manager.readConfiguration(EnvironmentHelper
    701                     .PropertiesToInputStream(props));
    702             assertEquals(3, manager.getLogger("").getHandlers().length);
    703 
    704             // two config class take effect orderly
    705             props.setProperty("config", className + "$MockValidConfig "
    706                     + className + "$MockValidConfig2");
    707             manager.readConfiguration(EnvironmentHelper
    708                     .PropertiesToInputStream(props));
    709             assertEquals(2, manager.getLogger("").getHandlers().length);
    710 
    711             props.setProperty("config", className + "$MockValidConfig2 "
    712                     + className + "$MockValidConfig");
    713             manager.readConfiguration(EnvironmentHelper
    714                     .PropertiesToInputStream(props));
    715             assertEquals(3, manager.getLogger("").getHandlers().length);
    716 
    717             // invalid config class which throw exception, just print exception
    718             // and
    719             // message
    720             props.setProperty("config", className
    721                     + "$MockInvalidConfigException");
    722             manager.readConfiguration(EnvironmentHelper
    723                     .PropertiesToInputStream(props));
    724 
    725             // invalid config class without default constructor, just print
    726             // exception and message
    727             props.setProperty("config", className
    728                     + "$MockInvalidConfigNoDefaultConstructor");
    729             manager.readConfiguration(EnvironmentHelper
    730                     .PropertiesToInputStream(props));
    731 
    732             // bad config class name, just print exception and message
    733             props.setProperty("config", "badname");
    734             manager.readConfiguration(EnvironmentHelper
    735                     .PropertiesToInputStream(props));
    736 
    737             // invalid separator, nothing happened
    738             props.setProperty("config", className + "$MockValidConfig2;"
    739                     + className + "$MockValidConfig");
    740             manager.readConfiguration(EnvironmentHelper
    741                     .PropertiesToInputStream(props));
    742             assertEquals(2, manager.getLogger("").getHandlers().length);
    743             props.setProperty("config", className + "$MockValidConfig2;"
    744                     + className + "$MockValidConfig " + className
    745                     + "$MockValidConfig");
    746             manager.readConfiguration(EnvironmentHelper
    747                     .PropertiesToInputStream(props));
    748             assertEquals(3, manager.getLogger("").getHandlers().length);
    749 
    750             // duplicate config class, take effect twice
    751             props.setProperty("config", className + "$MockValidConfig "
    752                     + className + "$MockValidConfig");
    753             manager.readConfiguration(EnvironmentHelper
    754                     .PropertiesToInputStream(props));
    755             assertEquals(4, manager.getLogger("").getHandlers().length);
    756 
    757             // invalid config classes mixed with valid config classes, valid
    758             // config
    759             // classes take effect
    760             props.setProperty("config", "badname " + className
    761                     + "$MockValidConfig " + className
    762                     + "$MockInvalidConfigNoDefaultConstructor " + className
    763                     + "$MockValidConfig");
    764             manager.readConfiguration(EnvironmentHelper
    765                     .PropertiesToInputStream(props));
    766             assertEquals(4, manager.getLogger("").getHandlers().length);
    767 
    768             // global property take effect before logger specified property
    769             props.setProperty("config", className + "$MockValidConfig");
    770             manager.readConfiguration(EnvironmentHelper
    771                     .PropertiesToInputStream(props));
    772             assertEquals(Level.FINE, manager.getLogger("").getLevel());
    773         } finally {
    774             System.setErr(err);
    775         }
    776 
    777     }
    778 
    779     public void testValidConfigClass() throws Exception {
    780         String oldPropertyValue = System.getProperty(CONFIG_CLASS);
    781         try {
    782             System.setProperty(CONFIG_CLASS, this.getClass().getName()
    783                     + "$ConfigClass");
    784             assertNull(manager.getLogger("testConfigClass.foo"));
    785 
    786             manager.readConfiguration();
    787             assertNull(manager.getLogger("testConfigClass.foo"));
    788             Logger l = Logger.getLogger("testConfigClass.foo.child");
    789             assertSame(Level.FINEST, manager.getLogger("").getLevel());
    790             assertEquals(0, manager.getLogger("").getHandlers().length);
    791             assertEquals("testConfigClass.foo", l.getParent().getName());
    792         } finally {
    793             Properties systemProperties = System.getProperties();
    794             if (oldPropertyValue != null) {
    795                 systemProperties.setProperty(CONFIG_CLASS, oldPropertyValue);
    796             } else {
    797                 systemProperties.remove(CONFIG_CLASS);
    798             }
    799         }
    800     }
    801 
    802     public void testNotExistConfigFile() throws Exception {
    803         String oldPropertyValue = System.getProperty(CONFIG_FILE);
    804         System.setProperty(CONFIG_FILE, "not.exist.config.file");
    805         try {
    806             LogManager.getLogManager().readConfiguration();
    807             fail("should throw FileNotFoundException");
    808         } catch (FileNotFoundException e) {
    809             // Expected
    810         } finally {
    811             Properties systemProperties = System.getProperties();
    812             if (oldPropertyValue != null) {
    813                 systemProperties.setProperty(CONFIG_FILE, oldPropertyValue);
    814             } else {
    815                 systemProperties.remove(CONFIG_FILE);
    816             }
    817         }
    818     }
    819 
    820     // regression for HARMONY-3075
    821     public void testGetLoggingMXBean() throws Exception {
    822         assertNotNull(LogManager.getLoggingMXBean());
    823     }
    824 
    825     /*
    826       * ----------------------------------------------------
    827       * mock classes
    828       * ----------------------------------------------------
    829       */
    830     public static class ConfigClass {
    831         public ConfigClass() throws Exception {
    832             LogManager man = LogManager.getLogManager();
    833             Properties props = LogManagerTest.initProps();
    834             props.put("testConfigClass.foo.level", "OFF");
    835             props.put("testConfigClass.foo.handlers", "java.util.logging.ConsoleHandler");
    836             props.put(".level", "FINEST");
    837             props.remove("handlers");
    838             InputStream in = EnvironmentHelper.PropertiesToInputStream(props);
    839             man.readConfiguration(in);
    840         }
    841     }
    842 
    843     public static class MockInvalidInitClass {
    844         public MockInvalidInitClass() {
    845             throw new RuntimeException();
    846         }
    847     }
    848 
    849     public static class TestInvalidConfigFile {
    850         public static void main(String[] args) {
    851             LogManager manager = LogManager.getLogManager();
    852             Logger root = manager.getLogger("");
    853             checkPropertyNull(manager);
    854             assertEquals(0, root.getHandlers().length);
    855             assertEquals(Level.INFO, root.getLevel());
    856 
    857             try {
    858                 manager.readConfiguration();
    859             } catch (Exception e) {
    860                 e.printStackTrace();
    861             }
    862             checkProperty(manager);
    863             assertNull(root.getHandlers()[0].getLevel());
    864             assertEquals(1, root.getHandlers().length);
    865             assertEquals(Level.INFO, root.getLevel());
    866 
    867             manager.reset();
    868             checkProperty(manager);
    869             assertEquals(0, root.getHandlers().length);
    870             assertEquals(Level.INFO, root.getLevel());
    871             try {
    872                 manager.readConfiguration();
    873             } catch (Exception e) {
    874                 e.printStackTrace();
    875             }
    876         }
    877     }
    878 
    879     public static class TestValidConfigFile {
    880         public static void main(String[] args) {
    881             LogManager manager = LogManager.getLogManager();
    882             Logger root = manager.getLogger("");
    883             checkPropertyNull(manager);
    884             assertEquals(2, root.getHandlers().length);
    885             assertEquals(root.getHandlers()[0].getLevel(), Level.OFF);
    886             assertEquals(Level.ALL, root.getLevel());
    887 
    888             try {
    889                 manager.readConfiguration();
    890             } catch (Exception e) {
    891                 e.printStackTrace();
    892             }
    893             checkPropertyNull(manager);
    894             assertEquals(root.getHandlers()[0].getLevel(), Level.OFF);
    895             assertEquals(2, root.getHandlers().length);
    896             assertEquals(Level.ALL, root.getLevel());
    897 
    898             manager.reset();
    899             checkPropertyNull(manager);
    900             assertEquals(0, root.getHandlers().length);
    901             assertEquals(Level.INFO, root.getLevel());
    902             try {
    903                 manager.readConfiguration();
    904             } catch (Exception e) {
    905                 e.printStackTrace();
    906             }
    907         }
    908     }
    909 
    910     public static class TestMockLogManager {
    911         public static void main(String[] args) {
    912             LogManager manager = LogManager.getLogManager();
    913             assertTrue(manager instanceof MockLogManager);
    914         }
    915     }
    916 
    917     public static class TestValidConfigClass {
    918         public static void main(String[] args) {
    919             LogManager manager = LogManager.getLogManager();
    920             Logger root = manager.getLogger("");
    921             checkPropertyNull(manager);
    922             assertEquals(1, root.getHandlers().length);
    923             assertEquals(Level.OFF, root.getLevel());
    924 
    925             try {
    926                 manager.readConfiguration();
    927             } catch (Exception e) {
    928                 e.printStackTrace();
    929             }
    930             checkPropertyNull(manager);
    931             assertEquals(1, root.getHandlers().length);
    932             assertEquals(Level.OFF, root.getLevel());
    933 
    934             try {
    935                 manager.readConfiguration();
    936             } catch (Exception e) {
    937                 e.printStackTrace();
    938             }
    939             checkPropertyNull(manager);
    940             assertEquals(1, root.getHandlers().length);
    941             assertEquals(Level.OFF, root.getLevel());
    942 
    943             manager.reset();
    944             checkPropertyNull(manager);
    945             assertEquals(0, root.getHandlers().length);
    946             assertEquals(Level.INFO, root.getLevel());
    947             try {
    948                 manager.readConfiguration();
    949             } catch (Exception e) {
    950                 e.printStackTrace();
    951             }
    952         }
    953     }
    954 
    955     public static class MockLogger extends Logger {
    956         public MockLogger(String name, String rbName) {
    957             super(name, rbName);
    958         }
    959     }
    960 
    961     public static class MockLogManager extends LogManager {
    962     }
    963 
    964     public static class MockConfigLogManager extends LogManager {
    965         public boolean isCalled = false;
    966 
    967         public void readConfiguration(InputStream ins) throws IOException {
    968             isCalled = true;
    969             super.readConfiguration(ins);
    970         }
    971     }
    972 
    973     public static class MockHandler extends Handler {
    974         static int number = 0;
    975 
    976         public MockHandler() {
    977             addNumber();
    978             // System.out.println(this + ":start:" + number);
    979         }
    980 
    981         private synchronized void addNumber() {
    982             number++;
    983         }
    984 
    985         public void close() {
    986             minusNumber();
    987             // System.out.println(this + ":close:" + number);
    988         }
    989 
    990         private synchronized void minusNumber() {
    991             number--;
    992         }
    993 
    994         public void flush() {
    995             // System.out.println(this + ":flush");
    996         }
    997 
    998         public void publish(LogRecord record) {
    999         }
   1000 
   1001     }
   1002 
   1003     public static class MockValidInitClass {
   1004         public MockValidInitClass() {
   1005             Properties p = new Properties();
   1006             p.put("handlers", className + "$MockHandler");
   1007             p.put(".level", "OFF");
   1008             InputStream in = null;
   1009             try {
   1010                 in = EnvironmentHelper.PropertiesToInputStream(p);
   1011                 LogManager manager = LogManager.getLogManager();
   1012                 manager.readConfiguration(in);
   1013             } catch (Exception e) {
   1014                 e.printStackTrace();
   1015             } finally {
   1016                 try {
   1017                     in.close();
   1018                 } catch (Exception e) {
   1019                 }
   1020             }
   1021         }
   1022     }
   1023 
   1024     public static class MockValidConfig {
   1025         public MockValidConfig() {
   1026             handler = new MockHandler();
   1027             LogManager manager = LogManager.getLogManager();
   1028             Logger root = null;
   1029             if (null != manager) {
   1030                 root = manager.getLogger("");
   1031             } else {
   1032                 System.out.println("null manager");
   1033             }
   1034             if (null != root) {
   1035                 root.addHandler(handler);
   1036                 root.setLevel(Level.OFF);
   1037             }
   1038         }
   1039     }
   1040 
   1041     public static class MockValidConfig2 {
   1042 
   1043         static Logger root = null;
   1044 
   1045         public MockValidConfig2() {
   1046             root = LogManager.getLogManager().getLogger("");
   1047             root.removeHandler(handler);
   1048         }
   1049     }
   1050 
   1051     public static class MockInvalidConfigException {
   1052         public MockInvalidConfigException() {
   1053             throw new RuntimeException("invalid config class - throw exception");
   1054         }
   1055     }
   1056 
   1057     public static class MockInvalidConfigNoDefaultConstructor {
   1058         public MockInvalidConfigNoDefaultConstructor(int i) {
   1059             throw new RuntimeException(
   1060                     "invalid config class - no default constructor");
   1061         }
   1062     }
   1063 
   1064     public static class MockPropertyChangeListener implements
   1065             PropertyChangeListener {
   1066 
   1067         PropertyChangeEvent event = null;
   1068 
   1069         public void propertyChange(PropertyChangeEvent event) {
   1070             this.event = event;
   1071         }
   1072 
   1073         public PropertyChangeEvent getEvent() {
   1074             return event;
   1075         }
   1076 
   1077         public void reset() {
   1078             event = null;
   1079         }
   1080 
   1081     }
   1082 
   1083     /*
   1084      * Test config class loading
   1085      * java -Djava.util.logging.config.class=badConfigClassName ClassLoadingTest
   1086      */
   1087     public static class ClassLoadingTest {
   1088         public static void main(String[] args) {
   1089             Thread.currentThread().setContextClassLoader(new MockErrorClassLoader());
   1090             try {
   1091                 LogManager.getLogManager();
   1092                 fail("Should throw mock error");
   1093             } catch (MockError e) {
   1094             }
   1095         }
   1096 
   1097         static class MockErrorClassLoader extends ClassLoader {
   1098             public Class<?> loadClass(String name) {
   1099                 throw new MockError();
   1100             }
   1101         }
   1102 
   1103         static class MockError extends Error {
   1104         }
   1105     }
   1106 
   1107 }
   1108