@Test
public void testScheduleTask() {

    AtomicBoolean httpTaskExecuted = new AtomicBoolean(false);
    AtomicBoolean http2TaskExecuted = new AtomicBoolean(false);
    new Wait();
    new WorkflowSystemTask("HTTP") {
        @Override
        public boolean isAsync() {
            return true;
        }
        @Override
        public void start(Workflow workflow, Task task, WorkflowExecutor executor) {
            httpTaskExecuted.set(true);
            task.setStatus(Status.COMPLETED);
            super.start(workflow, task, executor);
        }
    };
    new WorkflowSystemTask("HTTP2") {
        @Override
        public void start(Workflow workflow, Task task, WorkflowExecutor executor) {
            http2TaskExecuted.set(true);
            task.setStatus(Status.COMPLETED);
            super.start(workflow, task, executor);
        }
    };
    Workflow workflow = new Workflow();
    workflow.setWorkflowId("1");
    List<Task> tasks = new LinkedList<>();
    WorkflowTask taskToSchedule = new WorkflowTask();
    taskToSchedule.setWorkflowTaskType(TaskType.USER_DEFINED);
    taskToSchedule.setType("HTTP");
    WorkflowTask taskToSchedule2 = new WorkflowTask();
    taskToSchedule2.setWorkflowTaskType(TaskType.USER_DEFINED);
    taskToSchedule2.setType("HTTP2");
    WorkflowTask wait = new WorkflowTask();
    wait.setWorkflowTaskType(TaskType.WAIT);
    wait.setType("WAIT");
    wait.setTaskReferenceName("wait");
    Task task1 = new Task();
    task1.setTaskType(taskToSchedule.getType());
    task1.setTaskDefName(taskToSchedule.getName());
    task1.setReferenceTaskName(taskToSchedule.getTaskReferenceName());
    task1.setWorkflowInstanceId(workflow.getWorkflowId());
    task1.setCorrelationId(workflow.getCorrelationId());
    task1.setScheduledTime(System.currentTimeMillis());
    task1.setTaskId(IDGenerator.generate());
    task1.setInputData(new HashMap<>());
    task1.setStatus(Status.SCHEDULED);
    task1.setRetryCount(0);
    task1.setCallbackAfterSeconds(taskToSchedule.getStartDelay());
    task1.setWorkflowTask(taskToSchedule);
    Task task2 = new Task();
    task2.setTaskType(Wait.NAME);
    task2.setTaskDefName(taskToSchedule.getName());
    task2.setReferenceTaskName(taskToSchedule.getTaskReferenceName());
    task2.setWorkflowInstanceId(workflow.getWorkflowId());
    task2.setCorrelationId(workflow.getCorrelationId());
    task2.setScheduledTime(System.currentTimeMillis());
    task2.setInputData(new HashMap<>());
    task2.setTaskId(IDGenerator.generate());
    task2.setStatus(Status.IN_PROGRESS);
    task2.setWorkflowTask(taskToSchedule);
    Task task3 = new Task();
    task3.setTaskType(taskToSchedule2.getType());
    task3.setTaskDefName(taskToSchedule.getName());
    task3.setReferenceTaskName(taskToSchedule.getTaskReferenceName());
    task3.setWorkflowInstanceId(workflow.getWorkflowId());
    task3.setCorrelationId(workflow.getCorrelationId());
    task3.setScheduledTime(System.currentTimeMillis());
    task3.setTaskId(IDGenerator.generate());
    task3.setInputData(new HashMap<>());
    task3.setStatus(Status.SCHEDULED);
    task3.setRetryCount(0);
    task3.setCallbackAfterSeconds(taskToSchedule.getStartDelay());
    task3.setWorkflowTask(taskToSchedule);
    tasks.add(task1);
    tasks.add(task2);
    tasks.add(task3);
    when(executionDAOFacade.createTasks(tasks)).thenReturn(tasks);
    AtomicInteger startedTaskCount = new AtomicInteger(0);
    doAnswer(invocation -> {
        startedTaskCount.incrementAndGet();
        return null;
    }).when(executionDAOFacade)
            .updateTask(any());
    AtomicInteger queuedTaskCount = new AtomicInteger(0);
    final Answer answer = invocation -> {
        String queueName = invocation.getArgument(0, String.class);
        System.out.println(queueName);
        queuedTaskCount.incrementAndGet();
        return null;
    };
    doAnswer(answer).when(queueDAO).push(any(), any(), anyLong());
    doAnswer(answer).when(queueDAO).push(any(), any(), anyInt(), anyLong());
    boolean stateChanged = workflowExecutor.scheduleTask(workflow, tasks);
    assertEquals(2, startedTaskCount.get());
    assertEquals(1, queuedTaskCount.get());
    assertTrue(stateChanged);
    assertFalse(httpTaskExecuted.get());
    assertTrue(http2TaskExecuted.get());
}