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