View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.classic.pattern;
15  
16  import ch.qos.logback.classic.Level;
17  import ch.qos.logback.classic.Logger;
18  import ch.qos.logback.classic.LoggerContext;
19  import ch.qos.logback.classic.PatternLayout;
20  import ch.qos.logback.classic.spi.ILoggingEvent;
21  import ch.qos.logback.classic.spi.LoggingEvent;
22  
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  
26  import java.io.PrintWriter;
27  import java.io.StringWriter;
28  import java.util.regex.Matcher;
29  import java.util.regex.Pattern;
30  
31  import static ch.qos.logback.classic.util.TestHelper.makeNestedException;
32  import static ch.qos.logback.classic.util.TestHelper.positionOf;
33  import static org.assertj.core.api.Assertions.assertThat;
34  
35  /**
36   * @author Tomasz Nurkiewicz
37   * @since 2010-08-15, 18:34:21
38   */
39  public class RootCauseFirstThrowableProxyConverterTest {
40  
41      private LoggerContext context = new LoggerContext();
42      private ThrowableProxyConverter converter = new RootCauseFirstThrowableProxyConverter();
43      private StringWriter stringWriter = new StringWriter();
44      private PrintWriter printWriter = new PrintWriter(stringWriter);
45  
46      @BeforeEach
47      public void setUp() throws Exception {
48          converter.setContext(context);
49          converter.start();
50      }
51  
52      private ILoggingEvent createLoggingEvent(Throwable t) {
53          return new LoggingEvent(this.getClass().getName(), context.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG,
54                  "test message", t, null);
55      }
56  
57      @Test
58      public void integration() {
59          // given
60          context.setPackagingDataEnabled(true);
61          PatternLayout pl = new PatternLayout();
62          pl.setContext(context);
63          pl.setPattern("%m%rEx%n");
64          pl.start();
65  
66          // when
67          ILoggingEvent e = createLoggingEvent(new Exception("x"));
68          String result = pl.doLayout(e);
69  
70          // then
71          // make sure that at least some package data was output
72          Pattern p = Pattern.compile("\\s*at .*?\\[.*?\\]");
73          Matcher m = p.matcher(result);
74          int i = 0;
75          while (m.find()) {
76              i++;
77          }
78          assertThat(i).isGreaterThan(5);
79      }
80  
81      @Test
82      public void smoke() {
83          // given
84          Exception exception = new Exception("smoke");
85          exception.printStackTrace(printWriter);
86  
87          // when
88          ILoggingEvent le = createLoggingEvent(exception);
89          String result = converter.convert(le);
90  
91          // then
92          result = result.replace("common frames omitted", "more");
93          result = result.replaceAll(" ~?\\[.*\\]", "");
94          assertThat(result).isEqualTo(stringWriter.toString());
95      }
96  
97      @Test
98      public void nested() {
99          // given
100         Throwable nestedException = makeNestedException(2);
101         nestedException.printStackTrace(printWriter);
102 
103         // when
104         ILoggingEvent le = createLoggingEvent(nestedException);
105         String result = converter.convert(le);
106 
107         // then
108         assertThat(result).startsWith("java.lang.Exception: nesting level=0");
109         assertThat(positionOf("nesting level=0").in(result)).isLessThan(positionOf("nesting level =1").in(result));
110         assertThat(positionOf("nesting level =1").in(result)).isLessThan(positionOf("nesting level =2").in(result));
111     }
112 
113     @Test
114     public void cyclicCause() {
115         Exception e = new Exception("foo");
116         Exception e2 = new Exception(e);
117         e.initCause(e2);
118         ILoggingEvent le = createLoggingEvent(e);
119         String result = converter.convert(le);
120 
121         assertThat(result).startsWith("[CIRCULAR REFERENCE: java.lang.Exception: foo]");
122     }
123 
124     @Test
125     public void cyclicSuppressed() {
126         Exception e = new Exception("foo");
127         Exception e2 = new Exception(e);
128         e.addSuppressed(e2);
129         ILoggingEvent le = createLoggingEvent(e);
130         String result = converter.convert(le);
131 
132         assertThat(result).startsWith("java.lang.Exception: foo");
133         String circular = "Suppressed: [CIRCULAR REFERENCE: java.lang.Exception: foo]";
134         String wrapped = "Wrapped by: java.lang.Exception: java.lang.Exception: foo";
135 
136         assertThat(positionOf(circular).in(result)).isLessThan(positionOf(wrapped).in(result));
137     }
138 
139 }