Skip to content

Commit 9026fec

Browse files
author
Alan Christie
committed
feat: Add get_workflow_steps_driving_this_step and prior step ID to create_running_workflow_step
1 parent 2a67e62 commit 9026fec

File tree

3 files changed

+177
-4
lines changed

3 files changed

+177
-4
lines changed

tests/test_test_api_adapter.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,37 @@ def test_get_running_workflow_step():
267267
assert response["name"] == "step-1"
268268
assert not response["done"]
269269
assert response["running_workflow"]["id"] == rwfid
270+
assert "prior_running_workflow_step" not in response
271+
272+
273+
def test_get_running_workflow_step_with_prior_step():
274+
# Arrange
275+
utaa = UnitTestWorkflowAPIAdapter()
276+
response = utaa.create_workflow(workflow_definition={"name": "blah"})
277+
wfid = response["id"]
278+
response = utaa.create_running_workflow(
279+
user_id="dlister",
280+
workflow_id=wfid,
281+
project_id=TEST_PROJECT_ID,
282+
variables={},
283+
)
284+
rwfid = response["id"]
285+
response, _ = utaa.create_running_workflow_step(
286+
running_workflow_id=rwfid,
287+
step="step-1",
288+
prior_running_workflow_step_id="r-workflow-step-111",
289+
)
290+
rwfsid = response["id"]
291+
292+
# Act
293+
response, _ = utaa.get_running_workflow_step(running_workflow_step_id=rwfsid)
294+
295+
# Assert
296+
assert response["name"] == "step-1"
297+
assert not response["done"]
298+
assert response["running_workflow"]["id"] == rwfid
299+
assert "prior_running_workflow_step" in response
300+
assert response["prior_running_workflow_step"]["id"] == "r-workflow-step-111"
270301

271302

272303
def test_create_instance():
@@ -291,3 +322,69 @@ def test_create_and_get_instance():
291322

292323
# Assert
293324
assert response["running_workflow_step_id"] == "r-workflow-step-000"
325+
326+
327+
def test_get_workflow_steps_driving_this_step_when_1st_step():
328+
# Arrange
329+
utaa = UnitTestWorkflowAPIAdapter()
330+
response = utaa.create_workflow(
331+
workflow_definition={
332+
"name": "blah",
333+
"steps": [{"name": "step-1"}, {"name": "step-2"}, {"name": "step-3"}],
334+
}
335+
)
336+
response = utaa.create_running_workflow(
337+
user_id="dlister",
338+
workflow_id=response["id"],
339+
project_id=TEST_PROJECT_ID,
340+
variables={},
341+
)
342+
response, _ = utaa.create_running_workflow_step(
343+
running_workflow_id=response["id"], step="step-1"
344+
)
345+
rwfs_id = response["id"]
346+
347+
# Act
348+
response, _ = utaa.get_workflow_steps_driving_this_step(
349+
running_workflow_step_id=rwfs_id
350+
)
351+
352+
# Assert
353+
assert response["caller_step_index"] == 0
354+
assert len(response["steps"]) == 3
355+
assert response["steps"][0]["name"] == "step-1"
356+
assert response["steps"][1]["name"] == "step-2"
357+
assert response["steps"][2]["name"] == "step-3"
358+
359+
360+
def test_get_workflow_steps_driving_this_step_when_2nd_step():
361+
# Arrange
362+
utaa = UnitTestWorkflowAPIAdapter()
363+
response = utaa.create_workflow(
364+
workflow_definition={
365+
"name": "blah",
366+
"steps": [{"name": "step-1"}, {"name": "step-2"}, {"name": "step-3"}],
367+
}
368+
)
369+
response = utaa.create_running_workflow(
370+
user_id="dlister",
371+
workflow_id=response["id"],
372+
project_id=TEST_PROJECT_ID,
373+
variables={},
374+
)
375+
response, _ = utaa.create_running_workflow_step(
376+
running_workflow_id=response["id"], step="step-2"
377+
)
378+
rwfs_id = response["id"]
379+
380+
# Act
381+
response, _ = utaa.get_workflow_steps_driving_this_step(
382+
running_workflow_step_id=rwfs_id
383+
)
384+
385+
# Assert
386+
assert response["caller_step_index"] == 1
387+
assert len(response["steps"]) == 3
388+
assert response["steps"][0]["name"] == "step-1"
389+
assert response["steps"][1]["name"] == "step-2"
390+
assert response["steps"][2]["name"] == "step-3"

tests/wapi_adapter.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,16 @@ def get_workflow(self, *, workflow_id: str) -> dict[str, Any]:
8888
response["id"] = workflow_id
8989
return response, 0
9090

91-
def get_running_workflow(self, *, running_workflow_id: str) -> dict[str, Any]:
91+
def get_running_workflow(
92+
self, *, running_workflow_id: str
93+
) -> tuple[dict[str, Any], int]:
9294
UnitTestWorkflowAPIAdapter.lock.acquire()
9395
with open(_RUNNING_WORKFLOW_PICKLE_FILE, "rb") as pickle_file:
9496
running_workflow = Unpickler(pickle_file).load()
9597
UnitTestWorkflowAPIAdapter.lock.release()
9698

9799
if running_workflow_id not in running_workflow:
98-
return {}
100+
return {}, 0
99101
response = running_workflow[running_workflow_id]
100102
response["id"] = running_workflow_id
101103
return response, 0
@@ -123,7 +125,11 @@ def set_running_workflow_done(
123125
UnitTestWorkflowAPIAdapter.lock.release()
124126

125127
def create_running_workflow_step(
126-
self, *, running_workflow_id: str, step: str
128+
self,
129+
*,
130+
running_workflow_id: str,
131+
step: str,
132+
prior_running_workflow_step_id: str | None = None,
127133
) -> dict[str, Any]:
128134
UnitTestWorkflowAPIAdapter.lock.acquire()
129135
with open(_RUNNING_WORKFLOW_STEP_PICKLE_FILE, "rb") as pickle_file:
@@ -140,6 +146,10 @@ def create_running_workflow_step(
140146
"variables": {},
141147
"running_workflow": {"id": running_workflow_id},
142148
}
149+
if prior_running_workflow_step_id:
150+
record["prior_running_workflow_step"] = {
151+
"id": prior_running_workflow_step_id
152+
}
143153
running_workflow_step[running_workflow_step_id] = record
144154

145155
with open(_RUNNING_WORKFLOW_STEP_PICKLE_FILE, "wb") as pickle_file:
@@ -201,6 +211,44 @@ def set_running_workflow_step_done(
201211
Pickler(pickle_file).dump(running_workflow_step)
202212
UnitTestWorkflowAPIAdapter.lock.release()
203213

214+
def get_workflow_steps_driving_this_step(
215+
self,
216+
*,
217+
running_workflow_step_id: str,
218+
) -> tuple[dict[str, Any], int]:
219+
# To accomplish this we get the running workflow for the step,
220+
# then the workflow, then the steps from that workflow.
221+
# We return a dictionary and an HTTP response code.
222+
UnitTestWorkflowAPIAdapter.lock.acquire()
223+
with open(_RUNNING_WORKFLOW_STEP_PICKLE_FILE, "rb") as pickle_file:
224+
running_workflow_step = Unpickler(pickle_file).load()
225+
UnitTestWorkflowAPIAdapter.lock.release()
226+
227+
assert running_workflow_step_id in running_workflow_step
228+
229+
running_workflow_id: str = running_workflow_step[running_workflow_step_id][
230+
"running_workflow"
231+
]["id"]
232+
rwf_response, _ = self.get_running_workflow(
233+
running_workflow_id=running_workflow_id
234+
)
235+
assert rwf_response
236+
workflow_id: str = rwf_response["workflow"]["id"]
237+
wf_response, _ = self.get_workflow(workflow_id=workflow_id)
238+
assert wf_response
239+
# Find the caller's python in the step sequence (-1 if not found)
240+
caller_step_index: int = -1
241+
index: int = 0
242+
for step in wf_response["steps"]:
243+
if step["name"] == running_workflow_step[running_workflow_step_id]["name"]:
244+
caller_step_index = index
245+
break
246+
index += 1
247+
return {
248+
"caller_step_index": caller_step_index,
249+
"steps": wf_response["steps"].copy(),
250+
}, 0
251+
204252
def get_instance(self, *, instance_id: str) -> dict[str, Any]:
205253
UnitTestWorkflowAPIAdapter.lock.acquire()
206254
with open(_INSTANCE_PICKLE_FILE, "rb") as pickle_file:

workflow/workflow_abc.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ def create_running_workflow_step(
167167
*,
168168
running_workflow_id: str,
169169
step: str,
170+
prior_running_workflow_step_id: str | None = None,
170171
) -> tuple[dict[str, Any], int]:
171172
"""Create a RunningWorkflowStep Record (from a RunningWorkflow)"""
172173
# Should return:
@@ -191,10 +192,17 @@ def get_running_workflow_step(
191192
# "y": 2,
192193
# },
193194
# "running_workflow": {
194-
# "id": "r-workflow-00000000-0000-0000-0000-000000000001"
195+
# "id": "r-workflow-00000000-0000-0000-0000-000000000001",
195196
# },
196197
# }
197198
# If not present an empty dictionary should be returned.
199+
#
200+
# For steps that are not the first in a workflow the following field
201+
# can be expected in the response: -
202+
#
203+
# "prior_running_workflow_step": {
204+
# "id": "r-worflkow-step-00000000-0000-0000-0000-000000000001",
205+
# },
198206

199207
@abstractmethod
200208
def set_running_workflow_step_variables(
@@ -219,6 +227,26 @@ def set_running_workflow_step_done(
219227
"""Set the success value for a RunningWorkflowStep Record,
220228
If not successful an error code and message should be provided."""
221229

230+
@abstractmethod
231+
def get_workflow_steps_driving_this_step(
232+
self,
233+
*,
234+
running_workflow_step_id: str,
235+
) -> tuple[dict[str, Any], int]:
236+
"""Get all the step records that belong to the Workflow for the given
237+
RunningWorkflowStep record ID. You are also given the caller's position
238+
in the list, which will be -1 if the caller is not present."""
239+
# It should return:
240+
# {
241+
# "caller_step_index": 0,
242+
# "steps": "steps": [
243+
# {
244+
# "name": "step-name"
245+
# "specification": "{}",
246+
# }
247+
# ]
248+
# }
249+
222250
@abstractmethod
223251
def get_instance(self, *, instance_id: str) -> tuple[dict[str, Any], int]:
224252
"""Get an Instance Record"""

0 commit comments

Comments
 (0)