@@ -41,6 +41,8 @@ def test_child_handler_not_started(
4141 mock_result .is_succeeded .return_value = False
4242 mock_result .is_failed .return_value = False
4343 mock_result .is_started .return_value = False
44+ mock_result .is_replay_children .return_value = False
45+ mock_result .is_replay_children .return_value = False
4446 mock_state .get_checkpoint_result .return_value = mock_result
4547 mock_callable = Mock (return_value = "fresh_result" )
4648
@@ -80,6 +82,7 @@ def test_child_handler_already_succeeded():
8082 mock_state .durable_execution_arn = "test_arn"
8183 mock_result = Mock ()
8284 mock_result .is_succeeded .return_value = True
85+ mock_result .is_replay_children .return_value = False
8386 mock_result .result = json .dumps ("cached_result" )
8487 mock_state .get_checkpoint_result .return_value = mock_result
8588 mock_callable = Mock ()
@@ -99,6 +102,7 @@ def test_child_handler_already_succeeded_none_result():
99102 mock_state .durable_execution_arn = "test_arn"
100103 mock_result = Mock ()
101104 mock_result .is_succeeded .return_value = True
105+ mock_result .is_replay_children .return_value = False
102106 mock_result .result = None
103107 mock_state .get_checkpoint_result .return_value = mock_result
104108 mock_callable = Mock ()
@@ -155,6 +159,7 @@ def test_child_handler_already_started(
155159 mock_result .is_succeeded .return_value = False
156160 mock_result .is_failed .return_value = False
157161 mock_result .is_started .return_value = True
162+ mock_result .is_replay_children .return_value = False
158163 mock_state .get_checkpoint_result .return_value = mock_result
159164 mock_callable = Mock (return_value = "started_result" )
160165
@@ -281,6 +286,7 @@ def test_child_handler_default_serialization():
281286 mock_result .is_succeeded .return_value = False
282287 mock_result .is_failed .return_value = False
283288 mock_result .is_started .return_value = False
289+ mock_result .is_replay_children .return_value = False
284290 mock_state .get_checkpoint_result .return_value = mock_result
285291 complex_result = {"key" : "value" , "number" : 42 , "list" : [1 , 2 , 3 ]}
286292 mock_callable = Mock (return_value = complex_result )
@@ -306,6 +312,7 @@ def test_child_handler_custom_serdes_not_start():
306312 mock_result .is_succeeded .return_value = False
307313 mock_result .is_failed .return_value = False
308314 mock_result .is_started .return_value = False
315+ mock_result .is_replay_children .return_value = False
309316 mock_state .get_checkpoint_result .return_value = mock_result
310317 complex_result = {"key" : "value" , "number" : 42 , "list" : [1 , 2 , 3 ]}
311318 mock_callable = Mock (return_value = complex_result )
@@ -334,6 +341,7 @@ def test_child_handler_custom_serdes_already_succeeded():
334341 mock_result .is_succeeded .return_value = True
335342 mock_result .is_failed .return_value = False
336343 mock_result .is_started .return_value = False
344+ mock_result .is_replay_children .return_value = False
337345 mock_result .result = '{"key": "VALUE", "number": "84", "list": [1, 2, 3]}'
338346 mock_state .get_checkpoint_result .return_value = mock_result
339347 mock_callable = Mock ()
@@ -352,3 +360,94 @@ def test_child_handler_custom_serdes_already_succeeded():
352360
353361
354362# endregion child_handler
363+
364+
365+ # large payload with summary generator
366+ def test_child_handler_large_payload_with_summary_generator ():
367+ """Test child_handler with large payload and summary generator."""
368+ mock_state = Mock (spec = ExecutionState )
369+ mock_state .durable_execution_arn = "test_arn"
370+ mock_result = Mock ()
371+ mock_result .is_succeeded .return_value = False
372+ mock_result .is_failed .return_value = False
373+ mock_result .is_started .return_value = False
374+ mock_result .is_replay_children .return_value = False
375+ mock_state .get_checkpoint_result .return_value = mock_result
376+ large_result = "large" * 256 * 1024
377+ mock_callable = Mock (return_value = large_result )
378+
379+ def my_summary (result : str ) -> str :
380+ return "summary"
381+
382+ child_config : ChildConfig = ChildConfig [str ](summary_generator = my_summary )
383+
384+ actual_result = child_handler (
385+ mock_callable ,
386+ mock_state ,
387+ OperationIdentifier ("op9" , None , "test_name" ),
388+ child_config ,
389+ )
390+
391+ assert large_result == actual_result
392+ success_call = mock_state .create_checkpoint .call_args_list [1 ]
393+ success_operation = success_call [1 ]["operation_update" ]
394+ assert success_operation .context_options .replay_children
395+ expected_checkpoointed_result = "summary"
396+ assert success_operation .payload == expected_checkpoointed_result
397+
398+
399+ # large payload without summary generator
400+ def test_child_handler_large_payload_without_summary_generator ():
401+ """Test child_handler with large payload and no summary generator."""
402+ mock_state = Mock (spec = ExecutionState )
403+ mock_state .durable_execution_arn = "test_arn"
404+ mock_result = Mock ()
405+ mock_result .is_succeeded .return_value = False
406+ mock_result .is_failed .return_value = False
407+ mock_result .is_started .return_value = False
408+ mock_result .is_replay_children .return_value = False
409+ mock_state .get_checkpoint_result .return_value = mock_result
410+ large_result = "large" * 256 * 1024
411+ mock_callable = Mock (return_value = large_result )
412+ child_config : ChildConfig = ChildConfig ()
413+
414+ actual_result = child_handler (
415+ mock_callable ,
416+ mock_state ,
417+ OperationIdentifier ("op9" , None , "test_name" ),
418+ child_config ,
419+ )
420+
421+ assert large_result == actual_result
422+ success_call = mock_state .create_checkpoint .call_args_list [1 ]
423+ success_operation = success_call [1 ]["operation_update" ]
424+ assert success_operation .context_options .replay_children
425+ expected_checkpoointed_result = ""
426+ assert success_operation .payload == expected_checkpoointed_result
427+
428+
429+ # mocked children replay mode execute the function again
430+ def test_child_handler_replay_children_mode ():
431+ """Test child_handler in ReplayChildren mode."""
432+ mock_state = Mock (spec = ExecutionState )
433+ mock_state .durable_execution_arn = "test_arn"
434+ mock_result = Mock ()
435+ mock_result .is_succeeded .return_value = True
436+ mock_result .is_failed .return_value = False
437+ mock_result .is_started .return_value = True
438+ mock_result .is_replay_children .return_value = True
439+ mock_state .get_checkpoint_result .return_value = mock_result
440+ complex_result = {"key" : "value" , "number" : 42 , "list" : [1 , 2 , 3 ]}
441+ mock_callable = Mock (return_value = complex_result )
442+ child_config : ChildConfig = ChildConfig ()
443+
444+ actual_result = child_handler (
445+ mock_callable ,
446+ mock_state ,
447+ OperationIdentifier ("op9" , None , "test_name" ),
448+ child_config ,
449+ )
450+
451+ assert actual_result == complex_result
452+
453+ mock_state .create_checkpoint .assert_not_called ()
0 commit comments