Path: blob/master/test/jdk/java/lang/System/LoggerFinder/internal/SimpleConsoleLoggerTest/SimpleConsoleLoggerTest.java
41171 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import java.io.ByteArrayOutputStream;23import java.io.IOException;24import java.io.PrintStream;25import java.io.UncheckedIOException;26import java.util.Collections;27import java.util.Enumeration;28import java.util.ResourceBundle;29import java.util.concurrent.ConcurrentHashMap;30import java.util.concurrent.atomic.AtomicBoolean;31import java.util.concurrent.atomic.AtomicLong;32import java.util.function.Supplier;33import java.lang.System.Logger;34import java.lang.System.Logger.Level;35import java.util.EnumSet;36import java.util.HashMap;37import java.util.Locale;38import java.util.Map;39import jdk.internal.logger.SimpleConsoleLogger;40import jdk.internal.logger.SurrogateLogger;41import sun.util.logging.PlatformLogger;4243/**44* @test45* @bug 814036446* @summary JDK implementation specific unit test for SimpleConsoleLogger.47* Tests the behavior of SimpleConsoleLogger.48* @modules java.base/sun.util.logging49* java.base/jdk.internal.logger50* @build SimpleConsoleLoggerTest51* @run main/othervm SimpleConsoleLoggerTest52* @run main/othervm -Djdk.system.logger.level=OFF SimpleConsoleLoggerTest53* @run main/othervm -Djdk.system.logger.level=ERROR SimpleConsoleLoggerTest54* @run main/othervm -Djdk.system.logger.level=WARNING SimpleConsoleLoggerTest55* @run main/othervm -Djdk.system.logger.level=INFO SimpleConsoleLoggerTest56* @run main/othervm -Djdk.system.logger.level=DEBUG SimpleConsoleLoggerTest57* @run main/othervm -Djdk.system.logger.level=TRACE SimpleConsoleLoggerTest58* @run main/othervm -Djdk.system.logger.level=ALL SimpleConsoleLoggerTest59* @run main/othervm -Djdk.system.logger.level=WOMBAT SimpleConsoleLoggerTest60* @run main/othervm -Djdk.system.logger.level SimpleConsoleLoggerTest61* @run main/othervm -Djdk.system.logger.level=FINEST SimpleConsoleLoggerTest62* @run main/othervm -Djdk.system.logger.level=DEBUG -Djava.util.logging.SimpleFormatter.format=++++_%2$s%n%4$s:_%5$s%6$s%n SimpleConsoleLoggerTest63* @run main/othervm -Djdk.system.logger.level=DEBUG -Djdk.system.logger.format=++++_%2$s%n%4$s:_%5$s%6$s%n SimpleConsoleLoggerTest64*65* @author danielfuchs66*/67public class SimpleConsoleLoggerTest {6869static final RuntimePermission LOGGERFINDER_PERMISSION =70new RuntimePermission("loggerFinder");71final static boolean VERBOSE = false;7273public static class MyBundle extends ResourceBundle {7475final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();7677@Override78protected Object handleGetObject(String key) {79if (key.contains(" (translated)")) {80throw new RuntimeException("Unexpected key: " + key);81}82return map.computeIfAbsent(key, k -> k.toUpperCase(Locale.ROOT) + " (translated)");83}8485@Override86public Enumeration<String> getKeys() {87return Collections.enumeration(map.keySet());88}8990}91public static class MyLoggerBundle extends MyBundle {9293}949596static class ErrorStream extends PrintStream {9798static AtomicBoolean forward = new AtomicBoolean();99ByteArrayOutputStream out;100String saved = "";101public ErrorStream(ByteArrayOutputStream out) {102super(out);103this.out = out;104}105106@Override107public void write(int b) {108super.write(b);109if (forward.get()) err.write(b);110}111112@Override113public void write(byte[] b) throws IOException {114super.write(b);115if (forward.get()) err.write(b);116}117118@Override119public void write(byte[] buf, int off, int len) {120super.write(buf, off, len);121if (forward.get()) err.write(buf, off, len);122}123124public String peek() {125flush();126return out.toString();127}128129public String drain() {130flush();131String res = out.toString();132out.reset();133return res;134}135136public void store() {137flush();138saved = out.toString();139out.reset();140}141142public void restore() {143out.reset();144try {145out.write(saved.getBytes());146} catch(IOException io) {147throw new UncheckedIOException(io);148}149}150151static final PrintStream err = System.err;152static final ErrorStream errorStream = new ErrorStream(new ByteArrayOutputStream());153}154155private static StringBuilder appendProperty(StringBuilder b, String name) {156String value = System.getProperty(name);157if (value == null) return b;158return b.append(name).append("=").append(value).append('\n');159}160161public static void main(String[] args) {162Locale.setDefault(Locale.ENGLISH);163System.setErr(ErrorStream.errorStream);164try {165test(args);166} finally {167try {168System.setErr(ErrorStream.err);169} catch (Error | RuntimeException x) {170x.printStackTrace(ErrorStream.err);171}172}173}174175176public static void test(String[] args) {177178ErrorStream.errorStream.restore();179String l = System.getProperty("jdk.system.logger.level");180String f = System.getProperty("jdk.system.logger.format");181String jf = System.getProperty("java.util.logging.SimpleFormatter.format");182System.out.println("Running test: "183+ "\n\tjdk.system.logger.level=\"" + l + "\""184+ "\n\tjdk.system.logger.format=\"" + f + "\""185+ "\n\tjava.util.logging.SimpleFormatter.format=\"" + jf + "\"");186187test(l,f,jf);188System.out.println("\nPASSED: tested " + SEQUENCER.get() + " test cases");189}190191static final AtomicLong SEQUENCER = new AtomicLong();192public static void test(String defaultLevel, String defaultFormat, String julFormat) {193194final Map<Logger, String> loggerDescMap = new HashMap<>();195196SimpleConsoleLogger simple = SimpleConsoleLogger.makeSimpleLogger("test.logger");197loggerDescMap.put(simple, "SimpleConsoleLogger.makeSimpleLogger(\"test.logger\")");198SimpleConsoleLogger temporary = SurrogateLogger.makeSurrogateLogger("test.logger");199loggerDescMap.put(temporary, "SurrogateLogger.makeSimpleLogger(\"test.logger\")");200201Level level;202try {203level = defaultLevel == null ? null : Level.valueOf(defaultLevel);204} catch (IllegalArgumentException ex) {205level = null;206}207testLogger(loggerDescMap, simple, level, false, defaultFormat);208testLogger(loggerDescMap, temporary, null, true, julFormat);209}210211public static class Foo {212213}214215static void verbose(String msg) {216if (VERBOSE) {217System.out.println(msg);218}219}220221static String getName(Level level, boolean usePlatformLevel) {222if (usePlatformLevel) {223return PlatformLogger.toPlatformLevel(level).name();224} else {225return level.getName();226}227}228229// Calls the 8 methods defined on Logger and verify the230// parameters received by the underlying TestProvider.LoggerImpl231// logger.232private static void testLogger(Map<Logger, String> loggerDescMap,233SimpleConsoleLogger simple,234Level defaultLevel,235boolean usePlatformLevel,236String defaultFormat) {237238System.out.println("Testing " + loggerDescMap.get(simple) + " [" + simple +"]");239240String formatStrMarker = defaultFormat == null ? ""241: defaultFormat.startsWith("++++") ? "++++" : "";242String unexpectedMarker = defaultFormat == null ? "++++"243: defaultFormat.startsWith("++++") ? "????" : "++++";244String formatStrSpec = defaultFormat == null ? "[date]"245: defaultFormat.startsWith("++++") ? "++++" : "????";246String sep = defaultFormat == null ? ": " : ":_";247String sepw = defaultFormat == null ? " " : "_";248249Foo foo = new Foo();250String fooMsg = foo.toString();251for (Level loggerLevel : defaultLevel == null252? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {253for (Level messageLevel : Level.values()) {254ErrorStream.errorStream.drain();255String desc = "logger.log(messageLevel, foo): loggerLevel="256+ loggerLevel+", messageLevel="+messageLevel;257SEQUENCER.incrementAndGet();258simple.log(messageLevel, foo);259if (loggerLevel == Level.OFF || messageLevel == Level.OFF260|| messageLevel.compareTo(loggerLevel) < 0) {261if (!ErrorStream.errorStream.peek().isEmpty()) {262throw new RuntimeException("unexpected event in queue for "263+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());264}265} else {266String logged = ErrorStream.errorStream.drain();267String expected = getName(messageLevel, usePlatformLevel) + sep + fooMsg;268if (!logged.contains("SimpleConsoleLoggerTest testLogger")269|| !logged.contains(formatStrMarker)270|| logged.contains(unexpectedMarker)271|| !logged.contains(expected)) {272throw new RuntimeException("mismatch for " + desc273+ "\n\texpected:" + "\n<<<<\n"274+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"275+ expected276+ "\n>>>>"277+ "\n\t actual:"278+ "\n<<<<\n" + logged + ">>>>\n");279} else {280verbose("Got expected results for "281+ desc + "\n<<<<\n" + logged + ">>>>\n");282}283}284}285}286287String msg = "blah";288for (Level loggerLevel : defaultLevel == null289? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {290for (Level messageLevel : Level.values()) {291String desc = "logger.log(messageLevel, \"blah\"): loggerLevel="292+ loggerLevel+", messageLevel="+messageLevel;293SEQUENCER.incrementAndGet();294simple.log(messageLevel, msg);295if (loggerLevel == Level.OFF || messageLevel == Level.OFF296|| messageLevel.compareTo(loggerLevel) < 0) {297if (!ErrorStream.errorStream.peek().isEmpty()) {298throw new RuntimeException("unexpected event in queue for "299+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());300}301} else {302String logged = ErrorStream.errorStream.drain();303String expected = getName(messageLevel, usePlatformLevel) + sep + msg;304if (!logged.contains("SimpleConsoleLoggerTest testLogger")305|| !logged.contains(formatStrMarker)306|| logged.contains(unexpectedMarker)307|| !logged.contains(expected)) {308throw new RuntimeException("mismatch for " + desc309+ "\n\texpected:" + "\n<<<<\n"310+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"311+ expected312+ "\n>>>>"313+ "\n\t actual:"314+ "\n<<<<\n" + logged + ">>>>\n");315} else {316verbose("Got expected results for "317+ desc + "\n<<<<\n" + logged + ">>>>\n");318}319}320}321}322323Supplier<String> fooSupplier = new Supplier<String>() {324@Override325public String get() {326return this.toString();327}328};329330for (Level loggerLevel : defaultLevel == null331? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {332for (Level messageLevel : Level.values()) {333String desc = "logger.log(messageLevel, fooSupplier): loggerLevel="334+ loggerLevel+", messageLevel="+messageLevel;335SEQUENCER.incrementAndGet();336simple.log(messageLevel, fooSupplier);337if (loggerLevel == Level.OFF || messageLevel == Level.OFF338|| messageLevel.compareTo(loggerLevel) < 0) {339if (!ErrorStream.errorStream.peek().isEmpty()) {340throw new RuntimeException("unexpected event in queue for "341+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());342}343} else {344String logged = ErrorStream.errorStream.drain();345String expected = getName(messageLevel, usePlatformLevel) + sep + fooSupplier.get();346if (!logged.contains("SimpleConsoleLoggerTest testLogger")347|| !logged.contains(formatStrMarker)348|| logged.contains(unexpectedMarker)349|| !logged.contains(expected)) {350throw new RuntimeException("mismatch for " + desc351+ "\n\texpected:" + "\n<<<<\n"352+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"353+ expected354+ "\n>>>>"355+ "\n\t actual:"356+ "\n<<<<\n" + logged + ">>>>\n");357} else {358verbose("Got expected results for "359+ desc + "\n<<<<\n" + logged + ">>>>\n");360}361}362}363}364365366String format = "two params [{1} {2}]";367Object arg1 = foo;368Object arg2 = msg;369for (Level loggerLevel : defaultLevel == null370? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {371for (Level messageLevel : Level.values()) {372String desc = "logger.log(messageLevel, format, params...): loggerLevel="373+ loggerLevel+", messageLevel="+messageLevel;374SEQUENCER.incrementAndGet();375simple.log(messageLevel, format, foo, msg);376if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {377if (!ErrorStream.errorStream.peek().isEmpty()) {378throw new RuntimeException("unexpected event in queue for "379+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());380}381} else {382String logged = ErrorStream.errorStream.drain();383String msgFormat = format;384String text = java.text.MessageFormat.format(msgFormat, foo, msg);385String expected = getName(messageLevel, usePlatformLevel) + sep + text;386if (!logged.contains("SimpleConsoleLoggerTest testLogger")387|| !logged.contains(formatStrMarker)388|| !logged.contains(expected)) {389throw new RuntimeException("mismatch for " + desc390+ "\n\texpected:" + "\n<<<<\n"391+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"392+ expected393+ "\n>>>>"394+ "\n\t actual:"395+ "\n<<<<\n" + logged + ">>>>\n");396} else {397verbose("Got expected results for "398+ desc + "\n<<<<\n" + logged + ">>>>\n");399}400}401}402}403404Throwable thrown = new Exception("OK: log me!");405for (Level loggerLevel : defaultLevel == null406? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {407for (Level messageLevel : Level.values()) {408String desc = "logger.log(messageLevel, \"blah\", thrown): loggerLevel="409+ loggerLevel+", messageLevel="+messageLevel;410SEQUENCER.incrementAndGet();411simple.log(messageLevel, msg, thrown);412if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {413if (!ErrorStream.errorStream.peek().isEmpty()) {414throw new RuntimeException("unexpected event in queue for "415+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());416}417} else {418String logged = ErrorStream.errorStream.drain();419ByteArrayOutputStream baos = new ByteArrayOutputStream();420thrown.printStackTrace(new PrintStream(baos));421String text = baos.toString();422String expected = getName(messageLevel, usePlatformLevel) + sep + msg;423if (!logged.contains("SimpleConsoleLoggerTest testLogger")424|| !logged.contains(formatStrMarker)425|| !logged.contains(expected)426|| logged.contains(unexpectedMarker)427|| !logged.contains(text)) {428throw new RuntimeException("mismatch for " + desc429+ "\n\texpected:" + "\n<<<<\n"430+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"431+ msg +"\n"432+ text433+ ">>>>"434+ "\n\t actual:"435+ "\n<<<<\n" + logged + ">>>>\n");436} else {437verbose("Got expected results for "438+ desc + "\n<<<<\n" + logged + ">>>>\n");439}440}441}442}443444445for (Level loggerLevel : defaultLevel == null446? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {447for (Level messageLevel : Level.values()) {448String desc = "logger.log(messageLevel, thrown, fooSupplier): loggerLevel="449+ loggerLevel+", messageLevel="+messageLevel;450SEQUENCER.incrementAndGet();451simple.log(messageLevel, fooSupplier, thrown);452if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {453if (!ErrorStream.errorStream.peek().isEmpty()) {454throw new RuntimeException("unexpected event in queue for "455+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());456}457} else {458String logged = ErrorStream.errorStream.drain();459ByteArrayOutputStream baos = new ByteArrayOutputStream();460thrown.printStackTrace(new PrintStream(baos));461String text = baos.toString();462String expected = getName(messageLevel, usePlatformLevel) + sep + fooSupplier.get();463if (!logged.contains("SimpleConsoleLoggerTest testLogger")464|| !logged.contains(formatStrMarker)465|| !logged.contains(expected)466|| logged.contains(unexpectedMarker)467|| !logged.contains(text)) {468throw new RuntimeException("mismatch for " + desc469+ "\n\texpected:" + "\n<<<<\n"470+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"471+ expected +"\n"472+ text473+ ">>>>"474+ "\n\t actual:"475+ "\n<<<<\n" + logged + ">>>>\n");476} else {477verbose("Got expected results for "478+ desc + "\n<<<<\n" + logged + ">>>>\n");479}480}481}482}483484ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName());485for (Level loggerLevel : defaultLevel == null486? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {487for (Level messageLevel : Level.values()) {488String desc = "logger.log(messageLevel, bundle, format, params...): loggerLevel="489+ loggerLevel+", messageLevel="+messageLevel;490SEQUENCER.incrementAndGet();491simple.log(messageLevel, bundle, format, foo, msg);492if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {493if (!ErrorStream.errorStream.peek().isEmpty()) {494throw new RuntimeException("unexpected event in queue for "495+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());496}497} else {498String logged = ErrorStream.errorStream.drain();499String text = java.text.MessageFormat.format(bundle.getString(format), foo, msg);500if (!logged.contains("SimpleConsoleLoggerTest testLogger")501|| !logged.contains(formatStrMarker)502|| logged.contains(unexpectedMarker)503|| !logged.contains(getName(messageLevel, usePlatformLevel) + sep + text)) {504throw new RuntimeException("mismatch for " + desc505+ "\n\texpected:" + "\n<<<<\n"506+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"507+ getName(messageLevel, usePlatformLevel) + " " + text508+ "\n>>>>"509+ "\n\t actual:"510+ "\n<<<<\n" + logged + ">>>>\n");511} else {512verbose("Got expected results for "513+ desc + "\n<<<<\n" + logged + ">>>>\n");514}515}516}517}518519for (Level loggerLevel : defaultLevel == null520? EnumSet.of(Level.INFO) : EnumSet.of(defaultLevel)) {521for (Level messageLevel : Level.values()) {522String desc = "logger.log(messageLevel, bundle, \"blah\", thrown): loggerLevel="523+ loggerLevel+", messageLevel="+messageLevel;524SEQUENCER.incrementAndGet();525simple.log(messageLevel, bundle, msg, thrown);526if (loggerLevel == Level.OFF || messageLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {527if (!ErrorStream.errorStream.peek().isEmpty()) {528throw new RuntimeException("unexpected event in queue for "529+ desc +": " + "\n\t" + ErrorStream.errorStream.drain());530}531} else {532String logged = ErrorStream.errorStream.drain();533String textMsg = bundle.getString(msg);534ByteArrayOutputStream baos = new ByteArrayOutputStream();535thrown.printStackTrace(new PrintStream(baos));536String text = baos.toString();537String expected = getName(messageLevel, usePlatformLevel) + sep + textMsg;538if (!logged.contains("SimpleConsoleLoggerTest testLogger")539|| !logged.contains(formatStrMarker)540|| !logged.contains(expected)541|| logged.contains(unexpectedMarker)542|| !logged.contains(text)) {543throw new RuntimeException("mismatch for " + desc544+ "\n\texpected:" + "\n<<<<\n"545+ formatStrSpec + sepw + "SimpleConsoleLoggerTest testLogger\n"546+ expected +"\n"547+ text548+ ">>>>"549+ "\n\t actual:"550+ "\n<<<<\n" + logged + ">>>>\n");551} else {552verbose("Got expected results for "553+ desc + "\n<<<<\n" + logged + ">>>>\n");554}555}556}557}558559}560}561562563