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 diff --git a/tox.ini b/tox.ini index 7a89bd37..0b995699 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,7 +173,8 @@ deps = commands = dbt clean dbt deps - ; 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