jdk/test/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java
changeset 33875 c1c71107d45f
child 37672 03684934dc09
equal deleted inserted replaced
33874:46651fd30c0b 33875:c1c71107d45f
       
     1 /*
       
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 import java.security.AccessController;
       
    24 import java.security.CodeSource;
       
    25 import java.security.Permission;
       
    26 import java.security.PermissionCollection;
       
    27 import java.security.Permissions;
       
    28 import java.security.Policy;
       
    29 import java.security.PrivilegedAction;
       
    30 import java.security.ProtectionDomain;
       
    31 import java.util.Arrays;
       
    32 import java.util.Collections;
       
    33 import java.util.Enumeration;
       
    34 import java.util.HashMap;
       
    35 import java.util.Map;
       
    36 import java.util.Objects;
       
    37 import java.util.Queue;
       
    38 import java.util.ResourceBundle;
       
    39 import java.util.concurrent.ArrayBlockingQueue;
       
    40 import java.util.concurrent.ConcurrentHashMap;
       
    41 import java.util.concurrent.atomic.AtomicBoolean;
       
    42 import java.util.concurrent.atomic.AtomicLong;
       
    43 import java.util.function.Supplier;
       
    44 import java.lang.System.LoggerFinder;
       
    45 import java.lang.System.Logger;
       
    46 import java.lang.System.Logger.Level;
       
    47 import java.security.AccessControlException;
       
    48 import java.util.stream.Stream;
       
    49 import sun.util.logging.PlatformLogger;
       
    50 
       
    51 /**
       
    52  * @test
       
    53  * @bug     8140364
       
    54  * @summary JDK implementation specific unit test for JDK internal API.
       
    55  *   Tests a naive implementation of System.Logger, and in particular
       
    56  *   the default mapping provided by PlatformLogger.
       
    57  * @modules java.base/sun.util.logging
       
    58  * @build CustomSystemClassLoader BasePlatformLoggerTest
       
    59  * @run  main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest NOSECURITY
       
    60  * @run  main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest NOPERMISSIONS
       
    61  * @run  main/othervm -Djava.system.class.loader=CustomSystemClassLoader BasePlatformLoggerTest WITHPERMISSIONS
       
    62  * @author danielfuchs
       
    63  */
       
    64 public class BasePlatformLoggerTest {
       
    65 
       
    66     public static final RuntimePermission LOGGERFINDER_PERMISSION =
       
    67                 new RuntimePermission("loggerFinder");
       
    68 
       
    69     final static AtomicLong sequencer = new AtomicLong();
       
    70     final static boolean VERBOSE = false;
       
    71     static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() {
       
    72         @Override
       
    73         protected AtomicBoolean initialValue() {
       
    74             return  new AtomicBoolean(false);
       
    75         }
       
    76     };
       
    77     static final ThreadLocal<AtomicBoolean> allowAccess = new ThreadLocal<AtomicBoolean>() {
       
    78         @Override
       
    79         protected AtomicBoolean initialValue() {
       
    80             return  new AtomicBoolean(false);
       
    81         }
       
    82     };
       
    83     static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
       
    84         @Override
       
    85         protected AtomicBoolean initialValue() {
       
    86             return  new AtomicBoolean(false);
       
    87         }
       
    88     };
       
    89 
       
    90     static final Class<?> providerClass;
       
    91     static {
       
    92         try {
       
    93             providerClass = ClassLoader.getSystemClassLoader().loadClass("BasePlatformLoggerTest$BaseLoggerFinder");
       
    94         } catch (ClassNotFoundException ex) {
       
    95             throw new ExceptionInInitializerError(ex);
       
    96         }
       
    97     }
       
    98 
       
    99     static final PlatformLogger.Level[] julLevels = {
       
   100         PlatformLogger.Level.ALL,
       
   101         PlatformLogger.Level.FINEST,
       
   102         PlatformLogger.Level.FINER,
       
   103         PlatformLogger.Level.FINE,
       
   104         PlatformLogger.Level.CONFIG,
       
   105         PlatformLogger.Level.INFO,
       
   106         PlatformLogger.Level.WARNING,
       
   107         PlatformLogger.Level.SEVERE,
       
   108         PlatformLogger.Level.OFF,
       
   109     };
       
   110 
       
   111     static final Level[] mappedLevels = {
       
   112         Level.ALL,     // ALL
       
   113         Level.TRACE,   // FINEST
       
   114         Level.TRACE,   // FINER
       
   115         Level.DEBUG,   // FINE
       
   116         Level.DEBUG,   // CONFIG
       
   117         Level.INFO,    // INFO
       
   118         Level.WARNING, // WARNING
       
   119         Level.ERROR,   // SEVERE
       
   120         Level.OFF,     // OFF
       
   121     };
       
   122 
       
   123     final static Map<PlatformLogger.Level, Level> julToSpiMap;
       
   124     static {
       
   125         Map<PlatformLogger.Level, Level> map = new HashMap<>();
       
   126         if (mappedLevels.length != julLevels.length) {
       
   127             throw new ExceptionInInitializerError("Array lengths differ"
       
   128                 + "\n\tjulLevels=" + Arrays.deepToString(julLevels)
       
   129                 + "\n\tmappedLevels=" + Arrays.deepToString(mappedLevels));
       
   130         }
       
   131         for (int i=0; i<julLevels.length; i++) {
       
   132             map.put(julLevels[i], mappedLevels[i]);
       
   133         }
       
   134         julToSpiMap = Collections.unmodifiableMap(map);
       
   135     }
       
   136 
       
   137     public static class MyBundle extends ResourceBundle {
       
   138 
       
   139         final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();
       
   140 
       
   141         @Override
       
   142         protected Object handleGetObject(String key) {
       
   143             if (key.contains(" (translated)")) {
       
   144                 throw new RuntimeException("Unexpected key: " + key);
       
   145             }
       
   146             return map.computeIfAbsent(key, k -> k + " (translated)");
       
   147         }
       
   148 
       
   149         @Override
       
   150         public Enumeration<String> getKeys() {
       
   151             return Collections.enumeration(map.keySet());
       
   152         }
       
   153 
       
   154     }
       
   155     public static class MyLoggerBundle extends MyBundle {
       
   156 
       
   157     }
       
   158 
       
   159 
       
   160     public static interface TestLoggerFinder  {
       
   161         final ConcurrentHashMap<String, LoggerImpl> system = new ConcurrentHashMap<>();
       
   162         final ConcurrentHashMap<String, LoggerImpl> user = new ConcurrentHashMap<>();
       
   163         public Queue<LogEvent> eventQueue = new ArrayBlockingQueue<>(128);
       
   164 
       
   165         public static final class LogEvent implements Cloneable {
       
   166 
       
   167             public LogEvent() {
       
   168                 this(sequencer.getAndIncrement());
       
   169             }
       
   170 
       
   171             LogEvent(long sequenceNumber) {
       
   172                 this.sequenceNumber = sequenceNumber;
       
   173             }
       
   174 
       
   175             long sequenceNumber;
       
   176             boolean isLoggable;
       
   177             String loggerName;
       
   178             Level level;
       
   179             ResourceBundle bundle;
       
   180             Throwable thrown;
       
   181             Object[] args;
       
   182             Supplier<String> supplier;
       
   183             String msg;
       
   184 
       
   185             Object[] toArray() {
       
   186                 return new Object[] {
       
   187                     sequenceNumber,
       
   188                     isLoggable,
       
   189                     loggerName,
       
   190                     level,
       
   191                     bundle,
       
   192                     thrown,
       
   193                     args,
       
   194                     supplier,
       
   195                     msg,
       
   196                 };
       
   197             }
       
   198 
       
   199             @Override
       
   200             public String toString() {
       
   201                 return Arrays.deepToString(toArray());
       
   202             }
       
   203 
       
   204 
       
   205 
       
   206             @Override
       
   207             public boolean equals(Object obj) {
       
   208                 return obj instanceof LogEvent
       
   209                         && Objects.deepEquals(this.toArray(), ((LogEvent)obj).toArray());
       
   210             }
       
   211 
       
   212             @Override
       
   213             public int hashCode() {
       
   214                 return Objects.hash(toArray());
       
   215             }
       
   216 
       
   217             public LogEvent cloneWith(long sequenceNumber)
       
   218                     throws CloneNotSupportedException {
       
   219                 LogEvent cloned = (LogEvent)super.clone();
       
   220                 cloned.sequenceNumber = sequenceNumber;
       
   221                 return cloned;
       
   222             }
       
   223 
       
   224             public static LogEvent of(boolean isLoggable, String name,
       
   225                     Level level, ResourceBundle bundle,
       
   226                     String key, Throwable thrown) {
       
   227                 LogEvent evt = new LogEvent();
       
   228                 evt.isLoggable = isLoggable;
       
   229                 evt.loggerName = name;
       
   230                 evt.level = level;
       
   231                 evt.args = null;
       
   232                 evt.bundle = bundle;
       
   233                 evt.thrown = thrown;
       
   234                 evt.supplier = null;
       
   235                 evt.msg = key;
       
   236                 return evt;
       
   237             }
       
   238 
       
   239             public static LogEvent of(boolean isLoggable, String name,
       
   240                     Level level, Throwable thrown, Supplier<String> supplier) {
       
   241                 LogEvent evt = new LogEvent();
       
   242                 evt.isLoggable = isLoggable;
       
   243                 evt.loggerName = name;
       
   244                 evt.level = level;
       
   245                 evt.args = null;
       
   246                 evt.bundle = null;
       
   247                 evt.thrown = thrown;
       
   248                 evt.supplier = supplier;
       
   249                 evt.msg = null;
       
   250                 return evt;
       
   251             }
       
   252 
       
   253             public static LogEvent of(boolean isLoggable, String name,
       
   254                     Level level, ResourceBundle bundle,
       
   255                     String key, Object... params) {
       
   256                 LogEvent evt = new LogEvent();
       
   257                 evt.isLoggable = isLoggable;
       
   258                 evt.loggerName = name;
       
   259                 evt.level = level;
       
   260                 evt.args = params;
       
   261                 evt.bundle = bundle;
       
   262                 evt.thrown = null;
       
   263                 evt.supplier = null;
       
   264                 evt.msg = key;
       
   265                 return evt;
       
   266             }
       
   267 
       
   268             public static LogEvent of(long sequenceNumber,
       
   269                     boolean isLoggable, String name,
       
   270                     Level level, ResourceBundle bundle,
       
   271                     String key, Supplier<String> supplier,
       
   272                     Throwable thrown, Object... params) {
       
   273                 LogEvent evt = new LogEvent(sequenceNumber);
       
   274                 evt.loggerName = name;
       
   275                 evt.level = level;
       
   276                 evt.args = params;
       
   277                 evt.bundle = bundle;
       
   278                 evt.thrown = thrown;
       
   279                 evt.supplier = supplier;
       
   280                 evt.msg = key;
       
   281                 evt.isLoggable = isLoggable;
       
   282                 return evt;
       
   283             }
       
   284 
       
   285         }
       
   286 
       
   287         public class LoggerImpl implements Logger {
       
   288             private final String name;
       
   289             private Level level = Level.INFO;
       
   290 
       
   291             public LoggerImpl(String name) {
       
   292                 this.name = name;
       
   293             }
       
   294 
       
   295             @Override
       
   296             public String getName() {
       
   297                 return name;
       
   298             }
       
   299 
       
   300             @Override
       
   301             public boolean isLoggable(Level level) {
       
   302                 return this.level != Level.OFF && this.level.getSeverity() <= level.getSeverity();
       
   303             }
       
   304 
       
   305             @Override
       
   306             public void log(Level level, ResourceBundle bundle, String key, Throwable thrown) {
       
   307                 log(LogEvent.of(isLoggable(level), this.name, level, bundle, key, thrown));
       
   308             }
       
   309 
       
   310             @Override
       
   311             public void log(Level level, ResourceBundle bundle, String format, Object... params) {
       
   312                 log(LogEvent.of(isLoggable(level), name, level, bundle, format, params));
       
   313             }
       
   314 
       
   315             void log(LogEvent event) {
       
   316                 eventQueue.add(event);
       
   317             }
       
   318 
       
   319             @Override
       
   320             public void log(Level level, Supplier<String> msgSupplier) {
       
   321                 log(LogEvent.of(isLoggable(level), name, level, null, msgSupplier));
       
   322             }
       
   323 
       
   324             @Override
       
   325             public void log(Level level,  Supplier<String> msgSupplier, Throwable thrown) {
       
   326                 log(LogEvent.of(isLoggable(level), name, level, thrown, msgSupplier));
       
   327             }
       
   328         }
       
   329 
       
   330         public Logger getLogger(String name, Class<?> caller);
       
   331     }
       
   332 
       
   333     public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
       
   334         @Override
       
   335         public Logger getLogger(String name, Class<?> caller) {
       
   336             SecurityManager sm = System.getSecurityManager();
       
   337             if (sm != null) {
       
   338                 sm.checkPermission(LOGGERFINDER_PERMISSION);
       
   339             }
       
   340             PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader();
       
   341             ClassLoader callerLoader = AccessController.doPrivileged(pa);
       
   342             if (callerLoader == null) {
       
   343                 return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
       
   344             } else {
       
   345                 return user.computeIfAbsent(name, (n) -> new LoggerImpl(n));
       
   346             }
       
   347         }
       
   348     }
       
   349 
       
   350     static PlatformLogger getPlatformLogger(String name) {
       
   351         boolean old = allowAccess.get().get();
       
   352         allowAccess.get().set(true);
       
   353         try {
       
   354             return PlatformLogger.getLogger(name);
       
   355         } finally {
       
   356             allowAccess.get().set(old);
       
   357         }
       
   358     }
       
   359 
       
   360     static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS};
       
   361 
       
   362     static void setSecurityManager() {
       
   363         if (System.getSecurityManager() == null) {
       
   364             Policy.setPolicy(new SimplePolicy(allowControl, allowAccess, allowAll));
       
   365             System.setSecurityManager(new SecurityManager());
       
   366         }
       
   367     }
       
   368 
       
   369     public static void main(String[] args) {
       
   370         if (args.length == 0)
       
   371             args = new String[] {
       
   372                 "NOSECURITY",
       
   373                 "NOPERMISSIONS",
       
   374                 "WITHPERMISSIONS"
       
   375             };
       
   376 
       
   377 
       
   378         Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
       
   379             TestLoggerFinder provider;
       
   380             switch (testCase) {
       
   381                 case NOSECURITY:
       
   382                     System.out.println("\n*** Without Security Manager\n");
       
   383                     provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
       
   384                     test(provider, true);
       
   385                     System.out.println("Tetscase count: " + sequencer.get());
       
   386                     break;
       
   387                 case NOPERMISSIONS:
       
   388                     System.out.println("\n*** With Security Manager, without permissions\n");
       
   389                     setSecurityManager();
       
   390                     try {
       
   391                         provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
       
   392                         throw new RuntimeException("Expected exception not raised");
       
   393                     } catch (AccessControlException x) {
       
   394                         if (!LOGGERFINDER_PERMISSION.equals(x.getPermission())) {
       
   395                             throw new RuntimeException("Unexpected permission check", x);
       
   396                         }
       
   397                         final boolean control = allowControl.get().get();
       
   398                         try {
       
   399                             allowControl.get().set(true);
       
   400                             provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
       
   401                         } finally {
       
   402                             allowControl.get().set(control);
       
   403                         }
       
   404                     }
       
   405                     test(provider, false);
       
   406                     System.out.println("Tetscase count: " + sequencer.get());
       
   407                     break;
       
   408                 case WITHPERMISSIONS:
       
   409                     System.out.println("\n*** With Security Manager, with control permission\n");
       
   410                     setSecurityManager();
       
   411                     final boolean control = allowControl.get().get();
       
   412                     try {
       
   413                         allowControl.get().set(true);
       
   414                         provider = TestLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
       
   415                         test(provider, true);
       
   416                     } finally {
       
   417                         allowControl.get().set(control);
       
   418                     }
       
   419                     break;
       
   420                 default:
       
   421                     throw new RuntimeException("Unknown test case: " + testCase);
       
   422             }
       
   423         });
       
   424         System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");
       
   425     }
       
   426 
       
   427     public static void test(TestLoggerFinder provider, boolean hasRequiredPermissions) {
       
   428 
       
   429         final Map<PlatformLogger, String> loggerDescMap = new HashMap<>();
       
   430 
       
   431         TestLoggerFinder.LoggerImpl appSink;
       
   432         boolean before = allowControl.get().get();
       
   433         try {
       
   434             allowControl.get().set(true);
       
   435             appSink = TestLoggerFinder.LoggerImpl.class.cast(
       
   436                         provider.getLogger("foo", BasePlatformLoggerTest.class));
       
   437         } finally {
       
   438             allowControl.get().set(before);
       
   439         }
       
   440 
       
   441         TestLoggerFinder.LoggerImpl sysSink = null;
       
   442         before = allowControl.get().get();
       
   443         try {
       
   444             allowControl.get().set(true);
       
   445             sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
       
   446         } finally {
       
   447             allowControl.get().set(before);
       
   448         }
       
   449 
       
   450         if (hasRequiredPermissions && appSink == sysSink) {
       
   451             throw new RuntimeException("identical loggers");
       
   452         }
       
   453 
       
   454         if (provider.system.contains(appSink)) {
       
   455             throw new RuntimeException("app logger in system map");
       
   456         }
       
   457         if (!provider.user.contains(appSink)) {
       
   458             throw new RuntimeException("app logger not in appplication map");
       
   459         }
       
   460         if (hasRequiredPermissions && provider.user.contains(sysSink)) {
       
   461             throw new RuntimeException("sys logger in appplication map");
       
   462         }
       
   463         if (hasRequiredPermissions && !provider.system.contains(sysSink)) {
       
   464             throw new RuntimeException("sys logger not in system map");
       
   465         }
       
   466 
       
   467         PlatformLogger platform = getPlatformLogger("foo");
       
   468         loggerDescMap.put(platform, "PlatformLogger.getLogger(\"foo\")");
       
   469 
       
   470         testLogger(provider, loggerDescMap, "foo", null, platform, sysSink);
       
   471     }
       
   472 
       
   473     public static class Foo {
       
   474 
       
   475     }
       
   476 
       
   477     static void verbose(String msg) {
       
   478        if (VERBOSE) {
       
   479            System.out.println(msg);
       
   480        }
       
   481     }
       
   482 
       
   483     static void checkLogEvent(TestLoggerFinder provider, String desc,
       
   484             TestLoggerFinder.LogEvent expected) {
       
   485         TestLoggerFinder.LogEvent actual =  provider.eventQueue.poll();
       
   486         if (!expected.equals(actual)) {
       
   487             throw new RuntimeException("mismatch for " + desc
       
   488                     + "\n\texpected=" + expected
       
   489                     + "\n\t  actual=" + actual);
       
   490         } else {
       
   491             verbose("Got expected results for "
       
   492                     + desc + "\n\t" + expected);
       
   493         }
       
   494     }
       
   495 
       
   496     static void checkLogEvent(TestLoggerFinder provider, String desc,
       
   497             TestLoggerFinder.LogEvent expected, boolean expectNotNull) {
       
   498         TestLoggerFinder.LogEvent actual =  provider.eventQueue.poll();
       
   499         if (actual == null && !expectNotNull) return;
       
   500         if (actual != null && !expectNotNull) {
       
   501             throw new RuntimeException("Unexpected log event found for " + desc
       
   502                 + "\n\tgot: " + actual);
       
   503         }
       
   504         if (!expected.equals(actual)) {
       
   505             throw new RuntimeException("mismatch for " + desc
       
   506                     + "\n\texpected=" + expected
       
   507                     + "\n\t  actual=" + actual);
       
   508         } else {
       
   509             verbose("Got expected results for "
       
   510                     + desc + "\n\t" + expected);
       
   511         }
       
   512     }
       
   513 
       
   514     // Calls the methods defined on LogProducer and verify the
       
   515     // parameters received by the underlying TestLoggerFinder.LoggerImpl
       
   516     // logger.
       
   517     private static void testLogger(TestLoggerFinder provider,
       
   518             Map<PlatformLogger, String> loggerDescMap,
       
   519             String name,
       
   520             ResourceBundle loggerBundle,
       
   521             PlatformLogger logger,
       
   522             TestLoggerFinder.LoggerImpl sink) {
       
   523 
       
   524         System.out.println("Testing " + loggerDescMap.get(logger));
       
   525 
       
   526         Foo foo = new Foo();
       
   527         String fooMsg = foo.toString();
       
   528         System.out.println("\tlogger.<level>(fooMsg)");
       
   529         for (Level loggerLevel : Level.values()) {
       
   530             sink.level = loggerLevel;
       
   531             for (PlatformLogger.Level messageLevel :julLevels) {
       
   532                 Level expectedMessageLevel = julToSpiMap.get(messageLevel);
       
   533                 TestLoggerFinder.LogEvent expected =
       
   534                         TestLoggerFinder.LogEvent.of(
       
   535                             sequencer.get(),
       
   536                             loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,
       
   537                             name, expectedMessageLevel, loggerBundle,
       
   538                             fooMsg, null, (Throwable)null, (Object[])null);
       
   539                 String desc2 = "logger." + messageLevel.toString().toLowerCase()
       
   540                         + "(fooMsg): loggerLevel="
       
   541                         + loggerLevel+", messageLevel="+messageLevel;
       
   542                 if (messageLevel == PlatformLogger.Level.FINEST) {
       
   543                     logger.finest(fooMsg);
       
   544                     checkLogEvent(provider, desc2, expected);
       
   545                 } else if (messageLevel == PlatformLogger.Level.FINER) {
       
   546                     logger.finer(fooMsg);
       
   547                     checkLogEvent(provider, desc2, expected);
       
   548                 } else if (messageLevel == PlatformLogger.Level.FINE) {
       
   549                     logger.fine(fooMsg);
       
   550                     checkLogEvent(provider, desc2, expected);
       
   551                 } else if (messageLevel == PlatformLogger.Level.CONFIG) {
       
   552                     logger.config(fooMsg);
       
   553                     checkLogEvent(provider, desc2, expected);
       
   554                 } else if (messageLevel == PlatformLogger.Level.INFO) {
       
   555                     logger.info(fooMsg);
       
   556                     checkLogEvent(provider, desc2, expected);
       
   557                 } else if (messageLevel == PlatformLogger.Level.WARNING) {
       
   558                     logger.warning(fooMsg);
       
   559                     checkLogEvent(provider, desc2, expected);
       
   560                 } else if (messageLevel == PlatformLogger.Level.SEVERE) {
       
   561                     logger.severe(fooMsg);
       
   562                     checkLogEvent(provider, desc2, expected);
       
   563                 }
       
   564             }
       
   565         }
       
   566 
       
   567         Throwable thrown = new Exception("OK: log me!");
       
   568         System.out.println("\tlogger.<level>(msg, thrown)");
       
   569         for (Level loggerLevel : Level.values()) {
       
   570             sink.level = loggerLevel;
       
   571             for (PlatformLogger.Level messageLevel :julLevels) {
       
   572                 Level expectedMessageLevel = julToSpiMap.get(messageLevel);
       
   573                 TestLoggerFinder.LogEvent expected =
       
   574                         TestLoggerFinder.LogEvent.of(
       
   575                             sequencer.get(),
       
   576                             loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,
       
   577                             name, expectedMessageLevel, (ResourceBundle) null,
       
   578                             fooMsg, null, (Throwable)thrown, (Object[])null);
       
   579                 String desc2 = "logger." + messageLevel.toString().toLowerCase()
       
   580                         + "(msg, thrown): loggerLevel="
       
   581                         + loggerLevel+", messageLevel="+messageLevel;
       
   582                 if (messageLevel == PlatformLogger.Level.FINEST) {
       
   583                     logger.finest(fooMsg, thrown);
       
   584                     checkLogEvent(provider, desc2, expected);
       
   585                 } else if (messageLevel == PlatformLogger.Level.FINER) {
       
   586                     logger.finer(fooMsg, thrown);
       
   587                     checkLogEvent(provider, desc2, expected);
       
   588                 } else if (messageLevel == PlatformLogger.Level.FINE) {
       
   589                     logger.fine(fooMsg, thrown);
       
   590                     checkLogEvent(provider, desc2, expected);
       
   591                 } else if (messageLevel == PlatformLogger.Level.CONFIG) {
       
   592                     logger.config(fooMsg, thrown);
       
   593                     checkLogEvent(provider, desc2, expected);
       
   594                 } else if (messageLevel == PlatformLogger.Level.INFO) {
       
   595                     logger.info(fooMsg, thrown);
       
   596                     checkLogEvent(provider, desc2, expected);
       
   597                 } else if (messageLevel == PlatformLogger.Level.WARNING) {
       
   598                     logger.warning(fooMsg, thrown);
       
   599                     checkLogEvent(provider, desc2, expected);
       
   600                 } else if (messageLevel == PlatformLogger.Level.SEVERE) {
       
   601                     logger.severe(fooMsg, thrown);
       
   602                     checkLogEvent(provider, desc2, expected);
       
   603                 }
       
   604             }
       
   605         }
       
   606 
       
   607         String format = "two params [{1} {2}]";
       
   608         Object arg1 = foo;
       
   609         Object arg2 = fooMsg;
       
   610         System.out.println("\tlogger.<level>(format, arg1, arg2)");
       
   611         for (Level loggerLevel : Level.values()) {
       
   612             sink.level = loggerLevel;
       
   613             for (PlatformLogger.Level messageLevel :julLevels) {
       
   614                 Level expectedMessageLevel = julToSpiMap.get(messageLevel);
       
   615                 TestLoggerFinder.LogEvent expected =
       
   616                         TestLoggerFinder.LogEvent.of(
       
   617                             sequencer.get(),
       
   618                             loggerLevel != Level.OFF && expectedMessageLevel.compareTo(loggerLevel) >= 0,
       
   619                             name, expectedMessageLevel, (ResourceBundle) null,
       
   620                             format, null, (Throwable)null, foo, fooMsg);
       
   621                 String desc2 = "logger." + messageLevel.toString().toLowerCase()
       
   622                         + "(format, foo, fooMsg): loggerLevel="
       
   623                         + loggerLevel+", messageLevel="+messageLevel;
       
   624                 if (messageLevel == PlatformLogger.Level.FINEST) {
       
   625                     logger.finest(format, foo, fooMsg);
       
   626                     checkLogEvent(provider, desc2, expected);
       
   627                 } else if (messageLevel == PlatformLogger.Level.FINER) {
       
   628                     logger.finer(format, foo, fooMsg);
       
   629                     checkLogEvent(provider, desc2, expected);
       
   630                 } else if (messageLevel == PlatformLogger.Level.FINE) {
       
   631                     logger.fine(format, foo, fooMsg);
       
   632                     checkLogEvent(provider, desc2, expected);
       
   633                 } else if (messageLevel == PlatformLogger.Level.CONFIG) {
       
   634                     logger.config(format, foo, fooMsg);
       
   635                     checkLogEvent(provider, desc2, expected);
       
   636                 } else if (messageLevel == PlatformLogger.Level.INFO) {
       
   637                     logger.info(format, foo, fooMsg);
       
   638                     checkLogEvent(provider, desc2, expected);
       
   639                 } else if (messageLevel == PlatformLogger.Level.WARNING) {
       
   640                     logger.warning(format, foo, fooMsg);
       
   641                     checkLogEvent(provider, desc2, expected);
       
   642                 } else if (messageLevel == PlatformLogger.Level.SEVERE) {
       
   643                     logger.severe(format, foo, fooMsg);
       
   644                     checkLogEvent(provider, desc2, expected);
       
   645                 }
       
   646             }
       
   647         }
       
   648 
       
   649     }
       
   650 
       
   651     final static class PermissionsBuilder {
       
   652         final Permissions perms;
       
   653         public PermissionsBuilder() {
       
   654             this(new Permissions());
       
   655         }
       
   656         public PermissionsBuilder(Permissions perms) {
       
   657             this.perms = perms;
       
   658         }
       
   659         public PermissionsBuilder add(Permission p) {
       
   660             perms.add(p);
       
   661             return this;
       
   662         }
       
   663         public PermissionsBuilder addAll(PermissionCollection col) {
       
   664             if (col != null) {
       
   665                 for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
       
   666                     perms.add(e.nextElement());
       
   667                 }
       
   668             }
       
   669             return this;
       
   670         }
       
   671         public Permissions toPermissions() {
       
   672             final PermissionsBuilder builder = new PermissionsBuilder();
       
   673             builder.addAll(perms);
       
   674             return builder.perms;
       
   675         }
       
   676     }
       
   677 
       
   678     public static class SimplePolicy extends Policy {
       
   679         final static RuntimePermission CONTROL = LOGGERFINDER_PERMISSION;
       
   680         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
       
   681 
       
   682         final Permissions permissions;
       
   683         final Permissions allPermissions;
       
   684         final ThreadLocal<AtomicBoolean> allowControl;
       
   685         final ThreadLocal<AtomicBoolean> allowAccess;
       
   686         final ThreadLocal<AtomicBoolean> allowAll;
       
   687         public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl,
       
   688                 ThreadLocal<AtomicBoolean> allowAccess,
       
   689                 ThreadLocal<AtomicBoolean> allowAll) {
       
   690             this.allowControl = allowControl;
       
   691             this.allowAccess = allowAccess;
       
   692             this.allowAll = allowAll;
       
   693             permissions = new Permissions();
       
   694             allPermissions = new PermissionsBuilder()
       
   695                     .add(new java.security.AllPermission())
       
   696                     .toPermissions();
       
   697         }
       
   698 
       
   699         Permissions getPermissions() {
       
   700             if (allowControl.get().get() || allowAccess.get().get() || allowAll.get().get()) {
       
   701                 PermissionsBuilder builder =  new PermissionsBuilder()
       
   702                         .addAll(permissions);
       
   703                 if (allowControl.get().get()) {
       
   704                     builder.add(CONTROL);
       
   705                 }
       
   706                 if (allowAccess.get().get()) {
       
   707                     builder.add(ACCESS_LOGGING);
       
   708                 }
       
   709                 if (allowAll.get().get()) {
       
   710                     builder.addAll(allPermissions);
       
   711                 }
       
   712                 return builder.toPermissions();
       
   713             }
       
   714             return permissions;
       
   715         }
       
   716 
       
   717         @Override
       
   718         public boolean implies(ProtectionDomain domain, Permission permission) {
       
   719             return getPermissions().implies(permission);
       
   720         }
       
   721 
       
   722         @Override
       
   723         public PermissionCollection getPermissions(CodeSource codesource) {
       
   724             return new PermissionsBuilder().addAll(getPermissions()).toPermissions();
       
   725         }
       
   726 
       
   727         @Override
       
   728         public PermissionCollection getPermissions(ProtectionDomain domain) {
       
   729             return new PermissionsBuilder().addAll(getPermissions()).toPermissions();
       
   730         }
       
   731     }
       
   732 }