/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2009-2014 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009-2014 Jason Mehrens. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.mail.util.logging; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Comparator; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.logging.*; import javax.mail.PasswordAuthentication; import javax.mail.Session; import static org.junit.Assert.*; import org.junit.Test; /** * Test case for the LogManagerProperties spec. * * @author Jason Mehrens */ public class LogManagerPropertiesTest { /** * Holder used to inject Throwables into other APIs. */ private final static ThreadLocal<Throwable> PENDING = new ThreadLocal<Throwable>(); @Test public void testClone() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); Properties parent; LogManagerProperties mp; LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); parent = new Properties(); parent.put(key, "value"); read(manager, parent); parent = new Properties(); mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.getProperty(key)); assertTrue(contains(mp, key, "value")); //ensure copy worked. } finally { manager.reset(); } Properties clone = (Properties) mp.clone(); assertFalse(clone instanceof LogManagerProperties); assertEquals(Properties.class, clone.getClass()); assertNotSame(clone, parent); assertNotSame(clone, mp); assertEquals(mp.size(), clone.size()); assertTrue(clone.equals(mp)); //don't call mp.equals. } @Test public void testIsReflection() throws Exception { assertTrue(LogManagerProperties.isReflectionClass(Constructor.class.getName())); assertTrue(LogManagerProperties.isReflectionClass(Method.class.getName())); } @Test(expected = NullPointerException.class) public void testIsReflectionNull() throws Exception { LogManagerProperties.isReflectionClass((String) null); } @Test(expected = ClassNotFoundException.class) public void testIsReflectionInvaildName() throws Exception { LogManagerProperties.isReflectionClass("badClassName"); } @Test(expected = NullPointerException.class) public void testIsStaticUtilityClassNull() throws Exception { LogManagerProperties.isStaticUtilityClass((String) null); } @Test(expected = ClassNotFoundException.class) public void testIsStaticUtilityClassInvaildName() throws Exception { LogManagerProperties.isStaticUtilityClass("badClassName"); } @Test public void testIsStaticUtilityClass() throws Exception { String[] utils = { "java.lang.System", "java.nio.channels.Channels", "java.util.Collections", "javax.mail.internet.MimeUtility", "org.junit.Assert" }; testIsStaticUtilityClass(utils, true); String[] obj = { "java.lang.Exception", "java.lang.Object", "java.lang.Runtime", "java.io.Serializable" }; testIsStaticUtilityClass(obj, false); String[] enumerations = { "java.util.concurrent.TimeUnit" }; testIsStaticUtilityClass(enumerations, false); } private void testIsStaticUtilityClass(String[] names, boolean complement) throws Exception { assertFalse(names.length == 0); if (complement) { for (String name : names) { assertTrue(name, LogManagerProperties.isStaticUtilityClass(name)); } } else { for (String name : names) { assertFalse(name, LogManagerProperties.isStaticUtilityClass(name)); } } } @Test public void testGetProperty_String() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.getProperty(key)); assertTrue(contains(mp, key, "value")); //ensure copy worked. parent.put(key, "newValue"); assertEquals("newValue", mp.getProperty(key)); assertEquals("empty", mp.getProperty("")); } finally { manager.reset(); } } @Test public void testGetProperty_String_String() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.getProperty(key, null)); assertTrue(contains(mp, key, "value")); //ensure copy worked. parent.put(key, "newValue"); assertEquals("newValue", mp.getProperty(key, null)); assertEquals("default", mp.getProperty("unknown", "default")); assertEquals("empty", mp.getProperty("", null)); } finally { manager.reset(); } } @Test public void testGet() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.get(key)); assertTrue(contains(mp, key, "value")); //ensure copy worked. parent.put(key, "newValue"); assertEquals("newValue", mp.get(key)); assertEquals("empty", mp.get("")); } finally { manager.reset(); } } @Test public void testContainsKey() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertTrue(mp.containsKey(key)); assertTrue(contains(mp, key, "value")); //ensure copy worked. parent.put(key, "newValue"); assertEquals("newValue", mp.get(key)); assertTrue(mp.containsKey("")); } finally { manager.reset(); } } @Test public void testRemove() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.remove(key)); assertFalse(contains(mp, key, "value")); //ensure copy worked. parent.put(key, "newValue"); assertEquals("newValue", mp.remove(key)); assertEquals("empty", mp.remove("")); } finally { manager.reset(); } } @Test public void testPut() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.put(key, "newValue")); assertFalse(contains(mp, key, "value")); //ensure copy worked. assertTrue(contains(mp, key, "newValue")); //ensure copy worked. parent.put(key, "defValue"); assertEquals("newValue", mp.remove(key)); assertEquals("defValue", mp.remove(key)); assertEquals("empty", mp.put("", "")); } finally { manager.reset(); } } @Test public void testSetProperty() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String key = prefix.concat(".dummy"); Properties parent = new Properties(); parent.put(key, "value"); parent.put("", "empty"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, key, null)); assertEquals("value", mp.setProperty(key, "newValue")); assertFalse(contains(mp, key, "value")); //ensure copy worked. assertTrue(contains(mp, key, "newValue")); //ensure copy worked. parent.put(key, "defValue"); assertEquals("newValue", mp.remove(key)); assertEquals("defValue", mp.remove(key)); assertEquals("empty", mp.setProperty("", "")); } finally { manager.reset(); } } @Test public void testPropUtil() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); LogManager manager = LogManager.getLogManager(); try { String keyShort = "mail.smtp.reportsuccess"; String key = prefix + '.' + keyShort; Properties parent = new Properties(); parent.put(key, "true"); read(manager, parent); parent = new Properties(); LogManagerProperties mp = new LogManagerProperties(parent, prefix); assertFalse(contains(mp, keyShort, null)); final Session session = Session.getInstance(mp); final Object t = session.getTransport("smtp"); final String clazzName = "com.sun.mail.smtp.SMTPTransport"; assertEquals(clazzName, t.getClass().getName()); assertTrue(contains(mp, keyShort, "true")); } finally { manager.reset(); } } @Test public void testGetLogManager() throws Exception { LogManager manager = LogManagerProperties.getLogManager(); assertNotNull(manager); } @Test public void testToLanguageTag() throws Exception { assertEquals("en-US", LogManagerProperties.toLanguageTag(Locale.US)); assertEquals("en", LogManagerProperties.toLanguageTag(Locale.ENGLISH)); assertEquals("", LogManagerProperties.toLanguageTag(new Locale("", "", ""))); Locale l = new Locale("en", "US", "slang"); assertEquals("en-US-slang", LogManagerProperties.toLanguageTag(l)); l = new Locale("en", "", "slang"); assertEquals("en--slang", LogManagerProperties.toLanguageTag(l)); try { LogManagerProperties.toLanguageTag(null); fail("Null was allowed."); } catch (NullPointerException expect) { } } @Test public void testNewAuthenticator() throws Exception { try { LogManagerProperties.newAuthenticator(null); fail("Null was allowed."); } catch (NullPointerException expect) { } try { LogManagerProperties.newAuthenticator(""); fail("Empty class was allowed."); } catch (ClassNotFoundException expect) { } try { LogManagerProperties.newAuthenticator(Object.class.getName()); fail("Wrong type was allowed."); } catch (ClassCastException expect) { } final Class<?> type = ErrorAuthenticator.class; final javax.mail.Authenticator a = LogManagerProperties.newAuthenticator(type.getName()); assertEquals(type, a.getClass()); setPending(new RuntimeException()); try { LogManagerProperties.newAuthenticator(type.getName()); fail("Exception was not thrown."); } catch (InvocationTargetException expect) { assertEquals(RuntimeException.class, expect.getCause().getClass()); } finally { setPending(null); } } @Test public void testNewComparator() throws Exception { try { LogManagerProperties.newComparator(null); fail("Null was allowed."); } catch (NullPointerException expect) { } try { LogManagerProperties.newComparator(""); fail("Empty class was allowed."); } catch (ClassNotFoundException expect) { } try { LogManagerProperties.newComparator(Object.class.getName()); fail("Wrong type was allowed."); } catch (ClassCastException expect) { } final Class<?> type = ErrorComparator.class; final Comparator<? super LogRecord> c = LogManagerProperties.newComparator(type.getName()); assertEquals(type, c.getClass()); setPending(new RuntimeException()); try { LogManagerProperties.newComparator(type.getName()); fail("Exception was not thrown."); } catch (InvocationTargetException expect) { assertEquals(RuntimeException.class, expect.getCause().getClass()); } finally { setPending(null); } } @Test public void testReverseOrder() throws Exception { try { LogManagerProperties.reverseOrder(null); fail("Null was allowed."); } catch (NullPointerException expect) { } Comparator<LogRecord> c = new ErrorComparator(); Comparator<LogRecord> r = LogManagerProperties.reverseOrder(c); assertTrue(c.getClass() != r.getClass()); assertFalse(r instanceof ErrorComparator); assertFalse(r instanceof AscComparator); assertFalse(r instanceof DescComparator); c = new AscComparator(); r = LogManagerProperties.reverseOrder(c); assertTrue(r instanceof DescComparator); c = new AscComparator(); r = LogManagerProperties.reverseOrder(c); assertTrue(r instanceof DescComparator); } @Test public void testNewErrorManager() throws Exception { try { LogManagerProperties.newErrorManager(null); fail("Null was allowed."); } catch (NullPointerException expect) { } try { LogManagerProperties.newErrorManager(""); fail("Empty class was allowed."); } catch (ClassNotFoundException expect) { } try { LogManagerProperties.newErrorManager(Object.class.getName()); fail("Wrong type was allowed."); } catch (ClassCastException expect) { } final Class<?> type = ErrorManager.class; ErrorManager f = LogManagerProperties.newErrorManager(type.getName()); assertEquals(type, f.getClass()); setPending(new RuntimeException()); try { final String name = ErrorErrorManager.class.getName(); LogManagerProperties.newErrorManager(name); fail("Exception was not thrown."); } catch (InvocationTargetException expect) { assertEquals(RuntimeException.class, expect.getCause().getClass()); } finally { setPending(null); } } @Test public void testNewFilter() throws Exception { try { LogManagerProperties.newFilter(null); fail("Null was allowed."); } catch (NullPointerException expect) { } try { LogManagerProperties.newFilter(""); fail("Empty class was allowed."); } catch (ClassNotFoundException expect) { } try { LogManagerProperties.newFilter(Object.class.getName()); fail("Wrong type was allowed."); } catch (ClassCastException expect) { } final Class<?> type = ErrorFilter.class; final Filter f = LogManagerProperties.newFilter(type.getName()); assertEquals(type, f.getClass()); setPending(new RuntimeException()); try { LogManagerProperties.newFilter(type.getName()); fail("Exception was not thrown."); } catch (InvocationTargetException expect) { assertEquals(RuntimeException.class, expect.getCause().getClass()); } finally { setPending(null); } } @Test public void testNewFormatter() throws Exception { try { LogManagerProperties.newFormatter(null); fail("Null was allowed."); } catch (NullPointerException expect) { } try { LogManagerProperties.newFormatter(""); fail("Empty class was allowed."); } catch (ClassNotFoundException expect) { } try { LogManagerProperties.newFormatter(Object.class.getName()); fail("Wrong type was allowed."); } catch (ClassCastException expect) { } final Class<?> type = SimpleFormatter.class; final Formatter f = LogManagerProperties.newFormatter(type.getName()); assertEquals(type, f.getClass()); setPending(new RuntimeException()); try { final String name = ErrorFormatter.class.getName(); LogManagerProperties.newFormatter(name); fail("Exception was not thrown."); } catch (InvocationTargetException expect) { assertEquals(RuntimeException.class, expect.getCause().getClass()); } finally { setPending(null); } } @Test public void testEscapingAuthenticator() throws Exception { try { Class<?> k = ErrorAuthenticator.class; javax.mail.Authenticator a; a = LogManagerProperties.newAuthenticator(k.getName()); assertEquals(k, a.getClass()); setPending(new ThreadDeath()); try { a = LogManagerProperties.newAuthenticator(k.getName()); fail(String.valueOf(a)); } catch (ThreadDeath expect) { } setPending(new OutOfMemoryError()); try { a = LogManagerProperties.newAuthenticator(k.getName()); fail(String.valueOf(a)); } catch (OutOfMemoryError expect) { } } finally { setPending(null); } } @Test public void testEscapingComparator() throws Exception { try { Class<?> k = ErrorComparator.class; Comparator<? super LogRecord> c; c = LogManagerProperties.newComparator(k.getName()); assertEquals(k, c.getClass()); setPending(new ThreadDeath()); try { c = LogManagerProperties.newComparator(k.getName()); fail(String.valueOf(c)); } catch (ThreadDeath expect) { } setPending(new OutOfMemoryError()); try { c = LogManagerProperties.newComparator(k.getName()); fail(String.valueOf(c)); } catch (OutOfMemoryError expect) { } } finally { setPending(null); } } @Test public void testEscapingErrorErrorManager() throws Exception { try { Class<?> k = ErrorErrorManager.class; ErrorManager f; f = LogManagerProperties.newErrorManager(k.getName()); assertEquals(k, f.getClass()); setPending(new ThreadDeath()); try { f = LogManagerProperties.newErrorManager(k.getName()); fail(String.valueOf(f)); } catch (ThreadDeath expect) { } setPending(new OutOfMemoryError()); try { f = LogManagerProperties.newErrorManager(k.getName()); fail(String.valueOf(f)); } catch (OutOfMemoryError expect) { } } finally { setPending(null); } } @Test public void testEscapingFilter() throws Exception { try { Class<?> k = ErrorFilter.class; Filter f; f = LogManagerProperties.newFilter(k.getName()); assertEquals(k, f.getClass()); setPending(new ThreadDeath()); try { f = LogManagerProperties.newFilter(k.getName()); fail(String.valueOf(f)); } catch (ThreadDeath expect) { } setPending(new OutOfMemoryError()); try { f = LogManagerProperties.newFilter(k.getName()); fail(String.valueOf(f)); } catch (OutOfMemoryError expect) { } } finally { setPending(null); } } @Test public void testEscapingFormatter() throws Exception { try { Class<?> k = ErrorFormatter.class; Formatter f; f = LogManagerProperties.newFormatter(k.getName()); assertEquals(k, f.getClass()); setPending(new ThreadDeath()); try { f = LogManagerProperties.newFormatter(k.getName()); fail(String.valueOf(f)); } catch (ThreadDeath expect) { } setPending(new OutOfMemoryError()); try { f = LogManagerProperties.newFormatter(k.getName()); fail(String.valueOf(f)); } catch (OutOfMemoryError expect) { } } finally { setPending(null); } } private static void setPending(final Throwable t) { if (t != null) { PENDING.set(t); } else { PENDING.remove(); } } static void throwPendingIfSet() { final Throwable t = PENDING.get(); if (t != null) { if (t instanceof Error) { t.fillInStackTrace(); throw (Error) t; } else if (t instanceof RuntimeException) { t.fillInStackTrace(); throw (RuntimeException) t; } else { throw new AssertionError(t); } } } private void read(LogManager manager, Properties props) throws IOException { final ByteArrayOutputStream out = new ByteArrayOutputStream(512); props.store(out, "No comment"); manager.readConfiguration(new ByteArrayInputStream(out.toByteArray())); } private boolean contains(Properties props, String key, String value) { if (key == null) { throw new NullPointerException(); } //walk the entry set so we don't preload a key from the manager. for (Map.Entry<?, ?> e : props.entrySet()) { if (key.equals(e.getKey())) { return value.equals(e.getValue()); } } return false; } public static final class ErrorAuthenticator extends javax.mail.Authenticator { public ErrorAuthenticator() { throwPendingIfSet(); } @Override protected PasswordAuthentication getPasswordAuthentication() { throw new Error(""); } } public static class ErrorComparator implements Comparator<LogRecord>, Serializable { private static final long serialVersionUID = 1L; public ErrorComparator() { throwPendingIfSet(); } public int compare(LogRecord r1, LogRecord r2) { throw new Error(""); } } public static class AscComparator implements Comparator<LogRecord>, Serializable { private static final long serialVersionUID = 1L; public int compare(LogRecord r1, LogRecord r2) { throw new UnsupportedOperationException(); } public Comparator<LogRecord> reversed() { return new DescComparator(); } } public static class DescComparator implements Comparator<LogRecord>, Serializable { private static final long serialVersionUID = 1L; public int compare(LogRecord r1, LogRecord r2) { throw new UnsupportedOperationException(); } public Comparator<LogRecord> reversed() { return new AscComparator(); } } public static class ErrorFilter implements Filter { public ErrorFilter() { throwPendingIfSet(); } public boolean isLoggable(LogRecord record) { throw new Error(""); } } public static class ErrorFormatter extends Formatter { public ErrorFormatter() { throwPendingIfSet(); } public String format(LogRecord record) { throw new Error(""); } } public static class ErrorErrorManager extends ErrorManager { public ErrorErrorManager() { throwPendingIfSet(); } @Override public void error(String msg, Exception ex, int code) { throw new Error(""); } } }