Skip to content

Commit a4f9fc2

Browse files
committed
Make test pass deterministically
1 parent bb16132 commit a4f9fc2

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
See sibling file test_workflow_caller_cancellation_types.py for explanatory comments.
3+
"""
4+
15
import asyncio
26
import uuid
37
from dataclasses import dataclass, field
@@ -46,20 +50,29 @@ class TestContext:
4650
class HandlerWorkflow:
4751
def __init__(self):
4852
self.cancel_handler_released = asyncio.Event()
53+
self.caller_op_future_resolved = asyncio.Event()
4954

5055
@workflow.run
5156
async def run(self) -> None:
5257
# We want the cancel handler to be invoked, so this workflow must not close before
5358
# then.
5459
await self.cancel_handler_released.wait()
55-
# TODO: there is technically a race now between (1) caller server writing
56-
# NEXUS_OPERATION_CANCEL_REQUEST_FAILED in reponse to failed cancel handler in nexus task
57-
# and (2) NEXUS_OPERATION_COMPLETED due to this workflow completing.
60+
if (
61+
test_context.cancellation_type
62+
== workflow.NexusOperationCancellationType.WAIT_REQUESTED
63+
):
64+
# For WAIT_REQUESTED, we want to prove that the future can be unblocked before the
65+
# handler workflow completes.
66+
await self.caller_op_future_resolved.wait()
5867

5968
@workflow.signal
6069
def set_cancel_handler_released(self) -> None:
6170
self.cancel_handler_released.set()
6271

72+
@workflow.signal
73+
def set_caller_op_future_resolved(self) -> None:
74+
self.caller_op_future_resolved.set()
75+
6376

6477
@nexusrpc.service
6578
class Service:
@@ -159,6 +172,10 @@ async def run(self, input: Input) -> CancellationResult:
159172
test_context.cancellation_type
160173
== workflow.NexusOperationCancellationType.WAIT_REQUESTED
161174
):
175+
# For WAIT_REQUESTED, we need core to receive the NexusOperationCancelRequestCompleted
176+
# event. That event should trigger a workflow task, but does not currently due to
177+
# https://github.com/temporalio/temporal/issues/8175. Force a new WFT, allowing time for
178+
# the event hopefully to arrive.
162179
await workflow.sleep(0.1, summary="Force new WFT")
163180
error_type, error_cause_type = None, None
164181
try:
@@ -310,11 +327,12 @@ async def check_behavior_for_wait_cancellation_requested(
310327
caller_wf: WorkflowHandle[Any, CancellationResult],
311328
handler_wf: WorkflowHandle,
312329
) -> None:
313-
await handler_wf.result()
314330
await caller_wf.signal(CallerWorkflow.release)
315331
result = await caller_wf.result()
316332
assert result.error_type == "NexusOperationError"
317333
assert result.error_cause_type == "HandlerError"
334+
await handler_wf.signal(HandlerWorkflow.set_caller_op_future_resolved)
335+
await handler_wf.result()
318336
await assert_event_subsequence(
319337
[
320338
(caller_wf, EventType.EVENT_TYPE_WORKFLOW_EXECUTION_STARTED),
@@ -328,7 +346,11 @@ async def check_behavior_for_wait_cancellation_requested(
328346
caller_wf,
329347
EventType.EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED,
330348
)
331-
assert op_cancel_request_failed < caller_op_future_resolved
349+
handler_wf_completed = await get_event_time(
350+
handler_wf,
351+
EventType.EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED,
352+
)
353+
assert op_cancel_request_failed < caller_op_future_resolved < handler_wf_completed
332354

333355

334356
async def check_behavior_for_wait_cancellation_completed(
@@ -339,10 +361,14 @@ async def check_behavior_for_wait_cancellation_completed(
339361
await caller_wf.signal(CallerWorkflow.release)
340362
result = await caller_wf.result()
341363
assert not result.error_type
364+
# Note that the relative order of these two events is non-deterministic, since one is the result
365+
# of the cancel handler response being processed and the other is the result of the handler
366+
# workflow exiting.
367+
# (caller_wf, EventType.EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED)
368+
# (handler_wf, EventType.EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED)
342369
await assert_event_subsequence(
343370
[
344371
(caller_wf, EventType.EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED),
345-
(caller_wf, EventType.EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED),
346372
(handler_wf, EventType.EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED),
347373
(caller_wf, EventType.EVENT_TYPE_NEXUS_OPERATION_COMPLETED),
348374
]

0 commit comments

Comments
 (0)