@@ -278,6 +278,38 @@ def orchestrator(ctx: task.OrchestrationContext, _):
278278 assert state .runtime_status == client .OrchestrationStatus .TERMINATED
279279 assert state .serialized_output == json .dumps ("some reason for termination" )
280280
281+ def test_terminate_recursive ():
282+ def root (ctx : task .OrchestrationContext , _ ):
283+ result = yield ctx .call_sub_orchestrator (child )
284+ return result
285+ def child (ctx : task .OrchestrationContext , _ ):
286+ result = yield ctx .wait_for_external_event ("my_event" )
287+ return result
288+
289+ # Start a worker, which will connect to the sidecar in a background thread
290+ with worker .TaskHubGrpcWorker () as w :
291+ w .add_orchestrator (root )
292+ w .add_orchestrator (child )
293+ w .start ()
294+
295+ task_hub_client = client .TaskHubGrpcClient ()
296+ id = task_hub_client .schedule_new_orchestration (root )
297+ state = task_hub_client .wait_for_orchestration_start (id , timeout = 30 )
298+ assert state is not None
299+ assert state .runtime_status == client .OrchestrationStatus .RUNNING
300+
301+ # Terminate root orchestration(recursive set to True by default)
302+ task_hub_client .terminate_orchestration (id , output = "some reason for termination" )
303+ state = task_hub_client .wait_for_orchestration_completion (id , timeout = 30 )
304+ assert state is not None
305+ assert state .runtime_status == client .OrchestrationStatus .TERMINATED
306+
307+ # Verify that child orchestration is also terminated
308+ c = task_hub_client .wait_for_orchestration_completion (id , timeout = 30 )
309+ assert state is not None
310+ assert state .runtime_status == client .OrchestrationStatus .TERMINATED
311+
312+
281313
282314def test_continue_as_new ():
283315 all_results = []
0 commit comments