Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/System/Logger/default/DefaultLoggerTest.java
41154 views
1
/*
2
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
import java.security.AccessControlException;
24
import java.security.CodeSource;
25
import java.security.Permission;
26
import java.security.PermissionCollection;
27
import java.security.Permissions;
28
import java.security.Policy;
29
import java.security.ProtectionDomain;
30
import java.util.Arrays;
31
import java.util.Collections;
32
import java.util.Enumeration;
33
import java.util.HashMap;
34
import java.util.Map;
35
import java.util.Objects;
36
import java.util.Queue;
37
import java.util.ResourceBundle;
38
import java.util.concurrent.ArrayBlockingQueue;
39
import java.util.concurrent.ConcurrentHashMap;
40
import java.util.concurrent.atomic.AtomicBoolean;
41
import java.util.concurrent.atomic.AtomicLong;
42
import java.util.function.Supplier;
43
import java.lang.System.LoggerFinder;
44
import java.lang.System.Logger;
45
import java.lang.System.Logger.Level;
46
import java.lang.reflect.InvocationTargetException;
47
import java.lang.reflect.Method;
48
import java.util.function.Function;
49
import java.util.logging.Handler;
50
import java.util.logging.LogRecord;
51
import java.util.stream.Stream;
52
53
/**
54
* @test
55
* @bug 8140364 8145686
56
* @summary Tests default loggers returned by System.getLogger, and in
57
* particular the implementation of the the System.Logger method
58
* performed by the default binding.
59
* @modules java.logging
60
* @build DefaultLoggerTest AccessSystemLogger
61
* @run driver AccessSystemLogger
62
* @run main/othervm -Xbootclasspath/a:boot DefaultLoggerTest NOSECURITY
63
* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerTest NOPERMISSIONS
64
* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerTest WITHPERMISSIONS
65
* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerTest WITHCUSTOMWRAPPERS
66
* @run main/othervm -Xbootclasspath/a:boot -Djava.security.manager=allow DefaultLoggerTest WITHREFLECTION
67
* @author danielfuchs
68
*/
69
public class DefaultLoggerTest {
70
71
final static AtomicLong sequencer = new AtomicLong();
72
final static boolean VERBOSE = false;
73
static final ThreadLocal<AtomicBoolean> allowControl = new ThreadLocal<AtomicBoolean>() {
74
@Override
75
protected AtomicBoolean initialValue() {
76
return new AtomicBoolean(false);
77
}
78
};
79
static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
80
@Override
81
protected AtomicBoolean initialValue() {
82
return new AtomicBoolean(false);
83
}
84
};
85
86
public static final Queue<LogEvent> eventQueue = new ArrayBlockingQueue<>(128);
87
88
public static final class LogEvent {
89
90
public LogEvent() {
91
this(sequencer.getAndIncrement());
92
}
93
94
LogEvent(long sequenceNumber) {
95
this.sequenceNumber = sequenceNumber;
96
}
97
98
long sequenceNumber;
99
boolean isLoggable;
100
String loggerName;
101
java.util.logging.Level level;
102
ResourceBundle bundle;
103
Throwable thrown;
104
Object[] args;
105
String msg;
106
String className;
107
String methodName;
108
109
Object[] toArray() {
110
return new Object[] {
111
sequenceNumber,
112
isLoggable,
113
loggerName,
114
level,
115
bundle,
116
thrown,
117
args,
118
msg,
119
className,
120
methodName,
121
};
122
}
123
124
@Override
125
public String toString() {
126
return Arrays.deepToString(toArray());
127
}
128
129
@Override
130
public boolean equals(Object obj) {
131
return obj instanceof LogEvent
132
&& Objects.deepEquals(this.toArray(), ((LogEvent)obj).toArray());
133
}
134
135
@Override
136
public int hashCode() {
137
return Objects.hash(toArray());
138
}
139
public static LogEvent of(long sequenceNumber,
140
boolean isLoggable, String name,
141
java.util.logging.Level level, ResourceBundle bundle,
142
String key, Throwable thrown, Object... params) {
143
return LogEvent.of(sequenceNumber, isLoggable, name,
144
DefaultLoggerTest.class.getName(),
145
"testLogger", level, bundle, key,
146
thrown, params);
147
}
148
public static LogEvent of(long sequenceNumber,
149
boolean isLoggable, String name,
150
String className, String methodName,
151
java.util.logging.Level level, ResourceBundle bundle,
152
String key, Throwable thrown, Object... params) {
153
LogEvent evt = new LogEvent(sequenceNumber);
154
evt.loggerName = name;
155
evt.level = level;
156
evt.args = params;
157
evt.bundle = bundle;
158
evt.thrown = thrown;
159
evt.msg = key;
160
evt.isLoggable = isLoggable;
161
evt.className = className;
162
evt.methodName = methodName;
163
return evt;
164
}
165
166
}
167
168
static java.util.logging.Level mapToJul(Level level) {
169
switch (level) {
170
case ALL: return java.util.logging.Level.ALL;
171
case TRACE: return java.util.logging.Level.FINER;
172
case DEBUG: return java.util.logging.Level.FINE;
173
case INFO: return java.util.logging.Level.INFO;
174
case WARNING: return java.util.logging.Level.WARNING;
175
case ERROR: return java.util.logging.Level.SEVERE;
176
case OFF: return java.util.logging.Level.OFF;
177
}
178
throw new InternalError("No such level: " + level);
179
}
180
181
static void setLevel(java.util.logging.Logger sink, java.util.logging.Level loggerLevel) {
182
boolean before = allowAll.get().get();
183
try {
184
allowAll.get().set(true);
185
sink.setLevel(loggerLevel);
186
} finally {
187
allowAll.get().set(before);
188
}
189
}
190
191
public static class MyHandler extends Handler {
192
193
@Override
194
public java.util.logging.Level getLevel() {
195
return java.util.logging.Level.ALL;
196
}
197
198
@Override
199
public void publish(LogRecord record) {
200
eventQueue.add(LogEvent.of(sequencer.getAndIncrement(),
201
true, record.getLoggerName(),
202
record.getSourceClassName(),
203
record.getSourceMethodName(),
204
record.getLevel(),
205
record.getResourceBundle(), record.getMessage(),
206
record.getThrown(), record.getParameters()));
207
}
208
@Override
209
public void flush() {
210
}
211
@Override
212
public void close() throws SecurityException {
213
}
214
215
}
216
public static class MyBundle extends ResourceBundle {
217
218
final ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();
219
220
@Override
221
protected Object handleGetObject(String key) {
222
if (key.contains(" (translated)")) {
223
throw new RuntimeException("Unexpected key: " + key);
224
}
225
return map.computeIfAbsent(key, k -> k + " (translated)");
226
}
227
228
@Override
229
public Enumeration<String> getKeys() {
230
return Collections.enumeration(map.keySet());
231
}
232
233
}
234
public static class MyLoggerBundle extends MyBundle {
235
236
}
237
238
static final AccessSystemLogger accessSystemLogger = new AccessSystemLogger();
239
240
static enum TestCases {NOSECURITY, NOPERMISSIONS, WITHPERMISSIONS,
241
WITHCUSTOMWRAPPERS, WITHREFLECTION};
242
243
static void setSecurityManager() {
244
if (System.getSecurityManager() == null) {
245
Policy.setPolicy(new SimplePolicy(allowControl, allowAll));
246
System.setSecurityManager(new SecurityManager());
247
}
248
}
249
250
/**
251
* The CustomLoggerWrapper makes it possible to verify that classes
252
* which implements System.Logger will be skipped when looking for
253
* the calling method.
254
*/
255
static class CustomLoggerWrapper implements Logger {
256
257
Logger impl;
258
public CustomLoggerWrapper(Logger logger) {
259
this.impl = Objects.requireNonNull(logger);
260
}
261
262
263
@Override
264
public String getName() {
265
return impl.getName();
266
}
267
268
@Override
269
public boolean isLoggable(Level level) {
270
return impl.isLoggable(level);
271
}
272
273
@Override
274
public void log(Level level, ResourceBundle rb, String string, Throwable thrwbl) {
275
impl.log(level, rb, string, thrwbl);
276
}
277
278
@Override
279
public void log(Level level, ResourceBundle rb, String string, Object... os) {
280
impl.log(level, rb, string, os);
281
}
282
283
@Override
284
public void log(Level level, Object o) {
285
impl.log(level, o);
286
}
287
288
@Override
289
public void log(Level level, String string) {
290
impl.log(level, string);
291
}
292
293
@Override
294
public void log(Level level, Supplier<String> splr) {
295
impl.log(level, splr);
296
}
297
298
@Override
299
public void log(Level level, String string, Object... os) {
300
impl.log(level, string, os);
301
}
302
303
@Override
304
public void log(Level level, String string, Throwable thrwbl) {
305
impl.log(level, string, thrwbl);
306
}
307
308
@Override
309
public void log(Level level, Supplier<String> splr, Throwable thrwbl) {
310
Logger.super.log(level, splr, thrwbl);
311
}
312
313
@Override
314
public String toString() {
315
return super.toString() + "(impl=" + impl + ")";
316
}
317
318
}
319
320
/**
321
* The ReflectionLoggerWrapper additionally makes it possible to verify
322
* that code which use reflection to call System.Logger will be skipped
323
* when looking for the calling method.
324
*/
325
static class ReflectionLoggerWrapper implements Logger {
326
327
Logger impl;
328
public ReflectionLoggerWrapper(Logger logger) {
329
this.impl = Objects.requireNonNull(logger);
330
}
331
332
private Object invoke(Method m, Object... params) {
333
try {
334
return m.invoke(impl, params);
335
} catch (IllegalAccessException | IllegalArgumentException
336
| InvocationTargetException ex) {
337
throw new RuntimeException(ex);
338
}
339
}
340
341
@Override
342
public String getName() {
343
return impl.getName();
344
}
345
346
@Override
347
public boolean isLoggable(Level level) {
348
return impl.isLoggable(level);
349
}
350
351
@Override
352
public void log(Level level, ResourceBundle rb, String string, Throwable thrwbl) {
353
try {
354
invoke(System.Logger.class.getMethod(
355
"log", Level.class, ResourceBundle.class, String.class, Throwable.class),
356
level, rb, string, thrwbl);
357
} catch (NoSuchMethodException ex) {
358
throw new RuntimeException(ex);
359
}
360
}
361
362
@Override
363
public void log(Level level, ResourceBundle rb, String string, Object... os) {
364
try {
365
invoke(System.Logger.class.getMethod(
366
"log", Level.class, ResourceBundle.class, String.class, Object[].class),
367
level, rb, string, os);
368
} catch (NoSuchMethodException ex) {
369
throw new RuntimeException(ex);
370
}
371
}
372
373
@Override
374
public void log(Level level, String string) {
375
try {
376
invoke(System.Logger.class.getMethod(
377
"log", Level.class, String.class),
378
level, string);
379
} catch (NoSuchMethodException ex) {
380
throw new RuntimeException(ex);
381
}
382
}
383
384
@Override
385
public void log(Level level, String string, Object... os) {
386
try {
387
invoke(System.Logger.class.getMethod(
388
"log", Level.class, String.class, Object[].class),
389
level, string, os);
390
} catch (NoSuchMethodException ex) {
391
throw new RuntimeException(ex);
392
}
393
}
394
395
@Override
396
public void log(Level level, String string, Throwable thrwbl) {
397
try {
398
invoke(System.Logger.class.getMethod(
399
"log", Level.class, String.class, Throwable.class),
400
level, string, thrwbl);
401
} catch (NoSuchMethodException ex) {
402
throw new RuntimeException(ex);
403
}
404
}
405
406
407
@Override
408
public String toString() {
409
return super.toString() + "(impl=" + impl + ")";
410
}
411
412
}
413
414
public static void main(String[] args) {
415
if (args.length == 0)
416
args = new String[] {
417
"NOSECURITY",
418
"NOPERMISSIONS",
419
"WITHPERMISSIONS",
420
"WITHCUSTOMWRAPPERS",
421
"WITHREFLECTION"
422
};
423
424
// 1. Obtain destination loggers directly from the LoggerFinder
425
// - LoggerFinder.getLogger("foo", type)
426
427
428
Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
429
switch (testCase) {
430
case NOSECURITY:
431
System.out.println("\n*** Without Security Manager\n");
432
test(true);
433
System.out.println("Tetscase count: " + sequencer.get());
434
break;
435
case NOPERMISSIONS:
436
System.out.println("\n*** With Security Manager, without permissions\n");
437
setSecurityManager();
438
test(false);
439
System.out.println("Tetscase count: " + sequencer.get());
440
break;
441
case WITHPERMISSIONS:
442
System.out.println("\n*** With Security Manager, with control permission\n");
443
setSecurityManager();
444
final boolean control = allowControl.get().get();
445
try {
446
allowControl.get().set(true);
447
test(true);
448
} finally {
449
allowControl.get().set(control);
450
}
451
break;
452
case WITHCUSTOMWRAPPERS:
453
System.out.println("\n*** With Security Manager, with control permission, using custom Wrappers\n");
454
setSecurityManager();
455
final boolean previous = allowControl.get().get();
456
try {
457
allowControl.get().set(true);
458
test(CustomLoggerWrapper::new, true);
459
} finally {
460
allowControl.get().set(previous);
461
}
462
break;
463
case WITHREFLECTION:
464
System.out.println("\n*** With Security Manager,"
465
+ " with control permission,"
466
+ " using reflection while logging\n");
467
setSecurityManager();
468
final boolean before = allowControl.get().get();
469
try {
470
allowControl.get().set(true);
471
test(ReflectionLoggerWrapper::new, true);
472
} finally {
473
allowControl.get().set(before);
474
}
475
break;
476
477
default:
478
throw new RuntimeException("Unknown test case: " + testCase);
479
}
480
});
481
System.out.println("\nPASSED: Tested " + sequencer.get() + " cases.");
482
}
483
484
public static void test(boolean hasRequiredPermissions) {
485
test(Function.identity(), hasRequiredPermissions);
486
}
487
488
public static void test(Function<Logger, Logger> wrapper, boolean hasRequiredPermissions) {
489
490
ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());
491
final Map<Logger, String> loggerDescMap = new HashMap<>();
492
493
494
// 1. Test loggers returned by:
495
// - System.getLogger("foo")
496
// - and AccessSystemLogger.getLogger("foo")
497
Logger sysLogger1 = null;
498
try {
499
sysLogger1 = wrapper.apply(accessSystemLogger.getLogger("foo"));
500
loggerDescMap.put(sysLogger1, "AccessSystemLogger.getLogger(\"foo\")");
501
} catch (AccessControlException acx) {
502
if (hasRequiredPermissions) {
503
throw new RuntimeException("Unexpected security exception: ", acx);
504
}
505
if (!acx.getPermission().equals(SimplePolicy.LOGGERFINDER_PERMISSION)) {
506
throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
507
}
508
throw new RuntimeException("unexpected exception: " + acx, acx);
509
}
510
511
Logger appLogger1 = wrapper.apply(System.getLogger("foo"));
512
loggerDescMap.put(appLogger1, "System.getLogger(\"foo\");");
513
514
if (appLogger1 == sysLogger1) {
515
throw new RuntimeException("identical loggers");
516
}
517
518
// 2. Test loggers returned by:
519
// - System.getLogger(\"foo\", loggerBundle)
520
// - and AccessSystemLogger.getLogger(\"foo\", loggerBundle)
521
Logger appLogger2 = wrapper.apply(
522
System.getLogger("foo", loggerBundle));
523
loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)");
524
525
Logger sysLogger2 = null;
526
try {
527
sysLogger2 = wrapper.apply(accessSystemLogger.getLogger("foo", loggerBundle));
528
loggerDescMap.put(sysLogger2, "AccessSystemLogger.getLogger(\"foo\", loggerBundle)");
529
} catch (AccessControlException acx) {
530
if (hasRequiredPermissions) {
531
throw new RuntimeException("Unexpected security exception: ", acx);
532
}
533
if (!acx.getPermission().equals(SimplePolicy.LOGGERFINDER_PERMISSION)) {
534
throw new RuntimeException("Unexpected permission in exception: " + acx, acx);
535
}
536
throw new RuntimeException("unexpected exception: " + acx, acx);
537
}
538
if (appLogger2 == sysLogger2) {
539
throw new RuntimeException("identical loggers");
540
}
541
542
final java.util.logging.Logger sink;
543
final java.util.logging.Logger appSink;
544
final java.util.logging.Logger sysSink;
545
final java.util.logging.Handler appHandler;
546
final java.util.logging.Handler sysHandler;
547
final LoggerFinder provider;
548
allowAll.get().set(true);
549
try {
550
appSink = java.util.logging.Logger.getLogger("foo");
551
sysSink = accessSystemLogger.demandSystemLogger("foo");
552
sink = java.util.logging.Logger.getLogger("foo");
553
sink.addHandler(appHandler = sysHandler = new MyHandler());
554
sink.setUseParentHandlers(false);
555
provider = LoggerFinder.getLoggerFinder();
556
} finally {
557
allowAll.get().set(false);
558
}
559
try {
560
testLogger(provider, loggerDescMap, "foo", null, sysLogger1, sysSink);
561
testLogger(provider, loggerDescMap, "foo", null, appLogger1, appSink);
562
testLogger(provider, loggerDescMap, "foo", loggerBundle, sysLogger2, sysSink);
563
testLogger(provider, loggerDescMap, "foo", loggerBundle, appLogger2, appSink);
564
} finally {
565
allowAll.get().set(true);
566
try {
567
appSink.removeHandler(appHandler);
568
sysSink.removeHandler(sysHandler);
569
sysSink.setLevel(null);
570
appSink.setLevel(null);
571
} finally {
572
allowAll.get().set(false);
573
}
574
}
575
}
576
577
public static class Foo {
578
579
}
580
581
static void verbose(String msg) {
582
if (VERBOSE) {
583
System.out.println(msg);
584
}
585
}
586
587
// Calls the 8 methods defined on Logger and verify the
588
// parameters received by the underlying BaseLoggerFinder.LoggerImpl
589
// logger.
590
private static void testLogger(LoggerFinder provider,
591
Map<Logger, String> loggerDescMap,
592
String name,
593
ResourceBundle loggerBundle,
594
Logger logger,
595
java.util.logging.Logger sink) {
596
597
System.out.println("Testing " + loggerDescMap.get(logger));
598
599
Foo foo = new Foo();
600
String fooMsg = foo.toString();
601
for (Level loggerLevel : Level.values()) {
602
setLevel(sink, mapToJul(loggerLevel));
603
for (Level messageLevel : Level.values()) {
604
String desc = "logger.log(messageLevel, foo): loggerLevel="
605
+ loggerLevel+", messageLevel="+messageLevel;
606
607
LogEvent expected =
608
LogEvent.of(
609
sequencer.get(),
610
messageLevel.compareTo(loggerLevel) >= 0,
611
name, mapToJul(messageLevel), (ResourceBundle)null,
612
fooMsg, (Throwable)null, (Object[])null);
613
logger.log(messageLevel, foo);
614
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
615
if (eventQueue.poll() != null) {
616
throw new RuntimeException("unexpected event in queue for " + desc);
617
}
618
} else {
619
LogEvent actual = eventQueue.poll();
620
if (!expected.equals(actual)) {
621
throw new RuntimeException("mismatch for " + desc
622
+ "\n\texpected=" + expected
623
+ "\n\t actual=" + actual);
624
} else {
625
verbose("Got expected results for "
626
+ desc + "\n\t" + expected);
627
}
628
}
629
}
630
}
631
632
String msg = "blah";
633
for (Level loggerLevel : Level.values()) {
634
setLevel(sink, mapToJul(loggerLevel));
635
for (Level messageLevel : Level.values()) {
636
String desc = "logger.log(messageLevel, \"blah\"): loggerLevel="
637
+ loggerLevel+", messageLevel="+messageLevel;
638
LogEvent expected =
639
LogEvent.of(
640
sequencer.get(),
641
messageLevel.compareTo(loggerLevel) >= 0 && loggerLevel != Level.OFF,
642
name, mapToJul(messageLevel), loggerBundle,
643
msg, (Throwable)null, (Object[])null);
644
logger.log(messageLevel, msg);
645
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
646
if (eventQueue.poll() != null) {
647
throw new RuntimeException("unexpected event in queue for " + desc);
648
}
649
} else {
650
LogEvent actual = eventQueue.poll();
651
if (!expected.equals(actual)) {
652
throw new RuntimeException("mismatch for " + desc
653
+ "\n\texpected=" + expected
654
+ "\n\t actual=" + actual);
655
} else {
656
verbose("Got expected results for "
657
+ desc + "\n\t" + expected);
658
}
659
}
660
}
661
}
662
663
Supplier<String> fooSupplier = new Supplier<String>() {
664
@Override
665
public String get() {
666
return this.toString();
667
}
668
};
669
670
for (Level loggerLevel : Level.values()) {
671
setLevel(sink, mapToJul(loggerLevel));
672
for (Level messageLevel : Level.values()) {
673
String desc = "logger.log(messageLevel, fooSupplier): loggerLevel="
674
+ loggerLevel+", messageLevel="+messageLevel;
675
LogEvent expected =
676
LogEvent.of(
677
sequencer.get(),
678
messageLevel.compareTo(loggerLevel) >= 0,
679
name, mapToJul(messageLevel), (ResourceBundle)null,
680
fooSupplier.get(),
681
(Throwable)null, (Object[])null);
682
logger.log(messageLevel, fooSupplier);
683
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
684
if (eventQueue.poll() != null) {
685
throw new RuntimeException("unexpected event in queue for " + desc);
686
}
687
} else {
688
LogEvent actual = eventQueue.poll();
689
if (!expected.equals(actual)) {
690
throw new RuntimeException("mismatch for " + desc
691
+ "\n\texpected=" + expected
692
+ "\n\t actual=" + actual);
693
} else {
694
verbose("Got expected results for "
695
+ desc + "\n\t" + expected);
696
}
697
}
698
}
699
}
700
701
String format = "two params [{1} {2}]";
702
Object arg1 = foo;
703
Object arg2 = msg;
704
for (Level loggerLevel : Level.values()) {
705
setLevel(sink, mapToJul(loggerLevel));
706
for (Level messageLevel : Level.values()) {
707
String desc = "logger.log(messageLevel, format, params...): loggerLevel="
708
+ loggerLevel+", messageLevel="+messageLevel;
709
LogEvent expected =
710
LogEvent.of(
711
sequencer.get(),
712
messageLevel.compareTo(loggerLevel) >= 0 && loggerLevel != Level.OFF,
713
name, mapToJul(messageLevel), loggerBundle,
714
format, (Throwable)null, new Object[] {arg1, arg2});
715
logger.log(messageLevel, format, arg1, arg2);
716
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
717
if (eventQueue.poll() != null) {
718
throw new RuntimeException("unexpected event in queue for " + desc);
719
}
720
} else {
721
LogEvent actual = eventQueue.poll();
722
if (!expected.equals(actual)) {
723
throw new RuntimeException("mismatch for " + desc
724
+ "\n\texpected=" + expected
725
+ "\n\t actual=" + actual);
726
} else {
727
verbose("Got expected results for "
728
+ desc + "\n\t" + expected);
729
}
730
}
731
}
732
}
733
734
Throwable thrown = new Exception("OK: log me!");
735
for (Level loggerLevel : Level.values()) {
736
setLevel(sink, mapToJul(loggerLevel));
737
for (Level messageLevel : Level.values()) {
738
String desc = "logger.log(messageLevel, \"blah\", thrown): loggerLevel="
739
+ loggerLevel+", messageLevel="+messageLevel;
740
LogEvent expected =
741
LogEvent.of(
742
sequencer.get(),
743
messageLevel.compareTo(loggerLevel) >= 0 && loggerLevel != Level.OFF,
744
name, mapToJul(messageLevel), loggerBundle,
745
msg, thrown, (Object[]) null);
746
logger.log(messageLevel, msg, thrown);
747
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
748
if (eventQueue.poll() != null) {
749
throw new RuntimeException("unexpected event in queue for " + desc);
750
}
751
} else {
752
LogEvent actual = eventQueue.poll();
753
if (!expected.equals(actual)) {
754
throw new RuntimeException("mismatch for " + desc
755
+ "\n\texpected=" + expected
756
+ "\n\t actual=" + actual);
757
} else {
758
verbose("Got expected results for "
759
+ desc + "\n\t" + expected);
760
}
761
}
762
}
763
}
764
765
766
for (Level loggerLevel : Level.values()) {
767
setLevel(sink, mapToJul(loggerLevel));
768
for (Level messageLevel : Level.values()) {
769
String desc = "logger.log(messageLevel, thrown, fooSupplier): loggerLevel="
770
+ loggerLevel+", messageLevel="+messageLevel;
771
LogEvent expected =
772
LogEvent.of(
773
sequencer.get(),
774
messageLevel.compareTo(loggerLevel) >= 0,
775
name, mapToJul(messageLevel), (ResourceBundle)null,
776
fooSupplier.get(),
777
(Throwable)thrown, (Object[])null);
778
logger.log(messageLevel, fooSupplier, thrown);
779
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
780
if (eventQueue.poll() != null) {
781
throw new RuntimeException("unexpected event in queue for " + desc);
782
}
783
} else {
784
LogEvent actual = eventQueue.poll();
785
if (!expected.equals(actual)) {
786
throw new RuntimeException("mismatch for " + desc
787
+ "\n\texpected=" + expected
788
+ "\n\t actual=" + actual);
789
} else {
790
verbose("Got expected results for "
791
+ desc + "\n\t" + expected);
792
}
793
}
794
}
795
}
796
797
ResourceBundle bundle = ResourceBundle.getBundle(MyBundle.class.getName());
798
for (Level loggerLevel : Level.values()) {
799
setLevel(sink, mapToJul(loggerLevel));
800
for (Level messageLevel : Level.values()) {
801
String desc = "logger.log(messageLevel, bundle, format, params...): loggerLevel="
802
+ loggerLevel+", messageLevel="+messageLevel;
803
LogEvent expected =
804
LogEvent.of(
805
sequencer.get(),
806
messageLevel.compareTo(loggerLevel) >= 0 && loggerLevel != Level.OFF,
807
name, mapToJul(messageLevel), bundle,
808
format, (Throwable)null, new Object[] {foo, msg});
809
logger.log(messageLevel, bundle, format, foo, msg);
810
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
811
if (eventQueue.poll() != null) {
812
throw new RuntimeException("unexpected event in queue for " + desc);
813
}
814
} else {
815
LogEvent actual = eventQueue.poll();
816
if (!expected.equals(actual)) {
817
throw new RuntimeException("mismatch for " + desc
818
+ "\n\texpected=" + expected
819
+ "\n\t actual=" + actual);
820
} else {
821
verbose("Got expected results for "
822
+ desc + "\n\t" + expected);
823
}
824
}
825
}
826
}
827
828
for (Level loggerLevel : Level.values()) {
829
setLevel(sink, mapToJul(loggerLevel));
830
for (Level messageLevel : Level.values()) {
831
String desc = "logger.log(messageLevel, bundle, \"blah\", thrown): loggerLevel="
832
+ loggerLevel+", messageLevel="+messageLevel;
833
LogEvent expected =
834
LogEvent.of(
835
sequencer.get(),
836
messageLevel.compareTo(loggerLevel) >= 0 && loggerLevel != Level.OFF,
837
name, mapToJul(messageLevel), bundle,
838
msg, thrown, (Object[]) null);
839
logger.log(messageLevel, bundle, msg, thrown);
840
if (loggerLevel == Level.OFF || messageLevel.compareTo(loggerLevel) < 0) {
841
if (eventQueue.poll() != null) {
842
throw new RuntimeException("unexpected event in queue for " + desc);
843
}
844
} else {
845
LogEvent actual = eventQueue.poll();
846
if (!expected.equals(actual)) {
847
throw new RuntimeException("mismatch for " + desc
848
+ "\n\texpected=" + expected
849
+ "\n\t actual=" + actual);
850
} else {
851
verbose("Got expected results for "
852
+ desc + "\n\t" + expected);
853
}
854
}
855
}
856
}
857
}
858
859
final static class PermissionsBuilder {
860
final Permissions perms;
861
public PermissionsBuilder() {
862
this(new Permissions());
863
}
864
public PermissionsBuilder(Permissions perms) {
865
this.perms = perms;
866
}
867
public PermissionsBuilder add(Permission p) {
868
perms.add(p);
869
return this;
870
}
871
public PermissionsBuilder addAll(PermissionCollection col) {
872
if (col != null) {
873
for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
874
perms.add(e.nextElement());
875
}
876
}
877
return this;
878
}
879
public Permissions toPermissions() {
880
final PermissionsBuilder builder = new PermissionsBuilder();
881
builder.addAll(perms);
882
return builder.perms;
883
}
884
}
885
886
public static class SimplePolicy extends Policy {
887
888
static final Policy DEFAULT_POLICY = Policy.getPolicy();
889
890
static final RuntimePermission LOGGERFINDER_PERMISSION =
891
new RuntimePermission("loggerFinder");
892
final Permissions permissions;
893
final Permissions allPermissions;
894
final Permissions controlPermissions;
895
final ThreadLocal<AtomicBoolean> allowControl;
896
final ThreadLocal<AtomicBoolean> allowAll;
897
public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl, ThreadLocal<AtomicBoolean> allowAll) {
898
this.allowControl = allowControl;
899
this.allowAll = allowAll;
900
permissions = new Permissions();
901
902
// these are used for configuring the test itself...
903
controlPermissions = new Permissions();
904
controlPermissions.add(LOGGERFINDER_PERMISSION);
905
allPermissions = new Permissions();
906
allPermissions.add(new java.security.AllPermission());
907
908
}
909
910
@Override
911
public boolean implies(ProtectionDomain domain, Permission permission) {
912
if (allowAll.get().get()) return allPermissions.implies(permission);
913
if (allowControl.get().get()) return controlPermissions.implies(permission);
914
return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
915
}
916
917
@Override
918
public PermissionCollection getPermissions(CodeSource codesource) {
919
return new PermissionsBuilder().addAll(allowAll.get().get()
920
? allPermissions : allowControl.get().get()
921
? controlPermissions : permissions).toPermissions();
922
}
923
924
@Override
925
public PermissionCollection getPermissions(ProtectionDomain domain) {
926
return new PermissionsBuilder().addAll(allowAll.get().get()
927
? allPermissions : allowControl.get().get()
928
? controlPermissions : permissions).toPermissions();
929
}
930
}
931
}
932
933