package com.linkedin.parseq; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import org.testng.annotations.Test; import com.linkedin.parseq.trace.ResultType; import com.linkedin.parseq.trace.Trace; /** * @author Jaroslaw Odzga (jodzga@linkedin.com) */ public class TestFusionTask extends AbstractTaskTest { @Test public void testFlatMapFuncReturnNulll() { super.testFlatMapFuncReturnNulll(); } @Test public void testFlattenTaskReturnNulll() { super.testFlattenTaskReturnNulll(); } @Test public void testRecoverWithFuncReturnNulll() { super.testRecoverWithFuncReturnNulll(); } @Test public void testWithSideEffectFuncReturnNulll() { super.testWithSideEffectFuncReturnNulll(); } @Test public void testMap() { testMap(3); } @Test public void testFlatMap() { testFlatMap(5); } @Test public void testAndThenConsumer() { testAndThenConsumer(3); } @Test public void testAndThenTask() { testAndThenTask(3); } @Test public void testRecover() { testRecover(4); } @Test public void testCancelledRecover() { testCancelledRecover(4); } @Test public void testNoRecover() { testNoRecover(3); } @Test public void testTry() { testToTry(4); } @Test public void testRecoverWithSuccess() { testRecoverWithSuccess(2); } @Test public void testRecoverWithFailure() { testRecoverWithFailure(3); } @Test public void testRecoverWithCancelled() { testRecoverWithCancelled(2); } @Test public void testRecoverWithRecoverd() { testRecoverWithRecoverd(3); } @Test public void testWithSideEffectFullCompletion() throws Exception { testWithSideEffectFullCompletion(4); } @Test public void testWithSideEffectFailure() throws Exception { testWithSideEffectFailure(3); } @Test public void testOnFailure() { testOnFailure(3); } @Test public void testOnFailureWhenCancelled() { testOnFailureWhenCancelled(3); } @Test public void testWithTimeoutAsLastOperation() { Task<String> task = delayedValue("value", 250, TimeUnit.MILLISECONDS).map(x -> x + 1).map(x -> TASK_VALUE) .withTimeout(5, TimeUnit.MILLISECONDS); try { runAndWait("TestFusionTask.testWithTimeoutAsLastOperation", task); fail("should have failed!"); } catch (Exception ex) { assertSame(ex.getCause().getClass(), Exceptions.TIMEOUT_EXCEPTION.getClass()); } } @Test public void testWithTimeoutAsMiddleOperation() { Task<String> task = delayedValue("value", 250, TimeUnit.MILLISECONDS).map("first", x -> x + 3) .withTimeout(5, TimeUnit.MILLISECONDS).map("second", x -> TASK_VALUE); try { runAndWait("TestFusionTask.testWithTimeoutAsMiddleOperation", task); fail("should have failed!"); } catch (Exception ex) { assertSame(ex.getCause().getClass(), Exceptions.TIMEOUT_EXCEPTION.getClass()); } } @Test public void testTraceCompletness() throws InterruptedException { final Task<String> task = delayedValue("value", 10, TimeUnit.MILLISECONDS).map("duplicate", x -> x + x); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference<Trace> trace = new AtomicReference<>(); task.addListener(s -> { trace.set(task.getTrace()); latch.countDown(); }); runAndWait("TestFusionTask.testTraceCompletness", task); assertTrue(latch.await(100, TimeUnit.MILLISECONDS), "trace was not abtained in time"); assertTrue(trace.get().getTraceMap().values().stream() .allMatch(shallowTrace -> shallowTrace.getResultType().equals(ResultType.SUCCESS)), "all tasks in the trace should have ResultType=SUCCESS"); } @Override Task<String> getSuccessTask() { return Task.value("success", TASK_VALUE); } @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())); } }