content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * 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.activiti.engine.test.api.repository;
  
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
  
  import java.util.Date;
  import java.util.List;
  import org.activiti.engine.ActivitiException;
  import org.activiti.engine.impl.test.PluggableActivitiTestCase;
  import org.activiti.engine.repository.ProcessDefinition;
  import org.activiti.engine.runtime.ProcessInstance;
  import org.activiti.engine.task.Task;
  import org.activiti.engine.test.Deployment;
  
  public class ProcessDefinitionSuspensionTest extends PluggableActivitiTestCase {
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testProcessDefinitionActiveByDefault() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testSuspendActivateProcessDefinitionById() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
  
          // suspend
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
          processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isTrue();
  
          // activate
          repositoryService.activateProcessDefinitionById(processDefinition.getId());
          processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testSuspendActivateProcessDefinitionByKey() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
  
          // suspend
          repositoryService.suspendProcessDefinitionByKey(processDefinition.getKey());
          processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isTrue();
  
          // activate
          repositoryService.activateProcessDefinitionByKey(processDefinition.getKey());
          processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testCannotActivateActiveProcessDefinition() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
  
          assertThatExceptionOfType(ActivitiException.class).isThrownBy(() ->
              repositoryService.activateProcessDefinitionById(processDefinition.getId())
          );
      }
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testCannotSuspendActiveProcessDefinition() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          assertThat(processDefinition.isSuspended()).isFalse();
  
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          assertThatExceptionOfType(ActivitiException.class).isThrownBy(() ->
              repositoryService.suspendProcessDefinitionById(processDefinition.getId())
          );
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/db/processOne.bpmn20.xml", "org/activiti/engine/test/db/processTwo.bpmn20.xml",
          }
      )
      public void testQueryForActiveDefinitions() {
          // default = all definitions
          List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
          assertThat(processDefinitionList).hasSize(2);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(2);
  
          ProcessDefinition processDefinition = processDefinitionList.get(0);
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(2);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/db/processOne.bpmn20.xml", "org/activiti/engine/test/db/processTwo.bpmn20.xml",
          }
      )
      public void testQueryForSuspendedDefinitions() {
          // default = all definitions
          List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
          assertThat(processDefinitionList).hasSize(2);
  
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(2);
  
          ProcessDefinition processDefinition = processDefinitionList.get(0);
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(2);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(1);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/db/processOne.bpmn20.xml" })
      public void testStartProcessInstanceForSuspendedProcessDefinition() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          // By id
          assertThatExceptionOfType(ActivitiException.class)
              .isThrownBy(() -> runtimeService.startProcessInstanceById(processDefinition.getId()))
              .withMessageContaining("Cannot start process instance");
  
          // By Key
          assertThatExceptionOfType(ActivitiException.class)
              .isThrownBy(() -> runtimeService.startProcessInstanceByKey(processDefinition.getKey()))
              .withMessageContaining("Cannot start process instance");
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml" })
      public void testContinueProcessAfterProcessDefinitionSuspend() {
          // Start Process Instance
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          runtimeService.startProcessInstanceByKey(processDefinition.getKey());
  
          // Verify one task is created
          Task task = taskService.createTaskQuery().singleResult();
          assertThat(task).isNotNull();
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(1);
  
          // Suspend process definition
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          // Process should be able to continue
          taskService.complete(task.getId());
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(0);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml" })
      public void testSuspendProcessInstancesDuringProcessDefinitionSuspend() {
          int nrOfProcessInstances = 9;
  
          // Fire up a few processes for the deployed process definition
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          for (int i = 0; i < nrOfProcessInstances; i++) {
              runtimeService.startProcessInstanceByKey(processDefinition.getKey());
          }
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(nrOfProcessInstances);
  
          // Suspend process definitions and include process instances
          repositoryService.suspendProcessDefinitionById(processDefinition.getId(), true, null);
  
          // Verify all process instances are also suspended
          for (ProcessInstance processInstance : runtimeService.createProcessInstanceQuery().list()) {
              assertThat(processInstance.isSuspended()).isTrue();
          }
  
          // Verify all process instances can't be continued
          for (Task task : taskService.createTaskQuery().list()) {
              assertThatExceptionOfType(ActivitiException.class)
                  .as("A suspended task shouldn't be able to be continued")
                  .isThrownBy(() -> taskService.complete(task.getId()));
          }
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(0);
  
          // Activate the process definition again
          repositoryService.activateProcessDefinitionById(processDefinition.getId(), true, null);
  
          // Verify that all process instances can be completed
          for (Task task : taskService.createTaskQuery().list()) {
              taskService.complete(task.getId());
          }
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(0);
      }
  
      @Deployment
      public void testJobIsExecutedOnProcessDefinitionSuspend() {
          Date now = new Date();
          processEngineConfiguration.getClock().setCurrentTime(now);
  
          // Suspending the process definition should not stop the execution of
          // jobs
          // Added this test because in previous implementations, this was the
          // case.
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          runtimeService.startProcessInstanceById(processDefinition.getId());
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
          assertThat(managementService.createTimerJobQuery().count()).isEqualTo(1);
  
          // The jobs should simply be executed
          processEngineConfiguration.getClock().setCurrentTime(new Date(now.getTime() + (60 * 60 * 1000))); // Timer is set to fire on 5 minutes
          waitForJobExecutorToProcessAllJobs(2000L, 100L);
          assertThat(managementService.createJobQuery().count()).isEqualTo(0);
          assertThat(managementService.createTimerJobQuery().count()).isEqualTo(0);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml" })
      public void testDelayedSuspendProcessDefinition() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          Date startTime = new Date();
          processEngineConfiguration.getClock().setCurrentTime(startTime);
  
          // Suspend process definition in one week from now
          long oneWeekFromStartTime = startTime.getTime() + (7 * 24 * 60 * 60 * 1000);
          repositoryService.suspendProcessDefinitionById(
              processDefinition.getId(),
              false,
              new Date(oneWeekFromStartTime)
          );
  
          // Verify we can just start process instances
          runtimeService.startProcessInstanceById(processDefinition.getId());
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
  
          // verify there is a job created
          assertThat(
              managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).count()
          ).isEqualTo(1);
  
          // Move clock 8 days further and let job executor run
          long eightDaysSinceStartTime = oneWeekFromStartTime + (24 * 60 * 60 * 1000);
          processEngineConfiguration.getClock().setCurrentTime(new Date(eightDaysSinceStartTime));
          waitForJobExecutorToProcessAllJobs(5000L, 50L);
  
          // verify job is now removed
          assertThat(managementService.createJobQuery().processDefinitionId(processDefinition.getId()).count()).isEqualTo(
              0
          );
          assertThat(
              managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).count()
          ).isEqualTo(0);
  
          // Try to start process instance. It should fail now.
          assertThatExceptionOfType(ActivitiException.class)
              .isThrownBy(() -> runtimeService.startProcessInstanceById(processDefinition.getId()))
              .withMessageContaining("suspended");
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(1);
  
          // Activate again
          repositoryService.activateProcessDefinitionById(processDefinition.getId());
          runtimeService.startProcessInstanceById(processDefinition.getId());
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(2);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml" })
      public void testDelayedSuspendProcessDefinitionIncludingProcessInstances() {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          Date startTime = new Date();
          processEngineConfiguration.getClock().setCurrentTime(startTime);
  
          // Start some process instances
          int nrOfProcessInstances = 30;
          for (int i = 0; i < nrOfProcessInstances; i++) {
              runtimeService.startProcessInstanceById(processDefinition.getId());
          }
  
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(0);
          assertThat(taskService.createTaskQuery().suspended().count()).isEqualTo(0);
          assertThat(taskService.createTaskQuery().active().count()).isEqualTo(nrOfProcessInstances);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
  
          // Suspend process definition in one week from now
          long oneWeekFromStartTime = startTime.getTime() + (7 * 24 * 60 * 60 * 1000);
          repositoryService.suspendProcessDefinitionById(processDefinition.getId(), true, new Date(oneWeekFromStartTime));
  
          // Verify we can start process instances
          runtimeService.startProcessInstanceById(processDefinition.getId());
          nrOfProcessInstances = nrOfProcessInstances + 1;
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
  
          // verify there is a job created
          assertThat(
              managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).count()
          ).isEqualTo(1);
  
          // Move clock 9 days further and let job executor run
          long eightDaysSinceStartTime = oneWeekFromStartTime + (2 * 24 * 60 * 60 * 1000);
          processEngineConfiguration.getClock().setCurrentTime(new Date(eightDaysSinceStartTime));
          waitForJobExecutorToProcessAllJobs(30000L, 50L);
  
          // verify job is now removed
          assertThat(managementService.createJobQuery().processDefinitionId(processDefinition.getId()).count()).isEqualTo(
              0
          );
          assertThat(
              managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).count()
          ).isEqualTo(0);
  
          // Try to start process instance. It should fail now.
          assertThatExceptionOfType(ActivitiException.class)
              .isThrownBy(() -> runtimeService.startProcessInstanceById(processDefinition.getId()))
              .withMessageContaining("suspended");
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(nrOfProcessInstances);
          assertThat(taskService.createTaskQuery().suspended().count()).isEqualTo(nrOfProcessInstances);
          assertThat(taskService.createTaskQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(1);
  
          // Activate again
          repositoryService.activateProcessDefinitionById(processDefinition.getId(), true, null);
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(nrOfProcessInstances);
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(0);
          assertThat(taskService.createTaskQuery().suspended().count()).isEqualTo(0);
          assertThat(taskService.createTaskQuery().active().count()).isEqualTo(nrOfProcessInstances);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml" })
      public void testDelayedActivateProcessDefinition() {
          Date startTime = new Date();
          processEngineConfiguration.getClock().setCurrentTime(startTime);
  
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
          repositoryService.suspendProcessDefinitionById(processDefinition.getId());
  
          // Try to start process instance. It should fail now.
          assertThatExceptionOfType(ActivitiException.class)
              .isThrownBy(() -> runtimeService.startProcessInstanceById(processDefinition.getId()))
              .withMessageContaining("suspended");
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(1);
  
          // Activate in a day from now
          long oneDayFromStart = startTime.getTime() + (24 * 60 * 60 * 1000);
          repositoryService.activateProcessDefinitionById(processDefinition.getId(), false, new Date(oneDayFromStart));
  
          // Move clock two days and let job executor run
          long twoDaysFromStart = startTime.getTime() + (2 * 24 * 60 * 60 * 1000);
          processEngineConfiguration.getClock().setCurrentTime(new Date(twoDaysFromStart));
          waitForJobExecutorToProcessAllJobs(5000L, 50L);
  
          // Starting a process instance should now succeed
          runtimeService.startProcessInstanceById(processDefinition.getId());
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(1);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
      }
  
      public void testSuspendMultipleProcessDefinitionsByKey() {
          // Deploy three processes
          int nrOfProcessDefinitions = 3;
          for (int i = 0; i < nrOfProcessDefinitions; i++) {
              repositoryService
                  .createDeployment()
                  .addClasspathResource("org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml")
                  .deploy();
          }
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
  
          // Suspend all process definitions with same key
          repositoryService.suspendProcessDefinitionByKey("oneTaskProcess");
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(
              nrOfProcessDefinitions
          );
  
          // Activate again
          repositoryService.activateProcessDefinitionByKey("oneTaskProcess");
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
  
          // Start process instance
          runtimeService.startProcessInstanceByKey("oneTaskProcess");
  
          // And suspend again, cascading to process instances
          repositoryService.suspendProcessDefinitionByKey("oneTaskProcess", true, null);
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(
              nrOfProcessDefinitions
          );
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(1);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().count()).isEqualTo(1);
  
          // Clean DB
          for (org.activiti.engine.repository.Deployment deployment : repositoryService.createDeploymentQuery().list()) {
              repositoryService.deleteDeployment(deployment.getId(), true);
          }
      }
  
      public void testDelayedSuspendMultipleProcessDefinitionsByKey() {
          Date startTime = new Date();
          processEngineConfiguration.getClock().setCurrentTime(startTime);
          final long hourInMs = 60 * 60 * 1000;
  
          // Deploy five versions of the same process
          int nrOfProcessDefinitions = 5;
          for (int i = 0; i < nrOfProcessDefinitions; i++) {
              repositoryService
                  .createDeployment()
                  .addClasspathResource("org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml")
                  .deploy();
          }
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
  
          // Start process instance
          runtimeService.startProcessInstanceByKey("oneTaskProcess");
  
          // Suspend all process definitions with same key in 2 hours from now
          repositoryService.suspendProcessDefinitionByKey(
              "oneTaskProcess",
              true,
              new Date(startTime.getTime() + (2 * hourInMs))
          );
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(1);
  
          // Verify a job is created for each process definition
          assertThat(managementService.createTimerJobQuery().count()).isEqualTo(nrOfProcessDefinitions);
          for (ProcessDefinition processDefinition : repositoryService.createProcessDefinitionQuery().list()) {
              assertThat(
                  managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).count()
              ).isEqualTo(1);
          }
  
          // Move time 3 hours and run job executor
          processEngineConfiguration.getClock().setCurrentTime(new Date(startTime.getTime() + (3 * hourInMs)));
          waitForJobExecutorToProcessAllJobsAndExecutableTimerJobs(30000L, 100L);
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(
              nrOfProcessDefinitions
          );
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(1);
  
          // Activate again in 5 hours from now
          repositoryService.activateProcessDefinitionByKey(
              "oneTaskProcess",
              true,
              new Date(startTime.getTime() + (5 * hourInMs))
          );
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(0);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(
              nrOfProcessDefinitions
          );
          assertThat(runtimeService.createProcessInstanceQuery().suspended().count()).isEqualTo(1);
  
          // Move time 6 hours and run job executor
          processEngineConfiguration.getClock().setCurrentTime(new Date(startTime.getTime() + (6 * hourInMs)));
          waitForJobExecutorToProcessAllJobsAndExecutableTimerJobs(60000L, 100L);
          assertThat(repositoryService.createProcessDefinitionQuery().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().active().count()).isEqualTo(nrOfProcessDefinitions);
          assertThat(repositoryService.createProcessDefinitionQuery().suspended().count()).isEqualTo(0);
          assertThat(runtimeService.createProcessInstanceQuery().active().count()).isEqualTo(1);
  
          // Clean DB
          for (org.activiti.engine.repository.Deployment deployment : repositoryService.createDeploymentQuery().list()) {
              repositoryService.deleteDeployment(deployment.getId(), true);
          }
      }
  }
  