Skip to content

Commit 6302855

Browse files
author
Alan Christie
committed
test: Better test framework and new failure test
1 parent 7c3321c commit 6302855

File tree

3 files changed

+77
-26
lines changed

3 files changed

+77
-26
lines changed

tests/test_workflow_engine_examples.py

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,31 @@ def basic_engine():
2929
api_adapter=api_adapter, instance_launcher=instance_launcher
3030
)
3131
message_queue.set_receiver(workflow_engine.handle_message)
32-
return [
32+
print("Starting message queue...")
33+
message_queue.start()
34+
35+
yield [
3336
api_adapter,
3437
message_queue,
3538
message_dispatcher,
3639
workflow_engine,
3740
]
3841

42+
print("Stopping message queue...")
43+
message_queue.stop()
44+
message_queue.join()
45+
print("Stopped")
3946

40-
def test_workflow_engine_with_two_step_nop(basic_engine):
41-
# Arrange
42-
da, mq, md, _ = basic_engine
4347

44-
# Act
45-
# To test the WorkflowEngine we need to:
46-
# 1. Start the message queue
47-
# 2. Load and create a Workflow Definition
48-
# 3. Create a Running Workflow record
49-
# 4. Send a Workflow START message
48+
def start_workflow(md, da, workflow_file_name) -> str:
49+
"""A convenience function to handle all the 'START' logic for a workflow."""
50+
51+
# To start a workflow we need to:
52+
# 1. Load and create a Workflow Definition
53+
# 2. Create a Running Workflow record
54+
# 3. Send a Workflow START message
5055
#
51-
# 1. (Start the message queue)
52-
mq.start()
53-
# 2. (Load/create the workflow definition to be tested)
54-
workflow_file_name = "example-two-step-nop"
56+
# 1.
5557
workflow_path = os.path.join(
5658
os.path.dirname(__file__), "workflow-definitions", f"{workflow_file_name}.yaml"
5759
)
@@ -61,22 +63,30 @@ def test_workflow_engine_with_two_step_nop(basic_engine):
6163
wfid = da.create_workflow(workflow_definition=wf_definition)
6264
assert wfid
6365
print(f"Created workflow definition {wfid}")
64-
# 3. (Create a running workflow record)
66+
# 2.
6567
response = da.create_running_workflow(workflow_definition_id=wfid)
6668
r_wfid = response["id"]
6769
assert r_wfid
6870
print(f"Created running workflow {r_wfid}")
69-
# 4. (Send the Workflow START message)
71+
# 3.
7072
msg = WorkflowMessage()
7173
msg.timestamp = f"{datetime.now(timezone.utc).isoformat()}Z"
7274
msg.action = "START"
7375
msg.running_workflow = r_wfid
7476
md.send(msg)
7577
print("Sent START message")
7678

77-
# Assert
78-
# Wait until the workflow is done (successfully)
79-
# But don't wait for ever!
79+
return r_wfid
80+
81+
82+
def wait_for_workflow(da, mq, r_wfid, expect_success=True):
83+
"""A convenience function to wait for and check a workflow execution
84+
(by inspecting the anticipated DB/API records)."""
85+
86+
# We wait for the workflow to complete by polling the API and checking
87+
# the running workflow's 'done' status. The user can specify whether
88+
# the workflow is expected to succeed or fail. Any further checks
89+
# are the responsibility of the caller.
8090
attempts = 0
8191
done = False
8292
r_wf = None
@@ -91,18 +101,42 @@ def test_workflow_engine_with_two_step_nop(basic_engine):
91101
if attempts > 10:
92102
break
93103
time.sleep(0.5)
94-
# Stop the message queue
95-
print("Stopping message queue...")
96-
mq.stop()
97-
mq.join()
98-
print("Stopped")
99104
assert r_wf
100105
assert r_wf["done"]
101-
assert r_wf["success"]
102-
# Now check there are the right number of RunningWorkflowStep Records
106+
assert r_wf["success"] == expect_success
107+
108+
109+
def test_workflow_engine_with_two_step_nop(basic_engine):
110+
# Arrange
111+
da, mq, md, _ = basic_engine
112+
113+
# Act
114+
r_wfid = start_workflow(md, da, "example-two-step-nop")
115+
116+
# Assert
117+
wait_for_workflow(da, mq, r_wfid)
118+
# Additional, detailed checks...
119+
# Check there are the right number of RunningWorkflowStep Records
103120
# (and they're all set to success/done)
104121
response = da.get_running_workflow_steps(running_workflow_id=r_wfid)
105122
assert response["count"] == 2
106123
for step in response["running_workflow_steps"]:
107124
assert step["running_workflow_step"]["done"]
108125
assert step["running_workflow_step"]["success"]
126+
127+
128+
def test_workflow_engine_with_nop_fail(basic_engine):
129+
# Arrange
130+
da, mq, md, _ = basic_engine
131+
132+
# Act
133+
r_wfid = start_workflow(md, da, "example-nop-fail")
134+
135+
# Assert
136+
wait_for_workflow(da, mq, r_wfid, expect_success=False)
137+
# Additional, detailed checks...
138+
# Check we only haver one step, and it failed
139+
response = da.get_running_workflow_steps(running_workflow_id=r_wfid)
140+
assert response["count"] == 1
141+
assert response["running_workflow_steps"][0]["running_workflow_step"]["done"]
142+
assert not response["running_workflow_steps"][0]["running_workflow_step"]["success"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
kind: DataManagerWorkflow
3+
kind-version: "2024.1"
4+
name: two-step-nop
5+
description: >-
6+
A workflow with one step that fails
7+
steps:
8+
- name: step-1
9+
specification: >-
10+
{
11+
'collection': 'workflow-engine-unit-test-jobs',
12+
'job': 'nop-fail',
13+
'version': '1.0.0'
14+
}

tests/workflow-definitions/example-two-step-nop.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
kind: DataManagerWorkflow
33
kind-version: "2024.1"
44
name: two-step-nop
5+
description: >-
6+
A workflow with two steps.
7+
The steps do nothing, take no arguments, and simply return success.
58
steps:
69
- name: step-1
710
specification: >-

0 commit comments

Comments
 (0)