Skip to content

Commit 5e184cb

Browse files
bchamppyaythomas
authored andcommitted
fix: StopDurableExecution should return idempotent response
1 parent f9caf24 commit 5e184cb

3 files changed

Lines changed: 25 additions & 15 deletions

File tree

src/aws_durable_execution_sdk_python_testing/executor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,14 @@ def stop_execution(
323323
324324
Raises:
325325
ResourceNotFoundException: If execution does not exist
326-
ExecutionAlreadyStartedException: If execution is already completed
327326
"""
328327
execution = self.get_execution(execution_arn)
329328

330329
if execution.is_complete:
331-
# Context-aware mapping: execution already completed maps to ExecutionAlreadyStartedException
332-
msg: str = f"Execution {execution_arn} is already completed"
333-
raise ExecutionAlreadyStartedException(msg, execution_arn)
330+
# Idempotent: return the existing stop timestamp
331+
execution_op = execution.get_operation_execution_started()
332+
stop_timestamp = execution_op.end_timestamp or datetime.now(UTC)
333+
return StopDurableExecutionResponse(stop_timestamp=stop_timestamp)
334334

335335
# Use provided error or create a default one
336336
stop_error = error or ErrorObject.from_message(

tests/executor_test.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
SendDurableExecutionCallbackHeartbeatResponse,
4242
SendDurableExecutionCallbackSuccessResponse,
4343
StartDurableExecutionInput,
44+
StopDurableExecutionResponse,
4445
)
4546
from aws_durable_execution_sdk_python_testing.observer import (
4647
ExecutionNotifier,
@@ -2056,13 +2057,22 @@ def test_stop_execution(executor, mock_store):
20562057

20572058

20582059
def test_stop_execution_already_complete(executor, mock_store):
2059-
"""Test stop_execution with already completed execution."""
2060+
"""Test stop_execution with already completed execution returns idempotent response."""
20602061
mock_execution = Mock()
20612062
mock_execution.is_complete = True
2063+
mock_execution.durable_execution_arn = "test-arn"
2064+
2065+
# Mock the execution operation with end_timestamp
2066+
mock_execution_op = Mock()
2067+
mock_execution_op.end_timestamp = datetime(2023, 1, 1, 0, 1, 0, tzinfo=UTC)
2068+
mock_execution.get_operation_execution_started.return_value = mock_execution_op
2069+
20622070
mock_store.load.return_value = mock_execution
20632071

2064-
with pytest.raises(ExecutionAlreadyStartedException, match="already completed"):
2065-
executor.stop_execution("test-arn")
2072+
result = executor.stop_execution("test-arn")
2073+
2074+
assert isinstance(result, StopDurableExecutionResponse)
2075+
assert result.stop_timestamp == datetime(2023, 1, 1, 0, 1, 0, tzinfo=UTC)
20662076

20672077

20682078
def test_stop_execution_with_custom_error(executor, mock_store):

tests/web/handlers_test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -911,14 +911,15 @@ def test_stop_durable_execution_handler_success():
911911

912912

913913
def test_stop_durable_execution_handler_execution_already_stopped():
914-
"""Test StopDurableExecutionHandler with execution already stopped error."""
914+
"""Test StopDurableExecutionHandler with execution already stopped returns idempotent response."""
915915

916916
executor = Mock()
917917
handler = StopDurableExecutionHandler(executor)
918918

919-
# Mock executor to raise IllegalStateException
920-
executor.stop_execution.side_effect = IllegalStateException(
921-
"Execution test-arn is already completed"
919+
# Mock executor to return stop response with timestamp
920+
stop_timestamp = "2023-01-01T00:01:00Z"
921+
executor.stop_execution.return_value = StopDurableExecutionResponse(
922+
stop_timestamp=stop_timestamp
922923
)
923924

924925
request_body = {
@@ -941,10 +942,9 @@ def test_stop_durable_execution_handler_execution_already_stopped():
941942

942943
response = handler.handle(typed_route, request)
943944

944-
# Verify IllegalStateException maps to ServiceException in AWS-compliant format
945-
assert response.status_code == 500
946-
assert response.body["Type"] == "ServiceException"
947-
assert response.body["Message"] == "Execution test-arn is already completed"
945+
# Verify idempotent response with stop timestamp
946+
assert response.status_code == 200
947+
assert response.body["StopTimestamp"] == stop_timestamp
948948

949949

950950
def test_stop_durable_execution_handler_resource_not_found():

0 commit comments

Comments
 (0)