|
@@ -70,7 +70,7 @@ public final class LambdaTestUtils {
|
|
* @throws Exception if the handler wishes to raise an exception
|
|
* @throws Exception if the handler wishes to raise an exception
|
|
* that way.
|
|
* that way.
|
|
*/
|
|
*/
|
|
- Exception evaluate(int timeoutMillis, Exception caught) throws Exception;
|
|
|
|
|
|
+ Throwable evaluate(int timeoutMillis, Throwable caught) throws Throwable;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -116,7 +116,7 @@ public final class LambdaTestUtils {
|
|
Preconditions.checkNotNull(timeoutHandler);
|
|
Preconditions.checkNotNull(timeoutHandler);
|
|
|
|
|
|
long endTime = Time.now() + timeoutMillis;
|
|
long endTime = Time.now() + timeoutMillis;
|
|
- Exception ex = null;
|
|
|
|
|
|
+ Throwable ex = null;
|
|
boolean running = true;
|
|
boolean running = true;
|
|
int iterations = 0;
|
|
int iterations = 0;
|
|
while (running) {
|
|
while (running) {
|
|
@@ -128,9 +128,11 @@ public final class LambdaTestUtils {
|
|
// the probe failed but did not raise an exception. Reset any
|
|
// the probe failed but did not raise an exception. Reset any
|
|
// exception raised by a previous probe failure.
|
|
// exception raised by a previous probe failure.
|
|
ex = null;
|
|
ex = null;
|
|
- } catch (InterruptedException | FailFastException e) {
|
|
|
|
|
|
+ } catch (InterruptedException
|
|
|
|
+ | FailFastException
|
|
|
|
+ | VirtualMachineError e) {
|
|
throw e;
|
|
throw e;
|
|
- } catch (Exception e) {
|
|
|
|
|
|
+ } catch (Throwable e) {
|
|
LOG.debug("eventually() iteration {}", iterations, e);
|
|
LOG.debug("eventually() iteration {}", iterations, e);
|
|
ex = e;
|
|
ex = e;
|
|
}
|
|
}
|
|
@@ -145,15 +147,20 @@ public final class LambdaTestUtils {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// timeout
|
|
// timeout
|
|
- Exception evaluate = timeoutHandler.evaluate(timeoutMillis, ex);
|
|
|
|
- if (evaluate == null) {
|
|
|
|
- // bad timeout handler logic; fall back to GenerateTimeout so the
|
|
|
|
- // underlying problem isn't lost.
|
|
|
|
- LOG.error("timeout handler {} did not throw an exception ",
|
|
|
|
- timeoutHandler);
|
|
|
|
- evaluate = new GenerateTimeout().evaluate(timeoutMillis, ex);
|
|
|
|
|
|
+ Throwable evaluate;
|
|
|
|
+ try {
|
|
|
|
+ evaluate = timeoutHandler.evaluate(timeoutMillis, ex);
|
|
|
|
+ if (evaluate == null) {
|
|
|
|
+ // bad timeout handler logic; fall back to GenerateTimeout so the
|
|
|
|
+ // underlying problem isn't lost.
|
|
|
|
+ LOG.error("timeout handler {} did not throw an exception ",
|
|
|
|
+ timeoutHandler);
|
|
|
|
+ evaluate = new GenerateTimeout().evaluate(timeoutMillis, ex);
|
|
|
|
+ }
|
|
|
|
+ } catch (Throwable throwable) {
|
|
|
|
+ evaluate = throwable;
|
|
}
|
|
}
|
|
- throw evaluate;
|
|
|
|
|
|
+ return raise(evaluate);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -217,6 +224,7 @@ public final class LambdaTestUtils {
|
|
* @throws Exception the last exception thrown before timeout was triggered
|
|
* @throws Exception the last exception thrown before timeout was triggered
|
|
* @throws FailFastException if raised -without any retry attempt.
|
|
* @throws FailFastException if raised -without any retry attempt.
|
|
* @throws InterruptedException if interrupted during the sleep operation.
|
|
* @throws InterruptedException if interrupted during the sleep operation.
|
|
|
|
+ * @throws OutOfMemoryError you've run out of memory.
|
|
*/
|
|
*/
|
|
public static <T> T eventually(int timeoutMillis,
|
|
public static <T> T eventually(int timeoutMillis,
|
|
Callable<T> eval,
|
|
Callable<T> eval,
|
|
@@ -224,7 +232,7 @@ public final class LambdaTestUtils {
|
|
Preconditions.checkArgument(timeoutMillis >= 0,
|
|
Preconditions.checkArgument(timeoutMillis >= 0,
|
|
"timeoutMillis must be >= 0");
|
|
"timeoutMillis must be >= 0");
|
|
long endTime = Time.now() + timeoutMillis;
|
|
long endTime = Time.now() + timeoutMillis;
|
|
- Exception ex;
|
|
|
|
|
|
+ Throwable ex;
|
|
boolean running;
|
|
boolean running;
|
|
int sleeptime;
|
|
int sleeptime;
|
|
int iterations = 0;
|
|
int iterations = 0;
|
|
@@ -232,10 +240,12 @@ public final class LambdaTestUtils {
|
|
iterations++;
|
|
iterations++;
|
|
try {
|
|
try {
|
|
return eval.call();
|
|
return eval.call();
|
|
- } catch (InterruptedException | FailFastException e) {
|
|
|
|
|
|
+ } catch (InterruptedException
|
|
|
|
+ | FailFastException
|
|
|
|
+ | VirtualMachineError e) {
|
|
// these two exceptions trigger an immediate exit
|
|
// these two exceptions trigger an immediate exit
|
|
throw e;
|
|
throw e;
|
|
- } catch (Exception e) {
|
|
|
|
|
|
+ } catch (Throwable e) {
|
|
LOG.debug("evaluate() iteration {}", iterations, e);
|
|
LOG.debug("evaluate() iteration {}", iterations, e);
|
|
ex = e;
|
|
ex = e;
|
|
}
|
|
}
|
|
@@ -245,7 +255,26 @@ public final class LambdaTestUtils {
|
|
}
|
|
}
|
|
} while (running);
|
|
} while (running);
|
|
// timeout. Throw the last exception raised
|
|
// timeout. Throw the last exception raised
|
|
- throw ex;
|
|
|
|
|
|
+ return raise(ex);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Take the throwable and raise it as an exception or an error, depending
|
|
|
|
+ * upon its type. This allows callers to declare that they only throw
|
|
|
|
+ * Exception (i.e. can be invoked by Callable) yet still rethrow a
|
|
|
|
+ * previously caught Throwable.
|
|
|
|
+ * @param throwable Throwable to rethrow
|
|
|
|
+ * @param <T> expected return type
|
|
|
|
+ * @return never
|
|
|
|
+ * @throws Exception if throwable is an Exception
|
|
|
|
+ * @throws Error if throwable is not an Exception
|
|
|
|
+ */
|
|
|
|
+ private static <T> T raise(Throwable throwable) throws Exception {
|
|
|
|
+ if (throwable instanceof Exception) {
|
|
|
|
+ throw (Exception) throwable;
|
|
|
|
+ } else {
|
|
|
|
+ throw (Error) throwable;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -402,14 +431,14 @@ public final class LambdaTestUtils {
|
|
* @return TimeoutException
|
|
* @return TimeoutException
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
- public Exception evaluate(int timeoutMillis, Exception caught)
|
|
|
|
- throws Exception {
|
|
|
|
|
|
+ public Throwable evaluate(int timeoutMillis, Throwable caught)
|
|
|
|
+ throws Throwable {
|
|
String s = String.format("%s: after %d millis", message,
|
|
String s = String.format("%s: after %d millis", message,
|
|
timeoutMillis);
|
|
timeoutMillis);
|
|
String caughtText = caught != null
|
|
String caughtText = caught != null
|
|
? ("; " + robustToString(caught)) : "";
|
|
? ("; " + robustToString(caught)) : "";
|
|
|
|
|
|
- return (TimeoutException) (new TimeoutException(s + caughtText)
|
|
|
|
|
|
+ return (new TimeoutException(s + caughtText)
|
|
.initCause(caught));
|
|
.initCause(caught));
|
|
}
|
|
}
|
|
}
|
|
}
|