This is an automated email from the ASF dual-hosted git repository.

henry3260 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new b9aa889577c Cover long-running jobs in the deferrable BigQuery check 
system test (#74356)
b9aa889577c is described below

commit b9aa889577c7e2787ba3f2544e22df05a1b6a558
Author: Shahar Epstein <[email protected]>
AuthorDate: Fri Oct 16 19:54:20 2026 +0100

    Cover long-running jobs in the deferrable BigQuery check system test 
(#74356)
    
    The deferrable value and interval checks in the async BigQuery system
    test only ran trivial COUNT(*) queries, so their jobs were DONE before
    the trigger's first poll. The regression fixed in #74305, where
    BigQueryValueCheckTrigger and BigQueryIntervalCheckTrigger failed with
    "Job running" while the job was still RUNNING (#73981), could therefore
    never show up in the system test.
    
    Add a view backed by a JavaScript UDF that keeps a query RUNNING for
    tens of seconds and run both deferrable checks against it. The view
    only reads the existing two-row table, so each check job is billed at
    BigQuery's 10 MB minimum.
---
 .../bigquery/example_bigquery_queries_async.py     | 54 +++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git 
a/providers/google/tests/system/google/cloud/bigquery/example_bigquery_queries_async.py
 
b/providers/google/tests/system/google/cloud/bigquery/example_bigquery_queries_async.py
index 60080989320..df143389ba6 100644
--- 
a/providers/google/tests/system/google/cloud/bigquery/example_bigquery_queries_async.py
+++ 
b/providers/google/tests/system/google/cloud/bigquery/example_bigquery_queries_async.py
@@ -100,6 +100,26 @@ CONFIGURATION = {
     }
 }
 
+SLOW_VIEW_NAME = f"view_{DAG_ID}_{ENV_ID}_slow".replace("-", "_")
+
+# The JavaScript UDF spins for a fixed number of iterations per row, which 
keeps a query over the view
+# RUNNING for tens of seconds, i.e. across several poll intervals of the 
deferrable check operators
+# (#73981). `CURRENT_TIMESTAMP()` makes the view non-deterministic, so 
BigQuery never serves a repeated
+# check from the query cache. Nothing here scans more than the two-row table, 
so the jobs are billed at
+# the 10 MB minimum.
+CREATE_SLOW_VIEW_QUERY = f"""
+CREATE OR REPLACE FUNCTION `{DATASET_NAME}.slow_ds`(ds STRING) RETURNS STRING 
LANGUAGE js AS r'''
+  let acc = 0;
+  for (let i = 0; i < 500000000; i++) {{
+    acc = (acc * 31 + i) % 1000003;
+  }}
+  return acc >= 0 ? ds : null;
+''';
+CREATE OR REPLACE VIEW `{DATASET_NAME}.{SLOW_VIEW_NAME}` AS
+  SELECT value, name, `{DATASET_NAME}.slow_ds`(ds) AS ds
+  FROM `{DATASET_NAME}.{TABLE_NAME_1}`
+  WHERE CURRENT_TIMESTAMP() IS NOT NULL;
+"""
 
 default_args = {
     "execution_timeout": timedelta(hours=6),
@@ -262,6 +282,31 @@ with DAG(
         deferrable=True,
     )
 
+    create_slow_view = BigQueryInsertJobOperator(
+        task_id="create_slow_view",
+        configuration={"query": {"query": CREATE_SLOW_VIEW_QUERY, 
"useLegacySql": False}},
+        location=LOCATION,
+    )
+
+    check_value_long_running = BigQueryValueCheckOperator(
+        task_id="check_value_long_running",
+        sql=f"SELECT COUNT(*) FROM {DATASET_NAME}.{SLOW_VIEW_NAME} WHERE ds IS 
NOT NULL",
+        pass_value=2,
+        use_legacy_sql=False,
+        location=LOCATION,
+        deferrable=True,
+    )
+
+    check_interval_long_running = BigQueryIntervalCheckOperator(
+        task_id="check_interval_long_running",
+        table=f"{DATASET_NAME}.{SLOW_VIEW_NAME}",
+        days_back=1,
+        metrics_thresholds={"COUNT(*)": 1.5},
+        use_legacy_sql=False,
+        location=LOCATION,
+        deferrable=True,
+    )
+
     check_openlineage_events = OpenLineageTestOperator(
         task_id="check_openlineage_events",
         file_path=str(Path(__file__).parent / "resources" / "openlineage" / 
"bigquery_queries_async.json"),
@@ -272,7 +317,14 @@ with DAG(
     insert_query_job >> get_data >> get_data_result
     insert_query_job >> execute_query_save >> bigquery_execute_multi_query
     insert_query_job >> execute_long_running_query >> check_value >> 
check_interval
-    [check_count, check_interval, bigquery_execute_multi_query, 
get_data_result] >> delete_dataset
+    insert_query_job >> create_slow_view >> check_value_long_running >> 
check_interval_long_running
+    [
+        check_count,
+        check_interval,
+        check_interval_long_running,
+        bigquery_execute_multi_query,
+        get_data_result,
+    ] >> delete_dataset
     delete_dataset >> check_openlineage_events
 
     from tests_common.test_utils.watcher import watcher

Reply via email to