@@ -78,6 +78,17 @@ def run(self, ctx): # type: ignore[no-untyped-def]
7878 return self .status
7979
8080
81+ @workflow .defn (name = "async-query-wf" )
82+ class AsyncQueryWorkflow :
83+ @workflow .query ("current" )
84+ async def current (self ) -> int :
85+ await asyncio .sleep (0 )
86+ return 0
87+
88+ def run (self , ctx ): # type: ignore[no-untyped-def]
89+ yield ctx .wait_condition (lambda : False )
90+
91+
8192@activity .defn (name = "test-act" )
8293def echo_activity (val : str ) -> str :
8394 return f"result-{ val } "
@@ -673,6 +684,35 @@ async def test_query_task_executes_registered_query(self, mock_client: AsyncMock
673684 )
674685 mock_client .fail_query_task .assert_not_called ()
675686
687+ @pytest .mark .asyncio
688+ async def test_query_task_awaits_async_query_result (self , mock_client : AsyncMock ) -> None :
689+ worker = Worker (mock_client , task_queue = "q1" , workflows = [AsyncQueryWorkflow ], activities = [])
690+ task = {
691+ "query_task_id" : "qt-async" ,
692+ "query_task_attempt" : 1 ,
693+ "workflow_type" : "async-query-wf" ,
694+ "query_name" : "current" ,
695+ "history_events" : [],
696+ "workflow_arguments" : serializer .envelope ([], codec = "json" ),
697+ "query_arguments" : serializer .envelope ([], codec = "json" ),
698+ "payload_codec" : "json" ,
699+ }
700+
701+ outcome = await worker ._run_query_task (task )
702+
703+ assert outcome == "completed"
704+ mock_client .complete_query_task .assert_awaited_once_with (
705+ query_task_id = "qt-async" ,
706+ lease_owner = worker .worker_id ,
707+ query_task_attempt = 1 ,
708+ result = 0 ,
709+ codec = "json" ,
710+ workflow_id = None ,
711+ run_id = None ,
712+ query_name = "current" ,
713+ )
714+ mock_client .fail_query_task .assert_not_called ()
715+
676716 @pytest .mark .asyncio
677717 async def test_query_task_reports_unknown_query (self , mock_client : AsyncMock ) -> None :
678718 worker = Worker (mock_client , task_queue = "q1" , workflows = [QueryWorkflow ], activities = [])
@@ -723,6 +763,33 @@ async def test_query_task_completion_rejection_after_server_timeout_is_handled(
723763 mock_client .complete_query_task .assert_awaited_once ()
724764 mock_client .fail_query_task .assert_not_called ()
725765
766+ @pytest .mark .asyncio
767+ async def test_query_task_reports_query_result_completion_failure (
768+ self , mock_client : AsyncMock
769+ ) -> None :
770+ worker = Worker (mock_client , task_queue = "q1" , workflows = [QueryWorkflow ], activities = [])
771+ mock_client .complete_query_task .side_effect = TypeError ("Object is not payload safe" )
772+ task = {
773+ "query_task_id" : "qt-result-encode-failure" ,
774+ "query_task_attempt" : 1 ,
775+ "workflow_type" : "query-wf" ,
776+ "query_name" : "status" ,
777+ "history_events" : [],
778+ "workflow_arguments" : serializer .envelope ([], codec = "json" ),
779+ "query_arguments" : serializer .envelope ([], codec = "json" ),
780+ "payload_codec" : "json" ,
781+ }
782+
783+ outcome = await worker ._run_query_task (task )
784+
785+ assert outcome == "failed"
786+ mock_client .fail_query_task .assert_awaited_once ()
787+ call_kwargs = mock_client .fail_query_task .call_args .kwargs
788+ assert call_kwargs ["query_task_id" ] == "qt-result-encode-failure"
789+ assert call_kwargs ["query_task_attempt" ] == 1
790+ assert call_kwargs ["reason" ] == "query_result_encode_failed"
791+ assert call_kwargs ["failure_type" ] == "TypeError"
792+
726793
727794class TestActivityTaskExecution :
728795 @pytest .mark .asyncio
0 commit comments