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 
  24 import java.util.ResourceBundle;
  25 import java.util.function.Consumer;
  26 import java.lang.System.Logger.Level;
  27 import java.util.Arrays;
  28 import java.util.LinkedList;
  29 import java.util.Objects;
  30 import java.util.Queue;
  31 import java.util.function.Supplier;
  32 
  33 /**
  34  * @test
  35  * @bug 8140364
  36  * @summary Tests the default body of the System.Logger interface.
  37  * @author danielfuchs
  38  */
  39 public class LoggerInterfaceTest {
  40 
  41     public static class LoggerImpl implements System.Logger {
  42 
  43         public static class LogEvent implements Cloneable {
  44             Level level;
  45             ResourceBundle bundle;
  46             String msg;
  47             Throwable thrown;
  48             Object[] params;
  49             StackTraceElement[] callStack;
  50 
  51             @Override
  52             protected LogEvent clone() {
  53                 try {
  54                     return (LogEvent)super.clone();
  55                 } catch (CloneNotSupportedException x) {
  56                     throw new RuntimeException(x);
  57                 }
  58             }
  59 
  60 
  61         }
  62 
  63         public static class LogEventBuilder {
  64             private LogEvent event = new LogEvent();
  65             public LogEventBuilder level(Level level) {
  66                 event.level = level;
  67                 return this;
  68             }
  69             public LogEventBuilder stack(StackTraceElement... stack) {
  70                 event.callStack = stack;
  71                 return this;
  72             }
  73             public LogEventBuilder bundle(ResourceBundle bundle) {
  74                 event.bundle = bundle;
  75                 return this;
  76             }
  77             public LogEventBuilder msg(String msg) {
  78                 event.msg = msg;
  79                 return this;
  80             }
  81             public LogEventBuilder thrown(Throwable thrown) {
  82                 event.thrown = thrown;
  83                 return this;
  84             }
  85             public LogEventBuilder params(Object... params) {
  86                 event.params = params;
  87                 return this;
  88             }
  89             public LogEvent build() {
  90                 return event.clone();
  91             }
  92 
  93             public LogEventBuilder clear() {
  94                 event = new LogEvent();
  95                 return this;
  96             }
  97 
  98         }
  99 
 100         Level level = Level.WARNING;
 101         Consumer<LogEvent> consumer;
 102         final LogEventBuilder builder = new LogEventBuilder();
 103 
 104         @Override
 105         public String getName() {
 106             return "noname";
 107         }
 108 
 109         @Override
 110         public boolean isLoggable(Level level) {
 111             return level.getSeverity() >= this.level.getSeverity();
 112         }
 113 
 114         @Override
 115         public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
 116             builder.clear().level(level).bundle(bundle).msg(msg).thrown(thrown)
 117                     .stack(new Exception().getStackTrace());
 118             consumer.accept(builder.build());
 119         }
 120 
 121         @Override
 122         public void log(Level level, ResourceBundle bundle, String format, Object... params) {
 123             builder.clear().level(level).bundle(bundle).msg(format).params(params)
 124                     .stack(new Exception().getStackTrace());
 125             consumer.accept(builder.build());
 126         }
 127 
 128     }
 129 
 130     static class Throwing {
 131         @Override
 132         public String toString() {
 133             throw new RuntimeException("should not have been called");
 134         }
 135     }
 136     static class NotTrowing {
 137         private final String toString;
 138         private int count = 0;
 139         public NotTrowing(String toString) {
 140             this.toString = toString;
 141         }
 142 
 143         @Override
 144         public String toString() {
 145             return toString + "[" + (++count) + "]";
 146         }
 147     }
 148 
 149     public static void main(String[] args) {
 150         final LoggerImpl loggerImpl = new LoggerImpl();
 151         final System.Logger logger = loggerImpl;
 152         final Queue<LoggerImpl.LogEvent> events = new LinkedList<>();
 153         loggerImpl.consumer = (x) -> events.add(x);
 154 
 155         System.out.println("\nlogger.isLoggable(Level)");
 156         assertTrue(logger.isLoggable(Level.WARNING), "logger.isLoggable(Level.WARNING)","  ");
 157         assertFalse(logger.isLoggable(Level.INFO), "logger.isLoggable(Level.INFO)", "  ");
 158 
 159 
 160         System.out.println("\nlogger.log(Level, Object)");
 161         for (Level l : Level.values()) {
 162             boolean logged = l.compareTo(Level.WARNING) >= 0;
 163             Object[][] cases = new Object[][] {
 164                 {null}, {"baz"}
 165             };
 166             for (Object[] p : cases) {
 167                 String msg = (String)p[0];
 168                 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing();
 169                 String par1 = msg == null ? "(Object)null"
 170                         : logged ? "new NotTrowing(\""+ msg+"\")" : "new Throwing()";
 171                 System.out.println("  logger.log(" + l + ", " +  par1 + ")");
 172                 try {
 173                     logger.log(l, obj);
 174                     if (obj == null) {
 175                         throw new RuntimeException("Expected NullPointerException not thrown for"
 176                                   + " logger.log(" + l + ", " +  par1 + ")");
 177                     }
 178                 } catch (NullPointerException x) {
 179                     if (obj == null) {
 180                         System.out.println("    Got expected exception: " + x);
 181                         continue;
 182                     } else {
 183                         throw x;
 184                     }
 185                 }
 186                 LoggerImpl.LogEvent e = events.poll();
 187                 if (logged) {
 188                     assertNonNull(e, "e", "    ");
 189                     assertEquals(l, e.level, "e.level", "    ");
 190                     assertToString(e.msg, msg, 1, "e.msg", "    ");
 191                     assertEquals(e.bundle, null, "e.bundle", "    ");
 192                     assertEquals(e.params, null, "e.params", "    ");
 193                     assertEquals(e.thrown, null, "e.thrown", "    ");
 194                     assertEquals(e.bundle, null, "e.bundle", "    ");
 195                     assertEquals(e.callStack[0].getMethodName(), "log",
 196                                  "e.callStack[0].getMethodName()", "    ");
 197                     assertEquals(e.callStack[0].getClassName(),
 198                                 logger.getClass().getName(),
 199                                 "e.callStack[0].getClassName() ", "    ");
 200                     assertEquals(e.callStack[1].getMethodName(), "log",
 201                                  "e.callStack[1].getMethodName()", "    ");
 202                     assertEquals(e.callStack[1].getClassName(),
 203                                  System.Logger.class.getName(),
 204                                  "e.callStack[1].getClassName() ", "    ");
 205                     assertEquals(e.callStack[2].getMethodName(), "main",
 206                                  "e.callStack[2].getMethodName()", "    ");
 207                 } else {
 208                     assertEquals(e, null, "e", "    ");
 209                 }
 210             }
 211         }
 212         System.out.println("  logger.log(" + null + ", " +
 213                 "new NotThrowing(\"foobar\")" + ")");
 214         try {
 215             logger.log(null, new NotTrowing("foobar"));
 216             throw new RuntimeException("Expected NullPointerException not thrown for"
 217                                       + " logger.log(" + null + ", "
 218                                       + "new NotThrowing(\"foobar\")" + ")");
 219         } catch (NullPointerException x) {
 220             System.out.println("    Got expected exception: " + x);
 221         }
 222 
 223 
 224         System.out.println("\nlogger.log(Level, String)");
 225         for (Level l : Level.values()) {
 226             boolean logged = l.compareTo(Level.WARNING) >= 0;
 227             String par = "bar";
 228             System.out.println("  logger.log(" + l + ", \"" +  par +"\");");
 229             logger.log(l, par);
 230             LoggerImpl.LogEvent e = events.poll();
 231             assertNonNull(e, "e", "    ");
 232             assertEquals(e.level, l, "e.level", "    ");
 233             assertEquals(e.msg, "bar", "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",
 239                          "e.callStack[0].getMethodName()", "    ");
 240             assertEquals(e.callStack[0].getClassName(),
 241                          logger.getClass().getName(),
 242                          "e.callStack[0].getClassName() ", "    ");
 243             assertEquals(e.callStack[1].getMethodName(), "log",
 244                          "e.callStack[1].getMethodName()", "    ");
 245             assertEquals(e.callStack[1].getClassName(),
 246                          System.Logger.class.getName(),
 247                          "e.callStack[1].getClassName() ", "    ");
 248             assertEquals(e.callStack[2].getMethodName(), "main",
 249                          "e.callStack[2].getMethodName()", "    ");
 250 
 251             System.out.println("  logger.log(" + l + ", (String)null);");
 252             logger.log(l, (String)null);
 253             e = events.poll();
 254             assertNonNull(e, "e", "    ");
 255             assertEquals(e.level, l, "e.level", "    ");
 256             assertEquals(e.msg, null, "e.msg", "    ");
 257             assertEquals(e.bundle, null, "e.bundle", "    ");
 258             assertEquals(e.params, null, "e.params", "    ");
 259             assertEquals(e.thrown, null, "e.thrown", "    ");
 260             assertEquals(e.bundle, null, "e.bundle", "    ");
 261             assertEquals(e.callStack[0].getMethodName(), "log",
 262                          "e.callStack[0].getMethodName()", "    ");
 263             assertEquals(e.callStack[0].getClassName(),
 264                          logger.getClass().getName(),
 265                          "e.callStack[0].getClassName() ", "    ");
 266             assertEquals(e.callStack[1].getMethodName(), "log",
 267                          "e.callStack[1].getMethodName()", "    ");
 268             assertEquals(e.callStack[1].getClassName(),
 269                          System.Logger.class.getName(),
 270                          "e.callStack[1].getClassName() ", "    ");
 271             assertEquals(e.callStack[2].getMethodName(), "main",
 272                          "e.callStack[2].getMethodName()", "    ");
 273         }
 274 
 275         System.out.println("\nlogger.log(Level, Supplier<String>)");
 276         for (Level l : Level.values()) {
 277             boolean logged = l.compareTo(Level.WARNING) >= 0;
 278             Object[][] cases = new Object[][] {
 279                 {null}, {"baz"}
 280             };
 281             for (Object[] p : cases) {
 282                 String msg = (String)p[0];
 283                 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing();
 284                 final Supplier<String> s = msg == null ? null : () -> obj.toString();
 285                 String par1 = msg == null ? "(Supplier<String>)null"
 286                         : logged ? "() -> new NotTrowing(\""+ msg+"\").toString()" : "new Throwing()";
 287                 System.out.println("  logger.log(" + l + ", " +  par1 + ")");
 288                 try {
 289                     logger.log(l, s);
 290                     if (s == null) {
 291                         throw new RuntimeException("Expected NullPointerException not thrown for"
 292                                   + " logger.log(" + l + ", " +  par1 + ")");
 293                     }
 294                 } catch (NullPointerException x) {
 295                     if (s == null) {
 296                         System.out.println("    Got expected exception: " + x);
 297                         continue;
 298                     } else {
 299                         throw x;
 300                     }
 301                 }
 302                 LoggerImpl.LogEvent e = events.poll();
 303                 if (logged) {
 304                     assertNonNull(e, "e", "    ");
 305                     assertEquals(l, e.level, "e.level", "    ");
 306                     assertToString(e.msg, msg, 1, "e.msg", "    ");
 307                     assertEquals(e.bundle, null, "e.bundle", "    ");
 308                     assertEquals(e.params, null, "e.params", "    ");
 309                     assertEquals(e.thrown, null, "e.thrown", "    ");
 310                     assertEquals(e.bundle, null, "e.bundle", "    ");
 311                     assertEquals(e.callStack[0].getMethodName(), "log",
 312                                  "e.callStack[0].getMethodName()", "    ");
 313                     assertEquals(e.callStack[0].getClassName(),
 314                                  logger.getClass().getName(),
 315                                  "e.callStack[0].getClassName() ", "    ");
 316                     assertEquals(e.callStack[1].getMethodName(), "log",
 317                                  "e.callStack[1].getMethodName()", "    ");
 318                     assertEquals(e.callStack[1].getClassName(),
 319                                  System.Logger.class.getName(),
 320                                  "e.callStack[1].getClassName() ", "    ");
 321                     assertEquals(e.callStack[2].getMethodName(), "main",
 322                                  "e.callStack[2].getMethodName()", "    ");
 323                 } else {
 324                     assertEquals(e, null, "e", "    ");
 325                 }
 326             }
 327         }
 328         System.out.println("  logger.log(" + null + ", " + "() -> \"biz\"" + ")");
 329         try {
 330             logger.log(null, () -> "biz");
 331             throw new RuntimeException("Expected NullPointerException not thrown for"
 332                                       + " logger.log(" + null + ", "
 333                                       + "() -> \"biz\"" + ")");
 334         } catch (NullPointerException x) {
 335             System.out.println("    Got expected exception: " + x);
 336         }
 337 
 338         System.out.println("\nlogger.log(Level, String, Object...)");
 339         for (Level l : Level.values()) {
 340             boolean logged = l.compareTo(Level.WARNING) >= 0;
 341             String par = "bam";
 342             Object[] params = null;
 343             System.out.println("  logger.log(" + l + ", \"" +  par +"\", null);");
 344             logger.log(l, par, params);
 345             LoggerImpl.LogEvent e = events.poll();
 346             assertNonNull(e, "e", "    ");
 347             assertEquals(l, e.level, "e.level", "    ");
 348             assertEquals(e.msg, "bam", "e.msg", "    ");
 349             assertEquals(e.bundle, null, "e.bundle", "    ");
 350             assertEquals(e.params, null, "e.params", "    ");
 351             assertEquals(e.thrown, null, "e.thrown", "    ");
 352             assertEquals(e.bundle, null, "e.bundle", "    ");
 353             assertEquals(e.callStack[0].getMethodName(), "log",
 354                         "e.callStack[0].getMethodName()", "    ");
 355             assertEquals(e.callStack[0].getClassName(),
 356                          logger.getClass().getName(),
 357                          "e.callStack[0].getClassName() ", "    ");
 358             assertEquals(e.callStack[1].getMethodName(), "log",
 359                          "e.callStack[1].getMethodName()", "    ");
 360             assertEquals(e.callStack[1].getClassName(),
 361                          System.Logger.class.getName(),
 362                          "e.callStack[1].getClassName() ", "    ");
 363             assertEquals(e.callStack[2].getMethodName(), "main",
 364                          "e.callStack[2].getMethodName()", "    ");
 365 
 366             params = new Object[] {new NotTrowing("one")};
 367             par = "bam {0}";
 368             System.out.println("  logger.log(" + l + ", \"" +  par
 369                                + "\", new NotTrowing(\"one\"));");
 370             logger.log(l, par, params[0]);
 371             e = events.poll();
 372             assertNonNull(e, "e", "    ");
 373             assertEquals(l, e.level, "e.level", "    ");
 374             assertEquals(e.msg, par, "e.msg", "    ");
 375             assertEquals(e.bundle, null, "e.bundle", "    ");
 376             assertArrayEquals(e.params, params, "e.params", "    ");
 377             assertEquals(e.thrown, null, "e.thrown", "    ");
 378             assertEquals(e.bundle, null, "e.bundle", "    ");
 379             assertEquals(e.callStack[0].getMethodName(), "log",
 380                          "e.callStack[0].getMethodName()", "    ");
 381             assertEquals(e.callStack[0].getClassName(),
 382                          logger.getClass().getName(),
 383                          "e.callStack[0].getClassName() ", "    ");
 384             assertEquals(e.callStack[1].getMethodName(), "log",
 385                          "e.callStack[1].getMethodName()", "    ");
 386             assertEquals(e.callStack[1].getClassName(),
 387                          System.Logger.class.getName(),
 388                          "e.callStack[1].getClassName() ", "    ");
 389             assertEquals(e.callStack[2].getMethodName(), "main",
 390                          "e.callStack[2].getMethodName()", "    ");
 391 
 392             params = new Object[] {new NotTrowing("fisrt"), new NotTrowing("second")};
 393             par = "bam {0} {1}";
 394             System.out.println("  logger.log(" + l + ", \"" +  par
 395                               + "\", new NotTrowing(\"fisrt\"),"
 396                               + " new NotTrowing(\"second\"));");
 397             logger.log(l, par, params[0], params[1]);
 398             e = events.poll();
 399             assertNonNull(e, "e", "    ");
 400             assertEquals(l, e.level, "e.level", "    ");
 401             assertEquals(e.msg, par, "e.msg", "    ");
 402             assertEquals(e.bundle, null, "e.bundle", "    ");
 403             assertArrayEquals(e.params, params, "e.params", "    ");
 404             assertEquals(e.thrown, null, "e.thrown", "    ");
 405             assertEquals(e.bundle, null, "e.bundle", "    ");
 406             assertEquals(e.callStack[0].getMethodName(), "log",
 407                          "e.callStack[0].getMethodName()", "    ");
 408             assertEquals(e.callStack[0].getClassName(),
 409                          logger.getClass().getName(),
 410                          "e.callStack[0].getClassName() ", "    ");
 411             assertEquals(e.callStack[1].getMethodName(), "log",
 412                          "e.callStack[1].getMethodName()", "    ");
 413             assertEquals(e.callStack[1].getClassName(),
 414                          System.Logger.class.getName(),
 415                          "e.callStack[1].getClassName() ", "    ");
 416             assertEquals(e.callStack[2].getMethodName(), "main",
 417                          "e.callStack[2].getMethodName()", "    ");
 418 
 419             params = new Object[] {new NotTrowing("third"), new NotTrowing("fourth")};
 420             par = "bam {2}";
 421             System.out.println("  logger.log(" + l + ", \"" +  par
 422                               + "\", new Object[] {new NotTrowing(\"third\"),"
 423                               + " new NotTrowing(\"fourth\")});");
 424             logger.log(l, par, params);
 425             e = events.poll();
 426             assertNonNull(e, "e", "    ");
 427             assertEquals(l, e.level, "e.level", "    ");
 428             assertEquals(e.msg, par, "e.msg", "    ");
 429             assertEquals(e.bundle, null, "e.bundle", "    ");
 430             assertArrayEquals(e.params, params, "e.params", "    ");
 431             assertEquals(e.thrown, null, "e.thrown", "    ");
 432             assertEquals(e.bundle, null, "e.bundle", "    ");
 433             assertEquals(e.callStack[0].getMethodName(), "log",
 434                          "e.callStack[0].getMethodName()", "    ");
 435             assertEquals(e.callStack[0].getClassName(), logger.getClass().getName(),
 436                          "e.callStack[0].getClassName() ", "    ");
 437             assertEquals(e.callStack[1].getMethodName(), "log",
 438                          "e.callStack[1].getMethodName()", "    ");
 439             assertEquals(e.callStack[1].getClassName(),
 440                          System.Logger.class.getName(),
 441                          "e.callStack[1].getClassName() ", "    ");
 442             assertEquals(e.callStack[2].getMethodName(), "main",
 443                         "e.callStack[2].getMethodName()", "    ");
 444         }
 445 
 446         System.out.println("\nlogger.log(Level, String, Throwable)");
 447         for (Level l : Level.values()) {
 448             boolean logged = l.compareTo(Level.WARNING) >= 0;
 449             Object[][] cases = new Object[][] {
 450                 {null, null}, {null, new Throwable()}, {"biz", null}, {"boz", new Throwable()}
 451             };
 452             for (Object[] p : cases) {
 453                 String msg = (String)p[0];
 454                 Throwable thrown = (Throwable)p[1];
 455                 String par1 = msg == null ? "(String)null" : "\"" + msg + "\"";
 456                 String par2 = thrown == null ? "(Throwable)null" : "new Throwable()";
 457                 System.out.println("  logger.log(" + l + ", " +  par1 +", " + par2 + ")");
 458                 logger.log(l, msg, thrown);
 459                 LoggerImpl.LogEvent e = events.poll();
 460                 assertNonNull(e, "e", "    ");
 461                 assertEquals(e.level, l, "e.level", "    ");
 462                 assertEquals(e.msg, msg, "e.msg", "    ");
 463                 assertEquals(e.bundle, null, "e.bundle", "    ");
 464                 assertEquals(e.params, null, "e.params", "    ");
 465                 assertEquals(e.thrown, thrown, "e.thrown", "    ");
 466                 assertEquals(e.bundle, null, "e.bundle", "    ");
 467                 assertEquals(e.callStack[0].getMethodName(),
 468                              "log", "e.callStack[0].getMethodName()", "    ");
 469                 assertEquals(e.callStack[0].getClassName(),
 470                             logger.getClass().getName(),
 471                             "e.callStack[0].getClassName() ", "    ");
 472                 assertEquals(e.callStack[1].getMethodName(), "log",
 473                              "e.callStack[1].getMethodName()", "    ");
 474                 assertEquals(e.callStack[1].getClassName(),
 475                             System.Logger.class.getName(),
 476                             "e.callStack[1].getClassName() ", "    ");
 477                 assertEquals(e.callStack[2].getMethodName(), "main",
 478                              "e.callStack[2].getMethodName()", "    ");
 479             }
 480         }
 481 
 482         System.out.println("\nlogger.log(Level, Supplier<String>, Throwable)");
 483         for (Level l : Level.values()) {
 484             boolean logged = l.compareTo(Level.WARNING) >= 0;
 485             Object[][] cases = new Object[][] {
 486                 {null, null}, {null, new Throwable()}, {"biz", null}, {"boz", new Throwable()}
 487             };
 488             for (Object[] p : cases) {
 489                 String msg = (String)p[0];
 490                 Throwable thrown = (Throwable)p[1];
 491                 final Object obj = msg == null ? null : logged ? new NotTrowing(msg) : new Throwing();
 492                 final Supplier<String> s = msg == null ? null : () -> obj.toString();
 493                 String par1 = msg == null ? "(Supplier<String>)null"
 494                         : logged ? "() -> new NotTrowing(\""+ msg+"\").toString()" : "new Throwing()";
 495                 String par2 = thrown == null ? "(Throwable)null" : "new Throwable()";
 496                 System.out.println("  logger.log(" + l + ", " +  par1 +", " + par2 + ")");
 497                 try {
 498                     logger.log(l, s, thrown);
 499                     if (s== null) {
 500                         throw new RuntimeException("Expected NullPointerException not thrown for"
 501                                   + " logger.log(" + l + ", " +  par1 +", " + par2 + ")");
 502                     }
 503                 } catch (NullPointerException x) {
 504                     if (s == null) {
 505                         System.out.println("    Got expected exception: " + x);
 506                         continue;
 507                     } else {
 508                         throw x;
 509                     }
 510                 }
 511                 LoggerImpl.LogEvent e = events.poll();
 512                 if (logged) {
 513                     assertNonNull(e, "e", "    ");
 514                     assertEquals(l, e.level, "e.level", "    ");
 515                     assertToString(e.msg, msg, 1, "e.msg", "    ");
 516                     assertEquals(e.bundle, null, "e.bundle", "    ");
 517                     assertEquals(e.params, null, "e.params", "    ");
 518                     assertEquals(e.thrown, thrown, "e.thrown", "    ");
 519                     assertEquals(e.bundle, null, "e.bundle", "    ");
 520                     assertEquals(e.callStack[0].getMethodName(), "log",
 521                                  "e.callStack[0].getMethodName()", "    ");
 522                     assertEquals(e.callStack[0].getClassName(),
 523                                  logger.getClass().getName(),
 524                                  "e.callStack[0].getClassName() ", "    ");
 525                     assertEquals(e.callStack[1].getMethodName(), "log",
 526                                  "e.callStack[1].getMethodName()", "    ");
 527                     assertEquals(e.callStack[1].getClassName(),
 528                                  System.Logger.class.getName(),
 529                                  "e.callStack[1].getClassName() ", "    ");
 530                     assertEquals(e.callStack[2].getMethodName(), "main",
 531                                  "e.callStack[2].getMethodName()", "    ");
 532                 } else {
 533                     assertEquals(e, null, "e", "    ");
 534                 }
 535             }
 536         }
 537         System.out.println("  logger.log(" + null + ", " + "() -> \"biz\""
 538                            + ", " + "new Throwable()" + ")");
 539         try {
 540             logger.log(null, () -> "biz", new Throwable());
 541             throw new RuntimeException("Expected NullPointerException not thrown for"
 542                                       + " logger.log(" + null + ", "
 543                                       + "() -> \"biz\"" + ", "
 544                                       + "new Throwable()" + ")");
 545         } catch (NullPointerException x) {
 546             System.out.println("    Got expected exception: " + x);
 547         }
 548 
 549         System.out.println("Checking that we have no spurious events in the queue");
 550         assertEquals(events.poll(), null, "events.poll()", "  ");
 551     }
 552 
 553     static void assertTrue(boolean test, String what, String prefix) {
 554         if (!test) {
 555             throw new RuntimeException("Expected true for " + what);
 556         }
 557         System.out.println(prefix + "Got expected " + what + ": " + test);
 558     }
 559     static void assertFalse(boolean test, String what, String prefix) {
 560         if (test) {
 561             throw new RuntimeException("Expected false for " + what);
 562         }
 563         System.out.println(prefix + "Got expected " + what + ": " + test);
 564     }
 565     static void assertToString(String actual, String expected, int count, String what, String prefix) {
 566         assertEquals(actual, expected + "["+count+"]", what, prefix);
 567     }
 568     static void assertEquals(Object actual, Object expected, String what, String prefix) {
 569         if (!Objects.equals(actual, expected)) {
 570             throw new RuntimeException("Bad " + what + ":"
 571                     + "\n\t expected: " + expected
 572                     + "\n\t   actual: " + actual);
 573         }
 574         System.out.println(prefix + "Got expected " + what + ": " + actual);
 575     }
 576     static void assertArrayEquals(Object[] actual, Object[] expected, String what, String prefix) {
 577         if (!Objects.deepEquals(actual, expected)) {
 578             throw new RuntimeException("Bad " + what + ":"
 579                     + "\n\t expected: " + expected == null ? "null" : Arrays.deepToString(expected)
 580                     + "\n\t   actual: " + actual == null ? "null" : Arrays.deepToString(actual));
 581         }
 582         System.out.println(prefix + "Got expected " + what + ": " + Arrays.deepToString(actual));
 583     }
 584     static void assertNonNull(Object actual, String what, String prefix) {
 585         if (Objects.equals(actual, null)) {
 586             throw new RuntimeException("Bad " + what + ":"
 587                     + "\n\t expected: non null"
 588                     + "\n\t   actual: " + actual);
 589         }
 590         System.out.println(prefix + "Got expected " + what + ": " + "non null");
 591     }
 592 }