1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.joran;
15
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertFalse;
18 import static org.junit.Assert.assertNotNull;
19 import static org.junit.Assert.assertNull;
20 import static org.junit.Assert.assertTrue;
21
22 import java.io.IOException;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25
26 import org.junit.Ignore;
27 import org.junit.Test;
28 import org.slf4j.MDC;
29 import org.slf4j.event.KeyValuePair;
30
31 import ch.qos.logback.classic.AsyncAppender;
32 import ch.qos.logback.classic.ClassicTestConstants;
33 import ch.qos.logback.classic.Level;
34 import ch.qos.logback.classic.Logger;
35 import ch.qos.logback.classic.LoggerContext;
36 import ch.qos.logback.classic.jul.JULHelper;
37 import ch.qos.logback.classic.spi.ILoggingEvent;
38 import ch.qos.logback.classic.turbo.DebugUsersTurboFilter;
39 import ch.qos.logback.classic.turbo.NOPTurboFilter;
40 import ch.qos.logback.classic.turbo.TurboFilter;
41 import ch.qos.logback.core.ConsoleAppender;
42 import ch.qos.logback.core.CoreConstants;
43 import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
44 import ch.qos.logback.core.joran.action.ParamAction;
45 import ch.qos.logback.core.joran.spi.ActionException;
46 import ch.qos.logback.core.joran.spi.JoranException;
47 import ch.qos.logback.core.pattern.parser.Parser;
48 import ch.qos.logback.core.read.ListAppender;
49 import ch.qos.logback.core.spi.ErrorCodes;
50 import ch.qos.logback.core.spi.ScanException;
51 import ch.qos.logback.core.status.Status;
52 import ch.qos.logback.core.testUtil.RandomUtil;
53 import ch.qos.logback.core.testUtil.StatusChecker;
54 import ch.qos.logback.core.testUtil.StringListAppender;
55 import ch.qos.logback.core.util.CachingDateFormatter;
56 import ch.qos.logback.core.util.StatusPrinter;
57
58 public class JoranConfiguratorTest {
59
60 LoggerContext loggerContext = new LoggerContext();
61 Logger logger = loggerContext.getLogger(this.getClass().getName());
62 Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
63 StatusChecker checker = new StatusChecker(loggerContext);
64 int diff = RandomUtil.getPositiveInt();
65
66 void configure(String file) throws JoranException {
67 JoranConfigurator jc = new JoranConfigurator();
68 jc.setContext(loggerContext);
69 loggerContext.putProperty("diff", "" + diff);
70 jc.doConfigure(file);
71
72 }
73
74 @Test
75 public void simpleList() throws JoranException {
76 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleList.xml");
77 Logger logger = loggerContext.getLogger(this.getClass().getName());
78 Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
79 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
80 assertNotNull(listAppender);
81 assertEquals(0, listAppender.list.size());
82 String msg = "hello world";
83 logger.debug(msg);
84 assertEquals(1, listAppender.list.size());
85 ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
86 assertEquals(msg, le.getMessage());
87 }
88
89
90 @Test
91 public void asyncWithMultipleAppendersInRoot() throws JoranException {
92 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "async/logback_1614.xml");
93 Logger logger = loggerContext.getLogger(this.getClass().getName());
94 Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
95 AsyncAppender asyncAppender = (AsyncAppender) root.getAppender("ASYNC");
96 assertNotNull(asyncAppender);
97 ConsoleAppender<ILoggingEvent> console = (ConsoleAppender<ILoggingEvent>) root.getAppender("CONSOLE");
98 assertNotNull(console);
99 assertTrue(console.isStarted());
100
101 String msg = "hello world";
102 logger.warn(msg);
103 StatusPrinter.print(loggerContext);
104 }
105
106 @Test
107 public void simpleListWithImports() throws JoranException {
108 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleListWithImports.xml");
109 Logger logger = loggerContext.getLogger(this.getClass().getName());
110 Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
111 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
112 assertNotNull(listAppender);
113 assertEquals(0, listAppender.list.size());
114 String msg = "hello world";
115 logger.debug(msg);
116 assertEquals(1, listAppender.list.size());
117 ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
118 assertEquals(msg, le.getMessage());
119 }
120
121 @Test
122 public void level() throws JoranException {
123 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleLevel.xml");
124 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
125 assertEquals(0, listAppender.list.size());
126 String msg = "hello world";
127 logger.debug(msg);
128 assertEquals(0, listAppender.list.size());
129 }
130
131 @Test
132 public void additivity() throws JoranException {
133 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "additivity.xml");
134 Logger logger = loggerContext.getLogger("additivityTest");
135 assertFalse(logger.isAdditive());
136 }
137
138 @Test
139 public void rootLoggerLevelSettingBySystemProperty() throws JoranException {
140 String propertyName = "logback.level";
141
142 System.setProperty(propertyName, "INFO");
143 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "rootLevelByProperty.xml");
144
145 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
146 assertEquals(0, listAppender.list.size());
147 String msg = "hello world";
148 logger.debug(msg);
149 assertEquals(0, listAppender.list.size());
150 System.clearProperty(propertyName);
151 }
152
153 @Test
154 public void loggerLevelSettingBySystemProperty() throws JoranException {
155 String propertyName = "logback.level";
156 System.setProperty(propertyName, "DEBUG");
157 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "loggerLevelByProperty.xml");
158 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
159 assertEquals(0, listAppender.list.size());
160 String msg = "hello world";
161 logger.debug(msg);
162 assertEquals(1, listAppender.list.size());
163 System.clearProperty(propertyName);
164 }
165
166 @Test
167 public void appenderRefSettingBySystemProperty() throws JoranException {
168 final String propertyName = "logback.appenderRef";
169 System.setProperty(propertyName, "A");
170 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "appenderRefByProperty.xml");
171 final Logger logger = loggerContext.getLogger("ch.qos.logback.classic.joran");
172 final ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) logger.getAppender("A");
173 assertEquals(0, listAppender.list.size());
174 final String msg = "hello world";
175 logger.info(msg);
176
177 assertEquals(1, listAppender.list.size());
178 System.clearProperty(propertyName);
179 }
180
181 @Test
182 public void statusListener() throws JoranException {
183 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "statusListener.xml");
184 checker.assertIsErrorFree();
185 checker.assertContainsMatch(Status.WARN,
186 "Please use \"level\" attribute within <logger> or <root> elements instead.");
187 }
188
189 @Test
190 public void statusListenerWithImports() throws JoranException {
191 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "statusListenerWithImports.xml");
192
193 checker.assertIsErrorFree();
194 checker.assertContainsMatch(Status.WARN,
195 "Please use \"level\" attribute within <logger> or <root> elements instead.");
196 }
197
198 @Test
199 public void contextRename() throws JoranException {
200 loggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
201 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "contextRename.xml");
202 assertEquals("wombat", loggerContext.getName());
203 }
204
205 @Test
206 public void eval() throws JoranException {
207 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "callerData.xml");
208 String msg = "hello world";
209 logger.debug("toto");
210 logger.debug(msg);
211
212 StringListAppender<ILoggingEvent> slAppender = (StringListAppender<ILoggingEvent>) loggerContext
213 .getLogger("root").getAppender("STR_LIST");
214 assertNotNull(slAppender);
215 assertEquals(2, slAppender.strList.size());
216 assertTrue(slAppender.strList.get(0).contains(" DEBUG - toto"));
217
218 String str1 = slAppender.strList.get(1);
219 assertTrue(str1.contains("Caller+0"));
220 assertTrue(str1.contains(" DEBUG - hello world"));
221 }
222
223
224 @Test
225 public void missingConfigurationElement() throws JoranException {
226 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ossfuzz/noConfig.xml");
227
228 String msg1 = "Exception in body\\(\\) method for action \\["+ParamAction.class.getName()+"\\]";
229 checker.assertContainsMatch(Status.ERROR, msg1);
230
231 String msg2 = "current model is null. Is <configuration> element missing?";
232 checker.assertContainsException(ActionException.class, msg2 );
233 }
234
235 @Test
236 public void ignoreUnknownProperty() throws JoranException {
237
238 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ossfuzz/unknownProperty.xml");
239 String msg = "Ignoring unkown property \\[a\\] in \\[ch.qos.logback.classic.LoggerContext\\]";
240 checker.assertContainsMatch(Status.WARN, msg);
241 }
242
243
244 @Test
245 public void complexCollectionWihhNoKnownClass() throws JoranException {
246
247 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ossfuzz/nestedComplexWithNoKnownClass.xml");
248 String msg = "Could not find an appropriate class for property \\[listener\\]";
249 checker.assertContainsMatch(Status.ERROR, msg);
250 }
251
252 @Test
253 public void turboFilter() throws JoranException {
254
255
256
257 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo.xml");
258
259 TurboFilter filter = loggerContext.getTurboFilterList().get(0);
260 assertTrue(filter instanceof NOPTurboFilter);
261 }
262
263 @Test
264 public void testTurboFilterWithStringList() throws JoranException {
265
266
267
268
269 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo2.xml");
270
271
272
273 TurboFilter filter = loggerContext.getTurboFilterList().get(0);
274 assertTrue(filter instanceof DebugUsersTurboFilter);
275 DebugUsersTurboFilter dutf = (DebugUsersTurboFilter) filter;
276 assertEquals(2, dutf.getUsers().size());
277 }
278
279 @Test
280 public void testLevelFilter() throws JoranException {
281 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "levelFilter.xml");
282
283
284
285 logger.warn("hello");
286 logger.error("to be ignored");
287
288 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
289
290 assertNotNull(listAppender);
291 assertEquals(1, listAppender.list.size());
292 ILoggingEvent back = listAppender.list.get(0);
293 assertEquals(Level.WARN, back.getLevel());
294 assertEquals("hello", back.getMessage());
295 }
296
297 @Test
298 public void testEvaluatorFilter() throws JoranException {
299 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "evaluatorFilter.xml");
300
301
302
303 logger.warn("hello");
304 logger.error("to be ignored");
305
306 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
307
308 assertNotNull(listAppender);
309 assertEquals(1, listAppender.list.size());
310 ILoggingEvent back = listAppender.list.get(0);
311 assertEquals(Level.WARN, back.getLevel());
312 assertEquals("hello", back.getMessage());
313 }
314
315 @Test
316 public void testEvaluatorFilterWithImports() throws JoranException {
317 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "evaluatorFilterWithImports.xml");
318
319
320
321 logger.warn("hello");
322 logger.error("to be ignored");
323
324 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
325
326 assertNotNull(listAppender);
327 assertEquals(1, listAppender.list.size());
328 ILoggingEvent back = listAppender.list.get(0);
329 assertEquals(Level.WARN, back.getLevel());
330 assertEquals("hello", back.getMessage());
331 }
332
333 @Test
334 public void testTurboDynamicThreshold() throws JoranException {
335 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turboDynamicThreshold.xml");
336
337 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
338 assertEquals(0, listAppender.list.size());
339
340
341 MDC.put("userId", "user1");
342 logger.debug("hello user1");
343
344 MDC.put("userId", "user2");
345 logger.debug("hello user2");
346
347 assertEquals(1, listAppender.list.size());
348 ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
349 assertEquals("hello user2", le.getMessage());
350 }
351
352 @Test
353 public void testTurboDynamicThreshold2() throws JoranException {
354
355 try {
356 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turboDynamicThreshold2.xml");
357 } finally {
358
359 }
360 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
361 assertEquals(0, listAppender.list.size());
362
363
364 MDC.put("userId", "user1");
365 logger.debug("hello user1");
366
367 MDC.put("userId", "user2");
368 logger.debug("hello user2");
369
370 MDC.put("userId", "user3");
371 logger.debug("hello user3");
372
373 assertEquals(2, listAppender.list.size());
374 ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
375 assertEquals("hello user1", le.getMessage());
376 le = (ILoggingEvent) listAppender.list.get(1);
377 assertEquals("hello user2", le.getMessage());
378 }
379
380 @Test
381 public void timestamp() throws JoranException, IOException, InterruptedException {
382
383 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "timestamp-context.xml";
384 configure(configFileAsStr);
385
386 String r = loggerContext.getProperty("testTimestamp");
387 assertNotNull(r);
388 CachingDateFormatter sdf = new CachingDateFormatter("yyyy-MM");
389 String expected = sdf.format(System.currentTimeMillis());
390 assertEquals("expected \"" + expected + "\" but got " + r, expected, r);
391 }
392
393 @Test
394 public void timestampLocal() throws JoranException, IOException, InterruptedException {
395
396 String sysProp = "ch.qos.logback.classic.joran.JoranConfiguratorTest.timestampLocal";
397 System.setProperty(sysProp, "");
398
399 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "timestamp-local.xml";
400 configure(configFileAsStr);
401
402
403
404
405
406
407 String r = loggerContext.getProperty("testTimestamp");
408 assertNull(r);
409
410 String expected = "today is " + new SimpleDateFormat("yyyy-MM").format(new Date());
411 String sysPropValue = System.getProperty(sysProp);
412 assertEquals(expected, sysPropValue);
413 }
414
415 @Test
416 public void encoderCharset() throws JoranException, IOException, InterruptedException {
417
418 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "encoderCharset.xml";
419 configure(configFileAsStr);
420
421 ConsoleAppender<ILoggingEvent> consoleAppender = (ConsoleAppender<ILoggingEvent>) root.getAppender("CONSOLE");
422 assertNotNull(consoleAppender);
423 LayoutWrappingEncoder<ILoggingEvent> encoder = (LayoutWrappingEncoder<ILoggingEvent>) consoleAppender
424 .getEncoder();
425
426 assertEquals("UTF-8", encoder.getCharset().displayName());
427
428 checker.assertIsErrorFree();
429 }
430
431 void verifyJULLevel(String loggerName, Level expectedLevel) {
432 java.util.logging.Logger julLogger = JULHelper.asJULLogger(loggerName);
433 java.util.logging.Level julLevel = julLogger.getLevel();
434
435 if (expectedLevel == null) {
436 assertNull(julLevel);
437 } else {
438 assertEquals(JULHelper.asJULLevel(expectedLevel), julLevel);
439 }
440
441 }
442
443 @Test
444 public void levelChangePropagator0() throws JoranException, IOException, InterruptedException {
445 String loggerName = "changePropagator0" + diff;
446 java.util.logging.Logger.getLogger(loggerName).setLevel(java.util.logging.Level.INFO);
447 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/jul/levelChangePropagator0.xml";
448 configure(configFileAsStr);
449
450 checker.assertIsErrorFree();
451 verifyJULLevel(loggerName, null);
452 verifyJULLevel("a.b.c." + diff, Level.WARN);
453 verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
454 }
455
456 @Test
457 public void levelChangePropagator1() throws JoranException, IOException, InterruptedException {
458 String loggerName = "changePropagator1" + diff;
459 java.util.logging.Logger logger1 = java.util.logging.Logger.getLogger(loggerName);
460 logger1.setLevel(java.util.logging.Level.INFO);
461 verifyJULLevel(loggerName, Level.INFO);
462 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/jul/levelChangePropagator1.xml";
463 configure(configFileAsStr);
464
465 checker.assertIsErrorFree();
466 verifyJULLevel(loggerName, Level.INFO);
467 verifyJULLevel("a.b.c." + diff, Level.WARN);
468 verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
469 }
470
471 @Test
472 @Ignore
473 public void onConsoleRetro() throws JoranException, IOException, InterruptedException {
474 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/onConsoleRetro.xml";
475 configure(configFileAsStr);
476 Thread.sleep(400);
477
478 loggerContext.reset();
479 configure(configFileAsStr);
480 }
481
482 @Test
483 public void unreferencedAppenderShouldNotTriggerUnknownPropertyMessages() throws JoranException {
484 String configFileAsStr = ClassicTestConstants.ISSUES_PREFIX + "/logback1572.xml";
485 configure(configFileAsStr);
486 checker.assertContainsMatch(Status.WARN,
487 "Appender named \\[EMAIL\\] not referenced. Skipping further processing.");
488 checker.assertNoMatch("Ignoring unkown property \\[evaluator\\]");
489 }
490
491 @Test
492 public void LOGBACK_111() throws JoranException {
493 String configFileAsStr = ClassicTestConstants.ISSUES_PREFIX + "lbcore193.xml";
494 configure(configFileAsStr);
495 checker.assertContainsException(ScanException.class);
496 checker.assertContainsMatch(Status.ERROR, "Expecting RIGHT_PARENTHESIS token but got null");
497 checker.assertContainsMatch(Status.ERROR, "See also " + Parser.MISSING_RIGHT_PARENTHESIS);
498 }
499
500 @Test
501 public void properties() throws JoranException {
502 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "properties.xml";
503 assertNull(System.getProperty("sys"));
504
505 configure(configFileAsStr);
506 assertNotNull(loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
507 assertNull(loggerContext.getProperty("transientKey1"));
508 assertNull(loggerContext.getProperty("transientKey2"));
509 assertEquals("node0", loggerContext.getProperty("nodeId"));
510 assertEquals("tem", System.getProperty("sys"));
511 assertNotNull(loggerContext.getProperty("path"));
512 checker.assertIsErrorFree();
513 }
514
515 @Test
516 public void hostnameProperty() throws JoranException {
517 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "hostnameProperty.xml";
518 configure(configFileAsStr);
519 assertEquals("A", loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
520 }
521
522
523 @Test
524 public void sysProps() throws JoranException {
525 System.setProperty("k.lbcore254", ClassicTestConstants.ISSUES_PREFIX + "lbcore254");
526 JoranConfigurator configurator = new JoranConfigurator();
527 configurator.setContext(loggerContext);
528 configurator.doConfigure(ClassicTestConstants.ISSUES_PREFIX + "lbcore254.xml");
529
530 checker.assertIsErrorFree();
531 }
532
533 @Test
534 public void propsWithMissingRightCurlyBrace() throws JoranException {
535 System.setProperty("abc", "not important");
536 JoranConfigurator configurator = new JoranConfigurator();
537 configurator.setContext(loggerContext);
538 configurator.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "propsMissingRightCurlyBrace.xml");
539 checker.assertContainsMatch(Status.ERROR, "Problem while parsing");
540 }
541
542 @Test
543 public void packageDataDisabledByConfigAttribute() throws JoranException {
544 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "packagingDataDisabled.xml";
545 configure(configFileAsStr);
546 assertFalse(loggerContext.isPackagingDataEnabled());
547 }
548
549 @Test
550 public void packageDataEnabledByConfigAttribute() throws JoranException {
551 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "packagingDataEnabled.xml";
552 try {
553 configure(configFileAsStr);
554 } finally {
555
556 }
557 assertTrue(loggerContext.isPackagingDataEnabled());
558 }
559
560 @Test
561 public void valueOfConvention() throws JoranException {
562 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "valueOfConvention.xml";
563 configure(configFileAsStr);
564 checker.assertIsWarningOrErrorFree();
565 }
566
567 @Test
568 public void shutdownHookTest() throws JoranException {
569 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "issues/logback_1162.xml";
570 loggerContext.putProperty("output_dir", ClassicTestConstants.OUTPUT_DIR_PREFIX + "logback_issue_1162/");
571 configure(configFileAsStr);
572 assertNotNull(loggerContext.getObject(CoreConstants.SHUTDOWN_HOOK_THREAD));
573 }
574
575 @Test
576 public void appenderRefBeforeAppenderTest() throws JoranException {
577 String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "appenderRefBeforeAppender.xml";
578 configure(configFileAsStr);
579 Logger logger = loggerContext.getLogger(this.getClass().getName());
580 Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
581 ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
582 assertNotNull(listAppender);
583 assertEquals(0, listAppender.list.size());
584 String msg = "hello world";
585 logger.debug(msg);
586 assertEquals(1, listAppender.list.size());
587 ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
588 assertEquals(msg, le.getMessage());
589 checker.assertIsErrorFree();
590 }
591
592 @Test
593 public void unreferencedAppendersShouldBeSkipped() throws JoranException {
594 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "unreferencedAppender1.xml");
595
596 final ListAppender<ILoggingEvent> listAppenderA = (ListAppender<ILoggingEvent>) root.getAppender("A");
597 assertNotNull(listAppenderA);
598 checker.assertContainsMatch(Status.WARN, "Appender named \\[B\\] not referenced. Skipping further processing.");
599 }
600
601 @Test
602 public void asynAppenderListFirst() throws JoranException {
603 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "asyncAppender_list_first.xml");
604
605 final AsyncAppender asyncAppender = (AsyncAppender) root.getAppender("ASYNC");
606 assertNotNull(asyncAppender);
607 assertTrue(asyncAppender.isStarted());
608 }
609
610 @Test
611 public void asynAppenderListAfter() throws JoranException {
612 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "asyncAppender_list_after.xml");
613
614 final AsyncAppender asyncAppender = (AsyncAppender) root.getAppender("ASYNC");
615 assertNotNull(asyncAppender);
616 assertTrue(asyncAppender.isStarted());
617 }
618
619
620 @Test
621 public void missingPropertyErrorHandling() throws JoranException {
622 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "missingProperty.xml");
623
624 final ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
625 assertNotNull(listAppender);
626 assertTrue(listAppender.isStarted());
627 checker.assertContainsMatch(Status.WARN,
628 "Ignoring unkown property \\[inexistent\\] in \\[ch.qos.logback.core.read.ListAppender\\]");
629 }
630
631 @Test
632 public void kvp() throws JoranException {
633 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "pattern/kvp.xml");
634
635 String msg = "hello kvp";
636
637 KeyValuePair kvp1 = new KeyValuePair("k" + diff, "v" + diff);
638 KeyValuePair kvp2 = new KeyValuePair("k" + (diff + 1), "v" + (diff + 1));
639 KeyValuePair kvpNullKey = new KeyValuePair(null, "v" + (diff + 2));
640 KeyValuePair kvpNullValue = new KeyValuePair("k" + (diff + 3), null);
641
642 logger.atDebug().addKeyValue(kvp1.key, kvp1.value).log(msg);
643 logger.atDebug().addKeyValue(kvp2.key, kvp2.value).log(msg);
644 logger.atDebug().addKeyValue(kvpNullKey.key, kvpNullKey.value).log(msg);
645 logger.atDebug().addKeyValue(kvpNullValue.key, kvpNullValue.value).log(msg);
646
647 StringListAppender<ILoggingEvent> slAppender = (StringListAppender<ILoggingEvent>) loggerContext
648 .getLogger("root").getAppender("LIST");
649 assertNotNull(slAppender);
650 assertEquals(4, slAppender.strList.size());
651 assertTrue(slAppender.strList.get(0).contains(kvp1.key + "=\"" + kvp1.value + "\" " + msg));
652 assertTrue(slAppender.strList.get(1).contains(kvp2.key + "=\"" + kvp2.value + "\" " + msg));
653 assertTrue(slAppender.strList.get(2).contains("null=\"" + kvpNullKey.value + "\" " + msg));
654 assertTrue(slAppender.strList.get(3).contains(kvpNullValue.key + "=\"null\" " + msg));
655 }
656
657
658
659 @Test
660 public void ossFuzz_46697() throws JoranException {
661 System.out.println("==========");
662 configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ossfuzz/fuzz-46697.xml");
663
664 checker.assertContainsMatch(Status.ERROR, ErrorCodes.EMPTY_MODEL_STACK);
665 StatusPrinter.print(loggerContext);
666 }
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695 }