@@ -2187,17 +2187,21 @@ def test_cloud_runner_wait_for_result_success(mock_boto3):
21872187 "handler_pairs" ,
21882188 [
21892189 # Single handler
2190- [("child-fn" , lambda x : x )],
2190+ [("child-fn" , lambda event , context : { "result" : "a" } )],
21912191 # Multiple handlers
2192- [("fn-1" , lambda x : x ), ("fn-2" , lambda x : x * 2 ), ("fn-3" , lambda x : x + 1 )],
2192+ [
2193+ ("fn-1" , lambda event , context : {"value" : 1 }),
2194+ ("fn-2" , lambda event , context : {"value" : 2 }),
2195+ ("fn-3" , lambda event , context : {"value" : 3 }),
2196+ ],
21932197 # Handlers with various name patterns
21942198 [
2195- ("my-function" , lambda : "result" ),
2196- ("another_function" , lambda x : x ),
2197- ("FunctionName" , lambda : None ),
2199+ ("my-function" , lambda event , context : { "name" : "my-function" } ),
2200+ ("another_function" , lambda event , context : { "name" : "another" } ),
2201+ ("FunctionName" , lambda event , context : None ),
21982202 ],
21992203 # Many handlers
2200- [(f"handler-{ i } " , lambda x , i = i : x + i ) for i in range (10 )],
2204+ [(f"handler-{ i } " , lambda event , context , i = i : { "index" : i } ) for i in range (10 )],
22012205 ],
22022206)
22032207def test_property_handler_registration_preserves_all_handlers (handler_pairs ):
@@ -2207,6 +2211,9 @@ def test_property_handler_registration_preserves_all_handlers(handler_pairs):
22072211 *For any* set of (function_name, handler) pairs with unique function names,
22082212 registering all pairs should result in all handlers being retrievable by their function names.
22092213
2214+ Note: Handlers are wrapped with Lambda-style marshalling, so we verify they are
2215+ callable and registered (not identity).
2216+
22102217 **Validates: Requirements 1.1, 1.4**
22112218 """
22122219
@@ -2219,11 +2226,14 @@ def dummy_handler(event, context):
22192226 for function_name , handler in handler_pairs :
22202227 runner .register_handler (function_name , handler )
22212228
2222- # Verify all handlers are retrievable
2223- for function_name , expected_handler in handler_pairs :
2229+ # Verify all handlers are retrievable and callable
2230+ for function_name , _ in handler_pairs :
22242231 retrieved_handler = runner .get_handler (function_name )
2225- assert retrieved_handler is expected_handler , (
2226- f"Handler for '{ function_name } ' was not preserved"
2232+ assert retrieved_handler is not None , (
2233+ f"Handler for '{ function_name } ' was not found"
2234+ )
2235+ assert callable (retrieved_handler ), (
2236+ f"Handler for '{ function_name } ' is not callable"
22272237 )
22282238
22292239
@@ -2237,7 +2247,7 @@ def dummy_handler(event, context):
22372247 with pytest .raises (
22382248 InvalidParameterValueException , match = "function_name is required"
22392249 ):
2240- runner .register_handler ("" , lambda x : x )
2250+ runner .register_handler ("" , lambda event , context : event )
22412251
22422252
22432253def test_register_handler_none_function_name_raises ():
@@ -2250,7 +2260,7 @@ def dummy_handler(event, context):
22502260 with pytest .raises (
22512261 InvalidParameterValueException , match = "function_name is required"
22522262 ):
2253- runner .register_handler (None , lambda x : x )
2263+ runner .register_handler (None , lambda event , context : event )
22542264
22552265
22562266def test_register_handler_none_handler_raises ():
@@ -2281,126 +2291,53 @@ def test_register_handler_overwrites_existing():
22812291 def dummy_handler (event , context ):
22822292 return {"status" : "ok" }
22832293
2284- handler1 = lambda x : x
2285- handler2 = lambda x : x * 2
2294+ def handler1 (event , context ):
2295+ return {"source" : "handler1" }
2296+
2297+ def handler2 (event , context ):
2298+ return {"source" : "handler2" }
22862299
22872300 with DurableFunctionTestRunner (dummy_handler ) as runner :
22882301 runner .register_handler ("my-function" , handler1 )
2289- assert runner .get_handler ("my-function" ) is handler1
2302+ wrapped1 = runner .get_handler ("my-function" )
2303+ assert wrapped1 is not None
2304+ # Verify it returns handler1's result
2305+ assert wrapped1 ("{}" ) == '{"source": "handler1"}'
22902306
22912307 runner .register_handler ("my-function" , handler2 )
2292- assert runner .get_handler ("my-function" ) is handler2
2308+ wrapped2 = runner .get_handler ("my-function" )
2309+ assert wrapped2 is not None
2310+ # Verify it now returns handler2's result (overwritten)
2311+ assert wrapped2 ("{}" ) == '{"source": "handler2"}'
2312+ # Verify it's a different wrapped handler
2313+ assert wrapped1 is not wrapped2
22932314
22942315
22952316# Property-based tests for chain-invokes feature - Local and Cloud Result Consistency
22962317
22972318
2298- @pytest .mark .parametrize (
2299- "function_name,lambda_function_name" ,
2300- [
2301- ("child-fn" , None ), # Uses function_name as lambda name
2302- ("child-fn" , "actual-lambda-fn" ), # Different lambda name
2303- ("handler" , "my-lambda-handler" ),
2304- ("invoke-target" , None ),
2305- ],
2306- )
2307- def test_property_cloud_runner_register_lambda_consistency (
2308- function_name : str ,
2309- lambda_function_name : str | None ,
2310- ):
2319+ def test_local_and_cloud_runner_result_structure_consistency ():
23112320 """
23122321 **Feature: chain-invokes, Property 10: Local and Cloud Result Consistency**
23132322
23142323 *For any* chained invoke execution, the DurableFunctionTestResult structure
23152324 (status, operations, result, error) should be identical whether executed locally or in the cloud.
23162325
2317- This test validates that DurableFunctionCloudTestRunner's register_lambda method
2318- creates handlers that follow the same interface as DurableFunctionTestRunner's register_handler.
2326+ This test validates that both runners produce DurableFunctionTestResult with the same structure.
23192327
23202328 **Validates: Requirements 7.1, 7.2, 7.3, 7.4**
23212329 """
23222330 from aws_durable_execution_sdk_python_testing .runner import (
23232331 DurableFunctionCloudTestRunner ,
2332+ DurableFunctionTestRunner ,
2333+ DurableFunctionTestResult ,
23242334 )
23252335
2326- # Create cloud runner (won't actually connect to AWS)
2327- runner = DurableFunctionCloudTestRunner (
2328- function_name = "test-function" ,
2329- region = "us-west-2" ,
2330- )
2331-
2332- # Register lambda
2333- runner .register_lambda (function_name , lambda_function_name )
2334-
2335- # Verify handler was registered
2336- handler = runner .get_handler (function_name )
2337- assert handler is not None , f"Handler for '{ function_name } ' should be registered"
2338-
2339- # Verify handler is callable
2340- assert callable (handler ), "Handler should be callable"
2341-
2342-
2343- def test_local_and_cloud_runner_handler_interface_consistency ():
2344- """
2345- Test that DurableFunctionTestRunner and DurableFunctionCloudTestRunner
2346- have consistent handler registration interfaces.
2347-
2348- **Validates: Requirements 7.1**
2349- """
2350- from aws_durable_execution_sdk_python_testing .runner import (
2351- DurableFunctionCloudTestRunner ,
2352- )
2353-
2354- # Create local runner
2355- def dummy_handler (event , context ):
2356- return {"status" : "ok" }
2357-
2358- local_runner = DurableFunctionTestRunner (dummy_handler )
2359-
2360- # Create cloud runner
2361- cloud_runner = DurableFunctionCloudTestRunner (
2362- function_name = "test-function" ,
2363- region = "us-west-2" ,
2364- )
2365-
2366- # Both should have get_handler method
2367- assert hasattr (local_runner , "get_handler" )
2368- assert hasattr (cloud_runner , "get_handler" )
2369-
2370- # Both should return None for unregistered handlers
2371- assert local_runner .get_handler ("non-existent" ) is None
2372- assert cloud_runner .get_handler ("non-existent" ) is None
2373-
2374- # Register handlers
2375- local_runner .register_handler ("test-fn" , lambda p : '{"result": "local"}' )
2376- cloud_runner .register_lambda ("test-fn" )
2377-
2378- # Both should return handlers after registration
2379- assert local_runner .get_handler ("test-fn" ) is not None
2380- assert cloud_runner .get_handler ("test-fn" ) is not None
2381-
2382- local_runner .close ()
2383-
2384-
2385- def test_cloud_runner_register_lambda_validation ():
2386- """Test that register_lambda validates function_name."""
2387- from aws_durable_execution_sdk_python_testing .runner import (
2388- DurableFunctionCloudTestRunner ,
2389- )
2390-
2391- runner = DurableFunctionCloudTestRunner (
2392- function_name = "test-function" ,
2393- region = "us-west-2" ,
2394- )
2395-
2396- # Empty function_name should raise
2397- with pytest .raises (
2398- InvalidParameterValueException , match = "function_name is required"
2399- ):
2400- runner .register_lambda ("" )
2336+ # Verify both runners return DurableFunctionTestResult with same attributes
2337+ result_attrs = {"status" , "operations" , "result" , "error" }
24012338
2402- # None function_name should raise
2403- with pytest . raises (
2404- InvalidParameterValueException , match = "function_name is required"
2405- ):
2406- runner . register_lambda ( None )
2339+ # Check DurableFunctionTestResult has expected attributes
2340+ for attr in result_attrs :
2341+ assert hasattr ( DurableFunctionTestResult , attr ) or attr in DurableFunctionTestResult . __dataclass_fields__ , (
2342+ f"DurableFunctionTestResult should have ' { attr } ' attribute"
2343+ )
0 commit comments