Skip to content

Commit

Permalink
Support suppressed exceptions when trimming stack trace (junit-team#1451
Browse files Browse the repository at this point in the history
  • Loading branch information
panchenko authored and kcooney committed May 26, 2017
1 parent e0b5e24 commit 563d32c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
27 changes: 25 additions & 2 deletions src/main/java/org/junit/internal/Throwables.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -104,8 +105,30 @@ private static List<String> getTrimmedStackTraceLines(Throwable exception) {
return Collections.emptyList();
}

private static final Method getSuppressed = initGetSuppressed();

private static Method initGetSuppressed() {
try {
return Throwable.class.getMethod("getSuppressed");
} catch (Throwable e) {
return null;
}
}

private static boolean hasSuppressed(Throwable exception) {
if (getSuppressed == null) {
return false;
}
try {
Throwable[] suppressed = (Throwable[]) getSuppressed.invoke(exception);
return suppressed.length != 0;
} catch (Throwable e) {
return false;
}
}

private static List<String> getCauseStackTraceLines(Throwable exception) {
if (exception.getCause() != null) {
if (exception.getCause() != null || hasSuppressed(exception)) {
String fullTrace = getFullStackTrace(exception);
BufferedReader reader = new BufferedReader(
new StringReader(fullTrace.substring(exception.toString().length())));
Expand All @@ -114,7 +137,7 @@ private static List<String> getCauseStackTraceLines(Throwable exception) {
try {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("Caused by: ")) {
if (line.startsWith("Caused by: ") || line.trim().startsWith("Suppressed: ")) {
causedByLines.add(line);
while ((line = reader.readLine()) != null) {
causedByLines.add(line);
Expand Down
44 changes: 41 additions & 3 deletions src/test/java/org/junit/internal/StackTracesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
Expand Down Expand Up @@ -156,7 +158,24 @@ public void getTrimmedStackForJUnit4TestFailingInMethodRule() {
at("org.junit.internal.StackTracesTest$ThrowingMethodRule.apply"));
assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
}


@Test
public void getTrimmedStackWithSuppressedExceptions() {
assumeTrue("Running on 1.7+", TestWithSuppressedException.addSuppressed != null);
Result result = runTest(TestWithSuppressedException.class);
assertEquals("Should run the test", 1, result.getRunCount());
assertEquals("One test should fail", 1, result.getFailureCount());
Failure failure = result.getFailures().get(0);

assertHasTrimmedTrace(failure,
message("java.lang.RuntimeException: error"),
at("org.junit.internal.StackTracesTest$TestWithSuppressedException.alwaysThrows"),
message("\tSuppressed: java.lang.RuntimeException: suppressed"),
at("org.junit.internal.StackTracesTest$TestWithSuppressedException.alwaysThrows"),
framesInCommon());
assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
}

private abstract static class StringMatcher extends TypeSafeMatcher<String> {
}

Expand Down Expand Up @@ -190,7 +209,7 @@ private static StringMatcher message(String message) {
*/
private static class StackTraceLineMatcher extends StringMatcher {
private static final Pattern PATTERN
= Pattern.compile("at ([a-zA-Z0-9.$]+)\\([a-zA-Z0-9]+\\.java:[0-9]+\\)");
= Pattern.compile("\t*at ([a-zA-Z0-9.$]+)\\([a-zA-Z0-9]+\\.java:[0-9]+\\)");

private final String method;

Expand Down Expand Up @@ -228,7 +247,7 @@ private static StringMatcher at(String method) {
*/
private static class FramesRemovedMatcher extends StringMatcher {
private static final Pattern PATTERN
= Pattern.compile("\\.\\.\\. [0-9]+ ([a-z]+)");
= Pattern.compile("\t*\\.\\.\\. [0-9]+ ([a-z]+)");

private final String suffix;

Expand Down Expand Up @@ -409,4 +428,23 @@ private void doThrowExceptionWithoutCause() {
throw new RuntimeException("cause");
}
}

public static class TestWithSuppressedException {
static final Method addSuppressed = initAddSuppressed();

static Method initAddSuppressed() {
try {
return Throwable.class.getMethod("addSuppressed", Throwable.class);
} catch (Throwable e) {
return null;
}
}

@Test
public void alwaysThrows() throws Exception {
final RuntimeException exception = new RuntimeException("error");
addSuppressed.invoke(exception, new RuntimeException("suppressed"));
throw exception;
}
}
}

0 comments on commit 563d32c

Please sign in to comment.