Path: blob/master/test/jdk/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java
41154 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.CodeSource;24import java.security.Permission;25import java.security.PermissionCollection;26import java.security.Permissions;27import java.security.Policy;28import java.security.ProtectionDomain;29import java.util.Arrays;30import java.util.Collections;31import java.util.Enumeration;32import java.util.HashMap;33import java.util.Map;34import java.util.Objects;35import java.util.Queue;36import java.util.ResourceBundle;37import java.util.concurrent.ArrayBlockingQueue;38import java.util.concurrent.ConcurrentHashMap;39import java.util.concurrent.atomic.AtomicBoolean;40import java.util.concurrent.atomic.AtomicLong;41import java.util.function.Supplier;42import java.util.logging.Handler;43import java.util.logging.LogRecord;44import java.lang.System.LoggerFinder;45import java.lang.System.Logger;46import java.lang.System.Logger.Level;47import java.util.stream.Stream;4849/**50* @test51* @bug 814036452* @summary Tests the default implementation of System.Logger, when53* JUL is the default backend.54* @modules java.logging55* @build AccessSystemLogger DefaultLoggerFinderTest56* @run driver AccessSystemLogger57* @run main/othervm -Xbootclasspath/a:boot DefaultLoggerFinderTest NOSECURITY58* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerFinderTest NOPERMISSIONS59* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerFinderTest WITHPERMISSIONS60* @author danielfuchs61*/62public class DefaultLoggerFinderTest {6364static final RuntimePermission LOGGERFINDER_PERMISSION =65new RuntimePermission("loggerFinder");66final static AtomicLong sequencer = new AtomicLong();67final static boolean VERBOSE = false;68static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() {69@Override70protected AtomicBoolean initialValue() {71return new AtomicBoolean(false);72}73};74static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {75@Override76protected AtomicBoolean initialValue() {77return new AtomicBoolean(false);78}79};8081static final AccessSystemLogger accessSystemLogger = new AccessSystemLogger();8283public static final Queue<LogEvent> eventQueue = new ArrayBlockingQueue<>(128);8485public static final class LogEvent {8687public LogEvent() {88this(sequencer.getAndIncrement());89}9091LogEvent(long sequenceNumber) {92this.sequenceNumber = sequenceNumber;93}9495long sequenceNumber;96boolean isLoggable;97String loggerName;98java.util.logging.Level level;99ResourceBundle bundle;100Throwable thrown;101Object[] args;102String msg;103String className;104String methodName;105106Object[] toArray() {107return new Object[] {108sequenceNumber,109isLoggable,110loggerName,111level,112bundle,113thrown,114args,115msg,116className,117methodName,118};119}120121@Override122public String toString() {123return Arrays.deepToString(toArray());124}125126@Override127public boolean equals(Object obj) {128return obj instanceof LogEvent129&& Objects.deepEquals(this.toArray(), ((LogEvent)obj).toArray());130}131132@Override133public int hashCode() {134return Objects.hash(toArray());135}136public static LogEvent of(long sequenceNumber,137boolean isLoggable, String name,138java.util.logging.Level level, ResourceBundle bundle,139String key, Throwable thrown, Object... params) {140return LogEvent.of(sequenceNumber, isLoggable, name,141DefaultLoggerFinderTest.class.getName(),142"testLogger", level, bundle, key,143thrown, params);144}145public static LogEvent of(long sequenceNumber,146boolean isLoggable, String name,147String className, String methodName,148java.util.logging.Level level, ResourceBundle bundle,149String key, Throwable thrown, Object... params) {150LogEvent evt = new LogEvent(sequenceNumber);151evt.loggerName = name;152evt.level = level;153evt.args = params;154evt.bundle = bundle;155evt.thrown = thrown;156evt.msg = key;157evt.isLoggable = isLoggable;158evt.className = className;159evt.methodName = methodName;160return evt;161}162163}164165static java.util.logging.Level mapToJul(Level level) {166switch (level) {167case ALL: return java.util.logging.Level.ALL;168case TRACE: return java.util.logging.Level.FINER;169case DEBUG: return java.util.logging.Level.FINE;170case INFO: return java.util.logging.Level.INFO;171case WARNING: return java.util.logging.Level.WARNING;172case ERROR: return java.util.logging.Level.SEVERE;173case OFF: return java.util.logging.Level.OFF;174}175throw new InternalError("No such level: " + level);176}177178static final java.util.logging.Level[] julLevels = {179java.util.logging.Level.ALL,180new java.util.logging.Level("FINER_THAN_FINEST", java.util.logging.Level.FINEST.intValue() - 10) {},181java.util.logging.Level.FINEST,182new java.util.logging.Level("FINER_THAN_FINER", java.util.logging.Level.FINER.intValue() - 10) {},183java.util.logging.Level.FINER,184new java.util.logging.Level("FINER_THAN_FINE", java.util.logging.Level.FINE.intValue() - 10) {},185java.util.logging.Level.FINE,186new java.util.logging.Level("FINER_THAN_CONFIG", java.util.logging.Level.FINE.intValue() + 10) {},187java.util.logging.Level.CONFIG,188new java.util.logging.Level("FINER_THAN_INFO", java.util.logging.Level.INFO.intValue() - 10) {},189java.util.logging.Level.INFO,190new java.util.logging.Level("FINER_THAN_WARNING", java.util.logging.Level.INFO.intValue() + 10) {},191java.util.logging.Level.WARNING,192new java.util.logging.Level("FINER_THAN_SEVERE", java.util.logging.Level.SEVERE.intValue() - 10) {},193java.util.logging.Level.SEVERE,194new java.util.logging.Level("FATAL", java.util.logging.Level.SEVERE.intValue() + 10) {},195java.util.logging.Level.OFF,196};197198static final Level[] mappedLevels = {199Level.ALL, // ALL200Level.DEBUG, // FINER_THAN_FINEST201Level.DEBUG, // FINEST202Level.DEBUG, // FINER_THAN_FINER203Level.TRACE, // FINER204Level.TRACE, // FINER_THAN_FINE205Level.DEBUG, // FINE206Level.DEBUG, // FINER_THAN_CONFIG207Level.DEBUG, // CONFIG208Level.DEBUG, // FINER_THAN_INFO209Level.INFO, // INFO210Level.INFO, // FINER_THAN_WARNING211Level.WARNING, // WARNING212Level.WARNING, // FINER_THAN_SEVERE213Level.ERROR, // SEVERE214Level.ERROR, // FATAL215Level.OFF, // OFF216};217218final static Map<java.util.logging.Level, Level> julToSpiMap;219static {220Map<java.util.logging.Level, Level> map = new HashMap<>();221if (mappedLevels.length != julLevels.length) {222throw new ExceptionInInitializerError("Array lengths differ"223+ "\n\tjulLevels=" + Arrays.deepToString(julLevels)224+ "\n\tmappedLevels=" + Arrays.deepToString(mappedLevels));225}226for (int i=0; i<julLevels.length; i++) {227map.put(julLevels[i], mappedLevels[i]);228}229julToSpiMap = Collections.unmodifiableMap(map);230}231232public static class MyBundle extends ResourceBundle {233234final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();235236@Override237protected Object handleGetObject(String key) {238if (key.contains(" (translated)")) {239throw new RuntimeException("Unexpected key: " + key);240}241return map.computeIfAbsent(key, k -> k + " (translated)");242}243244@Override245public Enumeration<String> getKeys() {246return Collections.enumeration(map.keySet());247}248249}250251public static class MyHandler extends Handler {252253@Override254public java.util.logging.Level getLevel() {255return java.util.logging.Level.ALL;256}257258@Override259public void publish(LogRecord record) {260eventQueue.add(LogEvent.of(sequencer.getAndIncrement(),261true, record.getLoggerName(),262record.getSourceClassName(),263record.getSourceMethodName(),264record.getLevel(),265record.getResourceBundle(), record.getMessage(),266record.getThrown(), record.getParameters()));267}268@Override269public void flush() {270}271@Override272public void close() throws SecurityException {273}274275}276277public static class MyLoggerBundle extends MyBundle {278279}280281282static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};283284static void setSecurityManager() {285if (System.getSecurityManager() == null) {286Policy.setPolicy(new SimplePolicy(allowAll, allowControl));287System.setSecurityManager(new SecurityManager());288}289}290291public static void main(String[] args) {292if (args.length == 0)293args = new String[] {294"NOSECURITY",295"NOPERMISSIONS",296"WITHPERMISSIONS"297};298299final java.util.logging.Logger appSink = java.util.logging.Logger.getLogger("foo");300final java.util.logging.Logger sysSink = accessSystemLogger.demandSystemLogger("foo");301final java.util.logging.Logger sink = java.util.logging.Logger.getLogger("foo");302sink.addHandler(new MyHandler());303sink.setUseParentHandlers(VERBOSE);304305Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {306LoggerFinder provider;307switch (testCase) {308case NOSECURITY:309System.out.println("\n*** Without Security Manager\n");310provider = LoggerFinder.getLoggerFinder();311test(provider, true, appSink, sysSink);312System.out.println("Tetscase count: " + sequencer.get());313break;314case NOPERMISSIONS:315System.out.println("\n*** With Security Manager, without permissions\n");316setSecurityManager();317try {318provider = LoggerFinder.getLoggerFinder();319throw new RuntimeException("Expected exception not raised");320} catch (AccessControlException x) {321if (!LOGGERFINDER_PERMISSION.equals(x.getPermission())) {322throw new RuntimeException("Unexpected permission check", x);323}324final boolean control = allowControl.get().get();325try {326allowControl.get().set(true);327provider = LoggerFinder.getLoggerFinder();328} finally {329allowControl.get().set(control);330}331}332test(provider, false, appSink, sysSink);333System.out.println("Tetscase count: " + sequencer.get());334break;335case WITHPERMISSIONS:336System.out.println("\n*** With Security Manager, with control permission\n");337setSecurityManager();338final boolean control = allowControl.get().get();339try {340allowControl.get().set(true);341provider = LoggerFinder.getLoggerFinder();342test(provider, true, appSink, sysSink);343} finally {344allowControl.get().set(control);345}346break;347default:348throw new RuntimeException("Unknown test case: " + testCase);349}350});351System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");352}353354public static void test(LoggerFinder provider,355boolean hasRequiredPermissions,356java.util.logging.Logger appSink,357java.util.logging.Logger sysSink) {358359ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());360final Map<Logger, String> loggerDescMap = new HashMap<>();361362363Logger appLogger1 = null;364try {365appLogger1 = provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());366loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");367if (!hasRequiredPermissions) {368throw new RuntimeException("Managed to obtain a logger without permission");369}370} catch (AccessControlException acx) {371if (hasRequiredPermissions) {372throw new RuntimeException("Unexpected security exception: ", acx);373}374if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {375throw new RuntimeException("Unexpected permission in exception: " + acx, acx);376}377System.out.println("Got expected exception for logger: " + acx);378boolean old = allowControl.get().get();379allowControl.get().set(true);380try {381appLogger1 =provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());382loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");383} finally {384allowControl.get().set(old);385}386}387388Logger sysLogger1 = null;389try {390sysLogger1 = provider.getLogger("foo", Thread.class.getModule());391loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");392if (!hasRequiredPermissions) {393throw new RuntimeException("Managed to obtain a system logger without permission");394}395} catch (AccessControlException acx) {396if (hasRequiredPermissions) {397throw new RuntimeException("Unexpected security exception: ", acx);398}399if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {400throw new RuntimeException("Unexpected permission in exception: " + acx, acx);401}402System.out.println("Got expected exception for system logger: " + acx);403boolean old = allowControl.get().get();404allowControl.get().set(true);405try {406sysLogger1 = provider.getLogger("foo", Thread.class.getModule());407loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");408} finally {409allowControl.get().set(old);410}411}412if (appLogger1 == sysLogger1) {413throw new RuntimeException("identical loggers");414}415416Logger appLogger2 = null;417try {418appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());419loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");420if (!hasRequiredPermissions) {421throw new RuntimeException("Managed to obtain a logger without permission");422}423} catch (AccessControlException acx) {424if (hasRequiredPermissions) {425throw new RuntimeException("Unexpected security exception: ", acx);426}427if (!acx.getPermission().equals(LOGGERFINDER_PERMISSION)) {428throw new RuntimeException("Unexpected permission in exception: " + acx, acx);429}430System.out.println("Got expected exception for logger: " + acx);431boolean old = allowControl.get().get();432allowControl.get().set(true);433try {434appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());435loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");436} finally {437allowControl.get().set(old);438}439}440441Logger sysLogger2 = null;442try {443sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());444loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.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 localized system logger: " + acx);456boolean old = allowControl.get().get();457allowControl.get().set(true);458try {459sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());460loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");461} finally {462allowControl.get().set(old);463}464}465if (appLogger2 == sysLogger2) {466throw new RuntimeException("identical loggers");467}468if (appLogger2 == appLogger1) {469throw new RuntimeException("identical loggers");470}471if (sysLogger2 == sysLogger1) {472throw new RuntimeException("identical loggers");473}474475476testLogger(provider, loggerDescMap, "foo", null, appLogger1, appSink);477testLogger(provider, loggerDescMap, "foo", null, sysLogger1, sysSink);478testLogger(provider, loggerDescMap, "foo", loggerBundle, appLogger2, appSink);479testLogger(provider, loggerDescMap, "foo", loggerBundle, sysLogger2, sysSink);480481482Logger appLogger3 = System.getLogger("foo");483loggerDescMap.put(appLogger3, "System.getLogger(\"foo\")");484485testLogger(provider, loggerDescMap, "foo", null, appLogger3, appSink);486487Logger appLogger4 =488System.getLogger("foo", loggerBundle);489loggerDescMap.put(appLogger4, "System.getLogger(\"foo\", loggerBundle)");490491if (appLogger4 == appLogger1) {492throw new RuntimeException("identical loggers");493}494495testLogger(provider, loggerDescMap, "foo", loggerBundle, appLogger4, appSink);496497Logger sysLogger3 = accessSystemLogger.getLogger("foo");498loggerDescMap.put(sysLogger3, "AccessSystemLogger.getLogger(\"foo\")");499500testLogger(provider, loggerDescMap, "foo", null, sysLogger3, sysSink);501502Logger sysLogger4 =503accessSystemLogger.getLogger("foo", loggerBundle);504loggerDescMap.put(appLogger4, "AccessSystemLogger.getLogger(\"foo\", loggerBundle)");505506if (sysLogger4 == sysLogger1) {507throw new RuntimeException("identical loggers");508}509510testLogger(provider, loggerDescMap, "foo", loggerBundle, sysLogger4, sysSink);511512}513514public static class Foo {515516}517518static void verbose(String msg) {519if (VERBOSE) {520System.out.println(msg);521}522}523524static void setLevel(java.util.logging.Logger sink, java.util.logging.Level loggerLevel) {525boolean before = allowAll.get().get();526try {527allowAll.get().set(true);528sink.setLevel(loggerLevel);529} finally {530allowAll.get().set(before);531}532}533534535// Calls the 8 methods defined on Logger and verify the536// parameters received by the underlying Logger Impl537// logger.538private static void testLogger(LoggerFinder provider,539Map<Logger, String> loggerDescMap,540String name,541ResourceBundle loggerBundle,542Logger logger,543java.util.logging.Logger sink) {544545System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger + "]");546final java.util.logging.Level OFF = java.util.logging.Level.OFF;547548Foo foo = new Foo();549String fooMsg = foo.toString();550for (java.util.logging.Level loggerLevel : julLevels) {551setLevel(sink, loggerLevel);552for (Level messageLevel : Level.values()) {553java.util.logging.Level julLevel = mapToJul(messageLevel);554String desc = "logger.log(messageLevel, foo): loggerLevel="555+ loggerLevel+", messageLevel="+messageLevel;556LogEvent expected =557LogEvent.of(558sequencer.get(),559julLevel.intValue() >= loggerLevel.intValue(),560name, julLevel, (ResourceBundle)null,561fooMsg, (Throwable)null, (Object[])null);562logger.log(messageLevel, foo);563if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {564if (eventQueue.poll() != null) {565throw new RuntimeException("unexpected event in queue for " + desc);566}567} else {568LogEvent actual = eventQueue.poll();569if (!expected.equals(actual)) {570throw new RuntimeException("mismatch for " + desc571+ "\n\texpected=" + expected572+ "\n\t actual=" + actual);573} else {574verbose("Got expected results for "575+ desc + "\n\t" + expected);576}577}578}579}580581String msg = "blah";582for (java.util.logging.Level loggerLevel : julLevels) {583setLevel(sink, loggerLevel);584for (Level messageLevel : Level.values()) {585java.util.logging.Level julLevel = mapToJul(messageLevel);586String desc = "logger.log(messageLevel, \"blah\"): loggerLevel="587+ loggerLevel+", messageLevel="+messageLevel;588LogEvent expected =589LogEvent.of(590sequencer.get(),591julLevel.intValue() >= loggerLevel.intValue(),592name, julLevel, loggerBundle,593msg, (Throwable)null, (Object[])null);594logger.log(messageLevel, msg);595if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {596if (eventQueue.poll() != null) {597throw new RuntimeException("unexpected event in queue for " + desc);598}599} else {600LogEvent actual = eventQueue.poll();601if (!expected.equals(actual)) {602throw new RuntimeException("mismatch for " + desc603+ "\n\texpected=" + expected604+ "\n\t actual=" + actual);605} else {606verbose("Got expected results for "607+ desc + "\n\t" + expected);608}609}610}611}612613Supplier<String> fooSupplier = new Supplier<String>() {614@Override615public String get() {616return this.toString();617}618};619620for (java.util.logging.Level loggerLevel : julLevels) {621setLevel(sink, loggerLevel);622for (Level messageLevel : Level.values()) {623java.util.logging.Level julLevel = mapToJul(messageLevel);624String desc = "logger.log(messageLevel, fooSupplier): loggerLevel="625+ loggerLevel+", messageLevel="+messageLevel;626LogEvent expected =627LogEvent.of(628sequencer.get(),629julLevel.intValue() >= loggerLevel.intValue(),630name, julLevel, (ResourceBundle)null,631fooSupplier.get(),632(Throwable)null, (Object[])null);633logger.log(messageLevel, fooSupplier);634if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {635if (eventQueue.poll() != null) {636throw new RuntimeException("unexpected event in queue for " + desc);637}638} else {639LogEvent actual = eventQueue.poll();640if (!expected.equals(actual)) {641throw new RuntimeException("mismatch for " + desc642+ "\n\texpected=" + expected643+ "\n\t actual=" + actual);644} else {645verbose("Got expected results for "646+ desc + "\n\t" + expected);647}648}649}650}651652String format = "two params [{1} {2}]";653Object arg1 = foo;654Object arg2 = msg;655for (java.util.logging.Level loggerLevel : julLevels) {656setLevel(sink, loggerLevel);657for (Level messageLevel : Level.values()) {658java.util.logging.Level julLevel = mapToJul(messageLevel);659String desc = "logger.log(messageLevel, format, params...): loggerLevel="660+ loggerLevel+", messageLevel="+messageLevel;661LogEvent expected =662LogEvent.of(663sequencer.get(),664julLevel.intValue() >= loggerLevel.intValue(),665name, julLevel, loggerBundle,666format, (Throwable)null, new Object[] {arg1, arg2});667logger.log(messageLevel, format, arg1, arg2);668if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {669if (eventQueue.poll() != null) {670throw new RuntimeException("unexpected event in queue for " + desc);671}672} else {673LogEvent actual = eventQueue.poll();674if (!expected.equals(actual)) {675throw new RuntimeException("mismatch for " + desc676+ "\n\texpected=" + expected677+ "\n\t actual=" + actual);678} else {679verbose("Got expected results for "680+ desc + "\n\t" + expected);681}682}683}684}685686Throwable thrown = new Exception("OK: log me!");687for (java.util.logging.Level loggerLevel : julLevels) {688setLevel(sink, loggerLevel);689for (Level messageLevel : Level.values()) {690java.util.logging.Level julLevel = mapToJul(messageLevel);691String desc = "logger.log(messageLevel, \"blah\", thrown): loggerLevel="692+ loggerLevel+", messageLevel="+messageLevel;693LogEvent expected =694LogEvent.of(695sequencer.get(),696julLevel.intValue() >= loggerLevel.intValue(),697name, julLevel, loggerBundle,698msg, thrown, (Object[]) null);699logger.log(messageLevel, msg, thrown);700if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {701if (eventQueue.poll() != null) {702throw new RuntimeException("unexpected event in queue for " + desc);703}704} else {705LogEvent actual = eventQueue.poll();706if (!expected.equals(actual)) {707throw new RuntimeException("mismatch for " + desc708+ "\n\texpected=" + expected709+ "\n\t actual=" + actual);710} else {711verbose("Got expected results for "712+ desc + "\n\t" + expected);713}714}715}716}717718719for (java.util.logging.Level loggerLevel : julLevels) {720setLevel(sink, loggerLevel);721for (Level messageLevel : Level.values()) {722java.util.logging.Level julLevel = mapToJul(messageLevel);723String desc = "logger.log(messageLevel, thrown, fooSupplier): loggerLevel="724+ loggerLevel+", messageLevel="+messageLevel;725LogEvent expected =726LogEvent.of(727sequencer.get(),728julLevel.intValue() >= loggerLevel.intValue(),729name, julLevel, (ResourceBundle)null,730fooSupplier.get(),731(Throwable)thrown, (Object[])null);732logger.log(messageLevel, fooSupplier, thrown);733if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {734if (eventQueue.poll() != null) {735throw new RuntimeException("unexpected event in queue for " + desc);736}737} else {738LogEvent actual = eventQueue.poll();739if (!expected.equals(actual)) {740throw new RuntimeException("mismatch for " + desc741+ "\n\texpected=" + expected742+ "\n\t actual=" + actual);743} else {744verbose("Got expected results for "745+ desc + "\n\t" + expected);746}747}748}749}750751ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName());752for (java.util.logging.Level loggerLevel : julLevels) {753setLevel(sink, loggerLevel);754for (Level messageLevel : Level.values()) {755java.util.logging.Level julLevel = mapToJul(messageLevel);756String desc = "logger.log(messageLevel, bundle, format, params...): loggerLevel="757+ loggerLevel+", messageLevel="+messageLevel;758LogEvent expected =759LogEvent.of(760sequencer.get(),761julLevel.intValue() >= loggerLevel.intValue(),762name, julLevel, bundle,763format, (Throwable)null, new Object[] {foo, msg});764logger.log(messageLevel, bundle, format, foo, msg);765if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {766if (eventQueue.poll() != null) {767throw new RuntimeException("unexpected event in queue for " + desc);768}769} else {770LogEvent actual = eventQueue.poll();771if (!expected.equals(actual)) {772throw new RuntimeException("mismatch for " + desc773+ "\n\texpected=" + expected774+ "\n\t actual=" + actual);775} else {776verbose("Got expected results for "777+ desc + "\n\t" + expected);778}779}780}781}782783for (java.util.logging.Level loggerLevel : julLevels) {784setLevel(sink, loggerLevel);785for (Level messageLevel : Level.values()) {786java.util.logging.Level julLevel = mapToJul(messageLevel);787String desc = "logger.log(messageLevel, bundle, \"blah\", thrown): loggerLevel="788+ loggerLevel+", messageLevel="+messageLevel;789LogEvent expected =790LogEvent.of(791sequencer.get(),792julLevel.intValue() >= loggerLevel.intValue(),793name, julLevel, bundle,794msg, thrown, (Object[]) null);795logger.log(messageLevel, bundle, msg, thrown);796if (loggerLevel == OFF || julLevel.intValue() < loggerLevel.intValue()) {797if (eventQueue.poll() != null) {798throw new RuntimeException("unexpected event in queue for " + desc);799}800} else {801LogEvent actual = eventQueue.poll();802if (!expected.equals(actual)) {803throw new RuntimeException("mismatch for " + desc804+ "\n\texpected=" + expected805+ "\n\t actual=" + actual);806} else {807verbose("Got expected results for "808+ desc + "\n\t" + expected);809}810}811}812}813}814815final static class PermissionsBuilder {816final Permissions perms;817public PermissionsBuilder() {818this(new Permissions());819}820public PermissionsBuilder(Permissions perms) {821this.perms = perms;822}823public PermissionsBuilder add(Permission p) {824perms.add(p);825return this;826}827public PermissionsBuilder addAll(PermissionCollection col) {828if (col != null) {829for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {830perms.add(e.nextElement());831}832}833return this;834}835public Permissions toPermissions() {836final PermissionsBuilder builder = new PermissionsBuilder();837builder.addAll(perms);838return builder.perms;839}840}841842public static class SimplePolicy extends Policy {843844static final Policy DEFAULT_POLICY = Policy.getPolicy();845846final Permissions permissions;847final Permissions withControlPermissions;848final Permissions allPermissions;849final ThreadLocal<AtomicBoolean> allowAll;850final ThreadLocal<AtomicBoolean> allowControl;851public SimplePolicy(ThreadLocal<AtomicBoolean> allowAll,852ThreadLocal<AtomicBoolean> allowControl) {853this.allowAll = allowAll;854this.allowControl = allowControl;855permissions = new Permissions();856857withControlPermissions = new Permissions();858withControlPermissions.add(LOGGERFINDER_PERMISSION);859860// these are used for configuring the test itself...861allPermissions = new Permissions();862allPermissions.add(new java.security.AllPermission());863}864865@Override866public boolean implies(ProtectionDomain domain, Permission permission) {867if (allowAll.get().get()) return allPermissions.implies(permission);868if (allowControl.get().get()) return withControlPermissions.implies(permission);869return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);870}871872@Override873public PermissionCollection getPermissions(CodeSource codesource) {874return new PermissionsBuilder().addAll(875allowAll.get().get() ? allPermissions :876allowControl.get().get()877? withControlPermissions : permissions).toPermissions();878}879880@Override881public PermissionCollection getPermissions(ProtectionDomain domain) {882return new PermissionsBuilder().addAll(883allowAll.get().get() ? allPermissions :884allowControl.get().get()885? withControlPermissions : permissions).toPermissions();886}887}888}889890891