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
24import java.util.ResourceBundle;
25import java.util.function.Consumer;
26import java.lang.System.Logger.Level;
27import java.util.Arrays;
28import java.util.LinkedList;
29import java.util.Objects;
30import java.util.Queue;
31import 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 */
39public 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}
593