diff --git a/.changes/unreleased/Fixes-20240613-183117.yaml b/.changes/unreleased/Fixes-20240613-183117.yaml new file mode 100644 index 00000000000..14b1ee2bf08 --- /dev/null +++ b/.changes/unreleased/Fixes-20240613-183117.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: DOn't warn on `unit_test` config paths that are properly used +time: 2024-06-13T18:31:17.486497-07:00 +custom: + Author: QMalcolm + Issue: "10311" diff --git a/core/dbt/contracts/graph/manifest.py b/core/dbt/contracts/graph/manifest.py index 7138087d446..43209b6f9eb 100644 --- a/core/dbt/contracts/graph/manifest.py +++ b/core/dbt/contracts/graph/manifest.py @@ -986,6 +986,7 @@ def get_resource_fqns(self) -> Mapping[str, PathSet]: self.metrics.values(), self.semantic_models.values(), self.saved_queries.values(), + self.unit_tests.values(), ) for resource in all_resources: resource_type_plural = resource.resource_type.pluralize() diff --git a/tests/unit/graph/test_selector_methods.py b/tests/unit/graph/test_selector_methods.py index 58e414baafc..a796aadd79c 100644 --- a/tests/unit/graph/test_selector_methods.py +++ b/tests/unit/graph/test_selector_methods.py @@ -113,6 +113,7 @@ def test_select_fqn(manifest): assert search_manifest_using_method(manifest, method, "*.*.*_model") == { "mynamespace.union_model", "mynamespace.ephemeral_model", + "test_semantic_model", "union_model", "unit_test_table_model", } diff --git a/tests/unit/parser/test_manifest.py b/tests/unit/parser/test_manifest.py index 6a643e444f3..4aea05b948d 100644 --- a/tests/unit/parser/test_manifest.py +++ b/tests/unit/parser/test_manifest.py @@ -4,9 +4,13 @@ from dbt.contracts.graph.manifest import Manifest -from dbt.parser.manifest import ManifestLoader +from dbt.events.types import UnusedResourceConfigPath +from dbt.parser.manifest import ManifestLoader, _warn_for_unused_resource_config_paths from dbt.config import RuntimeConfig from dbt.flags import set_from_args +from dbt_common.events.event_manager_client import add_callback_to_manager +from tests.functional.utils import EventCatcher +from tests.unit.utils import config_from_parts_or_dicts @pytest.fixture @@ -91,3 +95,73 @@ def test_partial_parse_safe_update_project_parser_files_partially( assert "full_reparse_reason" in exc_info assert "KeyError: 'Whoopsie!'" == exc_info["exception"] assert isinstance(exc_info["code"], str) or isinstance(exc_info["code"], type(None)) + + +class TestWarnUnusedConfigs: + @pytest.fixture + def runtime_config(self) -> RuntimeConfig: + profile_cfg = { + "outputs": { + "test": { + "type": "postgres", + "dbname": "postgres", + "user": "test", + "host": "test", + "pass": "test", + "port": 5432, + "schema": "test", + }, + }, + "target": "test", + } + + project_cfg = { + "name": "query_headers", + "version": "0.1", + "profile": "test", + "config-version": 2, + } + + return config_from_parts_or_dicts(project=project_cfg, profile=profile_cfg) + + @pytest.mark.parametrize( + "resource_type,path,expect_used", + [ + ("data_tests", "unused_path", False), + ("data_tests", "minimal", True), + ("metrics", "unused_path", False), + ("metrics", "test", True), + ("models", "unused_path", False), + ("models", "pkg", True), + ("saved_queries", "unused_path", False), + ("saved_queries", "test", True), + ("seeds", "unused_path", False), + ("seeds", "pkg", True), + ("semantic_models", "unused_path", False), + ("semantic_models", "test", True), + ("sources", "unused_path", False), + ("sources", "pkg", True), + ("unit_tests", "unused_path", False), + ("unit_tests", "pkg", True), + ], + ) + def test_warn_for_unused_resource_config_paths( + self, + resource_type: str, + path: str, + expect_used: bool, + manifest: Manifest, + runtime_config: RuntimeConfig, + ) -> None: + catcher = EventCatcher(UnusedResourceConfigPath) + add_callback_to_manager(catcher.catch) + + setattr(runtime_config, resource_type, {path: {"+materialized": "table"}}) + + _warn_for_unused_resource_config_paths(manifest=manifest, config=runtime_config) + + if expect_used: + assert len(catcher.caught_events) == 0 + else: + assert len(catcher.caught_events) == 1 + assert f"{resource_type}.{path}" in str(catcher.caught_events[0].data) diff --git a/tests/unit/utils/manifest.py b/tests/unit/utils/manifest.py index d1210694762..2596235dcf8 100644 --- a/tests/unit/utils/manifest.py +++ b/tests/unit/utils/manifest.py @@ -1,4 +1,5 @@ from argparse import Namespace +from typing import List import pytest from dbt.artifacts.resources.v1.model import ModelConfig @@ -32,6 +33,8 @@ TestConfig, TestMetadata, RefArgs, + WhereFilter, + WhereFilterIntersection, ) from dbt.contracts.graph.unparsed import ( UnitTestInputFixture, @@ -854,7 +857,11 @@ def saved_query() -> SavedQuery: query_params=QueryParams( metrics=["my_metric"], group_by=[], - where=None, + where=WhereFilterIntersection( + where_filters=[ + WhereFilter(where_sql_template="1=1"), + ] + ), ), exports=[], unique_id=f"saved_query.{pkg}.{name}", @@ -976,13 +983,18 @@ def unit_tests(unit_test_table_model) -> list: @pytest.fixture -def metrics() -> list: - return [] +def metrics(metric: Metric) -> List[Metric]: + return [metric] + + +@pytest.fixture +def semantic_models(semantic_model: SemanticModel) -> List[SemanticModel]: + return [semantic_model] @pytest.fixture -def semantic_models() -> list: - return [] +def saved_queries(saved_query: SavedQuery) -> List[SavedQuery]: + return [saved_query] @pytest.fixture @@ -1001,6 +1013,7 @@ def manifest( metrics, semantic_models, files, + saved_queries, ) -> Manifest: manifest = Manifest( nodes={n.unique_id: n for n in nodes}, @@ -1012,6 +1025,7 @@ def manifest( files=files, exposures={}, metrics={m.unique_id: m for m in metrics}, + saved_queries={s.unique_id: s for s in saved_queries}, disabled={}, selectors={}, groups={},