Package org.camunda.bpm.engine.test.bpmn.event.timer

Source Code of org.camunda.bpm.engine.test.bpmn.event.timer.StartTimerEventTest

/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.camunda.bpm.engine.test.bpmn.event.timer;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.impl.cmd.DeleteJobsCmd;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor;
import org.camunda.bpm.engine.impl.test.PluggableProcessEngineTestCase;
import org.camunda.bpm.engine.impl.util.ClockUtil;
import org.camunda.bpm.engine.impl.util.IoUtil;
import org.camunda.bpm.engine.runtime.ExecutionQuery;
import org.camunda.bpm.engine.runtime.Job;
import org.camunda.bpm.engine.runtime.JobQuery;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.runtime.ProcessInstanceQuery;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.task.TaskQuery;
import org.camunda.bpm.engine.test.Deployment;

/**
* @author Joram Barrez
*/
public class StartTimerEventTest extends PluggableProcessEngineTestCase {

  @Deployment
  public void testDurationStartTimerEvent() throws Exception {

    // Set the clock fixed
    Date startTime = new Date();

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    // After setting the clock to time '50minutes and 5 seconds', the second
    // timer should fire
    ClockUtil.setCurrentTime(new Date(startTime.getTime() + ((50 * 60 * 1000) + 5000)));

    executeAllJobs();

    executeAllJobs();

    List<ProcessInstance> pi = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExample").list();
    assertEquals(1, pi.size());

    assertEquals(0, jobQuery.count());

  }

  @Deployment
  public void testFixedDateStartTimerEvent() throws Exception {

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    ClockUtil.setCurrentTime(new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").parse("15/11/2036 11:12:30"));
    executeAllJobs();

    List<ProcessInstance> pi = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExample").list();
    assertEquals(1, pi.size());

    assertEquals(0, jobQuery.count());

  }

  // FIXME: This test likes to run in an endless loop when invoking the
  // waitForJobExecutorOnCondition method
  @Deployment
  public void FAILING_testCycleDateStartTimerEvent() throws Exception {
    ClockUtil.setCurrentTime(new Date());

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    final ProcessInstanceQuery piq = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExample");

    assertEquals(0, piq.count());

    moveByMinutes(5);
    executeAllJobs();
    assertEquals(1, piq.count());
    assertEquals(1, jobQuery.count());

    moveByMinutes(5);
    executeAllJobs();
    assertEquals(1, piq.count());

    assertEquals(1, jobQuery.count());
    // have to manually delete pending timer
    cleanDB();

  }

  private void moveByMinutes(int minutes) throws Exception {
    ClockUtil.setCurrentTime(new Date(ClockUtil.getCurrentTime().getTime() + ((minutes * 60 * 1000) + 5000)));
  }

  @Deployment
  public void testCycleWithLimitStartTimerEvent() throws Exception {
    ClockUtil.setCurrentTime(new Date());

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    // ensure that the deployment Id is set on the new job
    Job job = jobQuery.singleResult();
    assertNotNull(job.getDeploymentId());

    final ProcessInstanceQuery piq = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExampleCycle");

    assertEquals(0, piq.count());

    moveByMinutes(5);
    executeAllJobs();
    assertEquals(1, piq.count());
    assertEquals(1, jobQuery.count());

    // ensure that the deployment Id is set on the new job
    job = jobQuery.singleResult();
    assertNotNull(job.getDeploymentId());

    moveByMinutes(5);
    executeAllJobs();
    assertEquals(2, piq.count());
    assertEquals(0, jobQuery.count());

  }

  @Deployment
  public void testExpressionStartTimerEvent() throws Exception {
    // ACT-1415: fixed start-date is an expression
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    ClockUtil.setCurrentTime(new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").parse("15/11/2036 11:12:30"));
    executeAllJobs();

    List<ProcessInstance> pi = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExample").list();
    assertEquals(1, pi.size());

    assertEquals(0, jobQuery.count());
  }

  @Deployment
  public void testVersionUpgradeShouldCancelJobs() throws Exception {
    ClockUtil.setCurrentTime(new Date());

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    // we deploy new process version, with some small change
    InputStream in = getClass().getResourceAsStream("StartTimerEventTest.testVersionUpgradeShouldCancelJobs.bpmn20.xml");
    String process = new String(IoUtil.readInputStream(in, "")).replaceAll("beforeChange", "changed");
    IoUtil.closeSilently(in);
    in = new ByteArrayInputStream(process.getBytes());
    String id = repositoryService.createDeployment().addInputStream("StartTimerEventTest.testVersionUpgradeShouldCancelJobs.bpmn20.xml", in).deploy().getId();
    IoUtil.closeSilently(in);

    assertEquals(1, jobQuery.count());

    moveByMinutes(5);
    executeAllJobs();
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processDefinitionKey("startTimerEventExample").singleResult();
    String pi = processInstance.getProcessInstanceId();
    assertEquals("changed", runtimeService.getActiveActivityIds(pi).get(0));

    assertEquals(1, jobQuery.count());

    cleanDB();
    repositoryService.deleteDeployment(id, true);
  }

  @Deployment
  public void testTimerShouldNotBeRecreatedOnDeploymentCacheReboot() {

    // Just to be sure, I added this test. Sounds like something that could
    // easily happen
    // when the order of deploy/parsing is altered.

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    // Reset deployment cache
    processEngineConfiguration.getDeploymentCache().discardProcessDefinitionCache();

    // Start one instance of the process definition, this will trigger a cache
    // reload
    runtimeService.startProcessInstanceByKey("startTimer");

    // No new jobs should have been created
    assertEquals(1, jobQuery.count());
  }

  // Test for ACT-1533
  public void testTimerShouldNotBeRemovedWhenUndeployingOldVersion() throws Exception {
    // Deploy test process
    InputStream in = getClass().getResourceAsStream("StartTimerEventTest.testTimerShouldNotBeRemovedWhenUndeployingOldVersion.bpmn20.xml");
    String process = new String(IoUtil.readInputStream(in, ""));
    IoUtil.closeSilently(in);

    in = new ByteArrayInputStream(process.getBytes());
    String firstDeploymentId = repositoryService.createDeployment().addInputStream("StartTimerEventTest.testVersionUpgradeShouldCancelJobs.bpmn20.xml", in)
        .deploy().getId();
    IoUtil.closeSilently(in);

    // After process start, there should be timer created
    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());

    // we deploy new process version, with some small change
    String processChanged = process.replaceAll("beforeChange", "changed");
    in = new ByteArrayInputStream(processChanged.getBytes());
    String secondDeploymentId = repositoryService.createDeployment().addInputStream("StartTimerEventTest.testVersionUpgradeShouldCancelJobs.bpmn20.xml", in)
        .deploy().getId();
    IoUtil.closeSilently(in);
    assertEquals(1, jobQuery.count());

    // Remove the first deployment
    repositoryService.deleteDeployment(firstDeploymentId, true);

    // The removal of an old version should not affect timer deletion
    // ACT-1533: this was a bug, and the timer was deleted!
    assertEquals(1, jobQuery.count());

    // Cleanup
    cleanDB();
    repositoryService.deleteDeployment(secondDeploymentId, true);
  }

  @Deployment
  public void testStartTimerEventInEventSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventInEventSubProcess");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    // execute existing timer job
    managementService.executeJob(managementService.createJobQuery().list().get(0).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());
  }

  @Deployment
  public void testNonInterruptingStartTimerEventInEventSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingStartTimerEventInEventSubProcess");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    // execute existing job timer
    managementService.executeJob(managementService.createJobQuery().list().get(0).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer start event is non
    // interrupting
    assertEquals(1, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());
  }

  @Deployment
  public void testStartTimerEventSubProcessInSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventSubProcessInSubProcess");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    // execute existing timer job
    managementService.executeJob(managementService.createJobQuery().list().get(0).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());

  }

  @Deployment
  public void testNonInterruptingStartTimerEventSubProcessInSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingStartTimerEventSubProcessInSubProcess");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    // execute existing timer job
    managementService.executeJob(jobQuery.list().get(0).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer start event is non
    // interrupting
    assertEquals(2, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  @Deployment
  public void testStartTimerEventWithTwoEventSubProcesses() {
    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventWithTwoEventSubProcesses");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // get all timer jobs ordered by dueDate
    List<Job> orderedJobList = jobQuery.orderByJobDuedate().asc().list();
    // execute first timer job
    managementService.executeJob(orderedJobList.get(0).getId());
    assertEquals(0, jobQuery.count());

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());

  }

  @Deployment
  public void testNonInterruptingStartTimerEventWithTwoEventSubProcesses() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingStartTimerEventWithTwoEventSubProcesses");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // get all timer jobs ordered by dueDate
    List<Job> orderedJobList = jobQuery.orderByJobDuedate().asc().list();
    // execute first timer job
    managementService.executeJob(orderedJobList.get(0).getId());
    assertEquals(1, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    DummyServiceTask.wasExecuted = false;

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer start event is non
    // interrupting
    assertEquals(1, executionQuery.count());

    // execute second timer job
    managementService.executeJob(orderedJobList.get(1).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer event is non interrupting
    assertEquals(1, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  @Deployment
  public void testStartTimerEventSubProcessWithUserTask() {
    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventSubProcessWithUserTask");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // get all timer jobs ordered by dueDate
    List<Job> orderedJobList = jobQuery.orderByJobDuedate().asc().list();
    // execute first timer job
    managementService.executeJob(orderedJobList.get(0).getId());
    assertEquals(0, jobQuery.count());

    // check if user task of event subprocess named "subProcess" exists
    assertEquals(1, taskQuery.count());
    assertEquals("subprocessUserTask", taskQuery.list().get(0).getTaskDefinitionKey());

    // check if execution exists because subprocess named "subProcess" is
    // already running
    assertEquals(1, executionQuery.count());

    // check if process instance exists because subprocess named "subProcess" is
    // already running
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  @Deployment(resources = { "org/camunda/bpm/engine/test/bpmn/event/timer/simpleProcessWithCallActivity.bpmn20.xml",
      "org/camunda/bpm/engine/test/bpmn/event/timer/StartTimerEventTest.testStartTimerEventWithTwoEventSubProcesses.bpmn20.xml" })
  public void testStartTimerEventSubProcessCalledFromCallActivity() {
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("calledProcess", "startTimerEventWithTwoEventSubProcesses");
    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("simpleCallActivityProcess", variables);

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // get all timer jobs ordered by dueDate
    List<Job> orderedJobList = jobQuery.orderByJobDuedate().asc().list();
    // execute first timer job
    managementService.executeJob(orderedJobList.get(0).getId());
    assertEquals(0, jobQuery.count());

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());

  }

  @Deployment(resources = { "org/camunda/bpm/engine/test/bpmn/event/timer/simpleProcessWithCallActivity.bpmn20.xml",
      "org/camunda/bpm/engine/test/bpmn/event/timer/StartTimerEventTest.testNonInterruptingStartTimerEventWithTwoEventSubProcesses.bpmn20.xml" })
  public void testNonInterruptingStartTimerEventSubProcessesCalledFromCallActivity() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingStartTimerEventWithTwoEventSubProcesses");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(1, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // get all timer jobs ordered by dueDate
    List<Job> orderedJobList = jobQuery.orderByJobDuedate().asc().list();
    // execute first timer job
    managementService.executeJob(orderedJobList.get(0).getId());
    assertEquals(1, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    DummyServiceTask.wasExecuted = false;

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer start event is non
    // interrupting
    assertEquals(1, executionQuery.count());

    // execute second timer job
    managementService.executeJob(orderedJobList.get(1).getId());
    assertEquals(0, jobQuery.count());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // check if user task still exists because timer start event is non
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution still exists because timer event is non interrupting
    assertEquals(1, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  @Deployment
  public void testStartTimerEventSubProcessInMultiInstanceSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventSubProcessInMultiInstanceSubProcess");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    String jobIdFirstLoop = jobQuery.list().get(0).getId();
    // execute timer job
    managementService.executeJob(jobIdFirstLoop);

    assertEquals(true, DummyServiceTask.wasExecuted);
    DummyServiceTask.wasExecuted = false;

    // execute multiInstance loop number 2
    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(1, jobQuery.count());
    String jobIdSecondLoop = jobQuery.list().get(0).getId();
    assertNotSame(jobIdFirstLoop, jobIdSecondLoop);
    // execute timer job
    managementService.executeJob(jobIdSecondLoop);

    assertEquals(true, DummyServiceTask.wasExecuted);

    // multiInstance loop finished
    assertEquals(0, jobQuery.count());

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    assertProcessEnded(processInstance.getId());
  }

  @Deployment
  public void testNonInterruptingStartTimerEventInMultiInstanceEventSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingStartTimerEventInMultiInstanceEventSubProcess");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(1, jobQuery.count());
    String jobIdFirstLoop = jobQuery.list().get(0).getId();
    // execute timer job
    managementService.executeJob(jobIdFirstLoop);

    assertEquals(true, DummyServiceTask.wasExecuted);
    DummyServiceTask.wasExecuted = false;

    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    // complete existing task to start new execution for multi instance loop
    // number 2
    taskService.complete(taskQuery.list().get(0).getId());

    // execute multiInstance loop number 2
    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(1, jobQuery.count());
    String jobIdSecondLoop = jobQuery.list().get(0).getId();
    assertNotSame(jobIdFirstLoop, jobIdSecondLoop);
    // execute timer job
    managementService.executeJob(jobIdSecondLoop);

    assertEquals(true, DummyServiceTask.wasExecuted);

    // multiInstance loop finished
    assertEquals(0, jobQuery.count());

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(1, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(2, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  @Deployment
  public void testStartTimerEventSubProcessInParallelMultiInstanceSubProcess() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("startTimerEventSubProcessInParallelMultiInstanceSubProcess");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(6, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // execute timer job
    for (Job job : jobQuery.list()) {
      managementService.executeJob(job.getId());

      assertEquals(true, DummyServiceTask.wasExecuted);
      DummyServiceTask.wasExecuted = false;
    }

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(0, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(0, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());

  }

  @Deployment
  public void testNonInterruptingStartTimerEventSubProcessWithParallelMultiInstance() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nonInterruptingParallelMultiInstance");

    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(6, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(2, jobQuery.count());
    // execute all timer jobs
    for (Job job : jobQuery.list()) {
      managementService.executeJob(job.getId());

      assertEquals(true, DummyServiceTask.wasExecuted);
      DummyServiceTask.wasExecuted = false;
    }

    assertEquals(0, jobQuery.count());

    // check if user task doesn't exist because timer start event is
    // interrupting
    assertEquals(2, taskQuery.count());

    // check if execution doesn't exist because timer start event is
    // interrupting
    assertEquals(6, executionQuery.count());

    // check if process instance doesn't exist because timer start event is
    // interrupting
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  /**
   * test scenario: - start process instance with multiInstance sequential -
   * execute interrupting timer job of event subprocess - execute non
   * interrupting timer boundary event of subprocess
   */
  @Deployment
  public void testStartTimerEventSubProcessInMultiInstanceSubProcessWithNonInterruptingBoundaryTimerEvent() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    // 1 start timer job and 1 boundary timer job
    assertEquals(2, jobQuery.count());
    // execute interrupting start timer event subprocess job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // after first interrupting start timer event sub process execution
    // multiInstance loop number 2
    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(2, jobQuery.count());

    // execute non interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after non interrupting boundary timer job execution
    assertEquals(1, jobQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(2, executionQuery.count());
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  /**
   * test scenario: - start process instance with multiInstance sequential -
   * execute interrupting timer job of event subprocess - execute interrupting
   * timer boundary event of subprocess
   */
  @Deployment
  public void testStartTimerEventSubProcessInMultiInstanceSubProcessWithInterruptingBoundaryTimerEvent() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    // 1 start timer job and 1 boundary timer job
    assertEquals(2, jobQuery.count());
    // execute interrupting start timer event subprocess job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // after first interrupting start timer event sub process execution
    // multiInstance loop number 2
    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(2, jobQuery.count());

    // execute interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after interrupting boundary timer job execution
    assertEquals(0, jobQuery.count());
    assertEquals(0, taskQuery.count());
    assertEquals(0, executionQuery.count());

    assertProcessEnded(processInstance.getId());

  }

  /**
   * test scenario: - start process instance with multiInstance sequential -
   * execute non interrupting timer job of event subprocess - execute
   * interrupting timer boundary event of subprocess
   */
  @Deployment
  public void testNonInterruptingStartTimerEventSubProcessInMultiInstanceSubProcessWithInterruptingBoundaryTimerEvent() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(2, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    // 1 start timer job and 1 boundary timer job
    assertEquals(2, jobQuery.count());
    // execute non interrupting start timer event subprocess job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // complete user task to finish execution of first multiInstance loop
    assertEquals(1, taskQuery.count());
    taskService.complete(taskQuery.list().get(0).getId());

    // after first non interrupting start timer event sub process execution
    // multiInstance loop number 2
    assertEquals(2, executionQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(2, jobQuery.count());

    // execute interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after interrupting boundary timer job execution
    assertEquals(0, jobQuery.count());
    assertEquals(0, taskQuery.count());
    assertEquals(0, executionQuery.count());
    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(0, processInstanceQuery.count());

  }

  /**
   * test scenario: - start process instance with multiInstance parallel -
   * execute interrupting timer job of event subprocess - execute non
   * interrupting timer boundary event of subprocess
   */
  @Deployment
  public void testStartTimerEventSubProcessInParallelMultiInstanceSubProcessWithNonInterruptingBoundaryTimerEvent() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(6, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(3, jobQuery.count());

    // execute interrupting timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // after interrupting timer job execution
    assertEquals(2, jobQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(5, executionQuery.count());

    // execute non interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after non interrupting boundary timer job execution
    assertEquals(1, jobQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(5, executionQuery.count());

    ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId());
    assertEquals(1, processInstanceQuery.count());

  }

  /**
   * test scenario: - start process instance with multiInstance parallel -
   * execute interrupting timer job of event subprocess - execute interrupting
   * timer boundary event of subprocess
   */
  @Deployment
  public void testStartTimerEventSubProcessInParallelMultiInstanceSubProcessWithInterruptingBoundaryTimerEvent() {
    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(6, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(3, jobQuery.count());

    // execute interrupting timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    // after interrupting timer job execution
    assertEquals(2, jobQuery.count());
    assertEquals(1, taskQuery.count());
    assertEquals(5, executionQuery.count());

    // execute interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after interrupting boundary timer job execution
    assertEquals(0, jobQuery.count());
    assertEquals(0, taskQuery.count());
    assertEquals(0, executionQuery.count());

    assertProcessEnded(processInstance.getId());

  }

  /**
   * test scenario: - start process instance with multiInstance parallel -
   * execute non interrupting timer job of event subprocess - execute
   * interrupting timer boundary event of subprocess
   */
  @Deployment
  public void testNonInterruptingStartTimerEventSubProcessInParallelMiSubProcessWithInterruptingBoundaryTimerEvent() {
    DummyServiceTask.wasExecuted = false;

    // start process instance
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process");

    // execute multiInstance loop number 1
    // check if execution exists
    ExecutionQuery executionQuery = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId());
    assertEquals(6, executionQuery.count());

    // check if user task exists
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.count());

    JobQuery jobQuery = managementService.createJobQuery();
    assertEquals(3, jobQuery.count());

    // execute non interrupting timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(1).getId());

    assertEquals(true, DummyServiceTask.wasExecuted);

    // after non interrupting timer job execution
    assertEquals(2, jobQuery.count());
    assertEquals(2, taskQuery.count());
    assertEquals(6, executionQuery.count());

    // execute interrupting boundary timer job
    managementService.executeJob(jobQuery.orderByJobDuedate().asc().list().get(0).getId());

    // after interrupting boundary timer job execution
    assertEquals(0, jobQuery.count());
    assertEquals(0, taskQuery.count());
    assertEquals(0, executionQuery.count());

    assertProcessEnded(processInstance.getId());

    // start process instance again and
    // test if boundary events deleted after all tasks are completed
    processInstance = runtimeService.startProcessInstanceByKey("process");
    jobQuery = managementService.createJobQuery();
    assertEquals(3, jobQuery.count());

    assertEquals(2, taskQuery.count());
    // complete all existing tasks
    for (Task task : taskQuery.list()) {
      taskService.complete(task.getId());
    }

    assertEquals(0, jobQuery.count());
    assertEquals(0, taskQuery.count());
    assertEquals(0, executionQuery.count());

    assertProcessEnded(processInstance.getId());

  }

  // util methods ////////////////////////////////////////

  /**
   * executes all jobs in this threads until they are either done or retries are
   * exhausted.
   */
  protected void executeAllJobs() {
    String nextJobId = getNextExecutableJobId();

    while (nextJobId != null) {
      try {
        managementService.executeJob(nextJobId);
      } catch (Throwable t) { /* ignore */
      }
      nextJobId = getNextExecutableJobId();
    }

  }

  protected String getNextExecutableJobId() {
    List<Job> jobs = managementService.createJobQuery().executable().listPage(0, 1);
    if (jobs.size() == 1) {
      return jobs.get(0).getId();
    } else {
      return null;
    }
  }

  private void cleanDB() {
    String jobId = managementService.createJobQuery().singleResult().getId();
    CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    commandExecutor.execute(new DeleteJobsCmd(jobId));
  }

}
TOP

Related Classes of org.camunda.bpm.engine.test.bpmn.event.timer.StartTimerEventTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.