/*
* 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("");
}
}
}