Skip to content

Commit a5dcae6

Browse files
test workflow endpoint doesn't seem to always send it back as complete but we can poll for that
1 parent 8c0453f commit a5dcae6

1 file changed

Lines changed: 47 additions & 14 deletions

File tree

tests/integration/client/orkes/test_orkes_clients.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from conductor.client.workflow.conductor_workflow import ConductorWorkflow
2727
from conductor.client.workflow.executor.workflow_executor import WorkflowExecutor
2828
from conductor.client.workflow.task.simple_task import SimpleTask
29-
from tests.integration.retry_helpers import retry_scenario
29+
from tests.integration.retry_helpers import retry_scenario, TERMINAL_WORKFLOW_STATES
3030

3131
SUFFIX = str(uuid())
3232
WORKFLOW_NAME = 'IntegrationTestOrkesClientsWf_' + SUFFIX
@@ -394,24 +394,28 @@ def __test_unit_test_workflow(self):
394394
execution = self.workflow_client.test_workflow(testRequest)
395395
assert execution != None
396396

397-
print(
398-
f"[test_workflow] workflow_id={getattr(execution, 'workflow_id', None)} "
399-
f"status={execution.status} "
400-
f"task_count={len(execution.tasks or [])}"
401-
)
402-
for t in (execution.tasks or []):
403-
print(
404-
f"[test_workflow] task ref={t.reference_task_name} "
405-
f"type={t.task_type} status={t.status} "
406-
f"retried={getattr(t, 'retry_count', None)}"
407-
)
397+
# There appears to be no guarantee about it actually coming back
398+
# complete, because it happens (often) that it does not. So we accept a
399+
# COMPLETED result immediately, but if it isn't COMPLETED yet we don't
400+
# fail: we poll the workflow and wait for it to reach a terminal state.
408401
if execution.status != "COMPLETED":
402+
#need to fix the print statement below to have the wf id and the status
409403
print(
410-
f"[test_workflow] non-terminal output={getattr(execution, 'output', None)}"
404+
f"[test_workflow] workflow_id={getattr(execution, 'workflow_id', None)} status={execution.status} (was expecting COMPLETED - but will poll for that now)"
411405
)
406+
workflow_id = getattr(execution, "workflow_id", None)
407+
polled = (
408+
self.__poll_workflow_until_complete(workflow_id)
409+
if workflow_id else None
410+
)
411+
if polled is not None:
412+
execution = polled
412413

413414
# Ensure workflow is completed successfully
414-
assert execution.status == "COMPLETED"
415+
assert execution.status == "COMPLETED", (
416+
f"workflow expected to be COMPLETED, but received {execution.status}, "
417+
f"workflow_id: {getattr(execution, 'workflow_id', None)}"
418+
)
415419

416420
# Ensure the inputs were captured correctly
417421
assert execution.input["loanAmount"] == testRequest.input["loanAmount"]
@@ -463,6 +467,35 @@ def __test_unit_test_workflow(self):
463467
# Workflow output takes the latest iteration output of a loopOver task.
464468
assert execution.output["phoneNumberValid"]
465469

470+
def __poll_workflow_until_complete(self, workflow_id, timeout_seconds=60,
471+
poll_interval=2):
472+
"""Poll ``workflow_id`` until it reaches a terminal state or the timeout
473+
passes, returning the last observed Workflow (or None if it could never
474+
be fetched). Transient poll errors are logged and retried within the
475+
timeout so a slow-but-eventually-complete run isn't reported as a bare
476+
failure.
477+
"""
478+
deadline = time.monotonic() + timeout_seconds
479+
workflow = None
480+
while True:
481+
try:
482+
workflow = self.workflow_client.get_workflow(
483+
workflow_id, include_tasks=True)
484+
except Exception as e: # transient blip against the shared server
485+
print(f"[test_workflow] error polling {workflow_id}: {e}")
486+
status = getattr(workflow, "status", None)
487+
if status in TERMINAL_WORKFLOW_STATES:
488+
print(f"[test_workflow] {workflow_id} reached {status}")
489+
return workflow
490+
if time.monotonic() >= deadline:
491+
print(
492+
f"[test_workflow] {workflow_id} still {status} after "
493+
f"{timeout_seconds}s; giving up wait"
494+
)
495+
return workflow
496+
print(f"[test_workflow] {workflow_id} still {status}; waiting")
497+
time.sleep(poll_interval)
498+
466499
def __test_unregister_workflow_definition(self):
467500
self.metadata_client.unregister_workflow_def(WORKFLOW_NAME, 1)
468501

0 commit comments

Comments
 (0)