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()