Repository: maven-surefire Updated Branches: refs/heads/master 6d901d141 -> 425078897
[SUREFIRE-1067] Nested causes conflated with wrapper exception Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/17cb7c56 Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/17cb7c56 Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/17cb7c56 Branch: refs/heads/master Commit: 17cb7c5698d2a42f52be9597bd63ae3a99ec8898 Parents: 6d901d1 Author: Tibor17 <tibo...@lycos.com> Authored: Fri Jun 5 18:38:25 2015 +0200 Committer: Tibor17 <tibo...@lycos.com> Committed: Fri Jul 3 00:42:10 2015 +0200 ---------------------------------------------------------------------- .../report/ClassNameStackTraceFilter.java | 39 ++++++ .../surefire/report/NullStackTraceFilter.java | 32 +++++ .../surefire/report/PojoStackTraceWriter.java | 2 +- .../surefire/report/SmartStackTraceParser.java | 126 ++++++++++--------- .../maven/surefire/report/StackTraceFilter.java | 28 +++++ .../report/SmartStackTraceParserTest.java | 40 +++--- .../common/junit4/JUnit4StackTraceWriter.java | 9 +- 7 files changed, 191 insertions(+), 85 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/ClassNameStackTraceFilter.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/ClassNameStackTraceFilter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/ClassNameStackTraceFilter.java new file mode 100644 index 0000000..6767430 --- /dev/null +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/ClassNameStackTraceFilter.java @@ -0,0 +1,39 @@ +package org.apache.maven.surefire.report; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Filters stacktrace element by class name. + */ +final class ClassNameStackTraceFilter + implements StackTraceFilter +{ + private final String className; + + ClassNameStackTraceFilter( String className ) + { + this.className = className; + } + + public boolean matches( StackTraceElement element ) + { + return className.equals( element.getClassName() ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/NullStackTraceFilter.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/NullStackTraceFilter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/NullStackTraceFilter.java new file mode 100644 index 0000000..cced1d4 --- /dev/null +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/NullStackTraceFilter.java @@ -0,0 +1,32 @@ +package org.apache.maven.surefire.report; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * always returns true + */ +final class NullStackTraceFilter + implements StackTraceFilter +{ + public boolean matches( StackTraceElement element ) + { + return true; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java index 8920b35..b9fb250 100644 --- a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java @@ -73,7 +73,7 @@ public class PojoStackTraceWriter return ""; } - return SmartStackTraceParser.innerMostWithFocusOnClass( t, testClass ); + return SmartStackTraceParser.stackTraceWithFocusOnClassAsString( t, testClass ); } public SafeThrowable getThrowable() http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java index 056eef3..175a671 100644 --- a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java @@ -32,6 +32,7 @@ import org.apache.maven.shared.utils.StringUtils; @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" ) public class SmartStackTraceParser { + private static final StackTraceFilter EVERY_STACK_ELEMENT = new NullStackTraceFilter(); private static final int MAX_LINE_LENGTH = 77; @@ -56,8 +57,8 @@ public class SmartStackTraceParser { this.testMethodName = testMethodName; this.testClassName = testClassName; - this.testClass = getClass( testClassName ); - this.simpleName = this.testClassName.substring( this.testClassName.lastIndexOf( "." ) + 1 ); + testClass = getClass( testClassName ); + simpleName = testClassName.substring( testClassName.lastIndexOf( "." ) + 1 ); this.throwable = new SafeThrowable( throwable ); stackTrace = throwable.getStackTrace(); } @@ -89,15 +90,16 @@ public class SmartStackTraceParser return throwable.getLocalizedMessage(); } - StringBuilder result = new StringBuilder(); - List<StackTraceElement> stackTraceElements = focusOnClass( stackTrace, testClass ); + final StringBuilder result = new StringBuilder(); + final List<StackTraceElement> stackTraceElements = focusOnClass( stackTrace, testClass ); Collections.reverse( stackTraceElements ); if ( stackTraceElements.isEmpty() ) { result.append( simpleName ); if ( StringUtils.isNotEmpty( testMethodName ) ) { - result.append( "." ).append( testMethodName ); + result.append( "." ) + .append( testMethodName ); } } else @@ -119,26 +121,27 @@ public class SmartStackTraceParser } if ( !stackTraceElement.getClassName().equals( testClassName ) ) { - result.append( getSimpleName( stackTraceElement.getClassName() ) ); // Add the name of the superclas - result.append( "." ); + result.append( getSimpleName( stackTraceElement.getClassName() ) ) // Add the name of the superclas + .append( "." ); } - result.append( stackTraceElement.getMethodName() ).append( ":" ).append( - stackTraceElement.getLineNumber() ); - result.append( "->" ); + result.append( stackTraceElement.getMethodName() ) + .append( ":" ) + .append( stackTraceElement.getLineNumber() ) + .append( "->" ); } if ( result.length() >= 2 ) { - result.deleteCharAt( result.length() - 1 ); - result.deleteCharAt( result.length() - 1 ); + result.deleteCharAt( result.length() - 1 ) + .deleteCharAt( result.length() - 1 ); } } Throwable target = throwable.getTarget(); if ( target instanceof AssertionError ) { - result.append( " " ); - result.append( throwable.getMessage() ); + result.append( " " ) + .append( throwable.getMessage() ); } else if ( "junit.framework.AssertionFailedError".equals( target.getClass().getName() ) || "junit.framework.ComparisonFailure".equals( target.getClass().getName() ) ) @@ -222,66 +225,50 @@ public class SmartStackTraceParser return testClass.getName().equals( lookFor ); } - static Throwable findInnermostWithClass( Throwable t, String className ) + static Throwable findTopmostWithClass( final Throwable t, StackTraceFilter filter ) { - Throwable match = t; + Throwable n = t; do { - if ( containsClassName( t.getStackTrace(), className ) ) + if ( containsClassName( n.getStackTrace(), filter ) ) { - match = t; + return n; } - t = t.getCause(); + n = n.getCause(); } - while ( t != null ); - return match; + while ( n != null ); + return t; } - public static String innerMostWithFocusOnClass( Throwable t, String className ) + public static String stackTraceWithFocusOnClassAsString( Throwable t, String className ) { - Throwable innermost = findInnermostWithClass( t, className ); - List<StackTraceElement> stackTraceElements = focusInsideClass( innermost.getStackTrace(), className ); - String s = causeToString( innermost.getCause() ); - return toString( t, stackTraceElements ) + s; + StackTraceFilter filter = new ClassNameStackTraceFilter( className ); + Throwable topmost = findTopmostWithClass( t, filter ); + List<StackTraceElement> stackTraceElements = focusInsideClass( topmost.getStackTrace(), filter ); + String s = causeToString( topmost.getCause(), filter ); + return toString( t, stackTraceElements, filter ) + s; } - static List<StackTraceElement> focusInsideClass( StackTraceElement[] stackTrace, String className ) + static List<StackTraceElement> focusInsideClass( StackTraceElement[] stackTrace, StackTraceFilter filter ) { List<StackTraceElement> result = new ArrayList<StackTraceElement>(); - boolean found = false; for ( StackTraceElement element : stackTrace ) { - if ( !found ) + if ( filter.matches( element ) ) { result.add( element ); } - - if ( className.equals( element.getClassName() ) ) - { - if ( found ) - { - result.add( element ); - } - found = true; - } - else - { - if ( found ) - { - break; - } - } } return result; } - static boolean containsClassName( StackTraceElement[] stackTrace, String className ) + static boolean containsClassName( StackTraceElement[] stackTrace, StackTraceFilter filter ) { for ( StackTraceElement element : stackTrace ) { - if ( className.equals( element.getClassName() ) ) + if ( filter.matches( element ) ) { return true; } @@ -289,31 +276,48 @@ public class SmartStackTraceParser return false; } - public static String causeToString( Throwable cause ) + private static String causeToString( Throwable cause, StackTraceFilter filter ) { - StringBuilder resp = new StringBuilder(); + String resp = ""; while ( cause != null ) { - resp.append( "Caused by: " ); - resp.append( toString( cause, Arrays.asList( cause.getStackTrace() ) ) ); + resp += "Caused by: "; + resp += toString( cause, Arrays.asList( cause.getStackTrace() ), filter ); cause = cause.getCause(); } - return resp.toString(); + return resp; } - public static String toString( Throwable t, Iterable<StackTraceElement> elements ) + public static String causeToString( Throwable cause ) { - StringBuilder result = new StringBuilder(); - result.append( t.getClass().getName() ); - result.append( ": " ); - result.append( t.getMessage() ); - result.append( "\n" ); + return causeToString( cause, EVERY_STACK_ELEMENT ); + } + + private static String toString( Throwable t, Iterable<StackTraceElement> elements, StackTraceFilter filter ) + { + String result = ""; + if ( t != null ) + { + result += t.getClass().getName(); + result += ": "; + result += t.getMessage(); + result += "\n"; + } for ( StackTraceElement element : elements ) { - result.append( "\tat " ).append( element.toString() ); - result.append( "\n" ); + if ( filter.matches( element ) ) + { + result += "\tat "; + result += element; + result += "\n"; + } } - return result.toString(); + return result; + } + + public static String toString( Throwable t, Iterable<StackTraceElement> elements ) + { + return toString( t, elements, EVERY_STACK_ELEMENT ); } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/StackTraceFilter.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/StackTraceFilter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/StackTraceFilter.java new file mode 100644 index 0000000..3124544 --- /dev/null +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/StackTraceFilter.java @@ -0,0 +1,28 @@ +package org.apache.maven.surefire.report; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * StackTrace element filter. + */ +interface StackTraceFilter +{ + boolean matches( StackTraceElement element ); +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/SmartStackTraceParserTest.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/SmartStackTraceParserTest.java b/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/SmartStackTraceParserTest.java index e66b853..bb9ffd9 100644 --- a/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/SmartStackTraceParserTest.java +++ b/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/SmartStackTraceParserTest.java @@ -24,12 +24,11 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; -import junit.framework.Assert; import junit.framework.AssertionFailedError; import junit.framework.ComparisonFailure; import junit.framework.TestCase; -import static org.apache.maven.surefire.report.SmartStackTraceParser.findInnermostWithClass; +import static org.apache.maven.surefire.report.SmartStackTraceParser.findTopmostWithClass; import static org.apache.maven.surefire.report.SmartStackTraceParser.focusInsideClass; @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" ) @@ -170,13 +169,13 @@ public class SmartStackTraceParserTest public void testCollections() { Throwable aThrownException = getAThrownException(); - List<StackTraceElement> innerMost = - focusInsideClass( aThrownException.getCause().getStackTrace(), TestClass1.InnerBTestClass.class.getName() ); - assertEquals( 3, innerMost.size() ); + focusInsideClass( aThrownException.getCause().getStackTrace(), + new ClassNameStackTraceFilter( TestClass1.InnerBTestClass.class.getName() ) ); + assertEquals( 2, innerMost.size() ); StackTraceElement inner = innerMost.get( 0 ); - assertEquals( TestClass2.InnerCTestClass.class.getName(), inner.getClassName() ); - StackTraceElement outer = innerMost.get( 2 ); + assertEquals( TestClass1.InnerBTestClass.class.getName(), inner.getClassName() ); + StackTraceElement outer = innerMost.get( 1 ); assertEquals( TestClass1.InnerBTestClass.class.getName(), outer.getClassName() ); } @@ -217,12 +216,13 @@ public class SmartStackTraceParserTest catch ( Throwable t ) { List<StackTraceElement> stackTraceElements = - focusInsideClass( t.getStackTrace(), InnerATestClass.class.getName() ); + focusInsideClass( t.getStackTrace(), + new ClassNameStackTraceFilter( InnerATestClass.class.getName() ) ); assertNotNull( stackTraceElements ); - assertEquals( 5, stackTraceElements.size() ); + assertEquals( 2, stackTraceElements.size() ); StackTraceElement innerMost = stackTraceElements.get( 0 ); - assertEquals( Assert.class.getName(), innerMost.getClassName() ); - StackTraceElement outer = stackTraceElements.get( 4 ); + assertEquals( InnerATestClass.class.getName(), innerMost.getClassName() ); + StackTraceElement outer = stackTraceElements.get( 1 ); assertEquals( InnerATestClass.class.getName(), outer.getClassName() ); } } @@ -257,10 +257,11 @@ public class SmartStackTraceParserTest public void testSingleNestedWithThread() { ExecutionException e = getSingleNested(); - String name = this.getClass().getName(); - Throwable focus = findInnermostWithClass( e, name ); + String name = getClass().getName(); + Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) ); assertEquals( e, focus ); - List<StackTraceElement> stackTraceElements = focusInsideClass( focus.getStackTrace(), name ); + List<StackTraceElement> stackTraceElements = + focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) ); assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name ); } @@ -269,16 +270,17 @@ public class SmartStackTraceParserTest { ExecutionException e = getDoubleNestedException(); - String name = this.getClass().getName(); - Throwable focus = findInnermostWithClass( e, name ); + String name = getClass().getName(); + Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) ); assertEquals( e, focus ); - List<StackTraceElement> stackTraceElements = focusInsideClass( focus.getStackTrace(), name ); + List<StackTraceElement> stackTraceElements = + focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) ); assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name ); name = "org.apache.maven.surefire.report.RunnableTestClass1"; - focus = findInnermostWithClass( e, name ); + focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) ); assertEquals( e.getCause(), focus ); - stackTraceElements = focusInsideClass( focus.getStackTrace(), name ); + stackTraceElements = focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) ); assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name ); } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/17cb7c56/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java ---------------------------------------------------------------------- diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java index 8e469ad..5f7cd97 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java @@ -74,8 +74,8 @@ public class JUnit4StackTraceWriter Throwable exception = junitFailure.getException(); if ( exception != null ) { - SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( getTestClassName(), exception, - getTestMethodName() ); + SmartStackTraceParser smartStackTraceParser = + new SmartStackTraceParser( getTestClassName(), exception, getTestMethodName() ); return smartStackTraceParser.getString(); } else @@ -94,11 +94,12 @@ public class JUnit4StackTraceWriter String testClass = getTestClassName(); try { - return SmartStackTraceParser.innerMostWithFocusOnClass( junitFailure.getException(), testClass ); + Throwable e = junitFailure.getException(); + return SmartStackTraceParser.stackTraceWithFocusOnClassAsString( e, testClass ); } catch ( Throwable t ) { - return SmartStackTraceParser.innerMostWithFocusOnClass( t, testClass ); + return SmartStackTraceParser.stackTraceWithFocusOnClassAsString( t, testClass ); } }