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.spi;
15  
16  import ch.qos.logback.core.util.EnvUtil;
17  import org.junit.jupiter.api.AfterEach;
18  import org.junit.jupiter.api.BeforeEach;
19  import org.junit.jupiter.api.Test;
20  
21  import java.io.PrintWriter;
22  import java.io.StringWriter;
23  import java.lang.reflect.InvocationTargetException;
24  
25  import static org.junit.jupiter.api.Assertions.assertEquals;
26  
27  public class ThrowableProxyTest {
28  
29      StringWriter sw = new StringWriter();
30      PrintWriter pw = new PrintWriter(sw);
31  
32      @BeforeEach
33      public void setUp() throws Exception {
34      }
35  
36      @AfterEach
37      public void tearDown() throws Exception {
38      }
39  
40      // compares Throwable.printStackTrace with output by ThrowableProxy
41      public void verify(Throwable t) {
42          t.printStackTrace(pw);
43  
44          IThrowableProxy tp = new ThrowableProxy(t);
45  
46          String result = ThrowableProxyUtil.asString(tp);
47          result = result.replace("common frames omitted", "more");
48          String expected = sw.toString();
49  
50  //         System.out.println("========expected");
51  //         System.out.println(expected);
52  //
53  //         System.out.println("========result");
54  //         System.out.println(result);
55  
56          assertEquals(expected, result);
57      }
58  
59      @Test
60      public void smoke() {
61          Exception e = new Exception("smoke");
62          verify(e);
63      }
64  
65      @Test
66      public void nested() {
67          Exception w = null;
68          try {
69              someMethod();
70          } catch (Exception e) {
71              w = new Exception("wrapping", e);
72          }
73          verify(w);
74      }
75  
76      @Test
77      public void suppressed() throws InvocationTargetException, IllegalAccessException {
78          Exception ex = null;
79          try {
80              someMethod();
81          } catch (Exception e) {
82              Exception fooException = new Exception("Foo");
83              Exception barException = new Exception("Bar");
84              e.addSuppressed(fooException);
85              e.addSuppressed(barException);
86  
87              ex = e;
88          }
89          verify(ex);
90      }
91  
92      @Test
93      public void suppressedWithCause() throws InvocationTargetException, IllegalAccessException {
94          // sense.
95          Exception ex = null;
96          try {
97              someMethod();
98          } catch (Exception e) {
99              ex = new Exception("Wrapper", e);
100             Exception fooException = new Exception("Foo");
101             Exception barException = new Exception("Bar");
102 
103             ex.addSuppressed(fooException);
104             e.addSuppressed(barException);
105 
106         }
107         verify(ex);
108     }
109 
110     @Test
111     public void suppressedWithSuppressed() throws Exception {
112         Exception ex = null;
113         try {
114             someMethod();
115         } catch (Exception e) {
116             ex = new Exception("Wrapper", e);
117             Exception fooException = new Exception("Foo");
118             Exception barException = new Exception("Bar");
119             barException.addSuppressed(fooException);
120             e.addSuppressed(barException);
121 
122         }
123         verify(ex);
124     }
125 
126     // see also https://jira.qos.ch/browse/LOGBACK-453
127     @Test
128     public void nullSTE() {
129         Throwable t = new Exception("someMethodWithNullException") {
130             private static final long serialVersionUID = 1L;
131 
132             @Override
133             public StackTraceElement[] getStackTrace() {
134                 return null;
135             }
136         };
137         // we can't test output as Throwable.printStackTrace method uses
138         // the private getOurStackTrace method instead of getStackTrace
139 
140         // tests ThrowableProxyUtil.steArrayToStepArray
141         new ThrowableProxy(t);
142 
143         // tests ThrowableProxyUtil.findNumberOfCommonFrames
144         Exception top = new Exception("top", t);
145         new ThrowableProxy(top);
146     }
147 
148     @Test
149     public void multiNested() {
150         Exception w = null;
151         try {
152             someOtherMethod();
153         } catch (Exception e) {
154             w = new Exception("wrapping", e);
155         }
156         verify(w);
157     }
158 
159     // see also https://jira.qos.ch/browse/LOGBACK-1454
160     @Test
161     public void cyclicCause() {
162         // Earlier JDKs may format things differently
163         if (!EnvUtil.isJDK16OrHigher())
164             return;
165         Exception e = new Exception("foo");
166         Exception e2 = new Exception(e);
167         e.initCause(e2);
168         verify(e);
169     }
170 
171     // see also https://jira.qos.ch/browse/LOGBACK-1454
172     @Test
173     public void cyclicSuppressed() {
174         // Earlier JDKs may format things differently
175         if (!EnvUtil.isJDK16OrHigher())
176             return;
177         Exception e = new Exception("foo");
178         Exception e2 = new Exception(e);
179         e.addSuppressed(e2);
180         verify(e);
181     }
182 
183     @Test
184     public void overriddenToString() {
185         Exception e = new Exception() {
186             public String toString() {
187                 return getClass().getName() + " [extra]";
188             }
189         };
190         verify(e);
191     }
192 
193     void someMethod() throws Exception {
194         throw new Exception("someMethod");
195     }
196 
197     void someMethodWithNullException() throws Exception {
198         throw new Exception("someMethodWithNullException") {
199             private static final long serialVersionUID = -2419053636101615373L;
200 
201             @Override
202             public StackTraceElement[] getStackTrace() {
203                 return null;
204             }
205         };
206     }
207 
208     void someOtherMethod() throws Exception {
209         try {
210             someMethod();
211         } catch (Exception e) {
212             throw new Exception("someOtherMethod", e);
213         }
214     }
215 
216 
217 }