@Test
public void asyncRollbackTest() throws InvalidProcessStateException {
// sync components (level-1 fail)
SequentialProcess subProcess = new SequentialProcess();
ProcessStep subStep1 = new SucceedingProcessStep();
ProcessStep subStep2 = new SucceedingProcessStep();
subProcess.add(subStep1);
subProcess.add(subStep2);
SequentialProcess process = new SequentialProcess();
ProcessStep step1 = new SucceedingProcessStep();
ProcessStep step2 = new SucceedingProcessStep();
ProcessStep step3 = new FailingProcessStep();
ProcessStep step4 = new SucceedingProcessStep();
process.add(step1);
process.add(step2);
process.add(subProcess);
process.add(step3);
process.add(step4);
AsyncComponent asyncProcess = new AsyncComponent(process);
asyncProcess.start();
TestUtil.wait(WAIT_FOR_ASYNC);
assertTrue(asyncProcess.getState() == ProcessState.FAILED);
assertTrue(process.getState() == ProcessState.FAILED);
assertTrue(step1.getState() == ProcessState.FAILED);
assertTrue(step2.getState() == ProcessState.FAILED);
assertTrue(subProcess.getState() == ProcessState.FAILED);
assertTrue(subStep1.getState() == ProcessState.FAILED);
assertTrue(subStep2.getState() == ProcessState.FAILED);
assertTrue(step3.getState() == ProcessState.FAILED);
assertTrue(step4.getState() == ProcessState.READY);
// sync components (level-2 fail)
subProcess = new SequentialProcess();
subStep1 = new SucceedingProcessStep();
subStep2 = new FailingProcessStep();
ProcessStep subStep3 = new SucceedingProcessStep();
subProcess.add(subStep1);
subProcess.add(subStep2);
subProcess.add(subStep3);
process = new SequentialProcess();
step1 = new SucceedingProcessStep();
step2 = new SucceedingProcessStep();
step3 = new SucceedingProcessStep();
process.add(step1);
process.add(step2);
process.add(subProcess);
process.add(step3);
asyncProcess = new AsyncComponent(process);
asyncProcess.start();
TestUtil.wait(WAIT_FOR_ASYNC);
assertTrue(asyncProcess.getState() == ProcessState.FAILED);
assertTrue(process.getState() == ProcessState.FAILED);
assertTrue(step1.getState() == ProcessState.FAILED);
assertTrue(step2.getState() == ProcessState.FAILED);
assertTrue(subProcess.getState() == ProcessState.FAILED);
assertTrue(subStep1.getState() == ProcessState.FAILED);
assertTrue(subStep2.getState() == ProcessState.FAILED);
assertTrue(subStep3.getState() == ProcessState.READY);
assertTrue(step3.getState() == ProcessState.READY);
// async components (level-1 fail)
// sync step fails
subProcess = new SequentialProcess();
subStep1 = new SucceedingProcessStep();
subStep2 = new SucceedingProcessStep();
subProcess.add(subStep1);
subProcess.add(subStep2);
process = new SequentialProcess();
step1 = new SucceedingProcessStep();
step2 = new BusySucceedingStep(); // make sure rollback waits for all async components
AsyncComponent asyncStep2 = new AsyncComponent(step2);
step3 = new FailingProcessStep();
step4 = new SucceedingProcessStep();
process.add(step1);
process.add(asyncStep2);
process.add(subProcess);
process.add(step3);
process.add(step4);
asyncProcess = new AsyncComponent(process);
asyncProcess.start();
TestUtil.wait(WAIT_FOR_ASYNC);
assertTrue(asyncProcess.getState() == ProcessState.FAILED);
assertTrue(process.getState() == ProcessState.FAILED);
assertTrue(step1.getState() == ProcessState.FAILED);
assertTrue(asyncStep2.getState() == ProcessState.FAILED);
assertTrue(asyncStep2.getState() == ProcessState.FAILED);
assertTrue(subProcess.getState() == ProcessState.FAILED);
assertTrue(subStep1.getState() == ProcessState.FAILED);
assertTrue(subStep2.getState() == ProcessState.FAILED);
assertTrue(step3.getState() == ProcessState.FAILED);
assertTrue(step4.getState() == ProcessState.READY);
// async step fails
subProcess = new SequentialProcess();
subStep1 = new SucceedingProcessStep();
subStep2 = new SucceedingProcessStep();
subProcess.add(subStep1);
subProcess.add(subStep2);
process = new SequentialProcess();
step1 = new SucceedingProcessStep();
step2 = new SucceedingProcessStep();
step3 = new BusyFailingStep(); // make sure rollback waits for all async components
AsyncComponent asyncStep3 = new AsyncComponent(step3);
step4 = new SucceedingProcessStep();
process.add(step1);
process.add(step2);
process.add(subProcess);
process.add(asyncStep3);
process.add(step4);
asyncProcess = new AsyncComponent(process);
asyncProcess.start();
TestUtil.wait(WAIT_FOR_ASYNC);
assertTrue(asyncProcess.getState() == ProcessState.FAILED);
assertTrue(process.getState() == ProcessState.FAILED);
assertTrue(step1.getState() == ProcessState.FAILED);
assertTrue(step2.getState() == ProcessState.FAILED);
assertTrue(subProcess.getState() == ProcessState.FAILED);
assertTrue(subStep1.getState() == ProcessState.FAILED);
assertTrue(subStep2.getState() == ProcessState.FAILED);
assertTrue(asyncStep3.getState() == ProcessState.FAILED);
assertTrue(step3.getState() == ProcessState.FAILED);
assertTrue(step4.getState() == ProcessState.READY || step4.getState() == ProcessState.FAILED);
// async components (level-2 fail)
subProcess = new SequentialProcess();
subStep1 = new SucceedingProcessStep();
subStep2 = new FailingProcessStep();
subStep3 = new SucceedingProcessStep();
subProcess.add(subStep1);
subProcess.add(subStep2);
subProcess.add(subStep3);
AsyncComponent asyncSubProcess = new AsyncComponent(subProcess);
process = new SequentialProcess();
step1 = new SucceedingProcessStep();
step2 = new SucceedingProcessStep();
step3 = new SucceedingProcessStep();
process.add(step1);
process.add(step2);
process.add(asyncSubProcess);
process.add(step3);
asyncProcess = new AsyncComponent(process);
asyncProcess.start();
TestUtil.wait(WAIT_FOR_ASYNC);
assertTrue(asyncProcess.getState() == ProcessState.FAILED);
assertTrue(process.getState() == ProcessState.FAILED);
assertTrue(step1.getState() == ProcessState.FAILED);
assertTrue(step2.getState() == ProcessState.FAILED);
assertTrue(asyncSubProcess.getState() == ProcessState.FAILED);
assertTrue(subProcess.getState() == ProcessState.FAILED);
assertTrue(subStep1.getState() == ProcessState.FAILED);
assertTrue(subStep2.getState() == ProcessState.FAILED);
assertTrue(subStep3.getState() == ProcessState.READY);
assertTrue(step3.getState() == ProcessState.READY || step3.getState() == ProcessState.FAILED);
}