Squashed 'SpiffWorkflow/' changes from 01a25fc3..0adfc8cb

0adfc8cb update spiff signal event
52d65dfc Merge pull request #346 from sartography/bugfix/update-split-task-inputs
23ca808c make sure tasks with boundary events are connected properly
de427431 remove pointless parser attribute and variable
3236b5b9 change subprocess start event validation error message text
a5ad0672 Merge pull request #344 from sartography/bugfix/gateway-in-loop
6b22a195 allow event definitions without refs
bb843873 clean up inclusive gateway a little
a7d81c02 prevent parallel gateways from waiting on descendants
802352a2 move test to proper location
ebcdde95 Merge pull request #343 from sartography/feature/event-payloads
87636472 add an additional test for boundary event parent removal
41423168 add escalation event test
26c5a9bb fix message event catch check
9bd018e5 Add test case for call activities in sub processes, fixed bug (#342)
546923b4 add serialization migration for boundary events
46d41e20 add spiff payload extensions + base spec improvements
a0f5fc2a remove boundary event parent
56277ff1 add event class
6de6fb2b reorganize event definitions
7db65566 fix subprocess cancel
442535ae do not allow the task trace to infinitely loop to get the trace w/ burnettk
dbe41c8e Merge pull request #339 from sartography/improvement/better-subworkflow-management
6c61f20a update parent attribute name
ea0a7bf4 update correlations when catching external messages
f511e2dd remove unneeded method from tests
953fa63c clean up workflow methods
efcdcf54 Merge pull request #338 from sartography/bugfix/triggered-multiinstance-tasks
11b78ce7 prevent errors synching children of MI tasks
bbb79e05 miscellaneous improvements
3f8e8d84 split bpmn workflow into two classes
61e01201 clean up workflow attributes & methods

git-subtree-dir: SpiffWorkflow
git-subtree-split: 0adfc8cbaec80d36f98a4136434e960f666fcfe2
This commit is contained in:
burnettk 2023-08-09 16:14:27 -04:00
parent c904ee907b
commit 38ff7e08da
51 changed files with 4082 additions and 487 deletions

View File

@ -46,8 +46,6 @@ 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_')
@ -57,15 +55,11 @@ 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_')
@ -75,15 +69,11 @@ 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')
@ -96,16 +86,12 @@ 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()
@ -122,8 +108,6 @@ 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')

View File

@ -76,7 +76,7 @@ class BpmnWorkflowTestCase(unittest.TestCase):
if (p.task_spec.name == parent_name or p.task_spec.bpmn_name == parent_name):
found = True
break
if p.parent is None and p.workflow != p.workflow.outer_workflow:
if p.parent is None and p.workflow != p.workflow.parent:
p = switch_workflow(p)
else:
p = p.parent
@ -117,13 +117,6 @@ 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
@ -140,7 +133,7 @@ class BpmnWorkflowTestCase(unittest.TestCase):
self.assertEqual(before_state, after_state)
self.workflow = after
self.workflow.script_engine = script_engine
def restore(self, state):
self.workflow = self.serializer.workflow_from_dict(state)

View File

@ -17,7 +17,6 @@ class CallActivityTest(BpmnWorkflowTestCase):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertDictEqual(self.workflow.data, {'pre_var': 'some string', 'my_var': 'World', 'my_other_var': 'Mike'})
def test_call_activity_has_same_script_engine(self):
@ -26,7 +25,6 @@ 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)
@ -42,7 +40,6 @@ 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())

View File

@ -1,5 +1,6 @@
from SpiffWorkflow.bpmn.specs.mixins.subworkflow_task import CallActivity
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.task import TaskState
from .BpmnWorkflowTestCase import BpmnWorkflowTestCase
@ -46,30 +47,27 @@ class CollaborationTest(BpmnWorkflowTestCase):
start.data['lover_name'] = 'Peggy'
workflow.do_engine_steps()
# An external message should be created
messages = workflow.get_bpmn_messages()
messages = workflow.get_events()
self.assertEqual(len(messages), 1)
self.assertEqual(len(workflow.bpmn_messages), 0)
self.assertEqual(len(workflow.bpmn_events), 0)
receive = workflow.get_tasks_from_spec_name('EventReceiveLetter')[0]
# Waiting Events should contain details about what we are no waiting on.
events = workflow.waiting_events()
self.assertEqual(1, len(events))
self.assertEqual("MessageEventDefinition", events[0]['event_type'])
self.assertEqual("Love Letter Response", events[0]['name'])
self.assertEqual(['lover'], events[0]['value'][0].correlation_keys)
self.assertEqual('from_name', events[0]['value'][0].retrieval_expression)
self.assertEqual('lover_name', events[0]['value'][0].name)
self.assertEqual("MessageEventDefinition", events[0].event_type)
self.assertEqual("Love Letter Response", events[0].name)
self.assertEqual(['lover'], events[0].value[0].correlation_keys)
self.assertEqual('from_name', events[0].value[0].retrieval_expression)
self.assertEqual('lover_name', events[0].value[0].name)
# As shown above, the waiting event is looking for a payload with a
# 'from_name' that should be used to retrieve the lover's name.
new_message_payload = {'from_name': 'Peggy', 'other_nonsense': 1001}
workflow.catch_bpmn_message('Love Letter Response', new_message_payload)
message = BpmnEvent(
receive.task_spec.event_definition,
{'from_name': 'Peggy', 'other_nonsense': 1001}
)
workflow.send_event(message)
workflow.do_engine_steps()
# The external message created above should be caught
self.assertEqual(receive.state, TaskState.COMPLETED)
# Spiff extensions allow us to specify the destination of a workflow
# but base BPMN does not, and all keys are added directly to the
# task data.
self.assertEqual(workflow.last_task.data, {'from_name': 'Peggy', 'lover_name': 'Peggy', 'other_nonsense': 1001})
self.assertEqual(workflow.correlations, {'lover':{'lover_name':'Peggy'}})
self.assertEqual(workflow.is_completed(), True)

View File

@ -36,8 +36,6 @@ class CustomInlineScriptTest(BpmnWorkflowTestCase):
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

View File

@ -20,7 +20,7 @@ class NestedProcessesTest(BpmnWorkflowTestCase):
self.complete_task('Action2', True)
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.complete_task('Action3', True)
self.complete_workflow()
self.assertTrue(self.workflow.is_completed())
def testResetToTop(self):
@ -36,7 +36,7 @@ class NestedProcessesTest(BpmnWorkflowTestCase):
self.complete_task('Action2')
self.complete_task('Action3')
self.complete_workflow()
self.assertTrue(self.workflow.is_completed())
def testResetToIntermediate(self):
@ -53,16 +53,27 @@ class NestedProcessesTest(BpmnWorkflowTestCase):
task.run()
self.complete_task('Action3')
self.complete_workflow()
self.assertTrue(self.workflow.is_completed())
def testResetToSubworkflow(self):
self.complete_task('Action1', True)
self.complete_task('Action2', True)
self.complete_task('Action3', True)
# "Nested level 1"
task = self.workflow.get_tasks_from_spec_name('sid-C014B4B9-889F-4EE9-9949-C89502C35CF0')[0]
self.workflow.reset_from_task_id(task.id)
self.workflow.do_engine_steps()
self.assertEqual(len(self.workflow.subprocesses), 1)
self.assertEqual(task.state, TaskState.WAITING)
self.complete_task('Action2', True)
self.complete_task('Action3', True)
self.assertTrue(self.workflow.is_completed())
def complete_task(self, name, save_restore=False):
self.do_next_named_step(name)
self.workflow.do_engine_steps()
if save_restore:
self.save_restore()
def complete_workflow(self):
self.complete_subworkflow()
self.complete_subworkflow()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))

View File

@ -46,3 +46,16 @@ class ParserTest(unittest.TestCase):
self.assertRaisesRegex(
ValidationException, "The process '\w+' was not found*",
self.parser.get_spec, "Process")
def testBoundaryEvent(self):
bpmn_file = os.path.join(os.path.dirname(__file__), 'data', 'boundary_event_split.bpmn')
self.parser.add_bpmn_file(bpmn_file)
spec = self.parser.get_spec('Process_0ymnx41')
gw1 = spec.task_specs.get('gw_1')
gw2 = spec.task_specs.get('gw_2')
task = spec.task_specs.get('task_2')
split_task = spec.task_specs.get(f'{task.name}.BoundaryEventSplit')
self.assertNotIn(task, gw1.outputs)
self.assertIn(split_task, gw1.outputs)
self.assertNotIn(task, gw2.outputs)
self.assertIn(split_task, gw2.outputs)

View File

@ -24,6 +24,10 @@ class ProcessParserTest(unittest.TestCase):
parser = _process_parser("multiple_call_activities.bpmn", "Process_90mmqlw")
assert parser.called_element_ids() == ["Process_sypm122", "Process_diu8ta2", "Process_l14lar1"]
def testHandlesNestedCallActivity(self):
parser = _process_parser("nested_call_activity.bpmn", "Process_expand_call_activity")
assert parser.called_element_ids() == ["is_this_missing", "set_permissions_process"]
def testCanAddDmnFromString(self):
parser = BpmnDmnParser()
parser.add_dmn_str(EMPTY_DMN)

View File

@ -24,7 +24,7 @@ class ResetSubProcessTest(BpmnWorkflowTestCase):
state = self.serializer.serialize_json(self.workflow)
self.workflow = self.serializer.deserialize_json(state)
self.workflow.spec = spec
self.workflow.subprocesses = subprocesses
self.workflow.subprocess_specs = subprocesses
def testSaveRestore(self):
self.actualTest(True)
@ -38,14 +38,11 @@ class ResetSubProcessTest(BpmnWorkflowTestCase):
task = self.workflow.get_ready_user_tasks()[0]
self.save_restore()
top_level_task = self.workflow.get_tasks_from_spec_name('Task1')[0]
# top_level_task.reset_token({}, reset_data=True)
self.workflow.reset_from_task_id(top_level_task.id)
task = self.workflow.get_ready_user_tasks()[0]
self.assertEqual(len(self.workflow.get_ready_user_tasks()), 1,
"There should only be one task in a ready state.")
self.assertEqual(len(self.workflow.get_ready_user_tasks()), 1, "There should only be one task in a ready state.")
self.assertEqual(task.get_name(), 'Task1')
def actualTest(self, save_restore=False):
self.workflow.do_engine_steps()
@ -73,7 +70,6 @@ class ResetSubProcessTest(BpmnWorkflowTestCase):
self.assertEqual(task.get_name(),'Subtask2A')
task.run()
self.workflow.do_engine_steps()
self.complete_subworkflow()
task = self.workflow.get_ready_user_tasks()[0]
self.assertEqual(task.get_name(),'Task2')
task.run()

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1oz74lp" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
<bpmn:process id="Process_0ymnx41" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_01pj69c</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:exclusiveGateway id="gw_1" default="Flow_1e2doc4">
<bpmn:incoming>Flow_01pj69c</bpmn:incoming>
<bpmn:outgoing>Flow_1imjpib</bpmn:outgoing>
<bpmn:outgoing>Flow_1e2doc4</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_01pj69c" sourceRef="StartEvent_1" targetRef="gw_1" />
<bpmn:exclusiveGateway id="gw_2" default="Flow_1baqf6p">
<bpmn:incoming>Flow_1imjpib</bpmn:incoming>
<bpmn:outgoing>Flow_1baqf6p</bpmn:outgoing>
<bpmn:outgoing>Flow_0a5mw5g</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_1imjpib" sourceRef="gw_1" targetRef="gw_2">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">False</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:task id="task_1">
<bpmn:incoming>Flow_1baqf6p</bpmn:incoming>
<bpmn:outgoing>Flow_0qrmpxi</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_1baqf6p" sourceRef="gw_2" targetRef="task_1" />
<bpmn:task id="task_2">
<bpmn:incoming>Flow_0a5mw5g</bpmn:incoming>
<bpmn:incoming>Flow_1e2doc4</bpmn:incoming>
<bpmn:outgoing>Flow_1or38ex</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_0a5mw5g" sourceRef="gw_2" targetRef="task_2">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">True</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_1e2doc4" sourceRef="gw_1" targetRef="task_2" />
<bpmn:endEvent id="Event_0wmymez">
<bpmn:incoming>Flow_0qrmpxi</bpmn:incoming>
<bpmn:incoming>Flow_1or38ex</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0qrmpxi" sourceRef="task_1" targetRef="Event_0wmymez" />
<bpmn:sequenceFlow id="Flow_1or38ex" sourceRef="task_2" targetRef="Event_0wmymez" />
<bpmn:boundaryEvent id="Event_0sh7wyp" attachedToRef="task_2">
<bpmn:signalEventDefinition id="SignalEventDefinition_0aridnp" />
</bpmn:boundaryEvent>
<bpmn:boundaryEvent id="Event_00eeq9m" attachedToRef="task_1">
<bpmn:signalEventDefinition id="SignalEventDefinition_0rlpg5k" />
</bpmn:boundaryEvent>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0ymnx41">
<bpmndi:BPMNEdge id="Flow_01pj69c_di" bpmnElement="Flow_01pj69c">
<di:waypoint x="188" y="177" />
<di:waypoint x="395" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1imjpib_di" bpmnElement="Flow_1imjpib">
<di:waypoint x="445" y="177" />
<di:waypoint x="495" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1baqf6p_di" bpmnElement="Flow_1baqf6p">
<di:waypoint x="545" y="177" />
<di:waypoint x="600" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0a5mw5g_di" bpmnElement="Flow_0a5mw5g">
<di:waypoint x="520" y="202" />
<di:waypoint x="520" y="290" />
<di:waypoint x="600" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1e2doc4_di" bpmnElement="Flow_1e2doc4">
<di:waypoint x="420" y="202" />
<di:waypoint x="420" y="320" />
<di:waypoint x="600" y="320" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0qrmpxi_di" bpmnElement="Flow_0qrmpxi">
<di:waypoint x="700" y="177" />
<di:waypoint x="762" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1or38ex_di" bpmnElement="Flow_1or38ex">
<di:waypoint x="700" y="290" />
<di:waypoint x="731" y="290" />
<di:waypoint x="731" y="177" />
<di:waypoint x="762" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Gateway_1vvx4a6_di" bpmnElement="gw_1" isMarkerVisible="true">
<dc:Bounds x="395" y="152" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0vqubcb_di" bpmnElement="gw_2" isMarkerVisible="true">
<dc:Bounds x="495" y="152" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_10scr9s_di" bpmnElement="task_1">
<dc:Bounds x="600" y="137" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0rfxfcx_di" bpmnElement="task_2">
<dc:Bounds x="600" y="250" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0wmymez_di" bpmnElement="Event_0wmymez">
<dc:Bounds x="762" y="159" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="152" y="159" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0becpnz_di" bpmnElement="Event_0sh7wyp">
<dc:Bounds x="642" y="312" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0n62i6p_di" bpmnElement="Event_00eeq9m">
<dc:Bounds x="642" y="119" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qnx3d3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="main" isExecutable="true">
<bpmn:startEvent id="Event_0gayte6">
<bpmn:outgoing>Flow_1b4mvkp</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1b4mvkp" sourceRef="Event_0gayte6" targetRef="set" />
<bpmn:scriptTask id="set" name="Set x = 0">
<bpmn:incoming>Flow_1b4mvkp</bpmn:incoming>
<bpmn:outgoing>Flow_0igglvl</bpmn:outgoing>
<bpmn:script>x = 0</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_0igglvl" sourceRef="set" targetRef="parallel" />
<bpmn:parallelGateway id="parallel">
<bpmn:incoming>Flow_0igglvl</bpmn:incoming>
<bpmn:incoming>Flow_0r5ndy6</bpmn:incoming>
<bpmn:outgoing>Flow_0ric3rl</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:sequenceFlow id="Flow_0ric3rl" sourceRef="parallel" targetRef="increment" />
<bpmn:scriptTask id="increment" name="Increment x">
<bpmn:incoming>Flow_0ric3rl</bpmn:incoming>
<bpmn:outgoing>Flow_19u7g47</bpmn:outgoing>
<bpmn:script>x += 1</bpmn:script>
</bpmn:scriptTask>
<bpmn:exclusiveGateway id="exclusive" default="Flow_0tubcbv">
<bpmn:incoming>Flow_19u7g47</bpmn:incoming>
<bpmn:outgoing>Flow_0tubcbv</bpmn:outgoing>
<bpmn:outgoing>Flow_1jejn7h</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_19u7g47" sourceRef="increment" targetRef="exclusive" />
<bpmn:endEvent id="Event_0nk70qa">
<bpmn:incoming>Flow_0tubcbv</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0tubcbv" sourceRef="exclusive" targetRef="Event_0nk70qa" />
<bpmn:sequenceFlow id="Flow_1jejn7h" name="x &#60; 2" sourceRef="exclusive" targetRef="task">
<bpmn:conditionExpression>x &lt; 2</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:task id="task" name="Task">
<bpmn:incoming>Flow_1jejn7h</bpmn:incoming>
<bpmn:outgoing>Flow_0r5ndy6</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_0r5ndy6" sourceRef="task" targetRef="parallel" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="main">
<bpmndi:BPMNShape id="Event_0gayte6_di" bpmnElement="Event_0gayte6">
<dc:Bounds x="172" y="222" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_18u8kup_di" bpmnElement="set">
<dc:Bounds x="260" y="200" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0ifyqd2_di" bpmnElement="parallel">
<dc:Bounds x="415" y="215" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="422" y="185" width="36" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0h7ytkx_di" bpmnElement="increment">
<dc:Bounds x="520" y="200" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1r9dzbn_di" bpmnElement="exclusive" isMarkerVisible="true">
<dc:Bounds x="675" y="215" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="677" y="185" width="46" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0nk70qa_di" bpmnElement="Event_0nk70qa">
<dc:Bounds x="782" y="222" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0o2cxkw_di" bpmnElement="task">
<dc:Bounds x="520" y="320" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1b4mvkp_di" bpmnElement="Flow_1b4mvkp">
<di:waypoint x="208" y="240" />
<di:waypoint x="260" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0igglvl_di" bpmnElement="Flow_0igglvl">
<di:waypoint x="360" y="240" />
<di:waypoint x="415" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ric3rl_di" bpmnElement="Flow_0ric3rl">
<di:waypoint x="465" y="240" />
<di:waypoint x="520" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_19u7g47_di" bpmnElement="Flow_19u7g47">
<di:waypoint x="620" y="240" />
<di:waypoint x="675" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0tubcbv_di" bpmnElement="Flow_0tubcbv">
<di:waypoint x="725" y="240" />
<di:waypoint x="782" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1jejn7h_di" bpmnElement="Flow_1jejn7h">
<di:waypoint x="700" y="265" />
<di:waypoint x="700" y="360" />
<di:waypoint x="620" y="360" />
<bpmndi:BPMNLabel>
<dc:Bounds x="707" y="339" width="25" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0r5ndy6_di" bpmnElement="Flow_0r5ndy6">
<di:waypoint x="520" y="360" />
<di:waypoint x="440" y="360" />
<di:waypoint x="440" y="265" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -1,201 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1larxsm" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.10.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
<bpmn:process id="SignalAndCancel" isExecutable="true">
<bpmn:startEvent id="Event_0sg9cla" name="Start">
<bpmn:outgoing>Flow_1f7we2y</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:scriptTask id="ON_SIGNAL" name="On Signal " camunda:resultVariable="test_message">
<bpmn:incoming>Flow_0mixvu9</bpmn:incoming>
<bpmn:outgoing>Flow_08knksn</bpmn:outgoing>
<bpmn:script>cancel="cancel_signal"</bpmn:script>
</bpmn:scriptTask>
<bpmn:userTask id="UserTaskOne" name="UserTaskOne" camunda:formKey="HowMany">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="how_many" label="How many?" type="long" defaultValue="1" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_02yqmm2</bpmn:incoming>
<bpmn:outgoing>Flow_1i2iik3</bpmn:outgoing>
</bpmn:userTask>
<bpmn:manualTask id="hello" name="Hello">
<bpmn:documentation>&lt;H1&gt;Hello&lt;/H1&gt;</bpmn:documentation>
<bpmn:incoming>Flow_0ynr3ge</bpmn:incoming>
<bpmn:outgoing>Flow_02yqmm2</bpmn:outgoing>
</bpmn:manualTask>
<bpmn:endEvent id="Event_0bs4tb7">
<bpmn:incoming>Flow_0xvajbj</bpmn:incoming>
</bpmn:endEvent>
<bpmn:manualTask id="Activity_0zko8f8" name="Good Bye">
<bpmn:documentation>&lt;H1&gt;Good Bye&lt;/H1&gt;</bpmn:documentation>
<bpmn:incoming>Flow_0elk2a3</bpmn:incoming>
<bpmn:outgoing>Flow_0xvajbj</bpmn:outgoing>
</bpmn:manualTask>
<bpmn:scriptTask id="ON_CANCEL" name="On Cancel" camunda:resultVariable="cancel_message">
<bpmn:documentation>&lt;H1&gt;Cancel Message&lt;/H1&gt;</bpmn:documentation>
<bpmn:incoming>Flow_0zc9byy</bpmn:incoming>
<bpmn:outgoing>Flow_0zy1z3a</bpmn:outgoing>
<bpmn:script>cancel="cancel_event"</bpmn:script>
</bpmn:scriptTask>
<bpmn:transaction id="Activity_053djnm">
<bpmn:incoming>Flow_1i2iik3</bpmn:incoming>
<bpmn:outgoing>Flow_0elk2a3</bpmn:outgoing>
<bpmn:startEvent id="Event_0wo2ff1">
<bpmn:outgoing>Flow_0syqz17</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id="UserTaskTwo" name="UserTaskTwo" camunda:formKey="FormModify">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="modify" label="Modify Data?" type="boolean" defaultValue="True" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_0syqz17</bpmn:incoming>
<bpmn:outgoing>Flow_0m0ilsi</bpmn:outgoing>
</bpmn:userTask>
<bpmn:endEvent id="Event_01m9nxq">
<bpmn:incoming>Flow_0m0ilsi</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0m0ilsi" sourceRef="UserTaskTwo" targetRef="Event_01m9nxq" />
<bpmn:sequenceFlow id="Flow_0syqz17" sourceRef="Event_0wo2ff1" targetRef="UserTaskTwo" />
</bpmn:transaction>
<bpmn:boundaryEvent id="Event_0dhiirm" name="TokenReset" attachedToRef="UserTaskOne">
<bpmn:outgoing>Flow_0mixvu9</bpmn:outgoing>
<bpmn:signalEventDefinition id="SignalEventDefinition_0fwhq9v" signalRef="Signal_1eo0jkr" />
</bpmn:boundaryEvent>
<bpmn:boundaryEvent id="Event_CANCEL" attachedToRef="Activity_053djnm">
<bpmn:outgoing>Flow_0zc9byy</bpmn:outgoing>
<bpmn:cancelEventDefinition id="CancelEventDefinition_1hi8rs6" />
</bpmn:boundaryEvent>
<bpmn:sequenceFlow id="Flow_1f7we2y" sourceRef="Event_0sg9cla" targetRef="Activity_1tajk3e" />
<bpmn:sequenceFlow id="Flow_0mixvu9" name="TestMessageFlow" sourceRef="Event_0dhiirm" targetRef="ON_SIGNAL" />
<bpmn:sequenceFlow id="Flow_02yqmm2" sourceRef="hello" targetRef="UserTaskOne" />
<bpmn:sequenceFlow id="Flow_1i2iik3" sourceRef="UserTaskOne" targetRef="Activity_053djnm" />
<bpmn:sequenceFlow id="Flow_0xvajbj" sourceRef="Activity_0zko8f8" targetRef="Event_0bs4tb7" />
<bpmn:sequenceFlow id="Flow_0elk2a3" sourceRef="Activity_053djnm" targetRef="Activity_0zko8f8" />
<bpmn:sequenceFlow id="Flow_0zc9byy" sourceRef="Event_CANCEL" targetRef="ON_CANCEL" />
<bpmn:endEvent id="Event_0a1dppg">
<bpmn:incoming>Flow_08knksn</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_08knksn" sourceRef="ON_SIGNAL" targetRef="Event_0a1dppg" />
<bpmn:endEvent id="Event_1d65clv">
<bpmn:incoming>Flow_0zy1z3a</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0zy1z3a" sourceRef="ON_CANCEL" targetRef="Event_1d65clv" />
<bpmn:scriptTask id="Activity_1tajk3e" name="setup" camunda:resultVariable="test_message">
<bpmn:incoming>Flow_1f7we2y</bpmn:incoming>
<bpmn:outgoing>Flow_0ynr3ge</bpmn:outgoing>
<bpmn:script>cancel="none"</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_0ynr3ge" sourceRef="Activity_1tajk3e" targetRef="hello" />
</bpmn:process>
<bpmn:signal id="Signal_1eo0jkr" name="cancel" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="SignalAndCancel">
<bpmndi:BPMNEdge id="Flow_1f7we2y_di" bpmnElement="Flow_1f7we2y">
<di:waypoint x="188" y="180" />
<di:waypoint x="210" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0mixvu9_di" bpmnElement="Flow_0mixvu9">
<di:waypoint x="560" y="238" />
<di:waypoint x="560" y="331" />
<bpmndi:BPMNLabel>
<dc:Bounds x="465" y="273" width="89" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_02yqmm2_di" bpmnElement="Flow_02yqmm2">
<di:waypoint x="460" y="180" />
<di:waypoint x="510" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1i2iik3_di" bpmnElement="Flow_1i2iik3">
<di:waypoint x="610" y="180" />
<di:waypoint x="679" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0xvajbj_di" bpmnElement="Flow_0xvajbj">
<di:waypoint x="1259" y="180" />
<di:waypoint x="1381" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0elk2a3_di" bpmnElement="Flow_0elk2a3">
<di:waypoint x="1029" y="180" />
<di:waypoint x="1159" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0zc9byy_di" bpmnElement="Flow_0zc9byy">
<di:waypoint x="869" y="298" />
<di:waypoint x="869" y="331" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_08knksn_di" bpmnElement="Flow_08knksn">
<di:waypoint x="610" y="371" />
<di:waypoint x="662" y="371" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0zy1z3a_di" bpmnElement="Flow_0zy1z3a">
<di:waypoint x="919" y="371" />
<di:waypoint x="972" y="371" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ynr3ge_di" bpmnElement="Flow_0ynr3ge">
<di:waypoint x="310" y="180" />
<di:waypoint x="360" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_130b520_di" bpmnElement="UserTaskOne">
<dc:Bounds x="510" y="140" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0bs4tb7_di" bpmnElement="Event_0bs4tb7">
<dc:Bounds x="1381" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0zko8f8_di" bpmnElement="Activity_0zko8f8">
<dc:Bounds x="1159" y="140" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_09cvrck_di" bpmnElement="ON_CANCEL">
<dc:Bounds x="819" y="331" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1d65clv_di" bpmnElement="Event_1d65clv">
<dc:Bounds x="972" y="353" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0x9874h_di" bpmnElement="ON_SIGNAL">
<dc:Bounds x="510" y="331" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0sg9cla_di" bpmnElement="Event_0sg9cla">
<dc:Bounds x="152" y="162" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="158" y="205" width="24" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1tajk3e_di" bpmnElement="Activity_1tajk3e">
<dc:Bounds x="210" y="140" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_06wus2t_di" bpmnElement="hello">
<dc:Bounds x="360" y="140" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0a1dppg_di" bpmnElement="Event_0a1dppg">
<dc:Bounds x="662" y="353" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_053djnm_di" bpmnElement="Activity_053djnm" isExpanded="true">
<dc:Bounds x="679" y="80" width="350" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0m0ilsi_di" bpmnElement="Flow_0m0ilsi">
<di:waypoint x="899" y="180" />
<di:waypoint x="951" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0syqz17_di" bpmnElement="Flow_0syqz17">
<di:waypoint x="755" y="180" />
<di:waypoint x="799" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0wo2ff1_di" bpmnElement="Event_0wo2ff1">
<dc:Bounds x="719" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1f1fveb_di" bpmnElement="UserTaskTwo">
<dc:Bounds x="799" y="140" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_01m9nxq_di" bpmnElement="Event_01m9nxq">
<dc:Bounds x="951" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0dhiirm_di" bpmnElement="Event_0dhiirm">
<dc:Bounds x="542" y="202" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="580" y="233" width="59" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1sc7ju9_di" bpmnElement="Event_CANCEL">
<dc:Bounds x="851" y="262" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Process_expand_call_activity" isExecutable="true">
<bpmn:subProcess id="Activity_0jqrbg8">
<bpmn:incoming>Flow_0rrlqcy</bpmn:incoming>
<bpmn:outgoing>Flow_1x7ckx0</bpmn:outgoing>
<bpmn:startEvent id="Event_1gj4k6s">
<bpmn:outgoing>Flow_09wo95v</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_09wo95v" sourceRef="Event_1gj4k6s" targetRef="Activity_0f25k4g" />
<bpmn:endEvent id="Event_12ep3rp">
<bpmn:incoming>Flow_0fbenj5</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0fbenj5" sourceRef="Activity_0f25k4g" targetRef="Event_12ep3rp" />
<bpmn:callActivity id="Activity_0f25k4g" name="missing?" calledElement="is_this_missing">
<bpmn:incoming>Flow_09wo95v</bpmn:incoming>
<bpmn:outgoing>Flow_0fbenj5</bpmn:outgoing>
</bpmn:callActivity>
</bpmn:subProcess>
<bpmn:endEvent id="Event_0woz4y5">
<bpmn:incoming>Flow_0q4zwqq</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1x7ckx0" sourceRef="Activity_0jqrbg8" targetRef="Activity_1tglo3a" />
<bpmn:startEvent id="Event_0l2o0kx">
<bpmn:outgoing>Flow_0rrlqcy</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_0rrlqcy" sourceRef="Event_0l2o0kx" targetRef="Activity_0jqrbg8" />
<bpmn:sequenceFlow id="Flow_0q4zwqq" sourceRef="Activity_1tglo3a" targetRef="Event_0woz4y5" />
<bpmn:subProcess id="Activity_1tglo3a" name="missing?">
<bpmn:incoming>Flow_1x7ckx0</bpmn:incoming>
<bpmn:outgoing>Flow_0q4zwqq</bpmn:outgoing>
<bpmn:startEvent id="Event_003dbci">
<bpmn:outgoing>Flow_1gg1sal</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1gg1sal" sourceRef="Event_003dbci" targetRef="Activity_00etcsd" />
<bpmn:endEvent id="Event_0e6rn1x">
<bpmn:incoming>Flow_151l7v5</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_151l7v5" sourceRef="Activity_00etcsd" targetRef="Event_0e6rn1x" />
<bpmn:callActivity id="Activity_00etcsd" name="also missing?" calledElement="set_permissions_process">
<bpmn:incoming>Flow_1gg1sal</bpmn:incoming>
<bpmn:outgoing>Flow_151l7v5</bpmn:outgoing>
</bpmn:callActivity>
</bpmn:subProcess>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_expand_call_activity">
<bpmndi:BPMNShape id="Event_0woz4y5_di" bpmnElement="Event_0woz4y5">
<dc:Bounds x="422" y="-128" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0jqrbg8_di" bpmnElement="Activity_0jqrbg8" isExpanded="true">
<dc:Bounds x="-170" y="-210" width="350" height="200" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1gj4k6s_di" bpmnElement="Event_1gj4k6s">
<dc:Bounds x="-130" y="-128" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_12ep3rp_di" bpmnElement="Event_12ep3rp">
<dc:Bounds x="122" y="-128" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_10rwvqv_di" bpmnElement="Activity_0f25k4g">
<dc:Bounds x="-40" y="-150" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_09wo95v_di" bpmnElement="Flow_09wo95v">
<di:waypoint x="-94" y="-110" />
<di:waypoint x="-40" y="-110" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0fbenj5_di" bpmnElement="Flow_0fbenj5">
<di:waypoint x="60" y="-110" />
<di:waypoint x="122" y="-110" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0l2o0kx_di" bpmnElement="Event_0l2o0kx">
<dc:Bounds x="-328" y="-128" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1jcx1cz_di" bpmnElement="Activity_1tglo3a">
<dc:Bounds x="240" y="-150" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1x7ckx0_di" bpmnElement="Flow_1x7ckx0">
<di:waypoint x="180" y="-110" />
<di:waypoint x="240" y="-110" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0rrlqcy_di" bpmnElement="Flow_0rrlqcy">
<di:waypoint x="-292" y="-110" />
<di:waypoint x="-170" y="-110" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0q4zwqq_di" bpmnElement="Flow_0q4zwqq">
<di:waypoint x="340" y="-110" />
<di:waypoint x="422" y="-110" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
<bpmndi:BPMNDiagram id="BPMNDiagram_16455gw">
<bpmndi:BPMNPlane id="BPMNPlane_0yuaj40" bpmnElement="Activity_1tglo3a">
<bpmndi:BPMNShape id="Event_003dbci_di" bpmnElement="Event_003dbci">
<dc:Bounds x="312" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0e6rn1x_di" bpmnElement="Event_0e6rn1x">
<dc:Bounds x="552" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_00bloq9_di" bpmnElement="Activity_00etcsd">
<dc:Bounds x="400" y="140" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1gg1sal_di" bpmnElement="Flow_1gg1sal">
<di:waypoint x="348" y="180" />
<di:waypoint x="400" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_151l7v5_di" bpmnElement="Flow_151l7v5">
<di:waypoint x="500" y="180" />
<di:waypoint x="552" y="180" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

File diff suppressed because it is too large Load Diff

View File

@ -48,7 +48,6 @@ 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())
@ -74,7 +73,7 @@ class ActionManagementTest(BpmnWorkflowTestCase):
time.sleep(self.FINISH_TIME_DELTA)
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(3, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertNotEqual('Finish Time', self.workflow.get_tasks(TaskState.WAITING)[0].task_spec.bpmn_name)
overdue_escalation_task = [
@ -86,8 +85,6 @@ 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())
def testRunThroughCancel(self):

View File

@ -80,7 +80,6 @@ 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())

View File

@ -1,9 +1,10 @@
from datetime import timedelta
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.event import BpmnEvent, BpmnEvent
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
from SpiffWorkflow.bpmn.PythonScriptEngineEnvironment import TaskDataEnvironment
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from SpiffWorkflow.task import TaskState
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
@ -29,7 +30,7 @@ class EventBasedGatewayTest(BpmnWorkflowTestCase):
self.save_restore()
self.workflow.script_engine = self.script_engine
self.assertEqual(len(waiting_tasks), 2)
self.workflow.catch(MessageEventDefinition('message_1'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('message_1'), {}))
self.workflow.do_engine_steps()
self.workflow.refresh_waiting_tasks()
self.assertEqual(self.workflow.is_completed(), True)
@ -42,8 +43,8 @@ class EventBasedGatewayTest(BpmnWorkflowTestCase):
self.workflow.do_engine_steps()
waiting_tasks = self.workflow.get_waiting_tasks()
self.assertEqual(len(waiting_tasks), 2)
timer_event = waiting_tasks[0].task_spec.event_definition.event_definitions[-1]
self.workflow.catch(timer_event)
timer_event_definition = waiting_tasks[0].task_spec.event_definition.event_definitions[-1]
self.workflow.catch(BpmnEvent(timer_event_definition))
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
self.assertEqual(self.workflow.is_completed(), True)
@ -55,7 +56,7 @@ class EventBasedGatewayTest(BpmnWorkflowTestCase):
spec, subprocess = self.load_workflow_spec('multiple-start-parallel.bpmn', 'main')
workflow = BpmnWorkflow(spec)
workflow.do_engine_steps()
workflow.catch(MessageEventDefinition('message_1'))
workflow.catch(MessageEventDefinition('message_2'))
workflow.catch(BpmnEvent(MessageEventDefinition('message_1'), {}))
workflow.catch(BpmnEvent(MessageEventDefinition('message_2'), {}))
workflow.refresh_waiting_tasks()
workflow.do_engine_steps()

View File

@ -2,7 +2,8 @@
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'matth'
@ -29,7 +30,6 @@ 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')
@ -50,7 +50,7 @@ class MessageInterruptsSpTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.workflow.do_engine_steps()
self.save_restore()

View File

@ -4,7 +4,8 @@ import unittest
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'matth'
@ -33,7 +34,6 @@ 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()
@ -52,7 +52,7 @@ class MessageInterruptsTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.save_restore()
self.workflow.do_engine_steps()
@ -64,7 +64,6 @@ 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)))
@ -80,7 +79,6 @@ 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()
@ -95,7 +93,7 @@ class MessageInterruptsTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.WAITING)))
@ -104,7 +102,6 @@ class MessageInterruptsTest(BpmnWorkflowTestCase):
self.do_next_exclusive_step('Acknowledge Interrupt Message')
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'matth'
@ -19,8 +20,7 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.save_restore()
self.do_next_exclusive_step(
'Select Test', choice='Message Non Interrupt')
self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt')
self.workflow.do_engine_steps()
self.save_restore()
@ -31,7 +31,6 @@ 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()
@ -43,19 +42,18 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.save_restore()
self.do_next_exclusive_step(
'Select Test', choice='Message Non Interrupt')
self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt')
self.workflow.do_engine_steps()
self.save_restore()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.save_restore()
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.READY)))
self.do_next_named_step('Acknowledge Non-Interrupt Message')
@ -71,14 +69,12 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.save_restore()
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))
def testRunThroughHappy(self):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.do_next_exclusive_step(
'Select Test', choice='Message Non Interrupt')
self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt')
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
@ -87,7 +83,6 @@ 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()
@ -96,45 +91,42 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
def testRunThroughMessageInterrupt(self):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.do_next_exclusive_step(
'Select Test', choice='Message Non Interrupt')
self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt')
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.READY)))
self.do_next_named_step('Acknowledge Non-Interrupt Message')
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(3, len(self.workflow.get_tasks(TaskState.WAITING)))
self.do_next_named_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.READY | TaskState.WAITING)))
def testRunThroughMessageInterruptOtherOrder(self):
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.do_next_exclusive_step(
'Select Test', choice='Message Non Interrupt')
self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt')
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.READY)))
self.do_next_named_step('Do Something That Takes A Long Time')
@ -145,7 +137,6 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.do_next_named_step('Acknowledge Non-Interrupt Message')
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))
def testRunThroughMessageInterruptOtherOrderSaveAndRestore(self):
@ -160,11 +151,11 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.save_restore()
self.workflow.do_engine_steps()
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.READY)))
self.do_next_named_step('Do Something That Takes A Long Time')
@ -177,5 +168,4 @@ class MessageNonInterruptTest(BpmnWorkflowTestCase):
self.save_restore()
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'matth'
@ -28,7 +29,6 @@ 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')
@ -49,11 +49,10 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(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('Ack Subprocess Done')
@ -78,10 +77,9 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(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')
@ -106,7 +104,7 @@ class MessageNonInterruptsSpTest(BpmnWorkflowTestCase):
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.do_next_named_step('Acknowledge SP Parallel Message')
self.workflow.do_engine_steps()
@ -114,7 +112,6 @@ 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')

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'matth'
@ -22,15 +23,14 @@ class MessagesTest(BpmnWorkflowTestCase):
self.workflow.do_engine_steps()
self.assertEqual([], self.workflow.get_tasks(TaskState.READY))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Wrong Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Wrong Message'), {}))
self.assertEqual([], self.workflow.get_tasks(TaskState.READY))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(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.bpmn_name)
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))
def testRunThroughSaveAndRestore(self):
@ -43,13 +43,12 @@ class MessagesTest(BpmnWorkflowTestCase):
self.assertEqual([], self.workflow.get_tasks(TaskState.READY))
self.assertEqual(2, len(self.workflow.get_tasks(TaskState.WAITING)))
self.workflow.catch(MessageEventDefinition('Wrong Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Wrong Message'), {}))
self.assertEqual([], self.workflow.get_tasks(TaskState.READY))
self.workflow.catch(MessageEventDefinition('Test Message'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('Test Message'), {}))
self.assertEqual(1, len(self.workflow.get_tasks(TaskState.READY)))
self.save_restore()
self.workflow.do_engine_steps()
self.complete_subworkflow()
self.assertEqual(0, len(self.workflow.get_tasks(TaskState.READY | TaskState.WAITING)))

View File

@ -1,5 +1,6 @@
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.specs.event_definitions import MessageEventDefinition
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.bpmn.specs.event_definitions.message import MessageEventDefinition
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
@ -28,7 +29,7 @@ class MultipleStartEventTest(BpmnWorkflowTestCase):
self.assertEqual(len(waiting_tasks), 1)
self.assertEqual(waiting_tasks[0].task_spec.name, 'StartEvent_1')
self.workflow.catch(MessageEventDefinition('message_1'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('message_1'), {}))
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
@ -62,7 +63,7 @@ class ParallelStartEventTest(BpmnWorkflowTestCase):
self.assertEqual(len(waiting_tasks), 1)
self.assertEqual(waiting_tasks[0].task_spec.name, 'StartEvent_1')
self.workflow.catch(MessageEventDefinition('message_1'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('message_1'), {}))
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
@ -71,11 +72,11 @@ class ParallelStartEventTest(BpmnWorkflowTestCase):
self.assertEqual(len(waiting_tasks), 1)
self.assertEqual(waiting_tasks[0].task_spec.name, 'StartEvent_1')
self.workflow.catch(MessageEventDefinition('message_2'))
self.workflow.catch(BpmnEvent(MessageEventDefinition('message_2'), {}))
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
# Now the first task should be ready
ready_tasks = self.workflow.get_ready_user_tasks()
self.assertEqual(len(ready_tasks), 1)
self.assertEqual(ready_tasks[0].task_spec.name, 'any_task')
self.assertEqual(ready_tasks[0].task_spec.name, 'any_task')

View File

@ -1,75 +0,0 @@
# -*- coding: utf-8 -*-
import unittest
from SpiffWorkflow.bpmn.specs.event_definitions import CancelEventDefinition, SignalEventDefinition
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
__author__ = 'kellym'
class MultipleEventsTest(BpmnWorkflowTestCase):
def setUp(self):
self.spec, self.subprocesses = self.load_workflow_spec('multipleEvents.bpmn', 'SignalAndCancel')
self.workflow = BpmnWorkflow(self.spec, self.subprocesses)
self.workflow.do_engine_steps()
ready_tasks = self.workflow.get_tasks(TaskState.READY)
self.assertEqual("hello", ready_tasks[0].get_name())
def test_cancel_does_nothing_if_no_one_is_listening(self,save_restore = False):
# Send cancel notifications to the workflow
self.workflow.catch(SignalEventDefinition('cancel')) # generate a cancel signal.
self.workflow.catch(CancelEventDefinition())
# Nothing should have happened.
ready_tasks = self.workflow.get_tasks(TaskState.READY)
self.assertEqual("hello", ready_tasks[0].get_name())
def test_cancel_works_with_signal(self,save_restore = False):
task = self.workflow.get_tasks(TaskState.READY)[0]
# Move to User Task 1
self.workflow.run_task_from_id(task.id)
self.workflow.do_engine_steps()
task = self.workflow.get_tasks(TaskState.READY)[0]
self.assertEqual('UserTaskOne', task.get_name())
# Send cancel notifications to the workflow
self.workflow.catch(SignalEventDefinition('cancel')) # generate a cancel signal.
self.workflow.catch(CancelEventDefinition())
self.workflow.do_engine_steps()
# The cancel event should have been called.
self.assertEqual("cancel_signal", self.workflow.last_task.data['cancel'])
def test_cancel_works_with_cancel_Event(self,save_restore = False):
task = self.workflow.get_tasks(TaskState.READY)[0]
# Move to User Task 2
self.workflow.run_task_from_id(task.id)
self.workflow.do_engine_steps()
task = self.workflow.get_tasks(TaskState.READY)[0]
self.workflow.run_task_from_id(task.id)
self.workflow.do_engine_steps()
task = self.workflow.get_tasks(TaskState.READY)[0]
self.assertEqual('UserTaskTwo', task.get_name())
# Send cancel notifications to the workflow
self.workflow.catch(SignalEventDefinition('cancel')) # generate a cancel signal.
self.workflow.catch(CancelEventDefinition())
self.workflow.do_engine_steps()
# The cancel event shave h
self.assertEqual("cancel_event", self.workflow.last_task.data['cancel'])
def suite():
return unittest.TestLoader().loadTestsFromTestCase(MultipleEventsTest)
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite())

View File

@ -19,7 +19,6 @@ 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)
@ -45,5 +44,4 @@ 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)

View File

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
import unittest
import datetime
import time
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
@ -38,9 +36,10 @@ class NITimerDurationTest(BpmnWorkflowTestCase):
starttime = datetime.datetime.now()
# test bpmn has a timeout of .2s; we should terminate loop before that.
# The subprocess will also wait
while len(self.workflow.get_waiting_tasks()) == 2 and loopcount < 10:
while event.state == TaskState.WAITING and loopcount < 10:
if save_restore:
self.save_restore()
event = self.workflow.get_tasks_from_spec_name('Event_0jyy8ao')[0]
time.sleep(0.1)
ready_tasks = self.workflow.get_tasks(TaskState.READY)
# There should be one ready task until the boundary event fires
@ -66,12 +65,5 @@ class NITimerDurationTest(BpmnWorkflowTestCase):
self.workflow.refresh_waiting_tasks()
self.workflow.do_engine_steps()
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'})
def suite():
return unittest.TestLoader().loadTestsFromTestCase(NITimerDurationTest)
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite())

View File

@ -1,7 +1,7 @@
import unittest
from datetime import datetime
from SpiffWorkflow.bpmn.specs.event_definitions import TimerEventDefinition
from SpiffWorkflow.bpmn.specs.event_definitions.timer import TimerEventDefinition
class TimeDurationParseTest(unittest.TestCase):
"Non-exhaustive ISO durations, but hopefully covers basic support"

View File

@ -1,7 +1,4 @@
# -*- coding: utf-8 -*-
import datetime
import unittest
import time
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
@ -70,7 +67,3 @@ class TimerCycleTest(BpmnWorkflowTestCase):
self.assertEqual(timer.state, TaskState.COMPLETED)
self.assertEqual(counter, 2)
def suite():
return unittest.TestLoader().loadTestsFromTestCase(TimerCycleTest)
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite())

View File

@ -22,7 +22,6 @@ 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
@ -63,7 +62,8 @@ class TransactionSubprocessTest(BpmnWorkflowTestCase):
# We should not have this task, as we followed the 'cancel branch'
print_task = self.workflow.get_tasks_from_spec_name("Activity_Print_Data")
self.assertEqual(len(print_task), 0)
self.assertEqual(len(print_task), 1)
self.assertEqual(print_task[0].state, TaskState.CANCELLED)
def testSubworkflowErrorCodeNone(self):
@ -94,7 +94,8 @@ class TransactionSubprocessTest(BpmnWorkflowTestCase):
# Make sure this branch didn't getfollowed
print_task = self.workflow.get_tasks_from_spec_name("Activity_Print_Data")
self.assertEqual(len(print_task), 0)
self.assertEqual(len(print_task), 1)
self.assertEqual(print_task[0].state, TaskState.CANCELLED)
def testSubworkflowErrorCodeOne(self):
@ -119,4 +120,5 @@ class TransactionSubprocessTest(BpmnWorkflowTestCase):
self.assertEqual(error_1_task.state, TaskState.COMPLETED)
print_task = self.workflow.get_tasks_from_spec_name("Activity_Print_Data")
self.assertEqual(len(print_task), 0)
self.assertEqual(len(print_task), 1)
self.assertEqual(print_task[0].state, TaskState.CANCELLED)

View File

@ -0,0 +1,19 @@
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from ..BpmnWorkflowTestCase import BpmnWorkflowTestCase
class ParallelGatewayLoopInputTest(BpmnWorkflowTestCase):
def setUp(self):
spec, subprocess_specs = self.load_workflow_spec('gateway_loop_input.bpmn', 'main')
self.workflow = BpmnWorkflow(spec, subprocess_specs)
def test_loop_input(self):
self.workflow.do_engine_steps()
ready = self.workflow.get_tasks(TaskState.READY)
self.assertEqual(len(ready), 1)
ready[0].run()
self.workflow.do_engine_steps()
self.assertTrue(self.workflow.is_completed())
self.assertDictEqual(self.workflow.data, { 'x': 2})

View File

@ -33,7 +33,6 @@ 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()

View File

@ -162,7 +162,6 @@ class BpmnWorkflowSerializerTest(BaseTestCase):
self.assertIsInstance(w1, BpmnWorkflow)
self.assertIsInstance(w2, BpmnWorkflow)
self.assertEqual(w1.data, w2.data)
self.assertEqual(w1.name, w2.name)
for task in w1.get_ready_user_tasks():
w2_task = w2.get_task_from_id(task.id)
self.assertIsNotNone(w2_task)

View File

@ -11,8 +11,6 @@ from .BaseTestCase import BaseTestCase
class Version_1_0_Test(BaseTestCase):
SERIALIZER_VERSION = "1.2"
def test_convert_subprocess(self):
# The serialization used here comes from NestedSubprocessTest saved at line 25 with version 1.0
fn = os.path.join(self.DATA_DIR, 'serialization', 'v1.0.json')
@ -92,3 +90,46 @@ class Version_1_1_Test(BaseTestCase):
ready_tasks[0].run()
ready_tasks = wf.get_tasks(TaskState.READY)
self.assertTrue(wf.is_completed())
class Version1_2_Test(BaseTestCase):
def test_remove_boundary_events(self):
fn = os.path.join(self.DATA_DIR, 'serialization', 'v1.2-boundary-events.json')
wf = self.serializer.deserialize_json(open(fn).read())
ready_tasks = wf.get_tasks(TaskState.READY)
ready_tasks[0].update_data({'value': 'asdf'})
ready_tasks[0].run()
wf.do_engine_steps()
ready_tasks = wf.get_tasks(TaskState.READY)
ready_tasks[0].update_data({'quantity': 2})
ready_tasks[0].run()
wf.do_engine_steps()
self.assertIn('value', wf.last_task.data)
# Check that workflow and next task completed
subprocess = wf.get_tasks_from_spec_name('Subprocess')[0]
self.assertEqual(subprocess.state, TaskState.COMPLETED)
print_task = wf.get_tasks_from_spec_name("Activity_Print_Data")[0]
self.assertEqual(print_task.state, TaskState.COMPLETED)
# Check that the boundary events were cancelled
cancel_task = wf.get_tasks_from_spec_name("Catch_Cancel_Event")[0]
self.assertEqual(cancel_task.state, TaskState.CANCELLED)
error_1_task = wf.get_tasks_from_spec_name("Catch_Error_1")[0]
self.assertEqual(error_1_task.state, TaskState.CANCELLED)
error_none_task = wf.get_tasks_from_spec_name("Catch_Error_None")[0]
self.assertEqual(error_none_task.state, TaskState.CANCELLED)
def test_remove_noninterrupting_boundary_events(self):
fn = os.path.join(self.DATA_DIR, 'serialization', 'v1.2-boundary-events-noninterrupting.json')
wf = self.serializer.deserialize_json(open(fn).read())
wf.get_tasks_from_spec_name('sid-D3365C47-2FAE-4D17-98F4-E68B345E18CE')[0].run()
wf.do_engine_steps()
self.assertEqual(1, len(wf.get_tasks(TaskState.READY)))
self.assertEqual(3, len(wf.get_tasks(TaskState.WAITING)))
wf.get_tasks_from_spec_name('sid-6FBBB56D-00CD-4C2B-9345-486986BB4992')[0].run()
wf.do_engine_steps()
self.assertTrue(wf.is_completed())

View File

@ -41,7 +41,6 @@ class CallActivityMessageTest(BaseTestCase):
current_task.update_data(step[1])
current_task.run()
self.workflow.do_engine_steps()
self.complete_subworkflow()
if save_restore:
self.save_restore()
ready_tasks = self.workflow.get_tasks(TaskState.READY)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from SpiffWorkflow.bpmn.event import BpmnEvent
from SpiffWorkflow.camunda.specs.event_definitions import MessageEventDefinition
from .BaseTestCase import BaseTestCase
@ -19,19 +19,19 @@ class ExternalMessageBoundaryTest(BaseTestCase):
def testThroughSaveRestore(self):
self.actual_test(save_restore=True)
def actual_test(self,save_restore = False):
def actual_test(self, save_restore=False):
self.workflow.do_engine_steps()
ready_tasks = self.workflow.get_tasks(TaskState.READY)
self.assertEqual(1, len(ready_tasks),'Expected to have only one ready task')
self.workflow.catch(MessageEventDefinition('Interrupt', payload='SomethingImportant', result_var='interrupt_var'))
self.workflow.catch(BpmnEvent(
MessageEventDefinition('Interrupt'),
{'result_var': 'interrupt_var', 'payload': 'SomethingImportant'}
))
self.workflow.do_engine_steps()
ready_tasks = self.workflow.get_tasks(TaskState.READY)
self.assertEqual(2,len(ready_tasks),'Expected to have two ready tasks')
# here because the thread just dies and doesn't lead to a task, we expect the data
# to die with it.
# item 1 should be at 'Pause'
self.assertEqual('Pause',ready_tasks[1].task_spec.bpmn_name)
self.assertEqual('SomethingImportant', ready_tasks[1].data['interrupt_var'])
@ -40,11 +40,11 @@ class ExternalMessageBoundaryTest(BaseTestCase):
self.assertEqual(False, ready_tasks[0].data['caughtinterrupt'])
ready_tasks[1].run()
self.workflow.do_engine_steps()
# what I think is going on here is that when we hit the reset, it is updating the
# last_task and appending the data to whatever happened there, so it would make sense that
# we have the extra variables that happened in 'pause'
# if on the other hand, we went on from 'meaningless task' those variables would not get added.
self.workflow.catch(MessageEventDefinition('reset', payload='SomethingDrastic', result_var='reset_var'))
self.workflow.catch(BpmnEvent(
MessageEventDefinition('reset'),
{'result_var': 'reset_var', 'payload': 'SomethingDrastic'}
))
ready_tasks = self.workflow.get_tasks(TaskState.READY)
# The user activity was cancelled and we should continue from the boundary event
self.assertEqual(2, len(ready_tasks), 'Expected to have two ready tasks')

View File

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
import unittest
import time
from datetime import timedelta
from SpiffWorkflow.task import TaskState
@ -26,8 +22,6 @@ class MessageBoundaryTest(BaseTestCase):
def testThroughSaveRestore(self):
self.actual_test(save_restore=True)
def actual_test(self,save_restore = False):
steps = [('Activity_Interrupt', {'interrupt_task':'No'}),
('Activity_Interrupt', {'interrupt_task': 'No'}),
@ -54,9 +48,3 @@ class MessageBoundaryTest(BaseTestCase):
self.workflow.do_engine_steps()
self.assertEqual(self.workflow.is_completed(),True,'Expected the workflow to be complete at this point')
def suite():
return unittest.TestLoader().loadTestsFromTestCase(MessageBoundaryTest)
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite())

View File

@ -82,7 +82,6 @@ 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',

View File

@ -77,7 +77,6 @@ class ResetTokenTestSubProcess(BaseTestCase):
task.update_data({step['formvar']: step['answer']})
task.run()
self.workflow.do_engine_steps()
self.complete_subworkflow()
if save_restore:
self.save_restore()

View File

@ -1,10 +1,7 @@
# -*- coding: utf-8 -*-
import unittest
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from .BaseTestCase import BaseTestCase
__author__ = 'kellym'
@ -62,9 +59,3 @@ class StartMessageTest(BaseTestCase):
'ApprovalResult': 'Yes',
'Done': 'OK!'
})
def suite():
return unittest.TestLoader().loadTestsFromTestCase(StartMessageTest)
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite())

View File

@ -33,7 +33,6 @@ class SubWorkflowTest(BaseTestCase):
task.update_data({"Field"+answer: answer})
task.run()
self.workflow.do_engine_steps()
self.complete_subworkflow()
if save_restore:
self.save_restore()

View File

@ -18,7 +18,7 @@ class CamundaExtensionsTest(BaseTestCase):
def assertMyExtension(self):
"""Assure that we have a very specific extension on specific task."""
task = self.workflow.get_task_spec_from_name("Task_User_Select_Type")
task = self.workflow.spec.get_task_spec_from_name("Task_User_Select_Type")
self.assertIsNotNone(task)
self.assertTrue(hasattr(task, 'extensions'))
self.assertTrue("my_extension" in task.extensions)

View File

@ -109,7 +109,7 @@ class TaskSpecTest(unittest.TestCase):
# Now refresh waiting tasks:
# Update the state of every WAITING task.
for thetask in self.workflow._get_waiting_tasks():
for thetask in [t for t in self.workflow.get_tasks(TaskState.WAITING)]:
thetask.task_spec._update(thetask)
self.do_next_unique_task('last')

View File

@ -2,16 +2,21 @@ import os
from lxml import etree
from SpiffWorkflow.bpmn.PythonScriptEngineEnvironment import Box
from SpiffWorkflow.dmn.engine.DMNEngine import DMNEngine
from SpiffWorkflow.dmn.parser.DMNParser import DMNParser, get_dmn_ns
class WorkflowSpec:
def __init__(self):
self.file = 'my_mock_file'
self.name = 'Mock Workflow Spec'
self.task_specs = {}
class Workflow:
def __init__(self, script_engine):
self.script_engine = script_engine
self.outer_workflow = self
self.spec = Box({'file': 'my_mock_file'})
self.parent = None
self.spec = WorkflowSpec()
self.top_workflow = self
class TaskSpec:
def __init__(self):

View File

@ -45,16 +45,11 @@ class DualConversationTest(BaseTestCase):
spec, subprocesses = self.load_workflow_spec('correlation_two_conversations.bpmn', 'message_send_process')
workflow = BpmnWorkflow(spec, subprocesses)
workflow.do_engine_steps()
messages = workflow.get_bpmn_messages()
messages = workflow.get_events()
self.assertEqual(len(messages), 2)
[ msg for msg in messages if msg.name== 'Message Send One' ][0]
[ msg for msg in messages if msg.name== 'Message Send Two' ][0]
# fixme: This seemed to test that we get a nested structure of correlation keys and correlation properties
# Perhaps there should be a way to get the keys and thier associated properties -
# but things should not default to a nested structure.
# self.assertIn('message_correlation_key_one', message_one.correlations)
# self.assertNotIn('message_correlation_key_one', message_two.correlations)
# self.assertIn('message_correlation_key_two', message_two.correlations)
# self.assertNotIn('message_correlation_key_two', message_one.correlations)
self.assertEqual('Message Send One', messages[0].event_definition.name)
self.assertEqual('Message Send Two', messages[1].event_definition.name)
self.assertIn('message_correlation_key_one', messages[0].correlations)
self.assertNotIn('message_correlation_key_one', messages[1].correlations)
self.assertIn('message_correlation_key_two', messages[1].correlations)
self.assertNotIn('message_correlation_key_two', messages[0].correlations)

View File

@ -0,0 +1,49 @@
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
from .BaseTestCase import BaseTestCase
class EventPayloadTest(BaseTestCase):
def testSignalEvent(self):
spec, subprocesses = self.load_workflow_spec('signal_event_payload.bpmn', 'event_test')
self.workflow = BpmnWorkflow(spec)
self.workflow.do_engine_steps()
self.save_restore()
set_data = self.workflow.get_tasks_from_spec_name('set_data')[0]
# Throw event creates payload from v1 & v2
set_data.data = {'v1': 1, 'v2': 2, 'v3': 3}
set_data.run()
self.workflow.do_engine_steps()
self.assertTrue(self.workflow.is_completed())
self.assertDictEqual(self.workflow.data, {
'v1': 1,
'v2': 2,
'v3': 3,
'result': {'r1': 1, 'r2': 2}
})
def testErrorEvent(self):
spec, subprocesses = self.load_workflow_spec('error_event_payload.bpmn', 'event_test')
self.workflow = BpmnWorkflow(spec, subprocesses)
self.workflow.do_engine_steps()
self.save_restore()
set_data = self.workflow.get_tasks_from_spec_name('set_data')[0]
# Throw event creates payload from v1 & v2
set_data.data = {'error': True, 'payload': 'ERROR!'}
set_data.run()
self.workflow.do_engine_steps()
self.assertTrue(self.workflow.is_completed())
self.assertEqual(self.workflow.data, {'result': 'ERROR!'})
def testEscalationEvent(self):
spec, subprocesses = self.load_workflow_spec('escalation_event_payload.bpmn', 'event_test')
self.workflow = BpmnWorkflow(spec, subprocesses)
self.workflow.do_engine_steps()
self.save_restore()
set_data = self.workflow.get_tasks_from_spec_name('set_data')[0]
# Throw event creates payload from v1 & v2
set_data.data = {'escalation': True, 'payload': 'ERROR!'}
set_data.run()
self.workflow.do_engine_steps()
self.assertTrue(self.workflow.is_completed())
self.assertEqual(self.workflow.data, {'result': 'ERROR!'})

View File

@ -84,4 +84,3 @@ 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()

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qnx3d3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="event_test" isExecutable="true" camunda:versionTag="1">
<bpmn:startEvent id="Event_0ecwc0v">
<bpmn:outgoing>Flow_1rbbx75</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1rbbx75" sourceRef="Event_0ecwc0v" targetRef="Activity_1qrttpi" />
<bpmn:subProcess id="Activity_1qrttpi">
<bpmn:incoming>Flow_1rbbx75</bpmn:incoming>
<bpmn:outgoing>Flow_077e1zz</bpmn:outgoing>
<bpmn:startEvent id="Event_09erd49">
<bpmn:outgoing>Flow_1as4f94</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:task id="set_data" name="Set Data">
<bpmn:incoming>Flow_1as4f94</bpmn:incoming>
<bpmn:outgoing>Flow_10mhppx</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_1as4f94" sourceRef="Event_09erd49" targetRef="set_data" />
<bpmn:exclusiveGateway id="Gateway_1v0x5mk" default="Flow_0wv10p6">
<bpmn:incoming>Flow_10mhppx</bpmn:incoming>
<bpmn:outgoing>Flow_0wv10p6</bpmn:outgoing>
<bpmn:outgoing>Flow_1o689w0</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_10mhppx" sourceRef="set_data" targetRef="Gateway_1v0x5mk" />
<bpmn:endEvent id="Event_03ddub8">
<bpmn:incoming>Flow_0wv10p6</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0wv10p6" sourceRef="Gateway_1v0x5mk" targetRef="Event_03ddub8" />
<bpmn:sequenceFlow id="Flow_1o689w0" sourceRef="Gateway_1v0x5mk" targetRef="throw">
<bpmn:conditionExpression>error</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:endEvent id="throw">
<bpmn:incoming>Flow_1o689w0</bpmn:incoming>
<bpmn:errorEventDefinition id="ErrorEventDefinition_0w6x2pp" errorRef="error_event" />
</bpmn:endEvent>
</bpmn:subProcess>
<bpmn:endEvent id="Event_1nd3odq">
<bpmn:incoming>Flow_01bfubj</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_01bfubj" sourceRef="catch" targetRef="Event_1nd3odq" />
<bpmn:boundaryEvent id="catch" attachedToRef="Activity_1qrttpi">
<bpmn:outgoing>Flow_01bfubj</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_147hq0b" errorRef="error_event" />
</bpmn:boundaryEvent>
<bpmn:endEvent id="Event_1n1i393">
<bpmn:incoming>Flow_077e1zz</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_077e1zz" sourceRef="Activity_1qrttpi" targetRef="Event_1n1i393" />
</bpmn:process>
<bpmn:error id="error_event" name="error_event" errorCode="1">
<bpmn:extensionElements>
<spiffworkflow:payloadExpression>payload</spiffworkflow:payloadExpression>
<spiffworkflow:variableName>result</spiffworkflow:variableName>
</bpmn:extensionElements>
</bpmn:error>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="event_test">
<bpmndi:BPMNShape id="Event_1n1i393_di" bpmnElement="Event_1n1i393">
<dc:Bounds x="822" y="317" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0ecwc0v_di" bpmnElement="Event_0ecwc0v">
<dc:Bounds x="172" y="317" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1nd3odq_di" bpmnElement="Event_1nd3odq">
<dc:Bounds x="702" y="542" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1ak58zv_di" bpmnElement="Activity_1qrttpi" isExpanded="true">
<dc:Bounds x="250" y="190" width="530" height="290" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_09erd49_di" bpmnElement="Event_09erd49">
<dc:Bounds x="290.33333333333337" y="272" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1cdl14w_di" bpmnElement="set_data">
<dc:Bounds x="380" y="250" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1v0x5mk_di" bpmnElement="Gateway_1v0x5mk" isMarkerVisible="true">
<dc:Bounds x="535" y="265" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_03ddub8_di" bpmnElement="Event_03ddub8">
<dc:Bounds x="642" y="272" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1f2rtpm_di" bpmnElement="throw">
<dc:Bounds x="642" y="382" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1as4f94_di" bpmnElement="Flow_1as4f94">
<di:waypoint x="326" y="290" />
<di:waypoint x="380" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_10mhppx_di" bpmnElement="Flow_10mhppx">
<di:waypoint x="480" y="290" />
<di:waypoint x="535" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0wv10p6_di" bpmnElement="Flow_0wv10p6">
<di:waypoint x="585" y="290" />
<di:waypoint x="642" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1o689w0_di" bpmnElement="Flow_1o689w0">
<di:waypoint x="560" y="315" />
<di:waypoint x="560" y="400" />
<di:waypoint x="642" y="400" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1dmzvc0_di" bpmnElement="catch">
<dc:Bounds x="512" y="462" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1rbbx75_di" bpmnElement="Flow_1rbbx75">
<di:waypoint x="208" y="335" />
<di:waypoint x="250" y="335" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_01bfubj_di" bpmnElement="Flow_01bfubj">
<di:waypoint x="530" y="498" />
<di:waypoint x="530" y="560" />
<di:waypoint x="702" y="560" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_077e1zz_di" bpmnElement="Flow_077e1zz">
<di:waypoint x="780" y="335" />
<di:waypoint x="822" y="335" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qnx3d3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="event_test" isExecutable="true" camunda:versionTag="1">
<bpmn:startEvent id="Event_0ecwc0v">
<bpmn:outgoing>Flow_1rbbx75</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1rbbx75" sourceRef="Event_0ecwc0v" targetRef="Activity_1qrttpi" />
<bpmn:subProcess id="Activity_1qrttpi">
<bpmn:incoming>Flow_1rbbx75</bpmn:incoming>
<bpmn:outgoing>Flow_077e1zz</bpmn:outgoing>
<bpmn:startEvent id="Event_09erd49">
<bpmn:outgoing>Flow_1as4f94</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:task id="set_data" name="Set Data">
<bpmn:incoming>Flow_1as4f94</bpmn:incoming>
<bpmn:outgoing>Flow_10mhppx</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="Flow_1as4f94" sourceRef="Event_09erd49" targetRef="set_data" />
<bpmn:exclusiveGateway id="Gateway_1v0x5mk" default="Flow_0wv10p6">
<bpmn:incoming>Flow_10mhppx</bpmn:incoming>
<bpmn:outgoing>Flow_0wv10p6</bpmn:outgoing>
<bpmn:outgoing>Flow_1o689w0</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="Flow_10mhppx" sourceRef="set_data" targetRef="Gateway_1v0x5mk" />
<bpmn:endEvent id="Event_03ddub8">
<bpmn:incoming>Flow_0wv10p6</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0wv10p6" sourceRef="Gateway_1v0x5mk" targetRef="Event_03ddub8" />
<bpmn:sequenceFlow id="Flow_1o689w0" sourceRef="Gateway_1v0x5mk" targetRef="throw">
<bpmn:conditionExpression>escalation</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:endEvent id="throw">
<bpmn:incoming>Flow_1o689w0</bpmn:incoming>
<bpmn:escalationEventDefinition id="escalationEventDefinition_0w6x2pp" escalationRef="escalation_event" />
</bpmn:endEvent>
</bpmn:subProcess>
<bpmn:endEvent id="Event_1nd3odq">
<bpmn:incoming>Flow_01bfubj</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_01bfubj" sourceRef="catch" targetRef="Event_1nd3odq" />
<bpmn:boundaryEvent id="catch" attachedToRef="Activity_1qrttpi">
<bpmn:outgoing>Flow_01bfubj</bpmn:outgoing>
<bpmn:escalationEventDefinition id="escalationEventDefinition_147hq0b" escalationRef="escalation_event" />
</bpmn:boundaryEvent>
<bpmn:endEvent id="Event_1n1i393">
<bpmn:incoming>Flow_077e1zz</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_077e1zz" sourceRef="Activity_1qrttpi" targetRef="Event_1n1i393" />
</bpmn:process>
<bpmn:escalation id="escalation_event" name="escalation_event" escalationCode="1">
<bpmn:extensionElements>
<spiffworkflow:payloadExpression>payload</spiffworkflow:payloadExpression>
<spiffworkflow:variableName>result</spiffworkflow:variableName>
</bpmn:extensionElements>
</bpmn:escalation>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="event_test">
<bpmndi:BPMNShape id="Event_1n1i393_di" bpmnElement="Event_1n1i393">
<dc:Bounds x="822" y="317" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0ecwc0v_di" bpmnElement="Event_0ecwc0v">
<dc:Bounds x="172" y="317" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1nd3odq_di" bpmnElement="Event_1nd3odq">
<dc:Bounds x="702" y="542" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1ak58zv_di" bpmnElement="Activity_1qrttpi" isExpanded="true">
<dc:Bounds x="250" y="190" width="530" height="290" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_09erd49_di" bpmnElement="Event_09erd49">
<dc:Bounds x="290.33333333333337" y="272" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1cdl14w_di" bpmnElement="set_data">
<dc:Bounds x="380" y="250" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1v0x5mk_di" bpmnElement="Gateway_1v0x5mk" isMarkerVisible="true">
<dc:Bounds x="535" y="265" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_03ddub8_di" bpmnElement="Event_03ddub8">
<dc:Bounds x="642" y="272" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1f2rtpm_di" bpmnElement="throw">
<dc:Bounds x="642" y="382" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1as4f94_di" bpmnElement="Flow_1as4f94">
<di:waypoint x="326" y="290" />
<di:waypoint x="380" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_10mhppx_di" bpmnElement="Flow_10mhppx">
<di:waypoint x="480" y="290" />
<di:waypoint x="535" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0wv10p6_di" bpmnElement="Flow_0wv10p6">
<di:waypoint x="585" y="290" />
<di:waypoint x="642" y="290" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1o689w0_di" bpmnElement="Flow_1o689w0">
<di:waypoint x="560" y="315" />
<di:waypoint x="560" y="400" />
<di:waypoint x="642" y="400" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1dmzvc0_di" bpmnElement="catch">
<dc:Bounds x="512" y="462" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1rbbx75_di" bpmnElement="Flow_1rbbx75">
<di:waypoint x="208" y="335" />
<di:waypoint x="250" y="335" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_01bfubj_di" bpmnElement="Flow_01bfubj">
<di:waypoint x="530" y="498" />
<di:waypoint x="530" y="560" />
<di:waypoint x="702" y="560" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_077e1zz_di" bpmnElement="Flow_077e1zz">
<di:waypoint x="780" y="335" />
<di:waypoint x="822" y="335" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qnx3d3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="event_test" isExecutable="true" camunda:versionTag="1">
<bpmn:startEvent id="Event_13na7s0">
<bpmn:outgoing>Flow_1snc2rf</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1snc2rf" sourceRef="Event_13na7s0" targetRef="Gateway_1vqojb2" />
<bpmn:parallelGateway id="Gateway_1vqojb2">
<bpmn:incoming>Flow_1snc2rf</bpmn:incoming>
<bpmn:outgoing>Flow_0izdnv7</bpmn:outgoing>
<bpmn:outgoing>Flow_1io9375</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:sequenceFlow id="Flow_0izdnv7" sourceRef="Gateway_1vqojb2" targetRef="set_data" />
<bpmn:sequenceFlow id="Flow_038p23k" sourceRef="set_data" targetRef="throw" />
<bpmn:intermediateThrowEvent id="throw" name="THrow">
<bpmn:incoming>Flow_038p23k</bpmn:incoming>
<bpmn:outgoing>Flow_0e7nmhg</bpmn:outgoing>
<bpmn:signalEventDefinition id="SignalEventDefinition_0r951u8" signalRef="Signal_1624y58" />
</bpmn:intermediateThrowEvent>
<bpmn:sequenceFlow id="Flow_0e7nmhg" sourceRef="throw" targetRef="Gateway_0wnznah" />
<bpmn:parallelGateway id="Gateway_0wnznah">
<bpmn:incoming>Flow_0e7nmhg</bpmn:incoming>
<bpmn:incoming>Flow_1a61be1</bpmn:incoming>
<bpmn:outgoing>Flow_0v3ccvw</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:endEvent id="Event_1dtkuop">
<bpmn:incoming>Flow_0v3ccvw</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0v3ccvw" sourceRef="Gateway_0wnznah" targetRef="Event_1dtkuop" />
<bpmn:sequenceFlow id="Flow_1io9375" sourceRef="Gateway_1vqojb2" targetRef="catch" />
<bpmn:intermediateCatchEvent id="catch" name="Catch">
<bpmn:incoming>Flow_1io9375</bpmn:incoming>
<bpmn:outgoing>Flow_1a61be1</bpmn:outgoing>
<bpmn:signalEventDefinition id="SignalEventDefinition_03j485x" signalRef="Signal_1624y58" />
</bpmn:intermediateCatchEvent>
<bpmn:sequenceFlow id="Flow_1a61be1" sourceRef="catch" targetRef="Gateway_0wnznah" />
<bpmn:manualTask id="set_data" name="Set Data">
<bpmn:incoming>Flow_0izdnv7</bpmn:incoming>
<bpmn:outgoing>Flow_038p23k</bpmn:outgoing>
</bpmn:manualTask>
</bpmn:process>
<bpmn:signal id="Signal_1624y58" name="Signal_1624y58">
<bpmn:extensionElements>
<spiffworkflow:payloadExpression>{'r1': v1, 'r2': v2}</spiffworkflow:payloadExpression>
<spiffworkflow:variableName>result</spiffworkflow:variableName>
</bpmn:extensionElements>
</bpmn:signal>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="event_test">
<bpmndi:BPMNShape id="Event_13na7s0_di" bpmnElement="Event_13na7s0">
<dc:Bounds x="222" y="222" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0zt2g0a_di" bpmnElement="Gateway_1vqojb2">
<dc:Bounds x="315" y="215" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1lcgmvw_di" bpmnElement="throw">
<dc:Bounds x="602" y="222" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="604" y="265" width="33" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_17kgifs_di" bpmnElement="Gateway_0wnznah">
<dc:Bounds x="715" y="215" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1dtkuop_di" bpmnElement="Event_1dtkuop">
<dc:Bounds x="842" y="222" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_13o2mxa_di" bpmnElement="catch">
<dc:Bounds x="602" y="332" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="606" y="375" width="29" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_143oof7_di" bpmnElement="set_data">
<dc:Bounds x="430" y="200" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1snc2rf_di" bpmnElement="Flow_1snc2rf">
<di:waypoint x="258" y="240" />
<di:waypoint x="315" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0izdnv7_di" bpmnElement="Flow_0izdnv7">
<di:waypoint x="365" y="240" />
<di:waypoint x="430" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_038p23k_di" bpmnElement="Flow_038p23k">
<di:waypoint x="530" y="240" />
<di:waypoint x="602" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0e7nmhg_di" bpmnElement="Flow_0e7nmhg">
<di:waypoint x="638" y="240" />
<di:waypoint x="715" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0v3ccvw_di" bpmnElement="Flow_0v3ccvw">
<di:waypoint x="765" y="240" />
<di:waypoint x="842" y="240" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1io9375_di" bpmnElement="Flow_1io9375">
<di:waypoint x="340" y="265" />
<di:waypoint x="340" y="350" />
<di:waypoint x="602" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1a61be1_di" bpmnElement="Flow_1a61be1">
<di:waypoint x="638" y="350" />
<di:waypoint x="740" y="350" />
<di:waypoint x="740" y="265" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>