View Javadoc
1   package org.apache.maven.surefire.report;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Field;
23  import java.util.List;
24  import java.util.concurrent.ExecutionException;
25  import java.util.concurrent.FutureTask;
26  
27  import junit.framework.Assert;
28  import junit.framework.AssertionFailedError;
29  import junit.framework.ComparisonFailure;
30  import junit.framework.TestCase;
31  
32  import static org.apache.maven.surefire.report.SmartStackTraceParser.findInnermostWithClass;
33  import static org.apache.maven.surefire.report.SmartStackTraceParser.focusInsideClass;
34  
35  @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" )
36  public class SmartStackTraceParserTest
37      extends TestCase
38  {
39  
40      public void testGetString()
41          throws Exception
42      {
43          ATestClass aTestClass = new ATestClass();
44          try
45          {
46              aTestClass.failInAssert();
47          }
48          catch ( AssertionError e )
49          {
50              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
51              String res = smartStackTraceParser.getString();
52              assertEquals( "ATestClass.failInAssert:30 X is not Z", res );
53  
54          }
55  
56      }
57  
58      public void testNestedFailure()
59          throws Exception
60      {
61          ATestClass aTestClass = new ATestClass();
62          try
63          {
64              aTestClass.nestedFailInAssert();
65          }
66          catch ( AssertionError e )
67          {
68              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
69              String res = smartStackTraceParser.getString();
70              assertEquals( "ATestClass.nestedFailInAssert:35->failInAssert:30 X is not Z", res );
71          }
72      }
73  
74      public void testNestedNpe()
75          throws Exception
76      {
77          ATestClass aTestClass = new ATestClass();
78          try
79          {
80              aTestClass.nestedNpe();
81          }
82          catch ( NullPointerException e )
83          {
84              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
85              String res = smartStackTraceParser.getString();
86              assertEquals( "ATestClass.nestedNpe:45->npe:40 NullPointer It was null", res );
87  
88          }
89      }
90  
91      public void testNestedNpeOutsideTest()
92          throws Exception
93      {
94          ATestClass aTestClass = new ATestClass();
95          try
96          {
97              aTestClass.nestedNpeOutsideTest();
98          }
99          catch ( NullPointerException e )
100         {
101             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
102             String res = smartStackTraceParser.getString();
103             assertEquals( "ATestClass.nestedNpeOutsideTest:55->npeOutsideTest:50 » NullPointer", res );
104 
105         }
106     }
107 
108     public void testLongMessageTruncation()
109         throws Exception
110     {
111         ATestClass aTestClass = new ATestClass();
112         try
113         {
114             aTestClass.aLongTestErrorMessage();
115         }
116         catch ( RuntimeException e )
117         {
118             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
119             String res = smartStackTraceParser.getString();
120             assertEquals( "ATestClass.aLongTestErrorMessage:60 Runtime This message will be truncated, so...", res );
121 
122         }
123     }
124 
125     public void testFailureInBaseClass()
126         throws Exception
127     {
128         ASubClass aTestClass = new ASubClass();
129         try
130         {
131             aTestClass.npe();
132         }
133         catch ( NullPointerException e )
134         {
135             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ASubClass.class, e );
136             String res = smartStackTraceParser.getString();
137             assertEquals( "ASubClass>ABaseClass.npe:27 » NullPointer It was null", res );
138         }
139     }
140 
141     public void testClassThatWillFail()
142         throws Exception
143     {
144         CaseThatWillFail aTestClass = new CaseThatWillFail();
145         try
146         {
147             aTestClass.testThatWillFail();
148         }
149         catch ( ComparisonFailure e )
150         {
151             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( CaseThatWillFail.class, e );
152             String res = smartStackTraceParser.getString();
153             assertEquals( "CaseThatWillFail.testThatWillFail:29 expected:<abc> but was:<def>", res );
154         }
155     }
156 
157     public Throwable getAThrownException()
158     {
159         try
160         {
161             TestClass1.InnerBTestClass.throwSomething();
162         }
163         catch ( Throwable t )
164         {
165             return t;
166         }
167         return null;
168     }
169 
170     public void testCollections()
171     {
172         Throwable aThrownException = getAThrownException();
173 
174         List<StackTraceElement> innerMost =
175             focusInsideClass( aThrownException.getCause().getStackTrace(), TestClass1.InnerBTestClass.class.getName() );
176         assertEquals( 3, innerMost.size() );
177         StackTraceElement inner = innerMost.get( 0 );
178         assertEquals( TestClass2.InnerCTestClass.class.getName(), inner.getClassName() );
179         StackTraceElement outer = innerMost.get( 2 );
180         assertEquals( TestClass1.InnerBTestClass.class.getName(), outer.getClassName() );
181     }
182 
183     public void testAssertionWithNoMessage()
184     {
185         try
186         {
187             new AssertionNoMessage().testThrowSomething();
188         }
189         catch ( ComparisonFailure e )
190         {
191             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( AssertionNoMessage.class, e );
192             String res = smartStackTraceParser.getString();
193             assertEquals( "AssertionNoMessage.testThrowSomething:29 expected:<abc> but was:<xyz>", res );
194         }
195     }
196 
197     public void testFailWithFail()
198     {
199         try
200         {
201             new FailWithFail().testThatWillFail();
202         }
203         catch ( AssertionFailedError e )
204         {
205             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( FailWithFail.class, e );
206             String res = smartStackTraceParser.getString();
207             assertEquals( "FailWithFail.testThatWillFail:29 abc", res );
208         }
209     }
210 
211     public void testCollectorWithNested()
212     {
213         try
214         {
215             InnerATestClass.testFake();
216         }
217         catch ( Throwable t )
218         {
219             List<StackTraceElement> stackTraceElements =
220                 focusInsideClass( t.getStackTrace(), InnerATestClass.class.getName() );
221             assertNotNull( stackTraceElements );
222             assertEquals( 5, stackTraceElements.size() );
223             StackTraceElement innerMost = stackTraceElements.get( 0 );
224             assertEquals( Assert.class.getName(), innerMost.getClassName() );
225             StackTraceElement outer = stackTraceElements.get( 4 );
226             assertEquals( InnerATestClass.class.getName(), outer.getClassName() );
227         }
228     }
229 
230     public void testNonClassNameStacktrace()
231     {
232         SmartStackTraceParser smartStackTraceParser =
233             new SmartStackTraceParser( "Not a class name", new Throwable( "my message" ), null );
234         assertEquals( "my message", smartStackTraceParser.getString() );
235     }
236 
237     public void testNullElementInStackTrace()
238         throws Exception
239     {
240         ATestClass aTestClass = new ATestClass();
241         try
242         {
243             aTestClass.failInAssert();
244         }
245         catch ( AssertionError e )
246         {
247             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
248             Field stackTrace = SmartStackTraceParser.class.getDeclaredField( "stackTrace" );
249             stackTrace.setAccessible( true );
250             stackTrace.set( smartStackTraceParser, new StackTraceElement[0] );
251             String res = smartStackTraceParser.getString();
252             assertEquals( "ATestClass X is not Z", res );
253         }
254 
255     }
256 
257     public void testSingleNestedWithThread()
258     {
259         ExecutionException e = getSingleNested();
260         String name = this.getClass().getName();
261         Throwable focus = findInnermostWithClass( e, name );
262         assertEquals( e, focus );
263         List<StackTraceElement> stackTraceElements = focusInsideClass( focus.getStackTrace(), name );
264         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
265     }
266 
267 
268     public void testDoubleNestedWithThread()
269     {
270         ExecutionException e = getDoubleNestedException();
271 
272         String name = this.getClass().getName();
273         Throwable focus = findInnermostWithClass( e, name );
274         assertEquals( e, focus );
275         List<StackTraceElement> stackTraceElements = focusInsideClass( focus.getStackTrace(), name );
276         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
277 
278         name = "org.apache.maven.surefire.report.RunnableTestClass1";
279         focus = findInnermostWithClass( e, name );
280         assertEquals( e.getCause(), focus );
281         stackTraceElements = focusInsideClass( focus.getStackTrace(), name );
282         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
283 
284     }
285 
286     public ExecutionException getSingleNested()
287     {
288         FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass2() );
289         new Thread( futureTask ).start();
290         try
291         {
292             futureTask.get();
293         }
294         catch ( InterruptedException e )
295         {
296             fail();
297         }
298         catch ( ExecutionException e )
299         {
300             return e;
301         }
302         fail();
303         return null;
304     }
305 
306     private ExecutionException getDoubleNestedException()
307     {
308         FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass1() );
309         new Thread( futureTask ).start();
310         try
311         {
312             futureTask.get();
313         }
314         catch ( InterruptedException e )
315         {
316             fail();
317         }
318         catch ( ExecutionException e )
319         {
320             return e;
321         }
322         return null;
323     }
324 }