Path: blob/master/test/jdk/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java
41161 views
/*1* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import java.io.ByteArrayOutputStream;23import java.io.IOException;24import java.io.PrintStream;25import java.io.UncheckedIOException;26import java.security.AccessControlException;27import java.security.CodeSource;28import java.security.Permission;29import java.security.PermissionCollection;30import java.security.Permissions;31import java.security.Policy;32import java.security.ProtectionDomain;33import java.util.Collections;34import java.util.Enumeration;35import java.util.HashMap;36import java.util.Map;37import java.util.ResourceBundle;38import java.util.stream.Stream;39import java.util.concurrent.ConcurrentHashMap;40import java.util.concurrent.atomic.AtomicBoolean;41import java.util.concurrent.atomic.AtomicLong;42import java.util.function.Supplier;43import java.lang.System.LoggerFinder;44import java.lang.System.Logger;45import java.lang.System.Logger.Level;46import java.security.AccessController;47import java.security.PrivilegedAction;48import java.util.EnumSet;49import java.util.Iterator;50import java.util.Locale;51import java.util.ServiceConfigurationError;52import java.util.ServiceLoader;53import java.util.concurrent.atomic.AtomicReference;54import jdk.internal.logger.SimpleConsoleLogger;5556/**57* @test58* @bug 8140364 818929159* @summary JDK implementation specific unit test for LoggerFinderLoader.60* Tests the behavior of LoggerFinderLoader with respect to the61* value of the internal diagnosability switches. Also test the62* DefaultLoggerFinder and SimpleConsoleLogger implementation.63* @modules java.base/sun.util.logging64* java.base/jdk.internal.logger65* @build AccessSystemLogger LoggerFinderLoaderTest CustomSystemClassLoader BaseLoggerFinder BaseLoggerFinder266* @run driver AccessSystemLogger67* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader LoggerFinderLoaderTest NOSECURITY68* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader LoggerFinderLoaderTest NOPERMISSIONS69* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader LoggerFinderLoaderTest WITHPERMISSIONS70* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true LoggerFinderLoaderTest NOSECURITY71* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true LoggerFinderLoaderTest NOPERMISSIONS72* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true LoggerFinderLoaderTest WITHPERMISSIONS73* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest NOSECURITY74* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest NOPERMISSIONS75* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest WITHPERMISSIONS76* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest NOSECURITY77* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest NOPERMISSIONS78* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest WITHPERMISSIONS79* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest NOSECURITY80* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest NOPERMISSIONS81* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Dtest.fails=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest WITHPERMISSIONS82* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true LoggerFinderLoaderTest NOSECURITY83* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true LoggerFinderLoaderTest NOPERMISSIONS84* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true LoggerFinderLoaderTest WITHPERMISSIONS85* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest NOSECURITY86* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest NOPERMISSIONS87* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=ERROR LoggerFinderLoaderTest WITHPERMISSIONS88* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest NOSECURITY89* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest NOPERMISSIONS90* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=DEBUG LoggerFinderLoaderTest WITHPERMISSIONS91* @run main/othervm -Xbootclasspath/a:boot -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest NOSECURITY92* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest NOPERMISSIONS93* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader -Djdk.logger.finder.singleton=true -Djdk.logger.finder.error=QUIET LoggerFinderLoaderTest WITHPERMISSIONS94* @author danielfuchs95*/96public class LoggerFinderLoaderTest {9798static final Policy DEFAULT_POLICY = Policy.getPolicy();99static final RuntimePermission LOGGERFINDER_PERMISSION =100new RuntimePermission("loggerFinder");101final static boolean VERBOSE = false;102static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() {103@Override104protected AtomicBoolean initialValue() {105return new AtomicBoolean(false);106}107};108static final ThreadLocal<AtomicBoolean> allowAccess = new ThreadLocal<AtomicBoolean>() {109@Override110protected AtomicBoolean initialValue() {111return new AtomicBoolean(false);112}113};114115final static AccessSystemLogger accessSystemLogger = new AccessSystemLogger();116static final Class<?>[] providerClass;117static {118try {119providerClass = new Class<?>[] {120ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder"),121ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder2")122};123} catch (ClassNotFoundException ex) {124throw new ExceptionInInitializerError(ex);125}126}127128/**129* What our test provider needs to implement.130*/131public static interface TestLoggerFinder {132public final static AtomicBoolean fails = new AtomicBoolean();133public final static AtomicReference<String> conf = new AtomicReference<>("");134public final static AtomicLong sequencer = new AtomicLong();135public final ConcurrentHashMap<String, LoggerImpl> system = new ConcurrentHashMap<>();136public final ConcurrentHashMap<String, LoggerImpl> user = new ConcurrentHashMap<>();137138public class LoggerImpl implements System.Logger {139final String name;140final Logger logger;141142public LoggerImpl(String name, Logger logger) {143this.name = name;144this.logger = logger;145}146147@Override148public String getName() {149return name;150}151152@Override153public boolean isLoggable(Logger.Level level) {154return logger.isLoggable(level);155}156157@Override158public void log(Logger.Level level, ResourceBundle bundle, String key, Throwable thrown) {159logger.log(level, bundle, key, thrown);160}161162@Override163public void log(Logger.Level level, ResourceBundle bundle, String format, Object... params) {164logger.log(level, bundle, format, params);165}166167}168169public Logger getLogger(String name, Module caller);170public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);171}172173public static class MyBundle extends ResourceBundle {174175final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();176177@Override178protected Object handleGetObject(String key) {179if (key.contains(" (translated)")) {180throw new RuntimeException("Unexpected key: " + key);181}182return map.computeIfAbsent(key, k -> k.toUpperCase(Locale.ROOT) + " (translated)");183}184185@Override186public Enumeration<String> getKeys() {187return Collections.enumeration(map.keySet());188}189190}191public static class MyLoggerBundle extends MyBundle {192193}194195static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};196197static void setSecurityManager() {198if (System.getSecurityManager() == null) {199Policy.setPolicy(new SimplePolicy(allowControl, allowAccess));200System.setSecurityManager(new SecurityManager());201}202}203204static LoggerFinder getLoggerFinder(Class<?> expectedClass,205String errorPolicy, boolean singleton) {206LoggerFinder provider = null;207try {208TestLoggerFinder.sequencer.incrementAndGet();209provider = LoggerFinder.getLoggerFinder();210if (TestLoggerFinder.fails.get() || singleton) {211if ("ERROR".equals(errorPolicy.toUpperCase(Locale.ROOT))) {212throw new RuntimeException("Expected exception not thrown");213} else if ("WARNING".equals(errorPolicy.toUpperCase(Locale.ROOT))) {214String warning = ErrorStream.errorStream.peek();215if (!warning.contains("WARNING: Failed to instantiate LoggerFinder provider; Using default.")) {216throw new RuntimeException("Expected message not found. Error stream contained: " + warning);217}218} else if ("DEBUG".equals(errorPolicy.toUpperCase(Locale.ROOT))) {219String warning = ErrorStream.errorStream.peek();220if (!warning.contains("WARNING: Failed to instantiate LoggerFinder provider; Using default.")) {221throw new RuntimeException("Expected message not found. Error stream contained: " + warning);222}223if (!warning.contains("WARNING: Exception raised trying to instantiate LoggerFinder")) {224throw new RuntimeException("Expected message not found. Error stream contained: " + warning);225}226if (TestLoggerFinder.fails.get()) {227if (!warning.contains("java.util.ServiceConfigurationError: java.lang.System$LoggerFinder: Provider BaseLoggerFinder could not be instantiated")) {228throw new RuntimeException("Expected message not found. Error stream contained: " + warning);229}230} else if (singleton) {231if (!warning.contains("java.util.ServiceConfigurationError: More than on LoggerFinder implementation")) {232throw new RuntimeException("Expected message not found. Error stream contained: " + warning);233}234}235} else if ("QUIET".equals(errorPolicy.toUpperCase(Locale.ROOT))) {236String warning = ErrorStream.errorStream.peek();237String smDeprecationWarning238= "WARNING: java.lang.System::setSecurityManager is deprecated and will be removed in a future release."239+ System.getProperty("line.separator");240if (warning.startsWith(smDeprecationWarning)) {241warning = warning.substring(smDeprecationWarning.length());242}243if (!warning.isEmpty()) {244throw new RuntimeException("Unexpected error message found: "245+ ErrorStream.errorStream.peek());246}247}248}249} catch(AccessControlException a) {250throw a;251} catch(Throwable t) {252if (TestLoggerFinder.fails.get() || singleton) {253// must check System.err254if ("ERROR".equals(errorPolicy.toUpperCase(Locale.ROOT))) {255provider = LoggerFinder.getLoggerFinder();256} else {257Throwable orig = t.getCause();258while (orig != null && orig.getCause() != null) orig = orig.getCause();259if (orig != null) orig.printStackTrace(ErrorStream.err);260throw new RuntimeException("Unexpected exception: " + t, t);261}262} else {263throw new RuntimeException("Unexpected exception: " + t, t);264}265}266expectedClass.cast(provider);267ErrorStream.errorStream.store();268System.out.println("*** Actual LoggerFinder class is: " + provider.getClass().getName());269return provider;270}271272273static class ErrorStream extends PrintStream {274275static AtomicBoolean forward = new AtomicBoolean();276ByteArrayOutputStream out;277String saved = "";278public ErrorStream(ByteArrayOutputStream out) {279super(out);280this.out = out;281}282283@Override284public void write(int b) {285super.write(b);286if (forward.get()) err.write(b);287}288289@Override290public void write(byte[] b) throws IOException {291super.write(b);292if (forward.get()) err.write(b);293}294295@Override296public void write(byte[] buf, int off, int len) {297super.write(buf, off, len);298if (forward.get()) err.write(buf, off, len);299}300301public String peek() {302flush();303return out.toString();304}305306public String drain() {307flush();308String res = out.toString();309out.reset();310return res;311}312313public void store() {314flush();315saved = out.toString();316out.reset();317}318319public void restore() {320out.reset();321try {322out.write(saved.getBytes());323} catch(IOException io) {324throw new UncheckedIOException(io);325}326}327328static final PrintStream err = System.err;329static final ErrorStream errorStream = new ErrorStream(new ByteArrayOutputStream());330}331332private static StringBuilder appendProperty(StringBuilder b, String name) {333String value = System.getProperty(name);334if (value == null) return b;335return b.append(name).append("=").append(value).append('\n');336}337338public static void main(String[] args) {339if (args.length == 0) {340args = new String[] {341"NOSECURITY",342"NOPERMISSIONS",343"WITHPERMISSIONS"344};345}346Locale.setDefault(Locale.ENGLISH);347System.setErr(ErrorStream.errorStream);348System.setProperty("jdk.logger.packages", TestLoggerFinder.LoggerImpl.class.getName());349//System.setProperty("jdk.logger.finder.error", "ERROR");350//System.setProperty("jdk.logger.finder.singleton", "true");351//System.setProperty("test.fails", "true");352TestLoggerFinder.fails.set(Boolean.getBoolean("test.fails"));353StringBuilder c = new StringBuilder();354appendProperty(c, "jdk.logger.packages");355appendProperty(c, "jdk.logger.finder.error");356appendProperty(c, "jdk.logger.finder.singleton");357appendProperty(c, "test.fails");358TestLoggerFinder.conf.set(c.toString());359try {360test(args);361} finally {362try {363System.setErr(ErrorStream.err);364} catch (Error | RuntimeException x) {365x.printStackTrace(ErrorStream.err);366}367}368}369370371public static void test(String[] args) {372373final String errorPolicy = System.getProperty("jdk.logger.finder.error", "WARNING");374final Boolean ensureSingleton = Boolean.getBoolean("jdk.logger.finder.singleton");375376final Class<?> expectedClass =377TestLoggerFinder.fails.get() || ensureSingleton378? jdk.internal.logger.DefaultLoggerFinder.class379: TestLoggerFinder.class;380381System.out.println("Declared provider class: " + providerClass[0]382+ "[" + providerClass[0].getClassLoader() + "]");383384if (!TestLoggerFinder.fails.get()) {385ServiceLoader<LoggerFinder> serviceLoader =386ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader());387Iterator<LoggerFinder> iterator = serviceLoader.iterator();388Object firstProvider = iterator.next();389if (!firstProvider.getClass().getName().equals("BaseLoggerFinder")) {390throw new RuntimeException("Unexpected provider: " + firstProvider.getClass().getName());391}392if (!iterator.hasNext()) {393throw new RuntimeException("Expected two providers");394}395}396397Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {398LoggerFinder provider;399ErrorStream.errorStream.restore();400switch (testCase) {401case NOSECURITY:402System.out.println("\n*** Without Security Manager\n");403System.out.println(TestLoggerFinder.conf.get());404provider = getLoggerFinder(expectedClass, errorPolicy, ensureSingleton);405test(provider, true);406System.out.println("Tetscase count: " + TestLoggerFinder.sequencer.get());407break;408case NOPERMISSIONS:409System.out.println("\n*** With Security Manager, without permissions\n");410System.out.println(TestLoggerFinder.conf.get());411setSecurityManager();412try {413provider = getLoggerFinder(expectedClass, errorPolicy, ensureSingleton);414throw new RuntimeException("Expected exception not raised");415} catch (AccessControlException x) {416if (!LOGGERFINDER_PERMISSION.equals(x.getPermission())) {417throw new RuntimeException("Unexpected permission check", x);418}419final boolean control = allowControl.get().get();420try {421allowControl.get().set(true);422provider = getLoggerFinder(expectedClass, errorPolicy, ensureSingleton);423} finally {424allowControl.get().set(control);425}426}427test(provider, false);428System.out.println("Tetscase count: " + TestLoggerFinder.sequencer.get());429break;430case WITHPERMISSIONS:431System.out.println("\n*** With Security Manager, with control permission\n");432System.out.println(TestLoggerFinder.conf.get());433setSecurityManager();434final boolean control = allowControl.get().get();435try {436allowControl.get().set(true);437provider = getLoggerFinder(expectedClass, errorPolicy, ensureSingleton);438test(provider, true);439} finally {440allowControl.get().set(control);441}442break;443default:444throw new RuntimeException("Unknown test case: " + testCase);445}446});447System.out.println("\nPASSED: Tested " + TestLoggerFinder.sequencer.get() + " cases.");448}449450public static void test(LoggerFinder provider, boolean hasRequiredPermissions) {451452ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());453final Map<Logger, String> loggerDescMap = new HashMap<>();454455System.Logger sysLogger = accessSystemLogger.getLogger("foo");456loggerDescMap.put(sysLogger, "accessSystemLogger.getLogger(\"foo\")");457System.Logger localizedSysLogger = accessSystemLogger.getLogger("fox", loggerBundle);458loggerDescMap.put(localizedSysLogger, "accessSystemLogger.getLogger(\"fox\", loggerBundle)");459System.Logger appLogger = System.getLogger("bar");460loggerDescMap.put(appLogger,"System.getLogger(\"bar\")");461System.Logger localizedAppLogger = System.getLogger("baz", loggerBundle);462loggerDescMap.put(localizedAppLogger,"System.getLogger(\"baz\", loggerBundle)");463464testLogger(provider, loggerDescMap, "foo", null, sysLogger);465testLogger(provider, loggerDescMap, "foo", loggerBundle, localizedSysLogger);466testLogger(provider, loggerDescMap, "foo", null, appLogger);467testLogger(provider, loggerDescMap, "foo", loggerBundle, localizedAppLogger);468}469470public static class Foo {471472}473474static void verbose(String msg) {475if (VERBOSE) {476System.out.println(msg);477}478}479480// Calls the 8 methods defined on Logger and verify the481// parameters received by the underlying TestProvider.LoggerImpl482// logger.483private static void testLogger(LoggerFinder provider,484Map<Logger, String> loggerDescMap,485String name,486ResourceBundle loggerBundle,487Logger logger) {488489System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger +"]");490AtomicLong sequencer = TestLoggerFinder.sequencer;491492Foo foo = new Foo();493String fooMsg = foo.toString();494for (Level loggerLevel : EnumSet.of(Level.INFO)) {495for (Level messageLevel : Level.values()) {496ErrorStream.errorStream.drain();497String desc = "logger.log(messageLevel, foo): loggerLevel="498+ loggerLevel+", messageLevel="+messageLevel;499sequencer.incrementAndGet();500logger.log(messageLevel, foo);501if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {502if (!ErrorStream.errorStream.peek().isEmpty()) {503throw new RuntimeException("unexpected event in queue for "504+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());505}506} else {507String logged = ErrorStream.errorStream.drain();508if (!logged.contains("LoggerFinderLoaderTest testLogger")509|| !logged.contains(messageLevel.getName() + ": " + fooMsg)) {510throw new RuntimeException("mismatch for " + desc511+ "\n\texpected:" + "\n<<<<\n"512+ "[date] LoggerFinderLoaderTest testLogger\n"513+ messageLevel.getName() + " " + fooMsg514+ "\n>>>>"515+ "\n\t actual:"516+ "\n<<<<\n" + logged + ">>>>\n");517} else {518verbose("Got expected results for "519+ desc + "\n<<<<\n" + logged + ">>>>\n");520}521}522}523}524525String msg = "blah";526for (Level loggerLevel : EnumSet.of(Level.INFO)) {527for (Level messageLevel : Level.values()) {528String desc = "logger.log(messageLevel, \"blah\"): loggerLevel="529+ loggerLevel+", messageLevel="+messageLevel;530sequencer.incrementAndGet();531logger.log(messageLevel, msg);532if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {533if (!ErrorStream.errorStream.peek().isEmpty()) {534throw new RuntimeException("unexpected event in queue for "535+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());536}537} else {538String logged = ErrorStream.errorStream.drain();539String msgText = loggerBundle == null ? msg : loggerBundle.getString(msg);540if (!logged.contains("LoggerFinderLoaderTest testLogger")541|| !logged.contains(messageLevel.getName() + ": " + msgText)) {542throw new RuntimeException("mismatch for " + desc543+ "\n\texpected:" + "\n<<<<\n"544+ "[date] LoggerFinderLoaderTest testLogger\n"545+ messageLevel.getName() + " " + msgText546+ "\n>>>>"547+ "\n\t actual:"548+ "\n<<<<\n" + logged + ">>>>\n");549} else {550verbose("Got expected results for "551+ desc + "\n<<<<\n" + logged + ">>>>\n");552}553}554}555}556557Supplier<String> fooSupplier = new Supplier<String>() {558@Override559public String get() {560return this.toString();561}562};563564for (Level loggerLevel : EnumSet.of(Level.INFO)) {565for (Level messageLevel : Level.values()) {566String desc = "logger.log(messageLevel, fooSupplier): loggerLevel="567+ loggerLevel+", messageLevel="+messageLevel;568sequencer.incrementAndGet();569logger.log(messageLevel, fooSupplier);570if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {571if (!ErrorStream.errorStream.peek().isEmpty()) {572throw new RuntimeException("unexpected event in queue for "573+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());574}575} else {576String logged = ErrorStream.errorStream.drain();577if (!logged.contains("LoggerFinderLoaderTest testLogger")578|| !logged.contains(messageLevel.getName() + ": " + fooSupplier.get())) {579throw new RuntimeException("mismatch for " + desc580+ "\n\texpected:" + "\n<<<<\n"581+ "[date] LoggerFinderLoaderTest testLogger\n"582+ messageLevel.getName() + " " + fooSupplier.get()583+ "\n>>>>"584+ "\n\t actual:"585+ "\n<<<<\n" + logged + ">>>>\n");586} else {587verbose("Got expected results for "588+ desc + "\n<<<<\n" + logged + ">>>>\n");589}590}591}592}593594595String format = "two params [{1} {2}]";596Object arg1 = foo;597Object arg2 = msg;598for (Level loggerLevel : EnumSet.of(Level.INFO)) {599for (Level messageLevel : Level.values()) {600String desc = "logger.log(messageLevel, format, params...): loggerLevel="601+ loggerLevel+", messageLevel="+messageLevel;602sequencer.incrementAndGet();603logger.log(messageLevel, format, foo, msg);604if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {605if (!ErrorStream.errorStream.peek().isEmpty()) {606throw new RuntimeException("unexpected event in queue for "607+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());608}609} else {610String logged = ErrorStream.errorStream.drain();611String msgFormat = loggerBundle == null ? format : loggerBundle.getString(format);612String text = java.text.MessageFormat.format(msgFormat, foo, msg);613if (!logged.contains("LoggerFinderLoaderTest testLogger")614|| !logged.contains(messageLevel.getName() + ": " + text)) {615throw new RuntimeException("mismatch for " + desc616+ "\n\texpected:" + "\n<<<<\n"617+ "[date] LoggerFinderLoaderTest testLogger\n"618+ messageLevel.getName() + " " + text619+ "\n>>>>"620+ "\n\t actual:"621+ "\n<<<<\n" + logged + ">>>>\n");622} else {623verbose("Got expected results for "624+ desc + "\n<<<<\n" + logged + ">>>>\n");625}626}627}628}629630Throwable thrown = new Exception("OK: log me!");631for (Level loggerLevel : EnumSet.of(Level.INFO)) {632for (Level messageLevel : Level.values()) {633String desc = "logger.log(messageLevel, \"blah\", thrown): loggerLevel="634+ loggerLevel+", messageLevel="+messageLevel;635sequencer.incrementAndGet();636logger.log(messageLevel, msg, thrown);637if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {638if (!ErrorStream.errorStream.peek().isEmpty()) {639throw new RuntimeException("unexpected event in queue for "640+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());641}642} else {643String logged = ErrorStream.errorStream.drain();644ByteArrayOutputStream baos = new ByteArrayOutputStream();645thrown.printStackTrace(new PrintStream(baos));646String text = baos.toString();647String msgText = loggerBundle == null ? msg : loggerBundle.getString(msg);648if (!logged.contains("LoggerFinderLoaderTest testLogger")649|| !logged.contains(messageLevel.getName() + ": " + msgText)650|| !logged.contains(text)) {651throw new RuntimeException("mismatch for " + desc652+ "\n\texpected:" + "\n<<<<\n"653+ "[date] LoggerFinderLoaderTest testLogger\n"654+ messageLevel.getName() + " " + msgText +"\n"655+ text656+ ">>>>"657+ "\n\t actual:"658+ "\n<<<<\n" + logged + ">>>>\n");659} else {660verbose("Got expected results for "661+ desc + "\n<<<<\n" + logged + ">>>>\n");662}663}664}665}666667668for (Level loggerLevel : EnumSet.of(Level.INFO)) {669for (Level messageLevel : Level.values()) {670String desc = "logger.log(messageLevel, thrown, fooSupplier): loggerLevel="671+ loggerLevel+", messageLevel="+messageLevel;672sequencer.incrementAndGet();673logger.log(messageLevel, fooSupplier, thrown);674if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {675if (!ErrorStream.errorStream.peek().isEmpty()) {676throw new RuntimeException("unexpected event in queue for "677+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());678}679} else {680String logged = ErrorStream.errorStream.drain();681ByteArrayOutputStream baos = new ByteArrayOutputStream();682thrown.printStackTrace(new PrintStream(baos));683String text = baos.toString();684if (!logged.contains("LoggerFinderLoaderTest testLogger")685|| !logged.contains(messageLevel.getName() + ": " + fooSupplier.get())686|| !logged.contains(text)) {687throw new RuntimeException("mismatch for " + desc688+ "\n\texpected:" + "\n<<<<\n"689+ "[date] LoggerFinderLoaderTest testLogger\n"690+ messageLevel.getName() + " " + fooSupplier.get() +"\n"691+ text692+ ">>>>"693+ "\n\t actual:"694+ "\n<<<<\n" + logged + ">>>>\n");695} else {696verbose("Got expected results for "697+ desc + "\n<<<<\n" + logged + ">>>>\n");698}699}700}701}702703ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName());704for (Level loggerLevel : EnumSet.of(Level.INFO)) {705for (Level messageLevel : Level.values()) {706String desc = "logger.log(messageLevel, bundle, format, params...): loggerLevel="707+ loggerLevel+", messageLevel="+messageLevel;708sequencer.incrementAndGet();709logger.log(messageLevel, bundle, format, foo, msg);710if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {711if (!ErrorStream.errorStream.peek().isEmpty()) {712throw new RuntimeException("unexpected event in queue for "713+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());714}715} else {716String logged = ErrorStream.errorStream.drain();717String text = java.text.MessageFormat.format(bundle.getString(format), foo, msg);718if (!logged.contains("LoggerFinderLoaderTest testLogger")719|| !logged.contains(messageLevel.getName() + ": " + text)) {720throw new RuntimeException("mismatch for " + desc721+ "\n\texpected:" + "\n<<<<\n"722+ "[date] LoggerFinderLoaderTest testLogger\n"723+ messageLevel.getName() + " " + text724+ "\n>>>>"725+ "\n\t actual:"726+ "\n<<<<\n" + logged + ">>>>\n");727} else {728verbose("Got expected results for "729+ desc + "\n<<<<\n" + logged + ">>>>\n");730}731}732}733}734735for (Level loggerLevel : EnumSet.of(Level.INFO)) {736for (Level messageLevel : Level.values()) {737String desc = "logger.log(messageLevel, bundle, \"blah\", thrown): loggerLevel="738+ loggerLevel+", messageLevel="+messageLevel;739sequencer.incrementAndGet();740logger.log(messageLevel, bundle, msg, thrown);741if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {742if (!ErrorStream.errorStream.peek().isEmpty()) {743throw new RuntimeException("unexpected event in queue for "744+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());745}746} else {747String logged = ErrorStream.errorStream.drain();748String textMsg = bundle.getString(msg);749ByteArrayOutputStream baos = new ByteArrayOutputStream();750thrown.printStackTrace(new PrintStream(baos));751String text = baos.toString();752if (!logged.contains("LoggerFinderLoaderTest testLogger")753|| !logged.contains(messageLevel.getName() + ": " + textMsg)754|| !logged.contains(text)) {755throw new RuntimeException("mismatch for " + desc756+ "\n\texpected:" + "\n<<<<\n"757+ "[date] LoggerFinderLoaderTest testLogger\n"758+ messageLevel.getName() + " " + textMsg +"\n"759+ text760+ ">>>>"761+ "\n\t actual:"762+ "\n<<<<\n" + logged + ">>>>\n");763} else {764verbose("Got expected results for "765+ desc + "\n<<<<\n" + logged + ">>>>\n");766}767}768}769}770771}772773final static class PermissionsBuilder {774final Permissions perms;775public PermissionsBuilder() {776this(new Permissions());777}778public PermissionsBuilder(Permissions perms) {779this.perms = perms;780}781public PermissionsBuilder add(Permission p) {782perms.add(p);783return this;784}785public PermissionsBuilder addAll(PermissionCollection col) {786if (col != null) {787for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {788perms.add(e.nextElement());789}790}791return this;792}793public Permissions toPermissions() {794final PermissionsBuilder builder = new PermissionsBuilder();795builder.addAll(perms);796return builder.perms;797}798}799800public static class SimplePolicy extends Policy {801final static RuntimePermission CONTROL = LOGGERFINDER_PERMISSION;802final static RuntimePermission ACCESS = new RuntimePermission("accessClassInPackage.jdk.internal.logger");803804final Permissions permissions;805final ThreadLocal<AtomicBoolean> allowControl;806final ThreadLocal<AtomicBoolean> allowAccess;807public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl, ThreadLocal<AtomicBoolean> allowAccess) {808this.allowControl = allowControl;809this.allowAccess = allowAccess;810permissions = new Permissions();811permissions.add(new RuntimePermission("setIO"));812}813814Permissions getPermissions() {815if (allowControl.get().get() || allowAccess.get().get()) {816PermissionsBuilder builder = new PermissionsBuilder()817.addAll(permissions);818if (allowControl.get().get()) {819builder.add(CONTROL);820}821if (allowAccess.get().get()) {822builder.add(ACCESS);823}824return builder.toPermissions();825}826return permissions;827}828829@Override830public boolean implies(ProtectionDomain domain, Permission permission) {831return getPermissions().implies(permission) ||832DEFAULT_POLICY.implies(domain, permission);833}834835@Override836public PermissionCollection getPermissions(CodeSource codesource) {837return new PermissionsBuilder().addAll(getPermissions()).toPermissions();838}839840@Override841public PermissionCollection getPermissions(ProtectionDomain domain) {842return new PermissionsBuilder().addAll(getPermissions()).toPermissions();843}844}845}846847848