diff --git a/.gitignore b/.gitignore index d16de1656..c58f8c2ea 100644 --- a/.gitignore +++ b/.gitignore @@ -277,3 +277,4 @@ coverage.xml .c9revisions .idea /venv +*~ \ No newline at end of file diff --git a/Makefile b/Makefile index 61cee6b53..a8b9819cd 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ tests-par: echo " pip install unittest-parallel"; \ exit 1; \ fi - unittest-parallel --module-fixtures -vs tests/SpiffWorkflow -p \*Test.py -t . + unittest-parallel --module-fixtures -qbs tests/SpiffWorkflow -p \*Test.py -t . .PHONY : tests-cov tests-cov: diff --git a/tests/SpiffWorkflow/bpmn/ApprovalsTest.py b/tests/SpiffWorkflow/bpmn/ApprovalsTest.py index 9247dec99..ef1c3c515 100644 --- a/tests/SpiffWorkflow/bpmn/ApprovalsTest.py +++ b/tests/SpiffWorkflow/bpmn/ApprovalsTest.py @@ -46,6 +46,8 @@ class ApprovalsTest(BpmnWorkflowTestCase): def testRunThroughHappy(self): self.do_next_named_step('First_Approval_Wins.Manager_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') self.do_next_named_step('Approvals.Manager_Approval__P_') @@ -55,11 +57,15 @@ class ApprovalsTest(BpmnWorkflowTestCase): self.do_next_named_step('Parallel_Approvals_SP.Step1') self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') self.do_next_named_step('Parallel_Approvals_SP.Supervisor_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.Parallel_SP_Done') def testRunThroughHappyOtherOrders(self): self.do_next_named_step('First_Approval_Wins.Supervisor_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') self.do_next_named_step('Approvals.Supervisor_Approval__P_') @@ -69,11 +75,15 @@ class ApprovalsTest(BpmnWorkflowTestCase): self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') self.do_next_named_step('Parallel_Approvals_SP.Step1') self.do_next_named_step('Parallel_Approvals_SP.Supervisor_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.Parallel_SP_Done') def testSaveRestore(self): self.do_next_named_step('First_Approval_Wins.Manager_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.save_restore() self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') @@ -86,12 +96,16 @@ class ApprovalsTest(BpmnWorkflowTestCase): self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') self.do_next_exclusive_step('Parallel_Approvals_SP.Step1') self.do_next_exclusive_step('Parallel_Approvals_SP.Supervisor_Approval') + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.Parallel_SP_Done') def testSaveRestoreWaiting(self): self.do_next_named_step('First_Approval_Wins.Manager_Approval') self.save_restore() + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') self.save_restore() @@ -108,6 +122,8 @@ class ApprovalsTest(BpmnWorkflowTestCase): self.save_restore() self.do_next_exclusive_step('Parallel_Approvals_SP.Supervisor_Approval') self.save_restore() + self.complete_subworkflow() + self.complete_subworkflow() self.do_next_exclusive_step('Approvals.Parallel_SP_Done') diff --git a/tests/SpiffWorkflow/bpmn/BpmnWorkflowTestCase.py b/tests/SpiffWorkflow/bpmn/BpmnWorkflowTestCase.py index 5f9b797c6..1896acde8 100644 --- a/tests/SpiffWorkflow/bpmn/BpmnWorkflowTestCase.py +++ b/tests/SpiffWorkflow/bpmn/BpmnWorkflowTestCase.py @@ -118,6 +118,13 @@ class BpmnWorkflowTestCase(unittest.TestCase): tasks[0].set_data(**set_attribs) tasks[0].run() + def complete_subworkflow(self): + # A side effect of finer grained contol over task execution is that tasks require more explicit intervention + # to change states. Subworkflows tasks no longer go directly to ready when the subworkflow completes. + # So they may need to explicitly refreshed to become ready, and then run. + self.workflow.refresh_waiting_tasks() + self.workflow.do_engine_steps() + def save_restore(self): script_engine = self.workflow.script_engine diff --git a/tests/SpiffWorkflow/bpmn/CallActivityEndEventTest.py b/tests/SpiffWorkflow/bpmn/CallActivityEndEventTest.py index 2fa5adfc5..0dfd32ab9 100644 --- a/tests/SpiffWorkflow/bpmn/CallActivityEndEventTest.py +++ b/tests/SpiffWorkflow/bpmn/CallActivityEndEventTest.py @@ -6,6 +6,8 @@ from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine from SpiffWorkflow.bpmn.workflow import BpmnWorkflow from SpiffWorkflow.exceptions import WorkflowTaskException +from SpiffWorkflow.task import TaskState + from .BpmnWorkflowTestCase import BpmnWorkflowTestCase __author__ = 'kellym' @@ -34,13 +36,12 @@ class CallActivityTest(BpmnWorkflowTestCase): self.workflow = BpmnWorkflow(self.spec, self.subprocesses, script_engine=CustomScriptEngine()) self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertTrue(self.workflow.is_completed()) self.assertIsInstance(self.workflow.script_engine, CustomScriptEngine) if save_restore: self.save_restore() - # We have to reset the script engine after deserialize. - self.workflow.script_engine = CustomScriptEngine() # Get the subworkflow sub_task = self.workflow.get_tasks_from_spec_name('Sub_Bpmn_Task')[0] @@ -54,6 +55,7 @@ class CallActivityTest(BpmnWorkflowTestCase): # data should be removed in the final output as well. self.workflow = BpmnWorkflow(self.spec, self.subprocesses) self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertTrue(self.workflow.is_completed()) self.assertNotIn('remove_this_var', self.workflow.last_task.data.keys()) @@ -66,6 +68,8 @@ class CallActivityTest(BpmnWorkflowTestCase): self.assertEquals(2, len(context.exception.task_trace)) self.assertRegexpMatches(context.exception.task_trace[0], 'Create Data \(.*?call_activity_call_activity.bpmn\)') self.assertRegexpMatches(context.exception.task_trace[1], 'Get Data Call Activity \(.*?call_activity_with_error.bpmn\)') + task = self.workflow.get_tasks_from_spec_name('Sub_Bpmn_Task')[0] + self.assertEqual(task.state, TaskState.ERROR) def suite(): return unittest.TestLoader().loadTestsFromTestCase(CallActivityTest) diff --git a/tests/SpiffWorkflow/bpmn/CallActivitySubProcessPropTest.py b/tests/SpiffWorkflow/bpmn/CallActivitySubProcessPropTest.py index e540f717e..7a69539b8 100644 --- a/tests/SpiffWorkflow/bpmn/CallActivitySubProcessPropTest.py +++ b/tests/SpiffWorkflow/bpmn/CallActivitySubProcessPropTest.py @@ -27,6 +27,8 @@ class CallActivitySubProcessPropTest(BpmnWorkflowTestCase): def actualTest(self, save_restore=False): self.workflow.do_engine_steps() + self.complete_subworkflow() + self.complete_subworkflow() if save_restore: self.save_restore() self.assertTrue(self.workflow.is_completed()) diff --git a/tests/SpiffWorkflow/bpmn/CustomScriptTest.py b/tests/SpiffWorkflow/bpmn/CustomScriptTest.py index d2b218862..ddd5e143c 100644 --- a/tests/SpiffWorkflow/bpmn/CustomScriptTest.py +++ b/tests/SpiffWorkflow/bpmn/CustomScriptTest.py @@ -38,6 +38,8 @@ class CustomInlineScriptTest(BpmnWorkflowTestCase): def actual_test(self, save_restore): if save_restore: self.save_restore() self.workflow.do_engine_steps() + self.complete_subworkflow() + self.complete_subworkflow() if save_restore: self.save_restore() data = self.workflow.last_task.data self.assertEqual(data['c1'], 'HELLO') @@ -49,8 +51,9 @@ class CustomInlineScriptTest(BpmnWorkflowTestCase): ready_task.data = {'custom_function': "bill"} with self.assertRaises(WorkflowTaskException) as e: self.workflow.do_engine_steps() - self.assertTrue('' in str(e.exception)) self.assertTrue('custom_function' in str(e.exception)) + task = self.workflow.get_tasks_from_spec_name('Activity_1y303ko')[0] + self.assertEqual(task.state, TaskState.ERROR) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/DataObjectReferenceTest.py b/tests/SpiffWorkflow/bpmn/DataObjectReferenceTest.py index 584202900..45b52430f 100644 --- a/tests/SpiffWorkflow/bpmn/DataObjectReferenceTest.py +++ b/tests/SpiffWorkflow/bpmn/DataObjectReferenceTest.py @@ -72,6 +72,9 @@ class DataObjectReferenceTest(BpmnWorkflowTestCase): self.assertNotIn('obj_1', ready_tasks[0].data) self.assertEqual(self.workflow.data['obj_1'], 'hello') + if save_restore: + self.save_restore() + # Make sure data objects are accessible inside a subprocess self.workflow.do_engine_steps() ready_tasks = self.workflow.get_ready_user_tasks() diff --git a/tests/SpiffWorkflow/bpmn/ExclusiveGatewayNoDefaultTest.py b/tests/SpiffWorkflow/bpmn/ExclusiveGatewayNoDefaultTest.py index 58fdb5d66..93e9f3603 100644 --- a/tests/SpiffWorkflow/bpmn/ExclusiveGatewayNoDefaultTest.py +++ b/tests/SpiffWorkflow/bpmn/ExclusiveGatewayNoDefaultTest.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- - - - -import sys -import os import unittest -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..')) + from SpiffWorkflow.bpmn.workflow import BpmnWorkflow -from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase from SpiffWorkflow.exceptions import WorkflowException +from SpiffWorkflow.task import TaskState + +from .BpmnWorkflowTestCase import BpmnWorkflowTestCase __author__ = 'essweine' @@ -25,6 +22,8 @@ class ExclusiveGatewayNoDefaultTest(BpmnWorkflowTestCase): first = self.workflow.get_tasks_from_spec_name('StartEvent_1')[0] first.data = { 'x': 1 } self.assertRaises(WorkflowException, self.workflow.do_engine_steps) + task = self.workflow.get_tasks_from_spec_name('Gateway_CheckValue')[0] + self.assertEqual(task.state, TaskState.ERROR) def suite(): return unittest.TestLoader().loadTestsFromTestCase(ExclusiveGatewayNoDefaultTest) diff --git a/tests/SpiffWorkflow/bpmn/IOSpecTest.py b/tests/SpiffWorkflow/bpmn/IOSpecTest.py index fe8dc7dd4..963fa3368 100644 --- a/tests/SpiffWorkflow/bpmn/IOSpecTest.py +++ b/tests/SpiffWorkflow/bpmn/IOSpecTest.py @@ -62,6 +62,8 @@ class CallActivityDataTest(BpmnWorkflowTestCase): self.assertNotIn('unused', task.data) self.complete_subprocess() + # Refreshing causes the subprocess to become ready + self.workflow.refresh_waiting_tasks() task = self.workflow.get_tasks(TaskState.READY)[0] # Originals should not change self.assertEqual(task.data['in_1'], 1) @@ -80,13 +82,11 @@ class CallActivityDataTest(BpmnWorkflowTestCase): waiting = self.workflow.get_tasks(TaskState.WAITING) def complete_subprocess(self): - # When we complete, the subworkflow task will move from WAITING to READY - waiting = self.workflow.get_tasks(TaskState.WAITING) - while len(waiting) > 0: - next_task = self.workflow.get_tasks(TaskState.READY)[0] - next_task.run() - waiting = self.workflow.get_tasks(TaskState.WAITING) - + # Complete the ready tasks in the subprocess + ready = self.workflow.get_tasks(TaskState.READY) + while len(ready) > 0: + ready[0].run() + ready = self.workflow.get_tasks(TaskState.READY) class IOSpecOnTaskTest(BpmnWorkflowTestCase): diff --git a/tests/SpiffWorkflow/bpmn/InclusiveGatewayTest.py b/tests/SpiffWorkflow/bpmn/InclusiveGatewayTest.py index 1b46e29d4..1d3b987dc 100644 --- a/tests/SpiffWorkflow/bpmn/InclusiveGatewayTest.py +++ b/tests/SpiffWorkflow/bpmn/InclusiveGatewayTest.py @@ -1,5 +1,6 @@ from SpiffWorkflow.bpmn.workflow import BpmnWorkflow from SpiffWorkflow.exceptions import WorkflowTaskException +from SpiffWorkflow.task import TaskState from .BpmnWorkflowTestCase import BpmnWorkflowTestCase @@ -26,6 +27,8 @@ class InclusiveGatewayTest(BpmnWorkflowTestCase): def testNoPathFromSecondGateway(self): self.set_data({'v': 0, 'u': -1, 'w': -1}) self.assertRaises(WorkflowTaskException, self.workflow.do_engine_steps) + task = self.workflow.get_tasks_from_spec_name('second')[0] + self.assertEqual(task.state, TaskState.ERROR) def testParallelCondition(self): self.set_data({'v': 0, 'u': 1, 'w': 1}) diff --git a/tests/SpiffWorkflow/bpmn/NestedProcessesTest.py b/tests/SpiffWorkflow/bpmn/NestedProcessesTest.py index 2fe55b778..e3eddf31c 100644 --- a/tests/SpiffWorkflow/bpmn/NestedProcessesTest.py +++ b/tests/SpiffWorkflow/bpmn/NestedProcessesTest.py @@ -25,9 +25,11 @@ class NestedProcessesTest(BpmnWorkflowTestCase): self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY))) self.do_next_named_step('Action3') self.workflow.do_engine_steps() + self.complete_subworkflow() + self.complete_subworkflow() + self.complete_subworkflow() self.save_restore() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/ParallelMultipleSplitsTest.py b/tests/SpiffWorkflow/bpmn/ParallelMultipleSplitsTest.py index d779337e7..b813a1955 100644 --- a/tests/SpiffWorkflow/bpmn/ParallelMultipleSplitsTest.py +++ b/tests/SpiffWorkflow/bpmn/ParallelMultipleSplitsTest.py @@ -32,6 +32,7 @@ class ParallelMultipleSplitsTest(BpmnWorkflowTestCase): self.workflow.do_engine_steps() self.do_next_named_step('SP 3 - Yes Task') self.workflow.do_engine_steps() + self.complete_subworkflow() self.do_next_named_step('Done') self.workflow.do_engine_steps() diff --git a/tests/SpiffWorkflow/bpmn/ProcessParserTest.py b/tests/SpiffWorkflow/bpmn/ProcessParserTest.py new file mode 100644 index 000000000..88d03dedc --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/ProcessParserTest.py @@ -0,0 +1,24 @@ +import os +import unittest + +from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnParser +from SpiffWorkflow.bpmn.parser.ProcessParser import ProcessParser + +def _process_parser(bpmn_filename, process_id): + parser = BpmnParser() + bpmn_file = os.path.join(os.path.dirname(__file__), 'data', bpmn_filename) + parser.add_bpmn_file(bpmn_file) + return parser.get_process_parser(process_id) + +class ProcessParserTest(unittest.TestCase): + def testReturnsEmptyListIfNoCallActivities(self): + parser = _process_parser("no-tasks.bpmn", "no_tasks") + assert parser.called_element_ids() == [] + + def testHandlesSingleCallActivity(self): + parser = _process_parser("single_call_activity.bpmn", "Process_p4pfxhq") + assert parser.called_element_ids() == ["SingleTask_Process"] + + def testHandlesMultipleCallActivities(self): + parser = _process_parser("multiple_call_activities.bpmn", "Process_90mmqlw") + assert parser.called_element_ids() == ["Process_sypm122", "Process_diu8ta2", "Process_l14lar1"] diff --git a/tests/SpiffWorkflow/bpmn/PythonScriptEngineEnvironmentTest.py b/tests/SpiffWorkflow/bpmn/PythonScriptEngineEnvironmentTest.py index cb9c40c07..58290f4fc 100644 --- a/tests/SpiffWorkflow/bpmn/PythonScriptEngineEnvironmentTest.py +++ b/tests/SpiffWorkflow/bpmn/PythonScriptEngineEnvironmentTest.py @@ -2,7 +2,7 @@ import json from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine -from SpiffWorkflow.bpmn.PythonScriptEngineEnvironment import BasePythonScriptEngineEnvironment +from SpiffWorkflow.bpmn.PythonScriptEngineEnvironment import BasePythonScriptEngineEnvironment, TaskDataEnvironment from SpiffWorkflow.bpmn.workflow import BpmnWorkflow from SpiffWorkflow.task import TaskState @@ -23,10 +23,19 @@ class NonTaskDataExampleEnvironment(BasePythonScriptEngineEnvironment): self.environment.update(external_methods or {}) exec(script, self.environment) self.environment = {k: v for k, v in self.environment.items() if k not in external_methods} + return True def user_defined_values(self): return {k: v for k, v in self.environment.items() if k not in self.globals} + +class AsyncScriptEnvironment(TaskDataEnvironment): + + def execute(self, script, context, external_methods=None): + super().execute(script, context, external_methods) + return None + + class PythonScriptEngineEnvironmentTest(BpmnWorkflowTestCase): def setUp(self): @@ -78,3 +87,24 @@ class PythonScriptEngineEnvironmentTest(BpmnWorkflowTestCase): task_data_len = len(json.dumps(task_data_to_check)) return task_data_len + +class StartedTaskTest(BpmnWorkflowTestCase): + + def setUp(self): + spec, subprocesses = self.load_workflow_spec('script-start.bpmn', 'Process_cozt5fu') + self.workflow = BpmnWorkflow(spec, subprocesses) + + def testStartedState(self): + script_engine_environemnt = AsyncScriptEnvironment() + script_engine = PythonScriptEngine(environment=script_engine_environemnt) + self.workflow.script_engine = script_engine + self.workflow.do_engine_steps() + script_task = self.workflow.get_tasks_from_spec_name('script')[0] + self.assertEqual(script_task.state, TaskState.STARTED) + script_task.complete() + manual_task = self.workflow.get_tasks_from_spec_name('manual')[0] + manual_task.run() + self.workflow.do_engine_steps() + end = self.workflow.get_tasks_from_spec_name('End')[0] + self.assertDictEqual(end.data, {'x': 1, 'y': 2, 'z': 3}) + self.assertTrue(self.workflow.is_completed()) diff --git a/tests/SpiffWorkflow/bpmn/ResetSubProcessTest.py b/tests/SpiffWorkflow/bpmn/ResetSubProcessTest.py index b9cd99be7..61a7cc4cc 100644 --- a/tests/SpiffWorkflow/bpmn/ResetSubProcessTest.py +++ b/tests/SpiffWorkflow/bpmn/ResetSubProcessTest.py @@ -35,7 +35,7 @@ class ResetSubProcessTest(BpmnWorkflowTestCase): self.workflow.do_engine_steps() top_level_task = self.workflow.get_ready_user_tasks()[0] - self.workflow.run_task_from_id(top_level_task.id) + top_level_task.run() self.workflow.do_engine_steps() task = self.workflow.get_ready_user_tasks()[0] self.save_restore() @@ -50,11 +50,11 @@ class ResetSubProcessTest(BpmnWorkflowTestCase): self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_ready_user_tasks())) task = self.workflow.get_ready_user_tasks()[0] - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(task.get_name(),'SubTask2') - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() task = self.workflow.get_tasks_from_spec_name('Task1')[0] task.reset_token(self.workflow.last_task.data) @@ -62,19 +62,20 @@ class ResetSubProcessTest(BpmnWorkflowTestCase): self.reload_save_restore() task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(task.get_name(),'Task1') - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(task.get_name(),'Subtask2') - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(task.get_name(),'Subtask2A') - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() + self.complete_subworkflow() task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(task.get_name(),'Task2') - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) diff --git a/tests/SpiffWorkflow/bpmn/data/multiple_call_activities.bpmn b/tests/SpiffWorkflow/bpmn/data/multiple_call_activities.bpmn new file mode 100644 index 000000000..0ce562e6a --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/data/multiple_call_activities.bpmn @@ -0,0 +1,62 @@ + + + + + Flow_0b6y930 + + + + Flow_0b6y930 + Flow_0eaeoas + + + + Flow_0eaeoas + Flow_0hqm48x + + + + Flow_0vhq9kk + + + + Flow_0hqm48x + Flow_0vhq9kk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SpiffWorkflow/bpmn/data/no-tasks.bpmn b/tests/SpiffWorkflow/bpmn/data/no-tasks.bpmn new file mode 100644 index 000000000..5299c7d39 --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/data/no-tasks.bpmn @@ -0,0 +1,26 @@ + + + + + Flow_184umot + + + Flow_184umot + + + + + + + + + + + + + + + + + + diff --git a/tests/SpiffWorkflow/bpmn/data/script-start.bpmn b/tests/SpiffWorkflow/bpmn/data/script-start.bpmn new file mode 100644 index 000000000..e35cbb044 --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/data/script-start.bpmn @@ -0,0 +1,87 @@ + + + + + Flow_1r4la8u + + + + Flow_1r4la8u + Flow_0rx8ly6 + Flow_0m6kw0s + + + + + Flow_0rx8ly6 + Flow_1wcrqdb + x, y = 1, 2 +z = x + y + + + Flow_0m6kw0s + Flow_0npa1g8 + + + + + Flow_1wcrqdb + Flow_0npa1g8 + Flow_1vd5x0n + + + Flow_1vd5x0n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SpiffWorkflow/bpmn/data/serialization/v1.1-task-states.json b/tests/SpiffWorkflow/bpmn/data/serialization/v1.1-task-states.json new file mode 100644 index 000000000..6fba7f4c8 --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/data/serialization/v1.1-task-states.json @@ -0,0 +1,563 @@ +{ + "serializer_version": "1.1", + "data": {}, + "last_task": "3a4a6596-3b3d-4cd5-9724-cd1ccc263676", + "success": true, + "tasks": { + "d10fb568-6104-4a26-9081-e29c8eb42e70": { + "id": "d10fb568-6104-4a26-9081-e29c8eb42e70", + "parent": null, + "children": [ + "f0a4e631-c30a-4444-b2b1-2cdc21179c65" + ], + "last_state_change": 1681913960.451874, + "state": 32, + "task_spec": "Root", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "f0a4e631-c30a-4444-b2b1-2cdc21179c65": { + "id": "f0a4e631-c30a-4444-b2b1-2cdc21179c65", + "parent": "d10fb568-6104-4a26-9081-e29c8eb42e70", + "children": [ + "3468f48a-c493-4731-9484-0821d046a0bc" + ], + "last_state_change": 1681913960.4591289, + "state": 32, + "task_spec": "Start", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "3468f48a-c493-4731-9484-0821d046a0bc": { + "id": "3468f48a-c493-4731-9484-0821d046a0bc", + "parent": "f0a4e631-c30a-4444-b2b1-2cdc21179c65", + "children": [ + "0366c1b3-d55e-42e4-a6fd-db2d6a1940eb" + ], + "last_state_change": 1681913960.460862, + "state": 32, + "task_spec": "StartEvent_1", + "triggered": false, + "workflow_name": "main", + "internal_data": { + "event_fired": true + }, + "data": {} + }, + "0366c1b3-d55e-42e4-a6fd-db2d6a1940eb": { + "id": "0366c1b3-d55e-42e4-a6fd-db2d6a1940eb", + "parent": "3468f48a-c493-4731-9484-0821d046a0bc", + "children": [ + "afd334bf-f987-46b3-b6df-779562c4b4bf", + "ad8b1640-55ac-4ff5-b07e-16c0b7c92976" + ], + "last_state_change": 1681913960.4621637, + "state": 32, + "task_spec": "task_1.BoundaryEventParent", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "afd334bf-f987-46b3-b6df-779562c4b4bf": { + "id": "afd334bf-f987-46b3-b6df-779562c4b4bf", + "parent": "0366c1b3-d55e-42e4-a6fd-db2d6a1940eb", + "children": [ + "3a4a6596-3b3d-4cd5-9724-cd1ccc263676" + ], + "last_state_change": 1681913960.4634154, + "state": 32, + "task_spec": "task_1", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "3a4a6596-3b3d-4cd5-9724-cd1ccc263676": { + "id": "3a4a6596-3b3d-4cd5-9724-cd1ccc263676", + "parent": "afd334bf-f987-46b3-b6df-779562c4b4bf", + "children": [ + "8ee8a04c-e784-4419-adb4-7c7f99f72bf6", + "00c5b447-760e-47dc-a77b-cffbf893d098" + ], + "last_state_change": 1681913960.4667528, + "state": 32, + "task_spec": "Gateway_1eg2w56", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "8ee8a04c-e784-4419-adb4-7c7f99f72bf6": { + "id": "8ee8a04c-e784-4419-adb4-7c7f99f72bf6", + "parent": "3a4a6596-3b3d-4cd5-9724-cd1ccc263676", + "children": [ + "cee7ab8e-d50b-4681-94f2-51bbd8dd6df1" + ], + "last_state_change": 1681913960.4669333, + "state": 16, + "task_spec": "task_2", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "cee7ab8e-d50b-4681-94f2-51bbd8dd6df1": { + "id": "cee7ab8e-d50b-4681-94f2-51bbd8dd6df1", + "parent": "8ee8a04c-e784-4419-adb4-7c7f99f72bf6", + "children": [ + "4695356f-8db1-48f6-a8bb-d610b2da7a63" + ], + "last_state_change": 1681913960.454116, + "state": 4, + "task_spec": "Gateway_1dpu3vt", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "4695356f-8db1-48f6-a8bb-d610b2da7a63": { + "id": "4695356f-8db1-48f6-a8bb-d610b2da7a63", + "parent": "cee7ab8e-d50b-4681-94f2-51bbd8dd6df1", + "children": [ + "f4ab0e07-d985-412f-aca0-369bd29797e1" + ], + "last_state_change": 1681913960.45428, + "state": 4, + "task_spec": "Event_1deqprp", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "f4ab0e07-d985-412f-aca0-369bd29797e1": { + "id": "f4ab0e07-d985-412f-aca0-369bd29797e1", + "parent": "4695356f-8db1-48f6-a8bb-d610b2da7a63", + "children": [ + "e326e6ec-f20d-4171-8133-24b160ad3404" + ], + "last_state_change": 1681913960.4544458, + "state": 4, + "task_spec": "main.EndJoin", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "e326e6ec-f20d-4171-8133-24b160ad3404": { + "id": "e326e6ec-f20d-4171-8133-24b160ad3404", + "parent": "f4ab0e07-d985-412f-aca0-369bd29797e1", + "children": [], + "last_state_change": 1681913960.4546103, + "state": 4, + "task_spec": "End", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "00c5b447-760e-47dc-a77b-cffbf893d098": { + "id": "00c5b447-760e-47dc-a77b-cffbf893d098", + "parent": "3a4a6596-3b3d-4cd5-9724-cd1ccc263676", + "children": [ + "c57e4be7-670c-41aa-9740-9fff831f6ccd" + ], + "last_state_change": 1681913960.4671006, + "state": 16, + "task_spec": "task_3", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "c57e4be7-670c-41aa-9740-9fff831f6ccd": { + "id": "c57e4be7-670c-41aa-9740-9fff831f6ccd", + "parent": "00c5b447-760e-47dc-a77b-cffbf893d098", + "children": [ + "ee2c8edc-5d5e-4fc2-ba4b-1801d000c6c3" + ], + "last_state_change": 1681913960.454881, + "state": 4, + "task_spec": "Gateway_1dpu3vt", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "ee2c8edc-5d5e-4fc2-ba4b-1801d000c6c3": { + "id": "ee2c8edc-5d5e-4fc2-ba4b-1801d000c6c3", + "parent": "c57e4be7-670c-41aa-9740-9fff831f6ccd", + "children": [ + "91a213bf-bef6-40fa-b0a4-7c7f58552184" + ], + "last_state_change": 1681913960.4550629, + "state": 4, + "task_spec": "Event_1deqprp", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "91a213bf-bef6-40fa-b0a4-7c7f58552184": { + "id": "91a213bf-bef6-40fa-b0a4-7c7f58552184", + "parent": "ee2c8edc-5d5e-4fc2-ba4b-1801d000c6c3", + "children": [ + "8166e255-1d17-4f94-8c0e-82cefe8500fd" + ], + "last_state_change": 1681913960.4552596, + "state": 4, + "task_spec": "main.EndJoin", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "8166e255-1d17-4f94-8c0e-82cefe8500fd": { + "id": "8166e255-1d17-4f94-8c0e-82cefe8500fd", + "parent": "91a213bf-bef6-40fa-b0a4-7c7f58552184", + "children": [], + "last_state_change": 1681913960.455456, + "state": 4, + "task_spec": "End", + "triggered": false, + "workflow_name": "main", + "internal_data": {}, + "data": {} + }, + "ad8b1640-55ac-4ff5-b07e-16c0b7c92976": { + "id": "ad8b1640-55ac-4ff5-b07e-16c0b7c92976", + "parent": "0366c1b3-d55e-42e4-a6fd-db2d6a1940eb", + "children": [], + "last_state_change": 1681913960.463645, + "state": 64, + "task_spec": "signal", + "triggered": false, + "workflow_name": "main", + "internal_data": { + "event_fired": false + }, + "data": {} + } + }, + "root": "d10fb568-6104-4a26-9081-e29c8eb42e70", + "spec": { + "name": "main", + "description": "main", + "file": "/home/essweine/work/sartography/code/SpiffWorkflow/tests/SpiffWorkflow/bpmn/data/diagram_1.bpmn", + "task_specs": { + "Start": { + "id": "main_1", + "name": "Start", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [], + "outputs": [ + "StartEvent_1" + ], + "typename": "StartTask" + }, + "main.EndJoin": { + "id": "main_2", + "name": "main.EndJoin", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Event_1deqprp" + ], + "outputs": [ + "End" + ], + "typename": "_EndJoin" + }, + "End": { + "id": "main_3", + "name": "End", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "main.EndJoin" + ], + "outputs": [], + "typename": "Simple" + }, + "StartEvent_1": { + "id": "main_4", + "name": "StartEvent_1", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Start" + ], + "outputs": [ + "task_1.BoundaryEventParent" + ], + "lane": null, + "documentation": null, + "position": { + "x": 179.0, + "y": 99.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "event_definition": { + "internal": false, + "external": false, + "typename": "NoneEventDefinition" + }, + "typename": "StartEvent", + "extensions": {} + }, + "task_1": { + "id": "main_5", + "name": "task_1", + "description": "Task 1", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "task_1.BoundaryEventParent" + ], + "outputs": [ + "Gateway_1eg2w56" + ], + "lane": null, + "documentation": null, + "position": { + "x": 270.0, + "y": 77.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "typename": "NoneTask", + "extensions": {} + }, + "task_1.BoundaryEventParent": { + "id": "main_6", + "name": "task_1.BoundaryEventParent", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "StartEvent_1" + ], + "outputs": [ + "task_1", + "signal" + ], + "lane": null, + "documentation": null, + "position": { + "x": 0, + "y": 0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "main_child_task_spec": "task_1", + "typename": "_BoundaryEventParent" + }, + "signal": { + "id": "main_7", + "name": "signal", + "description": "Signal Event", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "task_1.BoundaryEventParent" + ], + "outputs": [], + "lane": null, + "documentation": null, + "position": { + "x": 302.0, + "y": 139.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "event_definition": { + "internal": true, + "external": true, + "name": "Signal_08n3u9r", + "typename": "SignalEventDefinition" + }, + "cancel_activity": true, + "typename": "BoundaryEvent", + "extensions": {} + }, + "Gateway_1eg2w56": { + "id": "main_8", + "name": "Gateway_1eg2w56", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "task_1" + ], + "outputs": [ + "task_2", + "task_3" + ], + "lane": null, + "documentation": null, + "position": { + "x": 425.0, + "y": 92.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "split_task": null, + "threshold": null, + "cancel": false, + "typename": "ParallelGateway", + "extensions": {} + }, + "task_2": { + "id": "main_9", + "name": "task_2", + "description": "Task 2", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Gateway_1eg2w56" + ], + "outputs": [ + "Gateway_1dpu3vt" + ], + "lane": null, + "documentation": null, + "position": { + "x": 530.0, + "y": 77.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "typename": "NoneTask", + "extensions": {} + }, + "Gateway_1dpu3vt": { + "id": "main_10", + "name": "Gateway_1dpu3vt", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "task_2", + "task_3" + ], + "outputs": [ + "Event_1deqprp" + ], + "lane": null, + "documentation": null, + "position": { + "x": 685.0, + "y": 92.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "split_task": null, + "threshold": null, + "cancel": false, + "typename": "ParallelGateway", + "extensions": {} + }, + "Event_1deqprp": { + "id": "main_11", + "name": "Event_1deqprp", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Gateway_1dpu3vt" + ], + "outputs": [ + "main.EndJoin" + ], + "lane": null, + "documentation": null, + "position": { + "x": 792.0, + "y": 99.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "event_definition": { + "internal": false, + "external": false, + "typename": "NoneEventDefinition" + }, + "typename": "EndEvent", + "extensions": {} + }, + "task_3": { + "id": "main_12", + "name": "task_3", + "description": "Task 3", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Gateway_1eg2w56" + ], + "outputs": [ + "Gateway_1dpu3vt" + ], + "lane": null, + "documentation": null, + "position": { + "x": 530.0, + "y": 190.0 + }, + "data_input_associations": [], + "data_output_associations": [], + "io_specification": null, + "typename": "NoneTask", + "extensions": {} + }, + "Root": { + "id": "main_13", + "name": "Root", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [], + "outputs": [], + "typename": "Simple" + } + }, + "io_specification": null, + "data_objects": {}, + "correlation_keys": {}, + "typename": "BpmnProcessSpec" + }, + "subprocess_specs": {}, + "subprocesses": {}, + "bpmn_messages": [], + "correlations": {} +} diff --git a/tests/SpiffWorkflow/bpmn/data/single_call_activity.bpmn b/tests/SpiffWorkflow/bpmn/data/single_call_activity.bpmn new file mode 100644 index 000000000..39611faae --- /dev/null +++ b/tests/SpiffWorkflow/bpmn/data/single_call_activity.bpmn @@ -0,0 +1,38 @@ + + + + + Flow_04380wl + + + + Flow_1io4ukf + + + + Flow_04380wl + Flow_1io4ukf + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SpiffWorkflow/bpmn/events/ActionManagementTest.py b/tests/SpiffWorkflow/bpmn/events/ActionManagementTest.py index 0bd5c5789..1f1da73a3 100644 --- a/tests/SpiffWorkflow/bpmn/events/ActionManagementTest.py +++ b/tests/SpiffWorkflow/bpmn/events/ActionManagementTest.py @@ -50,6 +50,7 @@ class ActionManagementTest(BpmnWorkflowTestCase): self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertTrue(self.workflow.is_completed()) @@ -91,6 +92,7 @@ class ActionManagementTest(BpmnWorkflowTestCase): self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertTrue(self.workflow.is_completed()) diff --git a/tests/SpiffWorkflow/bpmn/events/CallActivityEscalationTest.py b/tests/SpiffWorkflow/bpmn/events/CallActivityEscalationTest.py index e8bae0e57..9ef11e413 100644 --- a/tests/SpiffWorkflow/bpmn/events/CallActivityEscalationTest.py +++ b/tests/SpiffWorkflow/bpmn/events/CallActivityEscalationTest.py @@ -80,6 +80,7 @@ class CallActivityEscalationTest(BpmnWorkflowTestCase): for task in self.workflow.get_tasks(TaskState.READY): task.set_data(should_escalate=False) self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.workflow.run_all() self.assertEqual(True, self.workflow.is_completed()) diff --git a/tests/SpiffWorkflow/bpmn/events/MessageInterruptsSpTest.py b/tests/SpiffWorkflow/bpmn/events/MessageInterruptsSpTest.py index 0b93d1e66..52d79dcc2 100644 --- a/tests/SpiffWorkflow/bpmn/events/MessageInterruptsSpTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MessageInterruptsSpTest.py @@ -28,6 +28,7 @@ class MessageInterruptsSpTest(BpmnWorkflowTestCase): self.do_next_exclusive_step('Do Something In a Subprocess') self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.do_next_exclusive_step('Ack Subprocess Done') @@ -35,8 +36,7 @@ class MessageInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughInterruptSaveAndRestore(self): @@ -58,8 +58,7 @@ class MessageInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/events/MessageInterruptsTest.py b/tests/SpiffWorkflow/bpmn/events/MessageInterruptsTest.py index bdd6d6c11..1ca3a201d 100644 --- a/tests/SpiffWorkflow/bpmn/events/MessageInterruptsTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MessageInterruptsTest.py @@ -30,13 +30,13 @@ class MessageInterruptsTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(0, len(self.workflow.get_tasks(TaskState.WAITING))) self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterruptSaveAndRestore(self): @@ -61,9 +61,9 @@ class MessageInterruptsTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughHappy(self): @@ -77,11 +77,11 @@ class MessageInterruptsTest(BpmnWorkflowTestCase): self.do_next_exclusive_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(0, len(self.workflow.get_tasks(TaskState.WAITING))) self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterrupt(self): @@ -101,8 +101,8 @@ class MessageInterruptsTest(BpmnWorkflowTestCase): self.do_next_exclusive_step('Acknowledge Interrupt Message') self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptTest.py b/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptTest.py index 3127cc78c..ce2d290e1 100644 --- a/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptTest.py @@ -31,13 +31,13 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(0, len(self.workflow.get_tasks(TaskState.WAITING))) self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterruptSaveAndRestore(self): @@ -71,8 +71,8 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughHappy(self): @@ -87,11 +87,11 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.do_next_exclusive_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(0, len(self.workflow.get_tasks(TaskState.WAITING))) self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterrupt(self): @@ -118,8 +118,8 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.do_next_named_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterruptOtherOrder(self): @@ -145,8 +145,8 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.do_next_named_step('Acknowledge Non-Interrupt Message') self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageInterruptOtherOrderSaveAndRestore(self): @@ -177,8 +177,8 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptsSpTest.py b/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptsSpTest.py index a10f8e93f..2297654af 100644 --- a/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptsSpTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MessageNonInterruptsSpTest.py @@ -28,6 +28,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.do_next_exclusive_step('Do Something In a Subprocess') self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.do_next_exclusive_step('Ack Subprocess Done') @@ -35,8 +36,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageSaveAndRestore(self): @@ -53,6 +53,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.do_next_named_step('Ack Subprocess Done') @@ -64,8 +65,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageOrder2SaveAndRestore(self): @@ -81,6 +81,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.workflow.catch(MessageEventDefinition('Test Message')) self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.do_next_named_step('Acknowledge SP Parallel Message') @@ -92,8 +93,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughMessageOrder3SaveAndRestore(self): @@ -114,6 +114,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() + self.complete_subworkflow() self.save_restore() self.do_next_named_step('Ack Subprocess Done') @@ -121,8 +122,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/events/MessagesTest.py b/tests/SpiffWorkflow/bpmn/events/MessagesTest.py index 2535daba4..3757f1c7c 100644 --- a/tests/SpiffWorkflow/bpmn/events/MessagesTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MessagesTest.py @@ -27,12 +27,11 @@ class MessagesTest(BpmnWorkflowTestCase): self.workflow.catch(MessageEventDefinition('Test Message')) self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY))) - self.assertEqual( - 'Test Message', self.workflow.get_tasks(TaskState.READY)[0].task_spec.description) + self.assertEqual('Test Message', self.workflow.get_tasks(TaskState.READY)[0].task_spec.description) self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def testRunThroughSaveAndRestore(self): @@ -52,8 +51,8 @@ class MessagesTest(BpmnWorkflowTestCase): self.save_restore() self.workflow.do_engine_steps() - self.assertEqual( - 0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) + self.complete_subworkflow() + self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING))) def suite(): diff --git a/tests/SpiffWorkflow/bpmn/events/MultipleThrowEventTest.py b/tests/SpiffWorkflow/bpmn/events/MultipleThrowEventTest.py index 031a1643b..0b7b383f8 100644 --- a/tests/SpiffWorkflow/bpmn/events/MultipleThrowEventTest.py +++ b/tests/SpiffWorkflow/bpmn/events/MultipleThrowEventTest.py @@ -19,6 +19,7 @@ class MultipleThrowEventIntermediateCatchTest(BpmnWorkflowTestCase): if save_restore: self.save_restore() self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(len(self.workflow.get_waiting_tasks()), 0) self.assertEqual(self.workflow.is_completed(), True) @@ -44,4 +45,5 @@ class MultipleThrowEventStartsEventTest(BpmnWorkflowTestCase): self.assertEqual(len(ready_tasks), 1) ready_tasks[0].run() self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(self.workflow.is_completed(), True) \ No newline at end of file diff --git a/tests/SpiffWorkflow/bpmn/events/NITimerDurationBoundaryTest.py b/tests/SpiffWorkflow/bpmn/events/NITimerDurationBoundaryTest.py index 136b3ef39..275640b00 100644 --- a/tests/SpiffWorkflow/bpmn/events/NITimerDurationBoundaryTest.py +++ b/tests/SpiffWorkflow/bpmn/events/NITimerDurationBoundaryTest.py @@ -65,7 +65,9 @@ class NITimerDurationTest(BpmnWorkflowTestCase): task.run() self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() - self.assertEqual(self.workflow.is_completed(),True) + self.workflow.do_engine_steps() + self.complete_subworkflow() + self.assertEqual(self.workflow.is_completed(), True) self.assertEqual(self.workflow.last_task.data, {'work_done': 'Yes', 'delay_reason': 'Just Because'}) diff --git a/tests/SpiffWorkflow/bpmn/events/TransactionSubprocssTest.py b/tests/SpiffWorkflow/bpmn/events/TransactionSubprocssTest.py index de7def175..4abae178b 100644 --- a/tests/SpiffWorkflow/bpmn/events/TransactionSubprocssTest.py +++ b/tests/SpiffWorkflow/bpmn/events/TransactionSubprocssTest.py @@ -25,6 +25,7 @@ class TransactionSubprocessTest(BpmnWorkflowTestCase): ready_tasks[0].update_data({'quantity': 2}) ready_tasks[0].run() self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertIn('value', self.workflow.last_task.data) # Check that workflow and next task completed diff --git a/tests/SpiffWorkflow/bpmn/serializer/VersionMigrationTest.py b/tests/SpiffWorkflow/bpmn/serializer/VersionMigrationTest.py index 393b2d76d..1b501b557 100644 --- a/tests/SpiffWorkflow/bpmn/serializer/VersionMigrationTest.py +++ b/tests/SpiffWorkflow/bpmn/serializer/VersionMigrationTest.py @@ -23,6 +23,10 @@ class Version_1_0_Test(BaseTestCase): self.assertEqual('Action3', ready_tasks[0].task_spec.description) ready_tasks[0].run() wf.do_engine_steps() + wf.refresh_waiting_tasks() + wf.do_engine_steps() + wf.refresh_waiting_tasks() + wf.do_engine_steps() self.assertEqual(True, wf.is_completed()) @@ -34,12 +38,16 @@ class Version_1_1_Test(BaseTestCase): wf.script_engine = PythonScriptEngine(environment=TaskDataEnvironment({"time": time})) wf.refresh_waiting_tasks() wf.do_engine_steps() + wf.refresh_waiting_tasks() + wf.do_engine_steps() self.assertTrue(wf.is_completed()) def test_convert_data_specs(self): fn = os.path.join(self.DATA_DIR, 'serialization', 'v1.1-data.json') wf = self.serializer.deserialize_json(open(fn).read()) wf.do_engine_steps() + wf.refresh_waiting_tasks() + wf.do_engine_steps() self.assertTrue(wf.is_completed()) def test_convert_exclusive_gateway(self): @@ -71,3 +79,16 @@ class Version_1_1_Test(BaseTestCase): wf.refresh_waiting_tasks() self.assertTrue(wf.is_completed()) self.assertEqual(wf.last_task.data['counter'], 20) + + def test_update_task_states(self): + fn = os.path.join(self.DATA_DIR, 'serialization', 'v1.1-task-states.json') + wf = self.serializer.deserialize_json(open(fn).read()) + start = wf.get_tasks_from_spec_name('Start')[0] + self.assertEqual(start.state, TaskState.COMPLETED) + signal = wf.get_tasks_from_spec_name('signal')[0] + self.assertEqual(signal.state, TaskState.CANCELLED) + ready_tasks = wf.get_tasks(TaskState.READY) + while len(ready_tasks) > 0: + ready_tasks[0].run() + ready_tasks = wf.get_tasks(TaskState.READY) + self.assertTrue(wf.is_completed()) diff --git a/tests/SpiffWorkflow/camunda/CallActivityMessageTest.py b/tests/SpiffWorkflow/camunda/CallActivityMessageTest.py index b5177c78a..8210b6c73 100644 --- a/tests/SpiffWorkflow/camunda/CallActivityMessageTest.py +++ b/tests/SpiffWorkflow/camunda/CallActivityMessageTest.py @@ -41,7 +41,7 @@ class CallActivityMessageTest(BaseTestCase): current_task.update_data(step[1]) current_task.run() self.workflow.do_engine_steps() - self.workflow.refresh_waiting_tasks() + self.complete_subworkflow() if save_restore: self.save_restore() ready_tasks = self.workflow.get_tasks(TaskState.READY) self.assertEqual(self.workflow.is_completed(),True,'Expected the workflow to be complete at this point') diff --git a/tests/SpiffWorkflow/camunda/ExternalMessageBoundaryEventTest.py b/tests/SpiffWorkflow/camunda/ExternalMessageBoundaryEventTest.py index 74b5dd99d..a416924af 100644 --- a/tests/SpiffWorkflow/camunda/ExternalMessageBoundaryEventTest.py +++ b/tests/SpiffWorkflow/camunda/ExternalMessageBoundaryEventTest.py @@ -50,7 +50,7 @@ class ExternalMessageBoundaryTest(BaseTestCase): self.workflow.catch(MessageEventDefinition('reset', payload='SomethingDrastic', result_var='reset_var')) ready_tasks = self.workflow.get_tasks(TaskState.READY) # The user activity was cancelled and we should continue from the boundary event - self.assertEqual(1, len(ready_tasks),'Expected to have two ready tasks') + self.assertEqual(2, len(ready_tasks), 'Expected to have two ready tasks') event = self.workflow.get_tasks_from_spec_name('Event_19detfv')[0] event.run() self.assertEqual('SomethingDrastic', event.data['reset_var']) diff --git a/tests/SpiffWorkflow/camunda/NIMessageBoundaryTest.py b/tests/SpiffWorkflow/camunda/NIMessageBoundaryTest.py index cd5120da0..68d1da71c 100644 --- a/tests/SpiffWorkflow/camunda/NIMessageBoundaryTest.py +++ b/tests/SpiffWorkflow/camunda/NIMessageBoundaryTest.py @@ -84,6 +84,7 @@ class NIMessageBoundaryTest(BaseTestCase): task.data['work_completed'] = 'Lots of Stuff' self.workflow.run_task_from_id(task.id) self.workflow.do_engine_steps() + self.complete_subworkflow() self.assertEqual(self.workflow.is_completed(),True) self.assertEqual(self.workflow.last_task.data,{'Event_InterruptBoundary_Response': 'Youre late!', 'flag_task': 'Yes', diff --git a/tests/SpiffWorkflow/camunda/ResetTokenSubWorkflowTest.py b/tests/SpiffWorkflow/camunda/ResetTokenSubWorkflowTest.py index f8a288e00..e444374ec 100644 --- a/tests/SpiffWorkflow/camunda/ResetTokenSubWorkflowTest.py +++ b/tests/SpiffWorkflow/camunda/ResetTokenSubWorkflowTest.py @@ -51,7 +51,7 @@ class ResetTokenTestSubProcess(BaseTestCase): firsttaskid = task.id self.assertEqual(step['taskname'], task.task_spec.name) task.update_data({step['formvar']: step['answer']}) - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() if save_restore: self.save_restore() @@ -75,8 +75,9 @@ class ResetTokenTestSubProcess(BaseTestCase): task = self.workflow.get_ready_user_tasks()[0] self.assertEqual(step['taskname'], task.task_spec.name) task.update_data({step['formvar']: step['answer']}) - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() + self.complete_subworkflow() if save_restore: self.save_restore() diff --git a/tests/SpiffWorkflow/camunda/SubWorkflowTest.py b/tests/SpiffWorkflow/camunda/SubWorkflowTest.py index 97aed8de8..930020ce6 100644 --- a/tests/SpiffWorkflow/camunda/SubWorkflowTest.py +++ b/tests/SpiffWorkflow/camunda/SubWorkflowTest.py @@ -31,8 +31,9 @@ class SubWorkflowTest(BaseTestCase): task = self.workflow.get_ready_user_tasks()[0] self.assertEqual("Activity_"+answer, task.task_spec.name) task.update_data({"Field"+answer: answer}) - self.workflow.run_task_from_id(task.id) + task.run() self.workflow.do_engine_steps() + self.complete_subworkflow() if save_restore: self.save_restore() self.assertEqual(self.workflow.last_task.data,{'FieldA': 'A', diff --git a/tests/SpiffWorkflow/spiff/PrescriptPostscriptTest.py b/tests/SpiffWorkflow/spiff/PrescriptPostscriptTest.py index f928f80c8..c44f1749e 100644 --- a/tests/SpiffWorkflow/spiff/PrescriptPostscriptTest.py +++ b/tests/SpiffWorkflow/spiff/PrescriptPostscriptTest.py @@ -58,6 +58,8 @@ class PrescriptPostsciptTest(BaseTestCase): self.workflow.do_engine_steps() ex = se.exception self.assertIn("Error occurred in the Pre-Script", str(ex)) + task = self.workflow.get_tasks_from_spec_name('Activity_1iqs4li')[0] + self.assertEqual(task.state, TaskState.ERROR) def call_activity_test(self, save_restore=False): @@ -82,3 +84,4 @@ class PrescriptPostsciptTest(BaseTestCase): ready_tasks = self.workflow.get_tasks(TaskState.READY) ready_tasks[0].set_data(**data) self.workflow.do_engine_steps() + self.complete_subworkflow()