You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a test with @Test(timeout = <timeout>) times out, it throws an exception which is supposed to have the stack trace of the method call which is actually stuck. This is not always the case however. More specifically: when the stuck method call is interruptible, the stack trace of the exception is totally wrong. This can be very misleading.
The root cause of the problem is in FailOnTimeout: the stack trace is grabbed from the stuck thread after it has been interrupted, which is a bug. The stack trace should be recorded before the thread is interrupted, and the recorded stack trace should later be injected in the timeout exception.
Unit test reproducing the issue:
@TestpublicvoidstackTraceContainsRealCauseOfTimeout() throwsThrowable {
StuckStatementstuck= newStuckStatement();
FailOnTimeoutstuckTimeout= newFailOnTimeout(stuck, TIMEOUT);
try {
stuckTimeout.evaluate();
// We must not get here, we expect a timeout exceptionfail("Expected timeout exception");
} catch (ExceptiontimeoutException) {
StackTraceElement[] stackTrace= timeoutException.getStackTrace();
booleanstackTraceContainsTheRealCauseOfTheTimeout= false;
booleanstackTraceContainsNotTheRealCauseOfTheTimeout= false;
for (StackTraceElementelement : stackTrace) {
StringmethodName= element.getMethodName();
if ("theRealCauseOfTheTimeout".equals(methodName)) {
stackTraceContainsTheRealCauseOfTheTimeout= true;
}
if ("notTheRealCauseOfTheTimeout".equals(methodName)) {
stackTraceContainsNotTheRealCauseOfTheTimeout= true;
}
}
assertTrue(
"Stack trace does not contain the real cause of the timeout",
stackTraceContainsTheRealCauseOfTheTimeout);
assertFalse(
"Stack trace contains another than the real cause of the timeout, which can be very misleading",
stackTraceContainsNotTheRealCauseOfTheTimeout);
}
}
privatestaticfinalclassStuckStatementextendsStatement {
@Overridepublicvoidevaluate() throwsThrowable {
try {
// Must show up in stack tracetheRealCauseOfTheTimeout();
} catch (InterruptedExceptione) {
} finally {
// Must _not_ show up in stack tracenotTheRealCauseOfTheTimeout();
}
}
privatevoidtheRealCauseOfTheTimeout() throwsInterruptedException {
sleep(MAX_VALUE);
}
privatevoidnotTheRealCauseOfTheTimeout() {
for (longnow= currentTimeMillis(), eta= now + 1000L; now < eta; now= currentTimeMillis()) {
// Doesn't matter, just pretend to be busyatan(now);
}
}
}
The text was updated successfully, but these errors were encountered:
When a test with
@Test(timeout = <timeout>)
times out, it throws an exception which is supposed to have the stack trace of the method call which is actually stuck. This is not always the case however. More specifically: when the stuck method call is interruptible, the stack trace of the exception is totally wrong. This can be very misleading.The root cause of the problem is in
FailOnTimeout
: the stack trace is grabbed from the stuck thread after it has been interrupted, which is a bug. The stack trace should be recorded before the thread is interrupted, and the recorded stack trace should later be injected in the timeout exception.Unit test reproducing the issue:
The text was updated successfully, but these errors were encountered: