/** * Equivalent to {@code failure("failure", failure)}. * @see #failure(String, Throwable) */ public static <T> Task<T> failure(final Throwable failure) { return failure("failure", failure); }
@Override Task<String> getFailureTask() { return Task.failure("failure", new RuntimeException(TASK_ERROR_MESSAGE)); }
@Override Task<String> getCancelledTask() { return Task.failure("cancelled", new CancellationException(new TimeoutException())); }
@Test public void testFailure() { Exception e = new Exception("ups!"); Task<Integer> task = Task.failure(e); try { runAndWait("TestTaskFactoryMethods.testFailure", task); fail("should have failed"); } catch (Exception ex) { assertEquals(task.getError(), e); } assertEquals(countTasks(task.getTrace()), 1); }
@Test public void testSimpleRetryPolicy() { Task<Void> task = withRetryPolicy("testSimpleRetryPolicy", RetryPolicy.attempts(3, 0), attempt -> Task.failure(new RuntimeException("current attempt: " + attempt))); runAndWaitException(task, RuntimeException.class); assertTrue(task.isDone()); assertEquals(task.getError().getMessage(), "current attempt: 2"); }
@Test public void testSimpleRetryPolicy() { Task<Void> task = withRetryPolicy("testSimpleRetryPolicy", RetryPolicy.attempts(3, 0), attempt -> Task.failure(new RuntimeException("current attempt: " + attempt))); runAndWaitException(task, RuntimeException.class); assertTrue(task.isDone()); assertEquals(task.getError().getMessage(), "current attempt: 2"); }
@Test public void testErrorTrace() throws InterruptedException { final Exception exception = new Exception("error message"); final Task<?> task = Task.failure("taskName", exception); try { runAndWait("TestTaskToTrace.testErrorTrace", task); fail("task should finish with Exception"); } catch (Throwable t) { assertEquals(exception, task.getError()); } verifyShallowTrace(task); }
@Test public void testErrorClassification() { Function<Throwable, ErrorClassification> errorClassifier = error -> error instanceof TimeoutException ? ErrorClassification.RECOVERABLE : ErrorClassification.UNRECOVERABLE; RetryPolicy retryPolicy = new RetryPolicyBuilder(). setTerminationPolicy(TerminationPolicy.limitAttempts(3)). setErrorClassifier(errorClassifier). build(); assertEquals(retryPolicy.getName(), "RetryPolicy.LimitAttempts"); Task<Void> task1 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new TimeoutException("current attempt: " + attempt))); runAndWaitException(task1, TimeoutException.class); assertTrue(task1.isDone()); assertEquals(task1.getError().getMessage(), "current attempt: 2"); Task<Void> task2 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new IllegalArgumentException("current attempt: " + attempt))); runAndWaitException(task2, IllegalArgumentException.class); assertTrue(task2.isDone()); assertEquals(task2.getError().getMessage(), "current attempt: 0"); }
@Test public void testErrorClassification() { Function<Throwable, ErrorClassification> errorClassifier = error -> error instanceof TimeoutException ? ErrorClassification.RECOVERABLE : ErrorClassification.UNRECOVERABLE; RetryPolicy retryPolicy = new RetryPolicyBuilder(). setTerminationPolicy(TerminationPolicy.limitAttempts(3)). setErrorClassifier(errorClassifier). build(); assertEquals(retryPolicy.getName(), "RetryPolicy.LimitAttempts"); Task<Void> task1 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new TimeoutException("current attempt: " + attempt))); runAndWaitException(task1, TimeoutException.class); assertTrue(task1.isDone()); assertEquals(task1.getError().getMessage(), "current attempt: 2"); Task<Void> task2 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new IllegalArgumentException("current attempt: " + attempt))); runAndWaitException(task2, IllegalArgumentException.class); assertTrue(task2.isDone()); assertEquals(task2.getError().getMessage(), "current attempt: 0"); } }
@Test public void testSingleTaskWithErrorCombinations() throws InterruptedException { final String errorMsg = "this task has failed"; final Exception exception = new Exception(errorMsg); final String[] loggers = new String[] { ALL_LOGGER, ROOT_LOGGER, planClassLogger(Task.failure("dummy", exception)) }; final int[] levels = new int[] { ListLogger.LEVEL_DEBUG, ListLogger.LEVEL_TRACE }; for (String logger : loggers) { for (int level : levels) { resetLoggers(); final Task<?> task = Task.failure("t1", exception); setLogLevel(logger, level); try { runAndWait("TestTaskLogging.testSingleTaskWithErrorCombinations", task); fail("task should finish with Error"); } catch (Throwable t) { assertEquals(exception, task.getError()); } for (String checkLogger : loggers) { if (logger.equals(checkLogger)) { assertTaskLogged(task, errorMsg, checkLogger, level); } else { assertEquals(Collections.emptyList(), getLogEntries(checkLogger)); } } } } }
@Test public void testCancellationPar() { Task<String> task = delayedValue("hello", 50, TimeUnit.MILLISECONDS); Task<String> test1 = Task.par(task, Task.failure(new RuntimeException("ups"))).map((a, b) -> a + b); try { runAndWait("TestTaskReuse.testCancellationPar-test1", test1); fail("should have failed!"); } catch (Exception ex) { assertTrue(test1.isFailed()); } Task<String> test2 = Task.par(task.map("1", x -> x + "1"), task.map("2", x -> x + "2")).map((a, b) -> a + b); try { runAndWait("TestTaskReuse.testCancellationPar-test2", test2); fail("should have failed!"); } catch (Exception ex) { assertTrue(test2.isFailed()); } }
@Test public void testFailureInNestedFlatMap() { final Exception failureReason = new Exception(); Task<String> failing = getSuccessTask() .flatMap(Task::value) .flatMap(Task::value) .flatMap(i -> Task.failure(failureReason)); Task<String> nested = failing .flatMap(Task::value) .flatMap(Task::value); try { runAndWait("AbstractTaskTest.testFailureInNestedFlatMap", nested); fail("should have failed"); } catch (Exception ex) { assertTrue(nested.isFailed()); } assertSame(nested.getError(), failureReason); }
@Test public void testShareableCancellationPar() { Task<String> task = delayedValue("hello", 50, TimeUnit.MILLISECONDS); Task<String> test1 = Task.par(task.shareable().map(x -> x + "1"), Task.failure(new RuntimeException("ups"))).map((a, b) -> a + b); try { runAndWait("TestTaskReuse.testShareableCancellationPar-test1", test1); fail("should have failed!"); } catch (Exception ex) { assertTrue(test1.isFailed()); } Task<String> test2 = Task.par(task.shareable().map("1", x -> x + "1"), task.shareable().map("2", x -> x + "2")).map((a, b) -> a + b); runAndWait("TestTaskReuse.testShareableCancellationPar-test2", test2); assertEquals(test2.get(), "hello1hello2"); }
/** * Equivalent to {@code failure("failure", failure)}. * @see #failure(String, Throwable) */ public static <T> Task<T> failure(final Throwable failure) { return failure("failure", failure); }