public virtual void testMigrateCompensationSubscriptionAddRemoveSubProcess()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(CompensationModels.COMPENSATION_ONE_TASK_SUBPROCESS_MODEL);
            var targetProcessDefinition =
                testHelper.DeployAndGetDefinition(CompensationModels.COMPENSATION_ONE_TASK_SUBPROCESS_MODEL);

            // subProcess is not mapped
            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("userTask2", "userTask2")
                .MapActivities("compensationBoundary", "compensationBoundary")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            testHelper.CompleteTask("userTask1");

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            testHelper.AssertEventSubscriptionMigrated("compensationHandler", "compensationHandler", null);

            // and the compensation can be triggered and completed
            testHelper.CompleteTask("userTask2");
            testHelper.CompleteTask("compensationHandler");

            testHelper.AssertProcessEnded(processInstance.Id);
        }
        public virtual void testMigrateGatewayWithIncident()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(EventBasedGatewayModels.TIMER_EVENT_BASED_GW_PROCESS);
            var targetProcessDefinition =
                testHelper.DeployAndGetDefinition(EventBasedGatewayModels.TIMER_EVENT_BASED_GW_PROCESS);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("eventBasedGateway", "eventBasedGateway")
                .MapActivities("timerCatch", "timerCatch")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(migrationPlan.SourceProcessDefinitionId);

            var timerJob = rule.ManagementService.CreateJobQuery()
                           .First();

            // create an incident
            rule.ManagementService.SetJobRetries(timerJob.Id, 0);
            var incidentBeforeMigration = rule.RuntimeService.CreateIncidentQuery()
                                          .First();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then job and incident still exist
            testHelper.AssertIntermediateTimerJobMigrated("timerCatch", "timerCatch");

            var jobAfterMigration = testHelper.SnapshotAfterMigration.Jobs[0];

            var incidentAfterMigration = rule.RuntimeService.CreateIncidentQuery()
                                         .First();

            Assert.NotNull(incidentAfterMigration);

            Assert.AreEqual(incidentBeforeMigration.Id, incidentAfterMigration.Id);
            Assert.AreEqual(jobAfterMigration.Id, incidentAfterMigration.Configuration);

            Assert.AreEqual("timerCatch", incidentAfterMigration.ActivityId);
            Assert.AreEqual(targetProcessDefinition.Id, incidentAfterMigration.ProcessDefinitionId);

            // and it is possible to complete the process
            rule.ManagementService.ExecuteJob(jobAfterMigration.Id);

            testHelper.CompleteTask("afterTimerCatch");
            testHelper.AssertProcessEnded(processInstance.Id);
        }
Exemple #3
0
        public virtual void testMigrateEventSubProcessToTransaction()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(EventSubProcessModels.MESSAGE_EVENT_SUBPROCESS_PROCESS);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(TransactionModels.ONE_TASK_TRANSACTION);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("eventSubProcess", "transaction")
                .MapActivities("eventSubProcessTask", "userTask")
                .Build();

            // when
            var processInstance = rule.RuntimeService.CreateProcessInstanceById(sourceProcessDefinition.Id)
                                  .StartBeforeActivity("eventSubProcessTask")
                                  .Execute();

            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            Assert.AreEqual(testHelper.GetSingleActivityInstanceBeforeMigration("eventSubProcess")
                            .Id, testHelper.GetSingleActivityInstanceAfterMigration("transaction")
                            .Id);

            testHelper.CompleteTask("userTask");
            testHelper.AssertProcessEnded(processInstance.Id);
        }
        public virtual void testMigrateIncidentForJob()
        {
            // given
//JAVA TO C# CONVERTER WARNING: The .NET Type.FullName property will not always yield results identical to the Java Class.GetName method:
            var sourceProcess = ModifiableBpmnModelInstance.Modify(ProcessModels.OneTaskProcess)
                                .UserTaskBuilder(USER_TASK_ID)
                                .BoundaryEvent(BOUNDARY_ID)
                                .TimerWithDate(TIMER_DATE)
                                .ServiceTask("failingTask")
                                .CamundaClass(typeof(FailingDelegate).FullName)
                                .EndEvent()
                                .Done();
            IBpmnModelInstance targetProcess = ModifiableBpmnModelInstance.Modify(sourceProcess)
                                               .ChangeElementId(USER_TASK_ID, "newUserTask")
                                               .ChangeElementId(BOUNDARY_ID, "newBoundary");

            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(sourceProcess);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(targetProcess);

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            // a timer job exists
            var jobBeforeMigration = rule.ManagementService.CreateJobQuery()
                                     .First();

            Assert.NotNull(jobBeforeMigration);

            // if the timer job is triggered the failing delegate fails and an incident is created
            executeJob(jobBeforeMigration);
            var incidentBeforeMigration = rule.RuntimeService.CreateIncidentQuery()
                                          .First();

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities(USER_TASK_ID, "newUserTask")
                .MapActivities(BOUNDARY_ID, "newBoundary")
                .Build();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then the job and incident still exists
            var jobAfterMigration = rule.ManagementService.CreateJobQuery(c => c.Id == jobBeforeMigration.Id)
                                    .First();

            Assert.NotNull(jobAfterMigration);
            var incidentAfterMigration = rule.RuntimeService.CreateIncidentQuery()
                                         .First();

            Assert.NotNull(incidentAfterMigration);

            // and it is still the same incident
            Assert.AreEqual(incidentBeforeMigration.Id, incidentAfterMigration.Id);
            Assert.AreEqual(jobAfterMigration.Id, incidentAfterMigration.Configuration);

            // and the activity, process definition and job definition references were updated
            Assert.AreEqual("newBoundary", incidentAfterMigration.ActivityId);
            Assert.AreEqual(targetProcessDefinition.Id, incidentAfterMigration.ProcessDefinitionId);
            Assert.AreEqual(jobAfterMigration.JobDefinitionId, incidentAfterMigration.JobDefinitionId);
        }
Exemple #5
0
        public virtual void testRemoveParallelMultiInstanceBodyOneInstanceFinished()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(MultiInstanceProcessModels.PAR_MI_ONE_TASK_PROCESS);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(ProcessModels.OneTaskProcess);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("userTask", "userTask")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(migrationPlan.SourceProcessDefinitionId);

            var firstTask = rule.TaskService.CreateTaskQuery()
                            ///*.ListPage(0, 1)*/
                            .ToList()
                            [0];

            rule.TaskService.Complete(firstTask.Id);

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            testHelper.AssertExecutionTreeAfterMigration()
            .HasProcessDefinitionId(targetProcessDefinition.Id)
            .Matches(ExecutionAssert.DescribeExecutionTree(null)
                     .Scope()
                     .Id(testHelper.SnapshotBeforeMigration.ProcessInstanceId)
                     .Child("userTask")
                     .Concurrent()
                     .NoScope()
                     .Up()
                     .Child("userTask")
                     .Concurrent()
                     .NoScope()
                     .Done());

            var userTaskInstances = testHelper.SnapshotBeforeMigration.ActivityTree.GetActivityInstances("userTask");

            testHelper.AssertActivityTreeAfterMigration()
            .HasStructure(ActivityInstanceAssert.DescribeActivityInstanceTree(targetProcessDefinition.Id)
                          .Activity("userTask", userTaskInstances[0].Id)
                          .Activity("userTask", userTaskInstances[1].Id)
                          .Done());

            var migratedTasks = testHelper.SnapshotAfterMigration.Tasks;

            Assert.AreEqual(2, migratedTasks.Count);

            // and it is possible to successfully complete the migrated instance
            foreach (var migratedTask in migratedTasks)
            {
                rule.TaskService.Complete(migratedTask.Id);
            }
            testHelper.AssertProcessEnded(testHelper.SnapshotBeforeMigration.ProcessInstanceId);
        }
Exemple #6
0
        public virtual void testMigrateParallelMultiInstanceTasksVariables()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(MultiInstanceProcessModels.PAR_MI_ONE_TASK_PROCESS);
            var targetProcessDefinition =
                testHelper.DeployAndGetDefinition(MultiInstanceProcessModels.PAR_MI_ONE_TASK_PROCESS);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities(miBodyOf("userTask"), miBodyOf("userTask"))
                .MapActivities("userTask", "userTask")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(migrationPlan.SourceProcessDefinitionId);

            var tasksBeforeMigration = rule.TaskService.CreateTaskQuery()

                                       .ToList();
            IDictionary <string, int?> loopCounterDistribution = new Dictionary <string, int?>();

            foreach (var task in tasksBeforeMigration)
            {
                var loopCounter = (int?)rule.TaskService.GetVariable(task.Id, LOOP_COUNTER);
                loopCounterDistribution[task.Id] = loopCounter;
            }

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            var tasks     = testHelper.SnapshotAfterMigration.Tasks;
            var firstTask = tasks[0];

            Assert.AreEqual(3, rule.TaskService.GetVariable(firstTask.Id, NUMBER_OF_INSTANCES));
            Assert.AreEqual(3, rule.TaskService.GetVariable(firstTask.Id, NUMBER_OF_ACTIVE_INSTANCES));
            Assert.AreEqual(0, rule.TaskService.GetVariable(firstTask.Id, NUMBER_OF_COMPLETED_INSTANCES));

            foreach (var task in tasks)
            {
                var loopCounter = (int?)rule.TaskService.GetVariable(task.Id, LOOP_COUNTER);
                Assert.NotNull(loopCounter);
                Assert.AreEqual(loopCounterDistribution[task.Id], loopCounter);
            }
        }
        public virtual void testParallelGatewayContinueExecution()
        {
            // given
            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(GatewayModels.PARALLEL_GW);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(GatewayModels.PARALLEL_GW);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("parallel1", "parallel1")
                .MapActivities("join", "join")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            testHelper.CompleteTask("parallel2");

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            Assert.AreEqual(1, rule.TaskService.CreateTaskQuery()
                            .Count());
            Assert.AreEqual(0, rule.TaskService.CreateTaskQuery(c => c.TaskDefinitionKeyWithoutCascade == "afterJoin")
                            .Count());

            testHelper.CompleteTask("parallel1");
            testHelper.CompleteTask("afterJoin");
            testHelper.AssertProcessEnded(processInstance.Id);
        }
Exemple #8
0
        public virtual void testRemoveIncidentForJob()
        {
            // given
            var sourceProcess = ModifiableBpmnModelInstance.Modify(ProcessModels.OneTaskProcess)
                                .UserTaskBuilder("userTask")
                                .BoundaryEvent("boundary")
                                .TimerWithDate(TIMER_DATE)
                                .ServiceTask("failingTask")
                                .CamundaClass("api.Runtime.FailingDelegate")
                                .EndEvent()
                                .Done();
            IBpmnModelInstance targetProcess = ModifiableBpmnModelInstance.Modify(sourceProcess)
                                               .ChangeElementId("userTask", "newUserTask")
                                               .ChangeElementId("boundary", "newBoundary");

            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(sourceProcess);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(targetProcess);

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            // a timer job exists
            var jobBeforeMigration = rule.ManagementService.CreateJobQuery()
                                     .First();

            Assert.NotNull(jobBeforeMigration);

            // if the timer job is triggered the failing delegate fails and an incident is created
            executeJob(jobBeforeMigration);
            var incidentBeforeMigration = rule.RuntimeService.CreateIncidentQuery()
                                          .First();

            Assert.AreEqual("boundary", incidentBeforeMigration.ActivityId);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("userTask", "newUserTask")
                .Build();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then the incident was removed
            var jobAfterMigration = rule.ManagementService.CreateJobQuery(c => c.Id == jobBeforeMigration.Id)
                                    .First();

            Assert.IsNull(jobAfterMigration);

            Assert.AreEqual(0, rule.RuntimeService.CreateIncidentQuery()
                            .Count());
        }
        public virtual void testMigrateEventSubprocessSignalTrigger()
        {
            var processModel = ProcessModels.OneTaskProcess.Clone();
            var eventTrigger = eventFactory.AddEventSubProcess(rule.ProcessEngine, processModel,
                                                               ProcessModels.ProcessKey, "eventSubProcess", "eventSubProcessStart");

            ModifiableBpmnModelInstance.Wrap(processModel)
            .StartEventBuilder("eventSubProcessStart")
            .UserTask("eventSubProcessTask")
            .EndEvent()
            .Done();

            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(processModel);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(processModel);

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("userTask", "userTask")
                .MapActivities("eventSubProcessStart", "eventSubProcessStart")
                .UpdateEventTrigger()
                .Build();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            eventTrigger.AssertEventTriggerMigrated(testHelper, "eventSubProcessStart");

            // and it is possible to trigger the event subprocess
            eventTrigger.Trigger(processInstance.Id);
            Assert.AreEqual(1, rule.TaskService.CreateTaskQuery()
                            .Count());

            // and complete the process instance
            testHelper.CompleteTask("eventSubProcessTask");
            testHelper.AssertProcessEnded(processInstance.Id);
        }
Exemple #10
0
        public virtual void testMigrateActiveCompensationEventSubProcess()
        {
            // given
            var processModel = ProcessModels.OneTaskProcess.Clone();
            var eventTrigger = eventFactory.AddEventSubProcess(rule.ProcessEngine, processModel,
                                                               ProcessModels.ProcessKey, "eventSubProcess", "eventSubProcessStart");

            ModifiableBpmnModelInstance.Wrap(processModel)
            .StartEventBuilder("eventSubProcessStart")
            .UserTask("eventSubProcessTask")
            .EndEvent()
            .Done();

            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(processModel);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(processModel);

            IProcessInstance processInstance = rule.RuntimeService.CreateProcessInstanceById(sourceProcessDefinition.Id)
                                               .StartBeforeActivity("eventSubProcessStart")
                                               .ExecuteWithVariablesInReturn();

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("eventSubProcess", "eventSubProcess")
                .MapActivities("eventSubProcessStart", "eventSubProcessStart")
                .UpdateEventTrigger()
                .MapActivities("eventSubProcessTask", "eventSubProcessTask")
                .Build();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            eventTrigger.AssertEventTriggerMigrated(testHelper, "eventSubProcessStart");

            // and it is possible to complete the process instance
            testHelper.CompleteTask("eventSubProcessTask");
            testHelper.AssertProcessEnded(processInstance.Id);
        }
        public virtual void testTrees()
        {
            // given
            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(ExternalTaskModels.ONE_EXTERNAL_TASK_PROCESS);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(ExternalTaskModels.ONE_EXTERNAL_TASK_PROCESS);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("externalTask", "externalTask")
                .Build();

            var processInstance = rule.RuntimeService.StartProcessInstanceById(sourceProcessDefinition.Id);

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then the execution and activity instance tree are exactly as before migration
            testHelper.AssertExecutionTreeAfterMigration()
            .HasProcessDefinitionId(targetProcessDefinition.Id)
            .Matches(ExecutionAssert.DescribeExecutionTree(null)
                     .Scope()
                     .Id(testHelper.SnapshotBeforeMigration.ProcessInstanceId)
                     .Child("externalTask")
                     .Scope()
                     .Id(testHelper.GetSingleExecutionIdForActivityBeforeMigration("externalTask"))
                     .Done());

            testHelper.AssertActivityTreeAfterMigration()
            .HasStructure(ActivityInstanceAssert.DescribeActivityInstanceTree(targetProcessDefinition.Id)
                          .Activity("externalTask", testHelper.GetSingleActivityInstanceBeforeMigration("externalTask")
                                    .Id)
                          .Done());
        }
Exemple #12
0
        public virtual void testVariableAtScopeExecutionInScopeActivity()
        {
            // given
            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(ONE_BOUNDARY_TASK);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(ONE_BOUNDARY_TASK);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapEqualActivities()
                .Build();

            var processInstance = runtimeService.StartProcessInstanceById(sourceProcessDefinition.Id);
            var executionTreeBeforeMigration = ExecutionTree.ForExecution(processInstance.Id, rule.ProcessEngine);

            var scopeExecution = executionTreeBeforeMigration.Executions[0];

            runtimeService.SetVariableLocal(scopeExecution.Id, "foo", 42);

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            var beforeMigration = testHelper.SnapshotBeforeMigration.GetSingleVariable("foo");

            Assert.AreEqual(1, testHelper.SnapshotAfterMigration.GetVariables()
                            .Count);
            testHelper.AssertVariableMigratedToExecution(beforeMigration, beforeMigration.ExecutionId);
        }
        public virtual void testMigrateActiveEventSubProcess()
        {
            // given
            var sourceProcessDefinition =
                testHelper.DeployAndGetDefinition(EventSubProcessModels.MESSAGE_EVENT_SUBPROCESS_PROCESS);
            var targetProcessDefinition =
                testHelper.DeployAndGetDefinition(EventSubProcessModels.MESSAGE_EVENT_SUBPROCESS_PROCESS);

            var processInstance = rule.RuntimeService.CreateProcessInstanceById(sourceProcessDefinition.Id)
                                  .StartBeforeActivity(EVENT_SUB_PROCESS_TASK_ID)
                                  .Execute();

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("eventSubProcess", "eventSubProcess")
                .MapActivities(EVENT_SUB_PROCESS_TASK_ID, EVENT_SUB_PROCESS_TASK_ID)
                .Build();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            testHelper.AssertExecutionTreeAfterMigration()
            .HasProcessDefinitionId(targetProcessDefinition.Id)
            .Matches(ExecutionAssert.DescribeExecutionTree(null)
                     .Scope()
                     .Id(processInstance.Id)
                     .Child(EVENT_SUB_PROCESS_TASK_ID)
                     .Scope()
                     .Id(testHelper.GetSingleExecutionIdForActivityBeforeMigration("eventSubProcess"))
                     .Done());

            testHelper.AssertActivityTreeAfterMigration()
            .HasStructure(ActivityInstanceAssert.DescribeActivityInstanceTree(targetProcessDefinition.Id)
                          .BeginScope("eventSubProcess",
                                      testHelper.GetSingleActivityInstanceBeforeMigration("eventSubProcess")
                                      .Id)
                          .Activity(EVENT_SUB_PROCESS_TASK_ID,
                                    testHelper.GetSingleActivityInstanceBeforeMigration(EVENT_SUB_PROCESS_TASK_ID)
                                    .Id)
                          .Done());

            testHelper.AssertEventSubscriptionRemoved(EVENT_SUB_PROCESS_START_ID, EventSubProcessModels.MESSAGE_NAME);
            testHelper.AssertEventSubscriptionCreated(EVENT_SUB_PROCESS_START_ID, EventSubProcessModels.MESSAGE_NAME);

            // and it is possible to complete the process instance
            testHelper.CompleteTask(EVENT_SUB_PROCESS_TASK_ID);
            testHelper.AssertProcessEnded(processInstance.Id);
        }
Exemple #14
0
        public virtual void testMultipleInstancesOfScope()
        {
            var sourceProcessDefinition = testHelper.DeployAndGetDefinition(ProcessModels.SubprocessProcess);
            var targetProcessDefinition = testHelper.DeployAndGetDefinition(ProcessModels.DoubleSubprocessProcess);

            var migrationPlan =
                rule.RuntimeService.CreateMigrationPlan(sourceProcessDefinition.Id, targetProcessDefinition.Id)
                .MapActivities("userTask", "userTask")
                .MapActivities("subProcess", "outerSubProcess")
                .Build();

            var processInstance = rule.RuntimeService.CreateProcessInstanceById(sourceProcessDefinition.Id)
                                  .StartBeforeActivity("subProcess")
                                  .StartBeforeActivity("subProcess")
                                  .Execute();

            // when
            testHelper.MigrateProcessInstance(migrationPlan, processInstance);

            // then
            testHelper.AssertExecutionTreeAfterMigration()
            .HasProcessDefinitionId(targetProcessDefinition.Id)
            .Matches(ExecutionAssert.DescribeExecutionTree(null)
                     .Scope()
                     .Id(testHelper.SnapshotBeforeMigration.ProcessInstanceId)
                     .Child(null)
                     .Concurrent()
                     .NoScope()
                     .Child(null)
                     .Scope()
                     .Child("userTask")
                     .Scope()
                     .Up()
                     .Up()
                     .Up()
                     .Child(null)
                     .Concurrent()
                     .NoScope()
                     .Child(null)
                     .Scope()
                     .Child("userTask")
                     .Scope()
                     .Done());

            var activityInstance = testHelper.SnapshotBeforeMigration.ActivityTree;

            testHelper.AssertActivityTreeAfterMigration()
            .HasStructure(ActivityInstanceAssert.DescribeActivityInstanceTree(targetProcessDefinition.Id)
                          .BeginScope("outerSubProcess", activityInstance.GetActivityInstances("subProcess")[0].Id)
                          .BeginScope("innerSubProcess")
                          .Activity("userTask",
                                    activityInstance.GetActivityInstances("subProcess")[0].GetActivityInstances("userTask")[0].Id)
                          .EndScope()
                          .EndScope()
                          .BeginScope("outerSubProcess", activityInstance.GetActivityInstances("subProcess")[1].Id)
                          .BeginScope("innerSubProcess")
                          .Activity("userTask",
                                    activityInstance.GetActivityInstances("subProcess")[1].GetActivityInstances("userTask")[0].Id)
                          .Done());

            var migratedTasks = testHelper.SnapshotAfterMigration.Tasks;

            Assert.AreEqual(2, migratedTasks.Count);

            foreach (var migratedTask in migratedTasks)
            {
                Assert.AreEqual(targetProcessDefinition.Id, migratedTask.ProcessDefinitionId);
            }

            // and it is possible to successfully complete the migrated instance
            foreach (var migratedTask in migratedTasks)
            {
                rule.TaskService.Complete(migratedTask.Id);
            }
            testHelper.AssertProcessEnded(testHelper.SnapshotBeforeMigration.ProcessInstanceId);
        }