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.AssertionFailedError;
28  import junit.framework.ComparisonFailure;
29  import junit.framework.TestCase;
30  import org.apache.maven.surefire.util.internal.DaemonThreadFactory;
31  
32  import static org.apache.maven.surefire.report.SmartStackTraceParser.*;
33  
34  @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" )
35  public class SmartStackTraceParserTest
36      extends TestCase
37  {
38      public void testGetString()
39          throws Exception
40      {
41          ATestClass aTestClass = new ATestClass();
42          try
43          {
44              aTestClass.failInAssert();
45          }
46          catch ( AssertionError e )
47          {
48              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
49              String res = smartStackTraceParser.getString();
50              assertEquals( "ATestClass.failInAssert:30 X is not Z", res );
51  
52          }
53  
54      }
55  
56      public void testNestedFailure()
57          throws Exception
58      {
59          ATestClass aTestClass = new ATestClass();
60          try
61          {
62              aTestClass.nestedFailInAssert();
63          }
64          catch ( AssertionError e )
65          {
66              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
67              String res = smartStackTraceParser.getString();
68              assertEquals( "ATestClass.nestedFailInAssert:35->failInAssert:30 X is not Z", res );
69          }
70      }
71  
72      public void testNestedNpe()
73          throws Exception
74      {
75          ATestClass aTestClass = new ATestClass();
76          try
77          {
78              aTestClass.nestedNpe();
79          }
80          catch ( NullPointerException e )
81          {
82              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
83              String res = smartStackTraceParser.getString();
84              assertEquals( "ATestClass.nestedNpe:45->npe:40 NullPointer It was null", res );
85  
86          }
87      }
88  
89      public void testNestedNpeOutsideTest()
90          throws Exception
91      {
92          ATestClass aTestClass = new ATestClass();
93          try
94          {
95              aTestClass.nestedNpeOutsideTest();
96          }
97          catch ( NullPointerException e )
98          {
99              SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
100             String res = smartStackTraceParser.getString();
101             assertEquals( "ATestClass.nestedNpeOutsideTest:55->npeOutsideTest:50 » NullPointer", res );
102 
103         }
104     }
105 
106     public void testLongMessageTruncation()
107         throws Exception
108     {
109         ATestClass aTestClass = new ATestClass();
110         try
111         {
112             aTestClass.aLongTestErrorMessage();
113         }
114         catch ( RuntimeException e )
115         {
116             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
117             String res = smartStackTraceParser.getString();
118             assertEquals( "ATestClass.aLongTestErrorMessage:60 Runtime This message will be truncated, so...", res );
119 
120         }
121     }
122 
123     public void testFailureInBaseClass()
124         throws Exception
125     {
126         ASubClass aTestClass = new ASubClass();
127         try
128         {
129             aTestClass.npe();
130         }
131         catch ( NullPointerException e )
132         {
133             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ASubClass.class, e );
134             String res = smartStackTraceParser.getString();
135             assertEquals( "ASubClass>ABaseClass.npe:27 » NullPointer It was null", res );
136         }
137     }
138 
139     public void testClassThatWillFail()
140         throws Exception
141     {
142         CaseThatWillFail aTestClass = new CaseThatWillFail();
143         try
144         {
145             aTestClass.testThatWillFail();
146         }
147         catch ( ComparisonFailure e )
148         {
149             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( CaseThatWillFail.class, e );
150             String res = smartStackTraceParser.getString();
151             assertEquals( "CaseThatWillFail.testThatWillFail:29 expected:<[abc]> but was:<[def]>", res );
152         }
153     }
154 
155     public Throwable getAThrownException()
156     {
157         try
158         {
159             TestClass1.InnerBTestClass.throwSomething();
160         }
161         catch ( Throwable t )
162         {
163             return t;
164         }
165         return null;
166     }
167 
168     public void testCollections()
169     {
170         Throwable aThrownException = getAThrownException();
171         List<StackTraceElement> innerMost =
172             focusInsideClass( aThrownException.getCause().getStackTrace(),
173                               new ClassNameStackTraceFilter( TestClass1.InnerBTestClass.class.getName() ) );
174         assertEquals( 2, innerMost.size() );
175         StackTraceElement inner = innerMost.get( 0 );
176         assertEquals( TestClass1.InnerBTestClass.class.getName(), inner.getClassName() );
177         StackTraceElement outer = innerMost.get( 1 );
178         assertEquals( TestClass1.InnerBTestClass.class.getName(), outer.getClassName() );
179     }
180 
181     public void testAssertionWithNoMessage()
182     {
183         try
184         {
185             new AssertionNoMessage().testThrowSomething();
186         }
187         catch ( ComparisonFailure e )
188         {
189             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( AssertionNoMessage.class, e );
190             String res = smartStackTraceParser.getString();
191             assertEquals( "AssertionNoMessage.testThrowSomething:29 expected:<[abc]> but was:<[xyz]>", res );
192         }
193     }
194 
195     public void testFailWithFail()
196     {
197         try
198         {
199             new FailWithFail().testThatWillFail();
200         }
201         catch ( AssertionFailedError e )
202         {
203             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( FailWithFail.class, e );
204             String res = smartStackTraceParser.getString();
205             assertEquals( "FailWithFail.testThatWillFail:29 abc", res );
206         }
207     }
208 
209     public void testCollectorWithNested()
210     {
211         try
212         {
213             InnerATestClass.testFake();
214         }
215         catch ( Throwable t )
216         {
217             List<StackTraceElement> stackTraceElements =
218                 focusInsideClass( t.getStackTrace(),
219                                   new ClassNameStackTraceFilter( InnerATestClass.class.getName() ) );
220             assertNotNull( stackTraceElements );
221             assertEquals( 2, stackTraceElements.size() );
222             StackTraceElement innerMost = stackTraceElements.get( 0 );
223             assertEquals( InnerATestClass.class.getName(), innerMost.getClassName() );
224             StackTraceElement outer = stackTraceElements.get( 1 );
225             assertEquals( InnerATestClass.class.getName(), outer.getClassName() );
226         }
227     }
228 
229     public void testNonClassNameStacktrace()
230     {
231         SmartStackTraceParser smartStackTraceParser =
232             new SmartStackTraceParser( "Not a class name", new Throwable( "my message" ), null );
233         assertEquals( "my message", smartStackTraceParser.getString() );
234     }
235 
236     public void testNullElementInStackTrace()
237         throws Exception
238     {
239         ATestClass aTestClass = new ATestClass();
240         try
241         {
242             aTestClass.failInAssert();
243         }
244         catch ( AssertionError e )
245         {
246             SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
247             Field stackTrace = SmartStackTraceParser.class.getDeclaredField( "stackTrace" );
248             stackTrace.setAccessible( true );
249             stackTrace.set( smartStackTraceParser, new StackTraceElement[0] );
250             String res = smartStackTraceParser.getString();
251             assertEquals( "ATestClass X is not Z", res );
252         }
253     }
254 
255     public void testSingleNestedWithThread()
256     {
257         ExecutionException e = getSingleNested();
258         String name = getClass().getName();
259         Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
260         assertSame( e, focus );
261         List<StackTraceElement> stackTraceElements =
262             focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
263         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
264     }
265 
266     public void testDoubleNestedWithThread()
267     {
268         ExecutionException e = getDoubleNestedException();
269 
270         String name = getClass().getName();
271         Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
272         assertSame( e, focus );
273         List<StackTraceElement> stackTraceElements =
274             focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
275         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
276 
277         name = RunnableTestClass1.class.getName();
278         focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
279         assertSame( e.getCause(), focus );
280         stackTraceElements = focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
281         assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
282     }
283 
284     public void testStackTraceWithFocusOnClassAsString()
285     {
286         try
287         {
288             new StackTraceFocusedOnClass.C().c();
289             fail();
290         }
291         catch ( Exception e )
292         {
293             String trace = stackTraceWithFocusOnClassAsString( e, StackTraceFocusedOnClass.B.class.getName() );
294 
295             assertEquals( "java.lang.RuntimeException: java.lang.IllegalStateException: java.io.IOException: I/O error\n"
296             + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:65)\n"
297             + "Caused by: java.lang.IllegalStateException: java.io.IOException: I/O error\n"
298             + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:61)\n"
299             + "Caused by: java.io.IOException: I/O error\n"
300             + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.abs(StackTraceFocusedOnClass.java:73)\n"
301             + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:61)\n",
302             trace );
303         }
304     }
305 
306     public ExecutionException getSingleNested()
307     {
308         FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass2() );
309         DaemonThreadFactory.newDaemonThread( 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         fail();
323         return null;
324     }
325 
326     private ExecutionException getDoubleNestedException()
327     {
328         FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass1() );
329         DaemonThreadFactory.newDaemonThread( futureTask ).start();
330         try
331         {
332             futureTask.get();
333         }
334         catch ( InterruptedException e )
335         {
336             fail();
337         }
338         catch ( ExecutionException e )
339         {
340             return e;
341         }
342         return null;
343     }
344 }