From eb1ba8967201a0b0662dd55f486a12f19e1fae5a Mon Sep 17 00:00:00 2001 From: Michael Carlone Date: Mon, 3 Aug 2026 17:54:28 -0400 Subject: [PATCH 1/3] Warm up Snowflake integration legs so mart assertions have data The per-commit test schema starts empty and upload_results only fires in on-run-end, after tests. A single dbt build therefore asserts against empty marts, making assert_consumption_daily_has_smb, assert_run_health_daily_has_invocations and assert_model_performance_valid unpassable on a fresh schema. Run a test-excluded build first to populate the source tables, then the real build. Adds ~43s per Snowflake leg. --- tox.ini | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tox.ini b/tox.ini index 7a89bd37..beabe6f0 100644 --- a/tox.ini +++ b/tox.ini @@ -114,12 +114,30 @@ commands = sqlfluff fix models --ignore parsing ## Integration Tests ### Snowflake ############################################################################################# +# Snowflake legs run `dbt build` TWICE, and the first pass excludes tests. +# +# The schema is per-commit (`dbt_artifacts_test_commit_..._` in +# profiles.yml), so every CI run starts against an empty schema. The source +# tables are created empty by the run itself and are only populated by +# `upload_results` in `on-run-end`, which fires AFTER all tests. On a single +# build the consumption/observability marts are therefore empty when their +# singular tests execute, and the three non-emptiness assertions +# (assert_consumption_daily_has_smb, assert_run_health_daily_has_invocations, +# assert_model_performance_valid) cannot pass. +# +# The first build populates the source tables via its own on-run-end hook; +# the second asserts against that data. Tests are excluded from the first +# pass or it would fail on those same three before any data lands. +# Only the CI-active envs (latest / 1.11 / 1.10) get the warm-up — +# `--exclude-resource-type` needs dbt-core >= 1.8, and 1.3-1.8 are +# local-debug-only (see the release.yml version-matrix comment). [testenv:integration_snowflake] changedir = integration_test_project deps = dbt-snowflake<2.0.0 commands = dbt clean dbt deps + dbt build --target snowflake --exclude-resource-type test dbt build --target snowflake [testenv:integration_snowflake_1_11_0] @@ -133,6 +151,7 @@ deps = commands = dbt clean dbt deps + dbt build --target snowflake --exclude-resource-type test dbt build --target snowflake [testenv:integration_snowflake_1_10_0] @@ -143,6 +162,7 @@ deps = commands = dbt clean dbt deps + dbt build --target snowflake --exclude-resource-type test dbt build --target snowflake [testenv:integration_snowflake_1_9_0] @@ -153,6 +173,7 @@ deps = commands = dbt clean dbt deps + ; dbt build --target snowflake --exclude-resource-type test ; dbt build --target snowflake [testenv:integration_snowflake_1_8_0] From 16b56c86ad55e7686f072f86fcaa58ca7c28348b Mon Sep 17 00:00:00 2001 From: Michael Carlone Date: Mon, 3 Aug 2026 17:58:58 -0400 Subject: [PATCH 2/3] Re-enable the Snowflake dbt 1.9 integration leg The build command was commented out in 151d13c, a broad tox refactor that reordered every env; no reason was recorded and the neighbouring 1.3-1.8 envs kept theirs. release.yml already schedules a snowflake/1_9_0 slot, so that slot has been running clean+deps and reporting green while validating nothing. We advertise 1.9 support via require-dbt-version, so it should be tested. Verified green with no other changes needed: PASS=129 ERROR=0. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index beabe6f0..0b995699 100644 --- a/tox.ini +++ b/tox.ini @@ -173,8 +173,8 @@ deps = commands = dbt clean dbt deps - ; dbt build --target snowflake --exclude-resource-type test - ; dbt build --target snowflake + dbt build --target snowflake --exclude-resource-type test + dbt build --target snowflake [testenv:integration_snowflake_1_8_0] changedir = integration_test_project From 81c9db02ee43aec9cb8359cc6b64bffe9983811e Mon Sep 17 00:00:00 2001 From: Michael Carlone Date: Mon, 3 Aug 2026 17:58:58 -0400 Subject: [PATCH 3/3] Make assert_lineage_edges_cover_models fail on an empty mart The test's comment claimed lineage_edges must be non-empty, but the only branch keyed off models_with_deps, which is itself empty when the mart is empty -- so it passed vacuously on a fresh schema. Add an explicit empty_mart branch. Verified it now fails (Got 1 result) on a single build against a fresh schema, and passes with the warm-up in place. --- .../assert_lineage_edges_cover_models.sql | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/integration_test_project/tests/assert_lineage_edges_cover_models.sql b/integration_test_project/tests/assert_lineage_edges_cover_models.sql index f0dd335d..8e8b3a19 100644 --- a/integration_test_project/tests/assert_lineage_edges_cover_models.sql +++ b/integration_test_project/tests/assert_lineage_edges_cover_models.sql @@ -1,7 +1,10 @@ {{ config(enabled = target.type == "snowflake") }} -- lineage_edges must be non-empty, and every model in the latest graph -- state that declares dependencies must appear as a child of >= 1 edge. --- Fails (returns rows) for any model-with-deps that has no edge. +-- Fails (returns rows) for any model-with-deps that has no edge, and for an +-- empty mart. The empty-mart branch matters: without it this test passes +-- vacuously when the mart has no rows at all, since models_with_deps is +-- itself empty in that case. with latest_models as ( select node_id @@ -22,9 +25,20 @@ models_with_deps as ( edge_children as ( select distinct child_node_id from {{ ref("dim_dbt__lineage_edges") }} +), + +edge_count as ( + select count(*) as row_count + from {{ ref("dim_dbt__lineage_edges") }} ) -select models_with_deps.node_id as model_missing_edge +select 'model_missing_edge: ' || models_with_deps.node_id as issue from models_with_deps left join edge_children on models_with_deps.node_id = edge_children.child_node_id where edge_children.child_node_id is null + +union all + +select 'empty_mart' as issue +from edge_count +where row_count = 0