Skip to content

Commit

Permalink
Limit data test deprecation warning to root_project (#10375)
Browse files Browse the repository at this point in the history
  • Loading branch information
gshank authored Jun 28, 2024
1 parent d936a63 commit c215697
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 23 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240627-154448.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Limit data_tests deprecation to root_project
time: 2024-06-27T15:44:48.579869-04:00
custom:
Author: gshank
Issue: "9835"
25 changes: 13 additions & 12 deletions core/dbt/contracts/graph/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ def get_full_source_name(self):
def get_source_representation(self):
return f'source("{self.source.name}", "{self.table.name}")'

def validate_data_tests(self):
def validate_data_tests(self, is_root_project: bool):
"""
sources parse tests differently than models, so we need to do some validation
here where it's done in the PatchParser for other nodes
Expand All @@ -1131,11 +1131,12 @@ def validate_data_tests(self):
"Invalid test config: cannot have both 'tests' and 'data_tests' defined"
)
if self.tests:
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
if is_root_project:
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
self.data_tests.extend(self.tests)
self.tests.clear()

Expand All @@ -1146,11 +1147,12 @@ def validate_data_tests(self):
"Invalid test config: cannot have both 'tests' and 'data_tests' defined"
)
if column.tests:
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
if is_root_project:
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
column.data_tests.extend(column.tests)
column.tests.clear()

Expand All @@ -1168,7 +1170,6 @@ def columns(self) -> Sequence[UnparsedColumn]:
return [] if self.table.columns is None else self.table.columns

def get_tests(self) -> Iterator[Tuple[Dict[str, Any], Optional[UnparsedColumn]]]:
self.validate_data_tests()
for data_test in self.data_tests:
yield normalize_test(data_test), None

Expand Down
27 changes: 17 additions & 10 deletions core/dbt/parser/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,37 +544,44 @@ def normalize_contract_attribute(self, data, path):
def normalize_access_attribute(self, data, path):
return self.normalize_attribute(data, path, "access")

@property
def is_root_project(self):
if self.root_project.project_name == self.project.project_name:
return True
return False

def validate_data_tests(self, data):
# Rename 'tests' -> 'data_tests' at both model-level and column-level
# Raise a validation error if the user has defined both names
def validate_and_rename(data):
def validate_and_rename(data, is_root_project: bool):
if data.get("tests"):
if "tests" in data and "data_tests" in data:
raise ValidationError(
"Invalid test config: cannot have both 'tests' and 'data_tests' defined"
)
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
if is_root_project:
deprecations.warn(
"project-test-config",
deprecated_path="tests",
exp_path="data_tests",
)
data["data_tests"] = data.pop("tests")

# model-level tests
validate_and_rename(data)
validate_and_rename(data, self.is_root_project)

# column-level tests
if data.get("columns"):
for column in data["columns"]:
validate_and_rename(column)
validate_and_rename(column, self.is_root_project)

# versioned models
if data.get("versions"):
for version in data["versions"]:
validate_and_rename(version)
validate_and_rename(version, self.is_root_project)
if version.get("columns"):
for column in version["columns"]:
validate_and_rename(column)
validate_and_rename(column, self.is_root_project)

def patch_node_config(self, node, patch):
if "access" in patch.config:
Expand Down
2 changes: 2 additions & 0 deletions core/dbt/parser/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ def get_generic_test_parser_for(self, package_name: str) -> "SchemaGenericTestPa
return generic_test_parser

def get_source_tests(self, target: UnpatchedSourceDefinition) -> Iterable[GenericTestNode]:
is_root_project = True if self.root_project.project_name == target.package_name else False
target.validate_data_tests(is_root_project)
for data_test, column in target.get_tests():
yield self.parse_source_test(
target=target,
Expand Down
41 changes: 40 additions & 1 deletion tests/functional/dependencies/test_local_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
import dbt.exceptions
import dbt_common.exceptions
import dbt_common.semver as semver
from dbt.tests.util import check_relations_equal, run_dbt, run_dbt_and_capture
from dbt import deprecations
from dbt.tests.util import (
check_relations_equal,
run_dbt,
run_dbt_and_capture,
write_file,
)
from tests.functional.utils import up_one

# todo: make self.unique_schema to fixture
Expand Down Expand Up @@ -353,3 +359,36 @@ def test_local_dependency_same_name_sneaky(self, prepare_dependencies, project):

# needed to avoid compilation errors from duplicate package names in test autocleanup
run_dbt(["clean"])


source_with_tests = """
sources:
- name: my_source
schema: invalid_schema
tables:
- name: my_table
- name: seed_source
schema: "{{ var('schema_override', target.schema) }}"
tables:
- name: "seed"
identifier: "seed_subpackage_generate_alias_name"
columns:
- name: id
tests:
- unique
- not_null
"""


class TestDependencyTestsConfig(BaseDependencyTest):
def test_dependency_tests_config(self, project):
run_dbt(["deps"])
# Write a file to local_dependency with a "tests" config
write_file(
source_with_tests, project.project_root, "local_dependency", "models", "schema.yml"
)
run_dbt(["parse"])
# Check that project-test-config is NOT in active deprecations, since "tests" is only
# in a dependent project.
expected = set()
assert expected == deprecations.active_deprecations

0 comments on commit c215697

Please sign in to comment.