Path: blob/master/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java
41161 views
/*1* Copyright (c) 2015, 2019, 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.security.AccessControlException;23import java.security.AccessController;24import java.security.CodeSource;25import java.security.Permission;26import java.security.PermissionCollection;27import java.security.Permissions;28import java.security.Policy;29import java.security.PrivilegedAction;30import java.security.ProtectionDomain;31import java.util.Arrays;32import java.util.Collections;33import java.util.Enumeration;34import java.util.HashMap;35import java.util.Map;36import java.util.Objects;37import java.util.Queue;38import java.util.ResourceBundle;39import java.util.concurrent.ArrayBlockingQueue;40import java.util.concurrent.ConcurrentHashMap;41import java.util.concurrent.atomic.AtomicBoolean;42import java.util.concurrent.atomic.AtomicLong;43import java.util.function.Supplier;44import sun.util.logging.PlatformLogger;45import java.lang.System.LoggerFinder;46import java.lang.System.Logger;47import java.lang.System.Logger.Level;48import java.util.stream.Stream;4950/**51* @test52* @bug 814036453* @summary JDK implementation specific unit test for JDK internal artifacts.54* Tests a naive implementation of System.Logger, and in particular55* the default mapping provided by PlatformLogger.Bridge.56* @modules java.base/sun.util.logging java.base/jdk.internal.logger57* @build CustomSystemClassLoader BaseLoggerFinder BaseLoggerBridgeTest58* @run main/othervm -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest NOSECURITY59* @run main/othervm -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest NOPERMISSIONS60* @run main/othervm -Djava.security.manager=allow -Djava.system.class.loader=CustomSystemClassLoader BaseLoggerBridgeTest WITHPERMISSIONS61* @author danielfuchs62*/63public class BaseLoggerBridgeTest {6465static final RuntimePermission LOGGERFINDER_PERMISSION =66new RuntimePermission("loggerFinder");67final static AtomicLong sequencer = new AtomicLong();68final static boolean VERBOSE = false;69// whether the implementation of Logger try to do a best70// effort for logp... Our base logger finder stub doesn't71// support logp, and thus the logp() implementation comes from72// LoggerWrapper - which does a best effort.73static final boolean BEST_EFFORT_FOR_LOGP = true;74static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() {75@Override76protected AtomicBoolean initialValue() {77return new AtomicBoolean(false);78}79};80static final ThreadLocal<AtomicBoolean> allowAccess = new ThreadLocal<AtomicBoolean>() {81@Override82protected AtomicBoolean initialValue() {83return new AtomicBoolean(false);84}85};86static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {87@Override88protected AtomicBoolean initialValue() {89return new AtomicBoolean(false);90}91};9293static final Class<?> providerClass;94static {95try {96providerClass = ClassLoader.getSystemClassLoader().loadClass("BaseLoggerFinder");97} catch (ClassNotFoundException ex) {98throw new ExceptionInInitializerError(ex);99}100}101102static final sun.util.logging.PlatformLogger.Level[] julLevels = {103sun.util.logging.PlatformLogger.Level.ALL,104sun.util.logging.PlatformLogger.Level.FINEST,105sun.util.logging.PlatformLogger.Level.FINER,106sun.util.logging.PlatformLogger.Level.FINE,107sun.util.logging.PlatformLogger.Level.CONFIG,108sun.util.logging.PlatformLogger.Level.INFO,109sun.util.logging.PlatformLogger.Level.WARNING,110sun.util.logging.PlatformLogger.Level.SEVERE,111sun.util.logging.PlatformLogger.Level.OFF,112};113114static final Level[] mappedLevels = {115Level.ALL, // ALL116Level.TRACE, // FINEST117Level.TRACE, // FINER118Level.DEBUG, // FINE119Level.DEBUG, // CONFIG120Level.INFO, // INFO121Level.WARNING, // WARNING122Level.ERROR, // SEVERE123Level.OFF, // OFF124};125126final static Map<sun.util.logging.PlatformLogger.Level, Level> julToSpiMap;127static {128Map<sun.util.logging.PlatformLogger.Level, Level> map = new HashMap<>();129if (mappedLevels.length != julLevels.length) {130throw new ExceptionInInitializerError("Array lengths differ"131+ "\n\tjulLevels=" + Arrays.deepToString(julLevels)132+ "\n\tmappedLevels=" + Arrays.deepToString(mappedLevels));133}134for (int i=0; i<julLevels.length; i++) {135map.put(julLevels[i], mappedLevels[i]);136}137julToSpiMap = Collections.unmodifiableMap(map);138}139140public static class MyBundle extends ResourceBundle {141142final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();143144@Override145protected Object handleGetObject(String key) {146if (key.contains(" (translated)")) {147throw new RuntimeException("Unexpected key: " + key);148}149return map.computeIfAbsent(key, k -> k + " (translated)");150}151152@Override153public Enumeration<String> getKeys() {154return Collections.enumeration(map.keySet());155}156157}158public static class MyLoggerBundle extends MyBundle {159160}161162public static interface TestLoggerFinder {163final ConcurrentHashMap<String, LoggerImpl> system = new ConcurrentHashMap<>();164final ConcurrentHashMap<String, LoggerImpl> user = new ConcurrentHashMap<>();165public Queue<LogEvent> eventQueue = new ArrayBlockingQueue<>(128);166167public static final class LogEvent implements Cloneable {168169public LogEvent() {170this(sequencer.getAndIncrement());171}172173LogEvent(long sequenceNumber) {174this.sequenceNumber = sequenceNumber;175}176177boolean callSupplier = false;178long sequenceNumber;179boolean isLoggable;180String loggerName;181Level level;182ResourceBundle bundle;183Throwable thrown;184Object[] args;185Supplier<String> supplier;186String msg;187188Object[] toArray(boolean callSupplier) {189return new Object[] {190sequenceNumber,191isLoggable,192loggerName,193level,194bundle,195thrown,196args,197callSupplier && supplier != null ? supplier.get() : supplier,198msg,199};200}201202boolean callSupplier(Object obj) {203return callSupplier || ((LogEvent)obj).callSupplier;204}205206@Override207public String toString() {208return Arrays.deepToString(toArray(false));209}210211@Override212public boolean equals(Object obj) {213return obj instanceof LogEvent214&& Objects.deepEquals(toArray(callSupplier(obj)), ((LogEvent)obj).toArray(callSupplier(obj)));215}216217@Override218public int hashCode() {219return Objects.hash(toArray(true));220}221222public LogEvent cloneWith(long sequenceNumber)223throws CloneNotSupportedException {224LogEvent cloned = (LogEvent)super.clone();225cloned.sequenceNumber = sequenceNumber;226return cloned;227}228229public static LogEvent of(boolean isLoggable, String name,230Level level, ResourceBundle bundle,231String key, Throwable thrown) {232LogEvent evt = new LogEvent();233evt.isLoggable = isLoggable;234evt.loggerName = name;235evt.level = level;236evt.args = null;237evt.bundle = bundle;238evt.thrown = thrown;239evt.supplier = null;240evt.msg = key;241return evt;242}243244public static LogEvent of(boolean isLoggable, String name,245Level level, Throwable thrown, Supplier<String> supplier) {246LogEvent evt = new LogEvent();247evt.isLoggable = isLoggable;248evt.loggerName = name;249evt.level = level;250evt.args = null;251evt.bundle = null;252evt.thrown = thrown;253evt.supplier = supplier;254evt.msg = null;255return evt;256}257258public static LogEvent of(boolean isLoggable, String name,259Level level, ResourceBundle bundle,260String key, Object... params) {261LogEvent evt = new LogEvent();262evt.isLoggable = isLoggable;263evt.loggerName = name;264evt.level = level;265evt.args = params;266evt.bundle = bundle;267evt.thrown = null;268evt.supplier = null;269evt.msg = key;270return evt;271}272273public static LogEvent of(long sequenceNumber,274boolean isLoggable, String name,275Level level, ResourceBundle bundle,276String key, Supplier<String> supplier,277Throwable thrown, Object... params) {278LogEvent evt = new LogEvent(sequenceNumber);279evt.loggerName = name;280evt.level = level;281evt.args = params;282evt.bundle = bundle;283evt.thrown = thrown;284evt.supplier = supplier;285evt.msg = key;286evt.isLoggable = isLoggable;287return evt;288}289290public static LogEvent ofp(boolean callSupplier, LogEvent evt) {291evt.callSupplier = callSupplier;292return evt;293}294}295296public class LoggerImpl implements Logger {297private final String name;298private Level level = Level.INFO;299300public LoggerImpl(String name) {301this.name = name;302}303304@Override305public String getName() {306return name;307}308309@Override310public boolean isLoggable(Level level) {311return this.level != Level.OFF && this.level.getSeverity() <= level.getSeverity();312}313314@Override315public void log(Level level, ResourceBundle bundle, String key, Throwable thrown) {316log(LogEvent.of(isLoggable(level), this.name, level, bundle, key, thrown));317}318319@Override320public void log(Level level, ResourceBundle bundle, String format, Object... params) {321log(LogEvent.of(isLoggable(level), name, level, bundle, format, params));322}323324void log(LogEvent event) {325eventQueue.add(event);326}327328@Override329public void log(Level level, Supplier<String> msgSupplier) {330log(LogEvent.of(isLoggable(level), name, level, null, msgSupplier));331}332333@Override334public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {335log(LogEvent.of(isLoggable(level), name, level, thrown, msgSupplier));336}337338}339340public Logger getLogger(String name, Module caller);341public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);342}343344static PlatformLogger.Bridge convert(Logger logger) {345boolean old = allowAll.get().get();346allowAccess.get().set(true);347try {348return PlatformLogger.Bridge.convert(logger);349} finally {350allowAccess.get().set(old);351}352}353354static Logger getLogger(String name, Module caller) {355boolean old = allowAll.get().get();356allowAccess.get().set(true);357try {358return jdk.internal.logger.LazyLoggers.getLogger(name, caller);359} finally {360allowAccess.get().set(old);361}362}363364static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};365366static void setSecurityManager() {367if (System.getSecurityManager() == null) {368// Ugly test hack: preload the resources needed by String.format369// We need to do that before setting the security manager370// because our implementation of CustomSystemClassLoader371// doesn't have the required permission.372System.out.println(String.format("debug: %s", "Setting security manager"));373Policy.setPolicy(new SimplePolicy(allowControl, allowAccess, allowAll));374System.setSecurityManager(new SecurityManager());375}376}377378public static void main(String[] args) {379if (args.length == 0)380args = new String[] {381"NOSECURITY",382"NOPERMISSIONS",383"WITHPERMISSIONS"384};385386387Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {388TestLoggerFinder provider;389switch (testCase) {390case NOSECURITY:391System.out.println("\n*** Without Security Manager\n");392provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());393test(provider, true);394System.out.println("Tetscase count: " + sequencer.get());395break;396case NOPERMISSIONS:397System.out.println("\n*** With Security Manager, without permissions\n");398setSecurityManager();399try {400provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());401throw new RuntimeException("Expected exception not raised");402} catch (AccessControlException x) {403if (!LOGGERFINDER_PERMISSION.equals(x.getPermission())) {404throw new RuntimeException("Unexpected permission check", x);405}406final boolean control = allowControl.get().get();407try {408allowControl.get().set(true);409provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());410} finally {411allowControl.get().set(control);412}413}414test(provider, false);415System.out.println("Tetscase count: " + sequencer.get());416break;417case WITHPERMISSIONS:418System.out.println("\n*** With Security Manager, with control permission\n");419setSecurityManager();420final boolean control = allowControl.get().get();421try {422allowControl.get().set(true);423provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());424test(provider, true);425} finally {426allowControl.get().set(control);427}428break;429default:430throw new RuntimeException("Unknown test case: " + testCase);431}432});433System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");434}435436public static void test(TestLoggerFinder provider, boolean hasRequiredPermissions) {437438ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());439final Map<Object, String> loggerDescMap = new HashMap<>();440441442TestLoggerFinder.LoggerImpl appSink = null;443try {444appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));445if (!hasRequiredPermissions) {446throw new RuntimeException("Managed to obtain a system logger without permission");447}448} catch (AccessControlException acx) {449if (hasRequiredPermissions) {450throw new RuntimeException("Unexpected security exception: ", acx);451}452if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {453throw new RuntimeException("Unexpected permission in exception: " + acx, acx);454}455System.out.println("Got expected exception for logger: " + acx);456boolean old = allowControl.get().get();457allowControl.get().set(true);458try {459appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));460} finally {461allowControl.get().set(old);462}463}464465466TestLoggerFinder.LoggerImpl sysSink = null;467try {468sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));469if (!hasRequiredPermissions) {470throw new RuntimeException("Managed to obtain a system logger without permission");471}472} catch (AccessControlException acx) {473if (hasRequiredPermissions) {474throw new RuntimeException("Unexpected security exception: ", acx);475}476if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {477throw new RuntimeException("Unexpected permission in exception: " + acx, acx);478}479System.out.println("Got expected exception for system logger: " + acx);480}481if (hasRequiredPermissions && appSink == sysSink) {482throw new RuntimeException("identical loggers");483}484485if (provider.system.contains(appSink)) {486throw new RuntimeException("app logger in system map");487}488if (!provider.user.contains(appSink)) {489throw new RuntimeException("app logger not in appplication map");490}491if (hasRequiredPermissions && provider.user.contains(sysSink)) {492throw new RuntimeException("sys logger in appplication map");493}494if (hasRequiredPermissions && !provider.system.contains(sysSink)) {495throw new RuntimeException("sys logger not in system map");496}497498Logger appLogger1 = System.getLogger("foo");499loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");500PlatformLogger.Bridge bridge = convert(appLogger1);501loggerDescMap.putIfAbsent(bridge, "PlatformLogger.Bridge.convert(System.getLogger(\"foo\"))");502testLogger(provider, loggerDescMap, "foo", null, bridge, appSink);503504Logger sysLogger1 = null;505try {506sysLogger1 = getLogger("foo", Thread.class.getModule());507loggerDescMap.put(sysLogger1,508"jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class.getModule())");509510if (!hasRequiredPermissions) {511// check that the provider would have thrown an exception512provider.getLogger("foo", Thread.class.getModule());513throw new RuntimeException("Managed to obtain a system logger without permission");514}515} catch (AccessControlException acx) {516if (hasRequiredPermissions) {517throw new RuntimeException("Unexpected security exception: ", acx);518}519if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {520throw new RuntimeException("Unexpected permission in exception: " + acx, acx);521}522System.out.println("Got expected exception for system logger: " + acx);523}524525if (hasRequiredPermissions) {526// if we don't have permissions sysSink will be null.527testLogger(provider, loggerDescMap, "foo", null,528PlatformLogger.Bridge.convert(sysLogger1), sysSink);529}530531Logger appLogger2 =532System.getLogger("foo", loggerBundle);533loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)");534535if (appLogger2 == appLogger1) {536throw new RuntimeException("identical loggers");537}538539if (provider.system.contains(appLogger2)) {540throw new RuntimeException("localized app logger in system map");541}542if (provider.user.contains(appLogger2)) {543throw new RuntimeException("localized app logger in appplication map");544}545546testLogger(provider, loggerDescMap, "foo", loggerBundle,547PlatformLogger.Bridge.convert(appLogger2), appSink);548549Logger sysLogger2 = null;550try {551sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());552loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");553if (!hasRequiredPermissions) {554throw new RuntimeException("Managed to obtain a system logger without permission");555}556} catch (AccessControlException acx) {557if (hasRequiredPermissions) {558throw new RuntimeException("Unexpected security exception: ", acx);559}560if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {561throw new RuntimeException("Unexpected permission in exception: " + acx, acx);562}563System.out.println("Got expected exception for localized system logger: " + acx);564}565if (hasRequiredPermissions && appLogger2 == sysLogger2) {566throw new RuntimeException("identical loggers");567}568if (hasRequiredPermissions && sysLogger2 == sysLogger1) {569throw new RuntimeException("identical loggers");570}571if (hasRequiredPermissions && provider.user.contains(sysLogger2)) {572throw new RuntimeException("localized sys logger in appplication map");573}574if (hasRequiredPermissions && provider.system.contains(sysLogger2)) {575throw new RuntimeException("localized sys logger not in system map");576}577578if (hasRequiredPermissions) {579// if we don't have permissions sysSink will be null.580testLogger(provider, loggerDescMap, "foo", loggerBundle,581PlatformLogger.Bridge.convert(sysLogger2), sysSink);582}583584}585586public static class Foo {587588}589590static void verbose(String msg) {591if (VERBOSE) {592System.out.println(msg);593}594}595596static void checkLogEvent(TestLoggerFinder provider, String desc,597TestLoggerFinder.LogEvent expected) {598TestLoggerFinder.LogEvent actual = provider.eventQueue.poll();599if (!Objects.equals(expected, actual)) {600throw new RuntimeException("mismatch for " + desc601+ "\n\texpected=" + expected602+ "\n\t actual=" + actual);603} else {604verbose("Got expected results for "605+ desc + "\n\t" + expected);606}607}608609static void checkLogEvent(TestLoggerFinder provider, String desc,610TestLoggerFinder.LogEvent expected, boolean expectNotNull) {611TestLoggerFinder.LogEvent actual = provider.eventQueue.poll();612if (actual == null && !expectNotNull) return;613if (actual != null && !expectNotNull) {614throw new RuntimeException("Unexpected log event found for " + desc615+ "\n\tgot: " + actual);616}617if (!expected.equals(actual)) {618throw new RuntimeException("mismatch for " + desc619+ "\n\texpected=" + expected620+ "\n\t actual=" + actual);621} else {622verbose("Got expected results for "623+ desc + "\n\t" + expected);624}625}626627static Supplier<String> logpMessage(ResourceBundle bundle,628String className, String methodName, Supplier<String> msg) {629if (BEST_EFFORT_FOR_LOGP && bundle == null630&& (className != null || methodName != null)) {631final String cName = className == null ? "" : className;632final String mName = methodName == null ? "" : methodName;633return () -> String.format("[%s %s] %s", cName, mName, msg.get());634} else {635return msg;636}637}638639static String logpMessage(ResourceBundle bundle,640String className, String methodName, String msg) {641if (BEST_EFFORT_FOR_LOGP && bundle == null642&& (className != null || methodName != null)) {643final String cName = className == null ? "" : className;644final String mName = methodName == null ? "" : methodName;645return String.format("[%s %s] %s", cName, mName, msg == null ? "" : msg);646} else {647return msg;648}649}650651// Calls the methods defined on LogProducer and verify the652// parameters received by the underlying TestLoggerFinder.LoggerImpl653// logger.654private static void testLogger(TestLoggerFinder provider,655Map<Object, String> loggerDescMap,656String name,657ResourceBundle loggerBundle,658PlatformLogger.Bridge logger,659TestLoggerFinder.LoggerImpl sink) {660661if (loggerDescMap.get(logger) == null) {662throw new RuntimeException("Test bug: Missing description");663}664System.out.println("Testing " + loggerDescMap.get(logger) +" [" + logger + "]");665666Foo foo = new Foo();667String fooMsg = foo.toString();668System.out.println("\tlogger.log(messageLevel, fooMsg)");669System.out.println("\tlogger.<level>(fooMsg)");670for (Level loggerLevel : Level.values()) {671sink.level = loggerLevel;672for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {673String desc = "logger.log(messageLevel, fooMsg): loggerLevel="674+ loggerLevel+", messageLevel="+messageLevel;675Level expectedMessageLevel = julToSpiMap.get(messageLevel);676TestLoggerFinder.LogEvent expected =677TestLoggerFinder.LogEvent.of(678sequencer.get(),679loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,680name, expectedMessageLevel, loggerBundle,681fooMsg, null, (Throwable)null, (Object[])null);682logger.log(messageLevel, fooMsg);683checkLogEvent(provider, desc, expected);684}685}686687Supplier<String> supplier = new Supplier<String>() {688@Override689public String get() {690return this.toString();691}692};693System.out.println("\tlogger.log(messageLevel, supplier)");694System.out.println("\tlogger.<level>(supplier)");695for (Level loggerLevel : Level.values()) {696sink.level = loggerLevel;697for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {698String desc = "logger.log(messageLevel, supplier): loggerLevel="699+ loggerLevel+", messageLevel="+messageLevel;700Level expectedMessageLevel = julToSpiMap.get(messageLevel);701TestLoggerFinder.LogEvent expected =702TestLoggerFinder.LogEvent.of(703sequencer.get(),704loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,705name, expectedMessageLevel, (ResourceBundle) null,706null, supplier, (Throwable)null, (Object[])null);707logger.log(messageLevel, supplier);708checkLogEvent(provider, desc, expected);709}710}711712String format = "two params [{1} {2}]";713Object arg1 = foo;714Object arg2 = fooMsg;715System.out.println("\tlogger.log(messageLevel, format, arg1, arg2)");716for (Level loggerLevel : Level.values()) {717sink.level = loggerLevel;718for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {719String desc = "logger.log(messageLevel, format, foo, fooMsg): loggerLevel="720+ loggerLevel+", messageLevel="+messageLevel;721Level expectedMessageLevel = julToSpiMap.get(messageLevel);722TestLoggerFinder.LogEvent expected =723TestLoggerFinder.LogEvent.of(724sequencer.get(),725loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,726name, expectedMessageLevel, loggerBundle,727format, null, (Throwable)null, arg1, arg2);728logger.log(messageLevel, format, arg1, arg2);729checkLogEvent(provider, desc, expected);730}731}732733Throwable thrown = new Exception("OK: log me!");734System.out.println("\tlogger.log(messageLevel, fooMsg, thrown)");735for (Level loggerLevel : Level.values()) {736sink.level = loggerLevel;737for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {738String desc = "logger.log(messageLevel, fooMsg, thrown): loggerLevel="739+ loggerLevel+", messageLevel="+messageLevel;740Level expectedMessageLevel = julToSpiMap.get(messageLevel);741TestLoggerFinder.LogEvent expected =742TestLoggerFinder.LogEvent.of(743sequencer.get(),744loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,745name, expectedMessageLevel, loggerBundle,746fooMsg, null, thrown, (Object[])null);747logger.log(messageLevel, fooMsg, thrown);748checkLogEvent(provider, desc, expected);749}750}751752System.out.println("\tlogger.log(messageLevel, thrown, supplier)");753for (Level loggerLevel : Level.values()) {754sink.level = loggerLevel;755for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {756String desc = "logger.log(messageLevel, thrown, supplier): loggerLevel="757+ loggerLevel+", messageLevel="+messageLevel;758Level expectedMessageLevel = julToSpiMap.get(messageLevel);759TestLoggerFinder.LogEvent expected =760TestLoggerFinder.LogEvent.of(761sequencer.get(),762loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,763name, expectedMessageLevel, (ResourceBundle)null,764null, supplier, thrown, (Object[])null);765logger.log(messageLevel, thrown, supplier);766checkLogEvent(provider, desc, expected);767}768}769770String sourceClass = "blah.Blah";771String sourceMethod = "blih";772System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, fooMsg)");773for (Level loggerLevel : Level.values()) {774sink.level = loggerLevel;775for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {776String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg): loggerLevel="777+ loggerLevel+", messageLevel="+messageLevel;778Level expectedMessageLevel = julToSpiMap.get(messageLevel);779boolean isLoggable = loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0;780TestLoggerFinder.LogEvent expected =781isLoggable || loggerBundle != null && BEST_EFFORT_FOR_LOGP?782TestLoggerFinder.LogEvent.of(783sequencer.get(),784isLoggable,785name, expectedMessageLevel, loggerBundle,786logpMessage(loggerBundle, sourceClass, sourceMethod, fooMsg),787null, (Throwable)null, (Object[]) null) : null;788logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg);789checkLogEvent(provider, desc, expected);790}791}792793System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, supplier)");794for (Level loggerLevel : Level.values()) {795sink.level = loggerLevel;796for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {797String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, supplier): loggerLevel="798+ loggerLevel+", messageLevel="+messageLevel;799Level expectedMessageLevel = julToSpiMap.get(messageLevel);800boolean isLoggable = loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0;801TestLoggerFinder.LogEvent expected = isLoggable ?802TestLoggerFinder.LogEvent.ofp(BEST_EFFORT_FOR_LOGP,803TestLoggerFinder.LogEvent.of(804sequencer.get(),805isLoggable,806name, expectedMessageLevel, null, null,807logpMessage(null, sourceClass, sourceMethod, supplier),808(Throwable)null, (Object[]) null)) : null;809logger.logp(messageLevel, sourceClass, sourceMethod, supplier);810checkLogEvent(provider, desc, expected);811}812}813814System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, format, arg1, arg2)");815for (Level loggerLevel : Level.values()) {816sink.level = loggerLevel;817for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {818String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, format, arg1, arg2): loggerLevel="819+ loggerLevel+", messageLevel="+messageLevel;820Level expectedMessageLevel = julToSpiMap.get(messageLevel);821boolean isLoggable = loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0;822TestLoggerFinder.LogEvent expected =823isLoggable || loggerBundle != null && BEST_EFFORT_FOR_LOGP?824TestLoggerFinder.LogEvent.of(825sequencer.get(),826loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,827name, expectedMessageLevel, loggerBundle,828logpMessage(loggerBundle, sourceClass, sourceMethod, format),829null, (Throwable)null, arg1, arg2) : null;830logger.logp(messageLevel, sourceClass, sourceMethod, format, arg1, arg2);831checkLogEvent(provider, desc, expected);832}833}834835System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, fooMsg, thrown)");836for (Level loggerLevel : Level.values()) {837sink.level = loggerLevel;838for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {839String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg, thrown): loggerLevel="840+ loggerLevel+", messageLevel="+messageLevel;841Level expectedMessageLevel = julToSpiMap.get(messageLevel);842boolean isLoggable = loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0;843TestLoggerFinder.LogEvent expected =844isLoggable || loggerBundle != null && BEST_EFFORT_FOR_LOGP ?845TestLoggerFinder.LogEvent.of(846sequencer.get(),847loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,848name, expectedMessageLevel, loggerBundle,849logpMessage(loggerBundle, sourceClass, sourceMethod, fooMsg),850null, thrown, (Object[])null) : null;851logger.logp(messageLevel, sourceClass, sourceMethod, fooMsg, thrown);852checkLogEvent(provider, desc, expected);853}854}855856System.out.println("\tlogger.logp(messageLevel, sourceClass, sourceMethod, thrown, supplier)");857for (Level loggerLevel : Level.values()) {858sink.level = loggerLevel;859for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {860String desc = "logger.logp(messageLevel, sourceClass, sourceMethod, thrown, supplier): loggerLevel="861+ loggerLevel+", messageLevel="+messageLevel;862Level expectedMessageLevel = julToSpiMap.get(messageLevel);863boolean isLoggable = loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0;864TestLoggerFinder.LogEvent expected = isLoggable ?865TestLoggerFinder.LogEvent.ofp(BEST_EFFORT_FOR_LOGP,866TestLoggerFinder.LogEvent.of(867sequencer.get(),868loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,869name, expectedMessageLevel, null, null,870logpMessage(null, sourceClass, sourceMethod, supplier),871thrown, (Object[])null)) : null;872logger.logp(messageLevel, sourceClass, sourceMethod, thrown, supplier);873checkLogEvent(provider, desc, expected);874}875}876877ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName());878System.out.println("\tlogger.logrb(messageLevel, bundle, format, arg1, arg2)");879for (Level loggerLevel : Level.values()) {880sink.level = loggerLevel;881for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {882String desc = "logger.logrb(messageLevel, bundle, format, arg1, arg2): loggerLevel="883+ loggerLevel+", messageLevel="+messageLevel;884Level expectedMessageLevel = julToSpiMap.get(messageLevel);885TestLoggerFinder.LogEvent expected =886TestLoggerFinder.LogEvent.of(887sequencer.get(),888loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,889name, expectedMessageLevel, bundle,890format, null, (Throwable)null, arg1, arg2);891logger.logrb(messageLevel, bundle, format, arg1, arg2);892checkLogEvent(provider, desc, expected);893}894}895896System.out.println("\tlogger.logrb(messageLevel, bundle, msg, thrown)");897for (Level loggerLevel : Level.values()) {898sink.level = loggerLevel;899for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {900String desc = "logger.logrb(messageLevel, bundle, msg, thrown): loggerLevel="901+ loggerLevel+", messageLevel="+messageLevel;902Level expectedMessageLevel = julToSpiMap.get(messageLevel);903TestLoggerFinder.LogEvent expected =904TestLoggerFinder.LogEvent.of(905sequencer.get(),906loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,907name, expectedMessageLevel, bundle,908fooMsg, null, thrown, (Object[])null);909logger.logrb(messageLevel, bundle, fooMsg, thrown);910checkLogEvent(provider, desc, expected);911}912}913914System.out.println("\tlogger.logrb(messageLevel, sourceClass, sourceMethod, bundle, format, arg1, arg2)");915for (Level loggerLevel : Level.values()) {916sink.level = loggerLevel;917for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {918String desc = "logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, format, arg1, arg2): loggerLevel="919+ loggerLevel+", messageLevel="+messageLevel;920Level expectedMessageLevel = julToSpiMap.get(messageLevel);921TestLoggerFinder.LogEvent expected =922TestLoggerFinder.LogEvent.of(923sequencer.get(),924loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,925name, expectedMessageLevel, bundle,926format, null, (Throwable)null, arg1, arg2);927logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, format, arg1, arg2);928checkLogEvent(provider, desc, expected);929}930}931932System.out.println("\tlogger.logrb(messageLevel, sourceClass, sourceMethod, bundle, msg, thrown)");933for (Level loggerLevel : Level.values()) {934sink.level = loggerLevel;935for (sun.util.logging.PlatformLogger.Level messageLevel :julLevels) {936String desc = "logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, msg, thrown): loggerLevel="937+ loggerLevel+", messageLevel="+messageLevel;938Level expectedMessageLevel = julToSpiMap.get(messageLevel);939TestLoggerFinder.LogEvent expected =940TestLoggerFinder.LogEvent.of(941sequencer.get(),942loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,943name, expectedMessageLevel, bundle,944fooMsg, null, thrown, (Object[])null);945logger.logrb(messageLevel, sourceClass, sourceMethod, bundle, fooMsg, thrown);946checkLogEvent(provider, desc, expected);947}948}949}950951final static class PermissionsBuilder {952final Permissions perms;953public PermissionsBuilder() {954this(new Permissions());955}956public PermissionsBuilder(Permissions perms) {957this.perms = perms;958}959public PermissionsBuilder add(Permission p) {960perms.add(p);961return this;962}963public PermissionsBuilder addAll(PermissionCollection col) {964if (col != null) {965for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {966perms.add(e.nextElement());967}968}969return this;970}971public Permissions toPermissions() {972final PermissionsBuilder builder = new PermissionsBuilder();973builder.addAll(perms);974return builder.perms;975}976}977978public static class SimplePolicy extends Policy {979final static RuntimePermission CONTROL = LOGGERFINDER_PERMISSION;980final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger");981final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");982983static final Policy DEFAULT_POLICY = Policy.getPolicy();984985final Permissions permissions;986final Permissions allPermissions;987final ThreadLocal<AtomicBoolean> allowControl;988final ThreadLocal<AtomicBoolean> allowAccess;989final ThreadLocal<AtomicBoolean> allowAll;990public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl,991ThreadLocal<AtomicBoolean> allowAccess,992ThreadLocal<AtomicBoolean> allowAll) {993this.allowControl = allowControl;994this.allowAccess = allowAccess;995this.allowAll = allowAll;996permissions = new Permissions();997allPermissions = new PermissionsBuilder()998.add(new java.security.AllPermission())999.toPermissions();1000}10011002Permissions getPermissions() {1003if (allowControl.get().get() || allowAccess.get().get() || allowAll.get().get()) {1004PermissionsBuilder builder = new PermissionsBuilder()1005.addAll(permissions);1006if (allowControl.get().get()) {1007builder.add(CONTROL);1008}1009if (allowAccess.get().get()) {1010builder.add(ACCESS_LOGGER);1011builder.add(ACCESS_LOGGING);1012}1013if (allowAll.get().get()) {1014builder.addAll(allPermissions);1015}1016return builder.toPermissions();1017}1018return permissions;1019}10201021@Override1022public boolean implies(ProtectionDomain domain, Permission permission) {1023return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);1024}10251026@Override1027public PermissionCollection getPermissions(CodeSource codesource) {1028return new PermissionsBuilder().addAll(getPermissions()).toPermissions();1029}10301031@Override1032public PermissionCollection getPermissions(ProtectionDomain domain) {1033return new PermissionsBuilder().addAll(getPermissions()).toPermissions();1034}1035}1036}103710381039