Skip to content

Commit 5f8c82b

Browse files
Assert Python workflow task fail and history parity
Assert Python workflow task fail and history parity
1 parent d9d059c commit 5f8c82b

3 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"schema": "durable-workflow.polyglot.control-plane-request-fixture",
3+
"version": 1,
4+
"operation": "workflow-task.fail",
5+
"request": {
6+
"method": "POST",
7+
"path": "/worker/workflow-tasks/workflow-task-231/fail",
8+
"body": {
9+
"lease_owner": "polyglot-worker-231",
10+
"workflow_task_attempt": 2,
11+
"failure": {
12+
"message": "non-deterministic command sequence",
13+
"type": "NonDeterminism",
14+
"stack_trace": "command 3 replay mismatch"
15+
}
16+
}
17+
},
18+
"semantic_body": {
19+
"task_id": "workflow-task-231",
20+
"lease_owner": "polyglot-worker-231",
21+
"workflow_task_attempt": 2,
22+
"message": "non-deterministic command sequence",
23+
"outcome": "failed"
24+
},
25+
"response_body": {
26+
"task_id": "workflow-task-231",
27+
"workflow_task_attempt": 2,
28+
"outcome": "failed",
29+
"run_status": "running"
30+
},
31+
"cli": {
32+
"argv": {
33+
"task-id": "workflow-task-231",
34+
"attempt": "2",
35+
"--lease-owner": "polyglot-worker-231",
36+
"--message": "non-deterministic command sequence",
37+
"--type": "NonDeterminism",
38+
"--stack-trace": "command 3 replay mismatch",
39+
"--json": true
40+
}
41+
},
42+
"sdk_python": {
43+
"method": "fail_workflow_task",
44+
"kwargs": {
45+
"task_id": "workflow-task-231",
46+
"lease_owner": "polyglot-worker-231",
47+
"workflow_task_attempt": 2,
48+
"message": "non-deterministic command sequence",
49+
"failure_type": "NonDeterminism",
50+
"stack_trace": "command 3 replay mismatch"
51+
}
52+
}
53+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"schema": "durable-workflow.polyglot.control-plane-request-fixture",
3+
"version": 1,
4+
"operation": "workflow-task.history",
5+
"request": {
6+
"method": "POST",
7+
"path": "/worker/workflow-tasks/workflow-task-231/history",
8+
"body": {
9+
"page_token": "history-page-2",
10+
"lease_owner": "polyglot-worker-231",
11+
"workflow_task_attempt": 2
12+
}
13+
},
14+
"semantic_body": {
15+
"task_id": "workflow-task-231",
16+
"lease_owner": "polyglot-worker-231",
17+
"workflow_task_attempt": 2,
18+
"page_token": "history-page-2",
19+
"last_sequence": 4,
20+
"next_page_token": "history-page-3"
21+
},
22+
"response_body": {
23+
"events": [
24+
{
25+
"event_id": 2,
26+
"event_type": "ActivityScheduled",
27+
"payload": {
28+
"activity_type": "inventory.sync-page"
29+
}
30+
},
31+
{
32+
"event_id": 3,
33+
"event_type": "ActivityCompleted",
34+
"payload": {
35+
"activity_id": "activity-231"
36+
}
37+
}
38+
],
39+
"last_sequence": 4,
40+
"next_page_token": "history-page-3"
41+
},
42+
"cli": {
43+
"argv": {
44+
"task-id": "workflow-task-231",
45+
"page-token": "history-page-2",
46+
"--lease-owner": "polyglot-worker-231",
47+
"--attempt": "2",
48+
"--json": true
49+
}
50+
},
51+
"sdk_python": {
52+
"method": "workflow_task_history",
53+
"kwargs": {
54+
"task_id": "workflow-task-231",
55+
"page_token": "history-page-2",
56+
"lease_owner": "polyglot-worker-231",
57+
"workflow_task_attempt": 2
58+
}
59+
}
60+
}

tests/test_client.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,34 @@ async def test_complete_workflow_task_matches_polyglot_fixture(self, client: Cli
14611461
assert mock.call_args.args[:2] == (fixture["request"]["method"], f"/api{fixture['request']['path']}")
14621462
assert mock.call_args.kwargs["json"] == fixture["request"]["body"]
14631463

1464+
@pytest.mark.asyncio
1465+
async def test_fail_workflow_task_matches_polyglot_fixture(self, client: Client) -> None:
1466+
fixture_path = Path(__file__).parent / "fixtures" / "control-plane" / "workflow-task-fail-parity.json"
1467+
fixture = json.loads(fixture_path.read_text())
1468+
resp = _mock_response(200, fixture["response_body"])
1469+
1470+
with patch.object(client._http, "request", new_callable=AsyncMock, return_value=resp) as mock:
1471+
result = await client.fail_workflow_task(**fixture["sdk_python"]["kwargs"])
1472+
1473+
assert result == fixture["response_body"]
1474+
assert result["outcome"] == fixture["semantic_body"]["outcome"]
1475+
assert mock.call_args.args[:2] == (fixture["request"]["method"], f"/api{fixture['request']['path']}")
1476+
assert mock.call_args.kwargs["json"] == fixture["request"]["body"]
1477+
1478+
@pytest.mark.asyncio
1479+
async def test_workflow_task_history_matches_polyglot_fixture(self, client: Client) -> None:
1480+
fixture_path = Path(__file__).parent / "fixtures" / "control-plane" / "workflow-task-history-parity.json"
1481+
fixture = json.loads(fixture_path.read_text())
1482+
resp = _mock_response(200, fixture["response_body"])
1483+
1484+
with patch.object(client._http, "request", new_callable=AsyncMock, return_value=resp) as mock:
1485+
page = await client.workflow_task_history(**fixture["sdk_python"]["kwargs"])
1486+
1487+
assert page == fixture["response_body"]
1488+
assert page["next_page_token"] == fixture["semantic_body"]["next_page_token"]
1489+
assert mock.call_args.args[:2] == (fixture["request"]["method"], f"/api{fixture['request']['path']}")
1490+
assert mock.call_args.kwargs["json"] == fixture["request"]["body"]
1491+
14641492
@pytest.mark.asyncio
14651493
async def test_body_shape(self, client: Client) -> None:
14661494
resp = _mock_response(200, {"task_id": "t1", "outcome": "failed"})

0 commit comments

Comments
 (0)