@Test public void testTaskWithCompletedDependencies() throws Exception { final List<String> sequence = new Vector<String>(); Task task1 = createTask(appender(sequence, "task1")); Task task2 = createTask(appender(sequence, "task2")); Task task3 = createTask(appender(sequence, "task3")); task1.schedule(); task1.waitFor(10000, TimeUnit.MILLISECONDS); task2.addPrerequisite(task1); task2.schedule(); task2.waitFor(10000, TimeUnit.MILLISECONDS); task3.addPrerequisite(task2); task3.schedule(); task3.waitFor(3500, TimeUnit.MILLISECONDS); assertArrayEquals(new String[] {"task1", "task2", "task3"}, sequence.toArray(new String[0])); }
@Test public void testSequenceWithDependencies() throws Exception { List<String> sequence = new Vector<String>(); Task task1 = createTask(appender(sequence, "task1")); Task task2 = createTask(appender(sequence, "task2")); SequenceTask seq = createSequence(); seq.add(appender(sequence, "subtask1")); seq.add(appender(sequence, "subtask2")); seq.add(appender(sequence, "subtask3")); seq.addPrerequisite(task1); task2.addPrerequisite(seq); seq.schedule(); task1.schedule(); task2.schedule(); task2.waitFor(3500, TimeUnit.MILLISECONDS); assertArrayEquals( new String[] {"task1", "subtask1", "subtask2", "subtask3", "task2"}, sequence.toArray(new String[0])); }
@Test(timeout = 1000) public void testAsyncThatThrowsException() throws Exception { AtomicInteger count = new AtomicInteger(0); Async<Integer> thrower = new Async<Integer>() { @Override public void submit(Callback<Integer> cb) { throw new RuntimeException("Intentionally failed for test purposes"); } }; Task throwerTask = m_coordinator.createTask(null, thrower, setter(count)); Task incrTask = m_coordinator.createTask(null, incr(count)); incrTask.addPrerequisite(throwerTask); incrTask.schedule(); throwerTask.schedule(); incrTask.waitFor(1500, TimeUnit.MILLISECONDS); assertEquals(1, count.get()); }
@Test public void testEnsureTaskIsSubmittedIfPreReqsCompleteWhileDependencyQueued() throws Exception { m_coordinator.setLoopDelay(1000); /** * This is a test case that tests a very specific race condition. The loopDelay is used to make * the race condition work */ // use latches so the finishing can be managed CountDownLatch aBlocker = new CountDownLatch(1); CountDownLatch bBlocker = new CountDownLatch(1); CountDownLatch cBlocker = new CountDownLatch(0); // we don't care when c finishes // create the tasks and a simple prerequisite and schedule Task a = createTask(waiter("A", aBlocker)); Task b = createTask(waiter("B", bBlocker)); Task c = createTask(waiter("C", cBlocker)); c.addPrerequisite(a); b.schedule(); a.schedule(); c.schedule(); // wait for the coordinator thread to process all of the above Thread.sleep(3500); /* we are not trying to set up the following situation * c has 1 'pendingPrereq' * the coordinator threads Q has 'a.complete, b.complete, c.addPrereq(b)' * * In this situation then the completing tasks will not be able to submit * 'c' because it has a pending prerequisite. * * By the time the prerequisite is added they are all complete. * * In this case we need to ensure the c is submitted */ // Because of the loopDelay.. this following will all sit on the queue // call countDown will allow these to complete bBlocker.countDown(); aBlocker.countDown(); // we wait just to a litlte to make sure the two completes get added Thread.sleep(100); // not we add the prerequisite c.addPrerequisite(b); c.waitFor(10000, TimeUnit.MILLISECONDS); assertTrue("Task C never completed", c.isFinished()); /* * If the queue call look this AFTER the call to c.addPrerequisite(b) increment pendingPrereqs * Q: a.complete, (pendingPrereq non zero) b.complete (pendingPrereq non zero) c.prereq(b) (decrementPrereqs) ..... */ }