@@ -1190,3 +1190,93 @@ async def test_nexus_direct_traceable_without_temporal_runs(
11901190 assert (
11911191 hierarchy == expected
11921192 ), f"Hierarchy mismatch.\n Expected:\n { expected } \n Actual:\n { hierarchy } "
1193+
1194+
1195+ # ---------------------------------------------------------------------------
1196+ # TestBuiltinQueryFiltering
1197+ # ---------------------------------------------------------------------------
1198+
1199+
1200+ @workflow .defn
1201+ class QueryFilteringWorkflow :
1202+ """Workflow with a user query and a signal to complete."""
1203+
1204+ def __init__ (self ) -> None :
1205+ self ._complete = False
1206+
1207+ @workflow .run
1208+ async def run (self ) -> str :
1209+ await workflow .wait_condition (lambda : self ._complete )
1210+ return "done"
1211+
1212+ @workflow .signal
1213+ def complete (self ) -> None :
1214+ self ._complete = True
1215+
1216+ @workflow .query
1217+ def my_query (self ) -> str :
1218+ return "query-result"
1219+
1220+
1221+ class TestBuiltinQueryFiltering :
1222+ """Verifies __temporal_ prefixed queries are not traced."""
1223+
1224+ async def test_temporal_prefixed_query_not_traced (
1225+ self ,
1226+ client : Client ,
1227+ ) -> None :
1228+ """__temporal_workflow_metadata query should not produce a trace,
1229+ but user-defined queries should still be traced.
1230+
1231+ Uses add_temporal_runs=False on the query client to suppress
1232+ client-side QueryWorkflow traces, isolating the test to
1233+ worker-side HandleQuery traces only.
1234+ """
1235+
1236+ task_queue = f"query-filter-{ uuid .uuid4 ()} "
1237+ collector = InMemoryRunCollector ()
1238+ mock_ls = make_mock_ls_client (collector )
1239+
1240+ # Worker client: add_temporal_runs=True so HandleQuery traces are created
1241+ worker_client = _make_temporal_client (client , mock_ls , add_temporal_runs = True )
1242+ # Query client: add_temporal_runs=False to suppress client-side traces
1243+ query_client = _make_temporal_client (client , mock_ls , add_temporal_runs = False )
1244+
1245+ async with new_worker (
1246+ worker_client ,
1247+ QueryFilteringWorkflow ,
1248+ task_queue = task_queue ,
1249+ max_cached_workflows = 0 ,
1250+ ) as worker :
1251+ handle = await query_client .start_workflow (
1252+ QueryFilteringWorkflow .run ,
1253+ id = f"query-filter-{ uuid .uuid4 ()} " ,
1254+ task_queue = worker .task_queue ,
1255+ )
1256+
1257+ # Wait for workflow to start by polling the user query
1258+ assert await _poll_query (
1259+ handle ,
1260+ QueryFilteringWorkflow .my_query ,
1261+ expected = "query-result" ,
1262+ ), "Workflow never started"
1263+
1264+ collector .clear ()
1265+
1266+ # Built-in queries — should NOT be traced
1267+ await handle .query ("__temporal_workflow_metadata" )
1268+ await handle .query ("__stack_trace" )
1269+ await handle .query ("__enhanced_stack_trace" )
1270+
1271+ # User query — should be traced
1272+ await handle .query (QueryFilteringWorkflow .my_query )
1273+
1274+ await handle .signal (QueryFilteringWorkflow .complete )
1275+ assert await handle .result () == "done"
1276+
1277+ # Built-in queries should be absent; only user query and signal remain.
1278+ traces = dump_traces (collector )
1279+ assert traces == [
1280+ ["HandleQuery:my_query" ],
1281+ ["HandleSignal:complete" ],
1282+ ], f"Unexpected traces: { traces } "
0 commit comments