Skip to content

Commit 61c403a

Browse files
authored
add tests for nest_type (#359)
1 parent 9d9c2ff commit 61c403a

8 files changed

Lines changed: 190 additions & 1 deletion

File tree

.github/workflows/integration-tests.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ jobs:
2222
with:
2323
path: language-sdk
2424

25+
- name: Checkout the latest Testing SDK
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
with:
28+
repository: aws/aws-durable-execution-sdk-python-testing
29+
path: testing-sdk
30+
2531
- name: Set up Python ${{ matrix.python-version }}
2632
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
2733
with:
@@ -34,6 +40,7 @@ jobs:
3440
working-directory: language-sdk
3541
run: |
3642
echo "Running SDK tests..."
43+
hatch run -- test:pip install -e ../testing-sdk
3744
hatch run -- test:pip install -e ../language-sdk
3845
hatch fmt --check
3946
hatch run types:check
@@ -54,6 +61,12 @@ jobs:
5461
with:
5562
path: language-sdk
5663

64+
- name: Checkout the latest Testing SDK
65+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
66+
with:
67+
repository: aws/aws-durable-execution-sdk-python-testing
68+
path: testing-sdk
69+
5770
- name: Set up Python 3.13
5871
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
5972
with:
@@ -92,6 +105,7 @@ jobs:
92105
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
93106
run: |
94107
echo "Building examples..."
108+
hatch run -- examples:pip install -e ../testing-sdk
95109
hatch run examples:build
96110
97111
# Get first integration example for testing

examples/examples-catalog.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,17 @@
221221
},
222222
"path": "./src/parallel/parallel.py"
223223
},
224+
{
225+
"name": "Parallel Operations",
226+
"description": "Executing multiple durable operations in parallel",
227+
"handler": "parallel.handler",
228+
"integration": true,
229+
"durableConfig": {
230+
"RetentionPeriodInDays": 7,
231+
"ExecutionTimeout": 300
232+
},
233+
"path": "./src/parallel/parallel.py"
234+
},
224235
{
225236
"name": "Map Operations",
226237
"description": "Processing collections using map-like durable operations",
@@ -232,6 +243,17 @@
232243
},
233244
"path": "./src/map/map_operations.py"
234245
},
246+
{
247+
"name": "Map Operations Flat",
248+
"description": "Processing collections using map-like durable operations in FLAT mode",
249+
"handler": "map_operations_flat.handler",
250+
"integration": true,
251+
"durableConfig": {
252+
"RetentionPeriodInDays": 7,
253+
"ExecutionTimeout": 300
254+
},
255+
"path": "./src/map/map_operations_flat.py"
256+
},
235257
{
236258
"name": "Map Large Scale",
237259
"description": "Processing collections using map-like durable operations in large scale",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Example demonstrating map operations for processing collections durably."""
2+
3+
from typing import Any
4+
5+
from aws_durable_execution_sdk_python.config import MapConfig, NestingType
6+
from aws_durable_execution_sdk_python.context import DurableContext
7+
from aws_durable_execution_sdk_python.execution import durable_execution
8+
9+
10+
@durable_execution
11+
def handler(_event: Any, context: DurableContext) -> list[int]:
12+
"""Process a list of items using context.map()."""
13+
items = [1, 2, 3, 4, 5]
14+
15+
# Use context.map() to process items concurrently and extract results immediately
16+
return context.map(
17+
inputs=items,
18+
func=lambda ctx, item, index, _: ctx.step(
19+
lambda _: item * 2, name=f"map_item_{index}"
20+
),
21+
name="map_operation",
22+
config=MapConfig(max_concurrency=2, nesting_type=NestingType.FLAT),
23+
).get_results()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Example demonstrating parallel operations for concurrent execution."""
2+
3+
from typing import Any
4+
5+
from aws_durable_execution_sdk_python.config import ParallelConfig, NestingType
6+
from aws_durable_execution_sdk_python.context import DurableContext
7+
from aws_durable_execution_sdk_python.execution import durable_execution
8+
from aws_durable_execution_sdk_python.config import Duration
9+
10+
11+
@durable_execution
12+
def handler(_event: Any, context: DurableContext) -> list[str]:
13+
"""Execute multiple operations in parallel using context.parallel()."""
14+
15+
# Use context.parallel() to execute functions concurrently and extract results immediately
16+
return context.parallel(
17+
functions=[
18+
lambda ctx: ctx.step(lambda _: "task 1 completed", name="task1"),
19+
lambda ctx: ctx.step(lambda _: "task 2 completed", name="task2"),
20+
lambda ctx: (
21+
ctx.wait(Duration.from_seconds(1), name="wait_in_task3"),
22+
"task 3 completed after wait",
23+
)[1],
24+
],
25+
name="parallel_operation",
26+
config=ParallelConfig(max_concurrency=2, nesting_type=NestingType.FLAT),
27+
).get_results()

examples/template.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,24 @@
420420
}
421421
}
422422
},
423+
"MapOperationsFlat": {
424+
"Type": "AWS::Serverless::Function",
425+
"Properties": {
426+
"CodeUri": "build/",
427+
"Handler": "map_operations_flat.handler",
428+
"Description": "Processing collections using map-like durable operations in FLAT mode",
429+
"Role": {
430+
"Fn::GetAtt": [
431+
"DurableFunctionRole",
432+
"Arn"
433+
]
434+
},
435+
"DurableConfig": {
436+
"RetentionPeriodInDays": 7,
437+
"ExecutionTimeout": 300
438+
}
439+
}
440+
},
423441
"MapWithLargeScale": {
424442
"Type": "AWS::Serverless::Function",
425443
"Properties": {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Tests for map_operations example."""
2+
3+
import pytest
4+
from aws_durable_execution_sdk_python.execution import InvocationStatus
5+
from aws_durable_execution_sdk_python.lambda_service import OperationStatus
6+
7+
from src.map import map_operations_flat
8+
from test.conftest import deserialize_operation_payload
9+
10+
11+
@pytest.mark.example
12+
@pytest.mark.durable_execution(
13+
handler=map_operations_flat.handler,
14+
lambda_function_name="Map Operations Flat",
15+
)
16+
def test_map_operations_flat(durable_runner):
17+
"""Test map_operations example using context.map()."""
18+
with durable_runner:
19+
result = durable_runner.run(input="test", timeout=10)
20+
21+
assert result.status is InvocationStatus.SUCCEEDED
22+
assert deserialize_operation_payload(result.result) == [2, 4, 6, 8, 10]
23+
24+
# Get the map operation (CONTEXT type with MAP subtype)
25+
map_op = result.get_context("map_operation")
26+
assert map_op is not None
27+
assert map_op.status is OperationStatus.SUCCEEDED
28+
29+
# Verify all five child operations exist
30+
assert len(map_op.child_operations) == 5
31+
32+
# Verify child step operation names
33+
child_names = {op.name for op in map_op.child_operations}
34+
expected_names = {f"map_item_{i}" for i in range(5)}
35+
assert child_names == expected_names
36+
37+
# Verify all children succeeded
38+
for child in map_op.child_operations:
39+
assert child.status is OperationStatus.SUCCEEDED

examples/test/parallel/test_parallel.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import pytest
44
from aws_durable_execution_sdk_python.execution import InvocationStatus
5-
from aws_durable_execution_sdk_python.lambda_service import OperationStatus
5+
from aws_durable_execution_sdk_python.lambda_service import (
6+
OperationStatus,
7+
OperationType,
8+
)
69

710
from src.parallel import parallel
811
from test.conftest import deserialize_operation_payload
@@ -35,4 +38,5 @@ def test_parallel(durable_runner):
3538

3639
# Verify all children succeeded
3740
for child in parallel_op.child_operations:
41+
assert child.operation_type == OperationType.CONTEXT
3842
assert child.status is OperationStatus.SUCCEEDED
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""Tests for parallel example."""
2+
3+
import pytest
4+
from aws_durable_execution_sdk_python.execution import InvocationStatus
5+
from aws_durable_execution_sdk_python.lambda_service import (
6+
OperationStatus,
7+
OperationType,
8+
)
9+
10+
from src.parallel import parallel_flat
11+
from test.conftest import deserialize_operation_payload
12+
13+
14+
@pytest.mark.example
15+
@pytest.mark.durable_execution(
16+
handler=parallel_flat.handler,
17+
lambda_function_name="Parallel Operations Flat",
18+
)
19+
def test_parallel_flat(durable_runner):
20+
"""Test parallel example using context.parallel()."""
21+
with durable_runner:
22+
result = durable_runner.run(input="test", timeout=100)
23+
24+
assert result.status is InvocationStatus.SUCCEEDED
25+
assert deserialize_operation_payload(result.result) == [
26+
"task 1 completed",
27+
"task 2 completed",
28+
"task 3 completed after wait",
29+
]
30+
31+
# Get the parallel operation (CONTEXT type with PARALLEL subtype)
32+
parallel_op = result.get_context("parallel_operation")
33+
assert parallel_op is not None
34+
assert parallel_op.status is OperationStatus.SUCCEEDED
35+
36+
# Verify all three child operations exist
37+
assert len(parallel_op.child_operations) == 3
38+
39+
# Verify all children succeeded
40+
for child in parallel_op.child_operations:
41+
assert child.operation_type != OperationType.CONTEXT
42+
assert child.status is OperationStatus.SUCCEEDED

0 commit comments

Comments
 (0)