1 2 import java.util.ResourceBundle; 3 import java.util.function.Consumer; 4 import java.lang.System.Logger.Level; 5 import java.util.Arrays; 6 import java.util.LinkedList; 7 import java.util.Objects; 8 import java.util.Queue; 9 import java.util.function.Supplier; 10 11 /* 12 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 13 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14 * 15 * This code is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License version 2 only, as 17 * published by the Free Software Foundation. 18 * 19 * This code is distributed in the hope that it will be useful, but WITHOUT 20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22 * version 2 for more details (a copy is included in the LICENSE file that 23 * accompanied this code). 24 * 25 * You should have received a copy of the GNU General Public License version 26 * 2 along with this work; if not, write to the Free Software Foundation, 27 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28 * 29 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30 * or visit www.oracle.com if you need additional information or have any 31 * questions. 32 */ 33 34 /** 35 * @test 36 * @bug 8046565 37 * @summary Tests the default body of the System.Logger interface. 38 * @author danielfuchs 39 */ 40 public class LoggerInterfaceTest { 41 42 public static class LoggerImpl implements System.Logger { 43 44 public static class LogEvent implements Cloneable { 45 Level level; 46 ResourceBundle bundle; 47 String msg; 48 Throwable thrown; 49 Object[] params; 50 StackTraceElement[] callStack; 51 52 @Override 53 protected LogEvent clone() { 54 try { 55 return (LogEvent)super.clone(); 56 } catch (CloneNotSupportedException x) { 57 throw new RuntimeException(x); 58 } 59 } 60 61 62 } 63 64 public static class LogEventBuilder { 65 private LogEvent event = new LogEvent(); 66 public LogEventBuilder level(Level level) { 67 event.level = level; 68 return this; 69 } 70 public LogEventBuilder stack(StackTraceElement... stack) { 71 event.callStack = stack; 72 return this; 73 } 74 public LogEventBuilder bundle(ResourceBundle bundle) { 75 event.bundle = bundle; 76 return this; 77 } 78 public LogEventBuilder msg(String msg) { 79 event.msg = msg; 80 return this; 81 } 82 public LogEventBuilder thrown(Throwable thrown) { 83 event.thrown = thrown; 84 return this; 85 } 86 public LogEventBuilder params(Object... params) { 87 event.params = params; 88 return this; 89 } 90 public LogEvent build() { 91 return event.clone(); 92 } 93 94 public LogEventBuilder clear() { 95 event = new LogEvent(); 96 return this; 97 } 98 99 } 100 101 Level level = Level.WARNING; 102 Consumer<LogEvent> consumer; 103 final LogEventBuilder builder = new LogEventBuilder(); 104 105 @Override 106 public String getName() { 107 return "noname"; 108 } 109 110 @Override 111 public boolean isLoggable(Level level) { 112 return level.getSeverity() >= this.level.getSeverity(); 113 } 114 115 @Override 116 public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) { 117 builder.clear().level(level).bundle(bundle).msg(msg).thrown(thrown) 118 .stack(new Exception().getStackTrace()); 119 consumer.accept(builder.build()); 120 } 121 122 @Override 123 public void log(Level level, ResourceBundle bundle, String format, Object... params) { 124 builder.clear().level(level).bundle(bundle).msg(format).params(params) 125 .stack(new Exception().getStackTrace()); 126 consumer.accept(builder.build()); 127 } 128 129 } 130 131 static class Throwing { 132 @Override 133 public String toString() { 134 throw new RuntimeException("should not have been called"); 135 } 136 } 137 static class NotTrowing { 138 private final String toString; 139 private int count = 0; 140 public NotTrowing(String toString) { 141 this.toString = toString; 142 } 143 144 @Override 145 public String toString() { 146 return toString + "[" + (++count) + "]"; 147 } 148 } 149 150 public static void main(String[] args) { 151 final LoggerImpl loggerImpl = new LoggerImpl(); 152 final System.Logger logger = loggerImpl; 153 final Queue<LoggerImpl.LogEvent> events = new LinkedList<>(); 154 loggerImpl.consumer = (x) -> events.add(x); 155 156 System.out.println("\nlogger.isLoggable(Level)"); 157 assertTrue(logger.isLoggable(Level.WARNING), "logger.isLoggable(Level.WARNING)"," "); 158 assertFalse(logger.isLoggable(Level.INFO), "logger.isLoggable(Level.INFO)", " "); 159 160 161 System.out.println("\nlogger.log(Level, Object)"); 162 for (Level l : Level.values()) { 163 boolean logged = l.compareTo(Level.WARNING) >= 0; 164 Object[][] cases = new Object[][] { 165 {null}, {"baz"} 166 }; 167 for (Object[] p : cases) { 168 String msg = (String)p[0]; 169 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing(); 170 String par1 = msg == null ? "(Object)null" 171 : logged ? "new NotTrowing(\""+ msg+"\")" : "new Throwing()"; 172 System.out.println(" logger.log(" + l + ", " + par1 + ")"); 173 try { 174 logger.log(l, obj); 175 if (logged && obj == null) { 176 throw new RuntimeException("Expected NullPointerException not thrown for" 177 + " logger.log(" + l + ", " + par1 + ")"); 178 } 179 } catch (NullPointerException x) { 180 if (logged && obj == null) { 181 System.out.println(" Got expected exception: " + x); 182 continue; 183 } else { 184 throw x; 185 } 186 } 187 LoggerImpl.LogEvent e = events.poll(); 188 if (logged) { 189 assertNonNull(e, "e", " "); 190 assertEquals(l, e.level, "e.level", " "); 191 assertToString(e.msg, msg, 1, "e.msg", " "); 192 assertEquals(e.bundle, null, "e.bundle", " "); 193 assertEquals(e.params, null, "e.params", " "); 194 assertEquals(e.thrown, null, "e.thrown", " "); 195 assertEquals(e.bundle, null, "e.bundle", " "); 196 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 197 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 198 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 199 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 200 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 201 } else { 202 assertEquals(e, null, "e", " "); 203 } 204 } 205 } 206 207 208 System.out.println("\nlogger.log(Level, String)"); 209 for (Level l : Level.values()) { 210 boolean logged = l.compareTo(Level.WARNING) >= 0; 211 String par = "bar"; 212 System.out.println(" logger.log(" + l + ", \"" + par +"\");"); 213 logger.log(l, par); 214 LoggerImpl.LogEvent e = events.poll(); 215 assertNonNull(e, "e", " "); 216 assertEquals(e.level, l, "e.level", " "); 217 assertEquals(e.msg, "bar", "e.msg", " "); 218 assertEquals(e.bundle, null, "e.bundle", " "); 219 assertEquals(e.params, null, "e.params", " "); 220 assertEquals(e.thrown, null, "e.thrown", " "); 221 assertEquals(e.bundle, null, "e.bundle", " "); 222 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 223 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 224 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 225 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 226 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 227 228 System.out.println(" logger.log(" + l + ", (String)null);"); 229 logger.log(l, (String)null); 230 e = events.poll(); 231 assertNonNull(e, "e", " "); 232 assertEquals(e.level, l, "e.level", " "); 233 assertEquals(e.msg, null, "e.msg", " "); 234 assertEquals(e.bundle, null, "e.bundle", " "); 235 assertEquals(e.params, null, "e.params", " "); 236 assertEquals(e.thrown, null, "e.thrown", " "); 237 assertEquals(e.bundle, null, "e.bundle", " "); 238 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 239 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 240 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 241 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 242 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 243 } 244 245 System.out.println("\nlogger.log(Level, Supplier<String>)"); 246 for (Level l : Level.values()) { 247 boolean logged = l.compareTo(Level.WARNING) >= 0; 248 Object[][] cases = new Object[][] { 249 {null}, {"baz"} 250 }; 251 for (Object[] p : cases) { 252 String msg = (String)p[0]; 253 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing(); 254 final Supplier<String> s = msg == null ? null : () -> obj.toString(); 255 String par1 = msg == null ? "(Supplier<String>)null" 256 : logged ? "() -> new NotTrowing(\""+ msg+"\").toString()" : "new Throwing()"; 257 System.out.println(" logger.log(" + l + ", " + par1 + ")"); 258 try { 259 logger.log(l, s); 260 if (logged && s == null) { 261 throw new RuntimeException("Expected NullPointerException not thrown for" 262 + " logger.log(" + l + ", " + par1 + ")"); 263 } 264 } catch (NullPointerException x) { 265 if (logged && s == null) { 266 System.out.println(" Got expected exception: " + x); 267 continue; 268 } else { 269 throw x; 270 } 271 } 272 LoggerImpl.LogEvent e = events.poll(); 273 if (logged) { 274 assertNonNull(e, "e", " "); 275 assertEquals(l, e.level, "e.level", " "); 276 assertToString(e.msg, msg, 1, "e.msg", " "); 277 assertEquals(e.bundle, null, "e.bundle", " "); 278 assertEquals(e.params, null, "e.params", " "); 279 assertEquals(e.thrown, null, "e.thrown", " "); 280 assertEquals(e.bundle, null, "e.bundle", " "); 281 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 282 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 283 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 284 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 285 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 286 } else { 287 assertEquals(e, null, "e", " "); 288 } 289 } 290 } 291 292 System.out.println("\nlogger.log(Level, String, Object...)"); 293 for (Level l : Level.values()) { 294 boolean logged = l.compareTo(Level.WARNING) >= 0; 295 String par = "bam"; 296 Object[] params = null; 297 System.out.println(" logger.log(" + l + ", \"" + par +"\", null);"); 298 logger.log(l, par, params); 299 LoggerImpl.LogEvent e = events.poll(); 300 assertNonNull(e, "e", " "); 301 assertEquals(l, e.level, "e.level", " "); 302 assertEquals(e.msg, "bam", "e.msg", " "); 303 assertEquals(e.bundle, null, "e.bundle", " "); 304 assertEquals(e.params, null, "e.params", " "); 305 assertEquals(e.thrown, null, "e.thrown", " "); 306 assertEquals(e.bundle, null, "e.bundle", " "); 307 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 308 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 309 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 310 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 311 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 312 313 params = new Object[] {new NotTrowing("one")}; 314 par = "bam {0}"; 315 System.out.println(" logger.log(" + l + ", \"" + par +"\", new NotTrowing(\"one\"));"); 316 logger.log(l, par, params[0]); 317 e = events.poll(); 318 assertNonNull(e, "e", " "); 319 assertEquals(l, e.level, "e.level", " "); 320 assertEquals(e.msg, par, "e.msg", " "); 321 assertEquals(e.bundle, null, "e.bundle", " "); 322 assertArrayEquals(e.params, params, "e.params", " "); 323 assertEquals(e.thrown, null, "e.thrown", " "); 324 assertEquals(e.bundle, null, "e.bundle", " "); 325 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 326 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 327 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 328 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 329 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 330 331 params = new Object[] {new NotTrowing("fisrt"), new NotTrowing("second")}; 332 par = "bam {0} {1}"; 333 System.out.println(" logger.log(" + l + ", \"" + par +"\", new NotTrowing(\"fisrt\"), new NotTrowing(\"second\"));"); 334 logger.log(l, par, params[0], params[1]); 335 e = events.poll(); 336 assertNonNull(e, "e", " "); 337 assertEquals(l, e.level, "e.level", " "); 338 assertEquals(e.msg, par, "e.msg", " "); 339 assertEquals(e.bundle, null, "e.bundle", " "); 340 assertArrayEquals(e.params, params, "e.params", " "); 341 assertEquals(e.thrown, null, "e.thrown", " "); 342 assertEquals(e.bundle, null, "e.bundle", " "); 343 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 344 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 345 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 346 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 347 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 348 349 params = new Object[] {new NotTrowing("third"), new NotTrowing("fourth")}; 350 par = "bam {2}"; 351 System.out.println(" logger.log(" + l + ", \"" + par +"\", new Object[] {new NotTrowing(\"third\"), new NotTrowing(\"fourth\")});"); 352 logger.log(l, par, params); 353 e = events.poll(); 354 assertNonNull(e, "e", " "); 355 assertEquals(l, e.level, "e.level", " "); 356 assertEquals(e.msg, par, "e.msg", " "); 357 assertEquals(e.bundle, null, "e.bundle", " "); 358 assertArrayEquals(e.params, params, "e.params", " "); 359 assertEquals(e.thrown, null, "e.thrown", " "); 360 assertEquals(e.bundle, null, "e.bundle", " "); 361 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 362 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 363 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 364 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 365 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 366 } 367 368 System.out.println("\nlogger.log(Level, String, Throwable)"); 369 for (Level l : Level.values()) { 370 boolean logged = l.compareTo(Level.WARNING) >= 0; 371 Object[][] cases = new Object[][] { 372 {null, null}, {null, new Throwable()}, {"biz", null}, {"boz", new Throwable()} 373 }; 374 for (Object[] p : cases) { 375 String msg = (String)p[0]; 376 Throwable thrown = (Throwable)p[1]; 377 String par1 = msg == null ? "(String)null" : "\"" + msg + "\""; 378 String par2 = thrown == null ? "(Throwable)null" : "new Throwable()"; 379 System.out.println(" logger.log(" + l + ", " + par1 +", " + par2 + ")"); 380 logger.log(l, msg, thrown); 381 LoggerImpl.LogEvent e = events.poll(); 382 assertNonNull(e, "e", " "); 383 assertEquals(e.level, l, "e.level", " "); 384 assertEquals(e.msg, msg, "e.msg", " "); 385 assertEquals(e.bundle, null, "e.bundle", " "); 386 assertEquals(e.params, null, "e.params", " "); 387 assertEquals(e.thrown, thrown, "e.thrown", " "); 388 assertEquals(e.bundle, null, "e.bundle", " "); 389 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 390 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 391 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 392 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 393 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 394 } 395 } 396 397 System.out.println("\nlogger.log(Level, Supplier<String>, Throwable)"); 398 for (Level l : Level.values()) { 399 boolean logged = l.compareTo(Level.WARNING) >= 0; 400 Object[][] cases = new Object[][] { 401 {null, null}, {null, new Throwable()}, {"biz", null}, {"boz", new Throwable()} 402 }; 403 for (Object[] p : cases) { 404 String msg = (String)p[0]; 405 Throwable thrown = (Throwable)p[1]; 406 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing(); 407 final Supplier<String> s = msg == null ? null : () -> obj.toString(); 408 String par1 = msg == null ? "(Supplier<String>)null" 409 : logged ? "() -> new NotTrowing(\""+ msg+"\").toString()" : "new Throwing()"; 410 String par2 = thrown == null ? "(Throwable)null" : "new Throwable()"; 411 System.out.println(" logger.log(" + l + ", " + par1 +", " + par2 + ")"); 412 try { 413 logger.log(l, s, thrown); 414 if (logged && s == null) { 415 throw new RuntimeException("Expected NullPointerException not thrown for" 416 + " logger.log(" + l + ", " + par1 +", " + par2 + ")"); 417 } 418 } catch (NullPointerException x) { 419 if (logged && s == null) { 420 System.out.println(" Got expected exception: " + x); 421 continue; 422 } else { 423 throw x; 424 } 425 } 426 LoggerImpl.LogEvent e = events.poll(); 427 if (logged) { 428 assertNonNull(e, "e", " "); 429 assertEquals(l, e.level, "e.level", " "); 430 assertToString(e.msg, msg, 1, "e.msg", " "); 431 assertEquals(e.bundle, null, "e.bundle", " "); 432 assertEquals(e.params, null, "e.params", " "); 433 assertEquals(e.thrown, thrown, "e.thrown", " "); 434 assertEquals(e.bundle, null, "e.bundle", " "); 435 assertEquals(e.callStack[0].getMethodName(), "log", "e.callStack[0].getMethodName()", " "); 436 assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(), "e.callStack[0].getClassName() ", " "); 437 assertEquals(e.callStack[1].getMethodName(), "log", "e.callStack[1].getMethodName()", " "); 438 assertEquals(e.callStack[1].getClassName(), System.Logger.class.getName(), "e.callStack[1].getClassName() ", " "); 439 assertEquals(e.callStack[2].getMethodName(), "main", "e.callStack[2].getMethodName()", " "); 440 } else { 441 assertEquals(e, null, "e", " "); 442 } 443 } 444 } 445 446 System.out.println("Checking that we have no spurious events in the queue"); 447 assertEquals(events.poll(), null, "events.poll()", " "); 448 } 449 450 static void assertTrue(boolean test, String what, String prefix) { 451 if (!test) { 452 throw new RuntimeException("Expected true for " + what); 453 } 454 System.out.println(prefix + "Got expected " + what + ": " + test); 455 } 456 static void assertFalse(boolean test, String what, String prefix) { 457 if (test) { 458 throw new RuntimeException("Expected false for " + what); 459 } 460 System.out.println(prefix + "Got expected " + what + ": " + test); 461 } 462 static void assertToString(String actual, String expected, int count, String what, String prefix) { 463 assertEquals(actual, expected + "["+count+"]", what, prefix); 464 } 465 static void assertEquals(Object actual, Object expected, String what, String prefix) { 466 if (!Objects.equals(actual, expected)) { 467 throw new RuntimeException("Bad " + what + ":" 468 + "\n\t expected: " + expected 469 + "\n\t actual: " + actual); 470 } 471 System.out.println(prefix + "Got expected " + what + ": " + actual); 472 } 473 static void assertArrayEquals(Object[] actual, Object[] expected, String what, String prefix) { 474 if (!Objects.deepEquals(actual, expected)) { 475 throw new RuntimeException("Bad " + what + ":" 476 + "\n\t expected: " + expected == null ? "null" : Arrays.deepToString(expected) 477 + "\n\t actual: " + actual == null ? "null" : Arrays.deepToString(actual)); 478 } 479 System.out.println(prefix + "Got expected " + what + ": " + Arrays.deepToString(actual)); 480 } 481 static void assertNonNull(Object actual, String what, String prefix) { 482 if (Objects.equals(actual, null)) { 483 throw new RuntimeException("Bad " + what + ":" 484 + "\n\t expected: non null" 485 + "\n\t actual: " + actual); 486 } 487 System.out.println(prefix + "Got expected " + what + ": " + "non null"); 488 } 489 }