Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename tests: singular + generic #3880

Merged
merged 6 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
## dbt 1.0.0 (Release TBD)

### Breaking changes

- The two type of test definitions are now "singular" and "generic" (instead of "data" and "schema", respectively). The `test_type:` selection method accepts `test_type:singular` and `test_type:generic`. (It will also accept `test_type:schema` and `test_type:data` for backwards compatibility) ([#3234](https://github.com/dbt-labs/dbt/issues/3234), [#3880](https://github.com/dbt-labs/dbt/pull/3880)). **Not backwards compatible:** The `--data` and `--schema` flags to `dbt test` are no longer supported, and tests no longer have the tags `'data'` and `'schema'` automatically applied.

### Features
- Normalize global CLI arguments/flags ([#2990](https://github.com/dbt-labs/dbt/issues/2990), [#3839](https://github.com/dbt-labs/dbt/pull/3839))
- Generic test FQNs have changed to include the relative path, resource, and column (if applicable) where they are defined. This makes it easier to configure them from the `tests` block in `dbt_project.yml` ([#3259](https://github.com/dbt-labs/dbt/pull/3259), [#3880](https://github.com/dbt-labs/dbt/pull/3880)

### Fixes
- Add generic tests defined on sources to the manifest once, not twice ([#3347](https://github.com/dbt-labs/dbt/issues/3347), [#3880](https://github.com/dbt-labs/dbt/pull/3880))

### Under the hood

Expand Down
10 changes: 5 additions & 5 deletions core/dbt/clients/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
)

from dbt.clients._jinja_blocks import BlockIterator, BlockData, BlockTag
from dbt.contracts.graph.compiled import CompiledSchemaTestNode
from dbt.contracts.graph.parsed import ParsedSchemaTestNode
from dbt.contracts.graph.compiled import CompiledGenericTestNode
from dbt.contracts.graph.parsed import ParsedGenericTestNode
from dbt.exceptions import (
InternalException, raise_compiler_error, CompilationException,
invalid_materialization_argument, MacroReturn, JinjaRenderingException,
Expand Down Expand Up @@ -627,12 +627,12 @@ def extract_toplevel_blocks(
)


SCHEMA_TEST_KWARGS_NAME = '_dbt_schema_test_kwargs'
GENERIC_TEST_KWARGS_NAME = '_dbt_generic_test_kwargs'


def add_rendered_test_kwargs(
context: Dict[str, Any],
node: Union[ParsedSchemaTestNode, CompiledSchemaTestNode],
node: Union[ParsedGenericTestNode, CompiledGenericTestNode],
capture_macros: bool = False,
) -> None:
"""Render each of the test kwargs in the given context using the native
Expand Down Expand Up @@ -662,4 +662,4 @@ def _convert_function(
return value

kwargs = deep_map(_convert_function, node.test_metadata.kwargs)
context[SCHEMA_TEST_KWARGS_NAME] = kwargs
context[GENERIC_TEST_KWARGS_NAME] = kwargs
4 changes: 2 additions & 2 deletions core/dbt/compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from dbt.contracts.graph.manifest import Manifest, UniqueID
from dbt.contracts.graph.compiled import (
COMPILED_TYPES,
CompiledSchemaTestNode,
CompiledGenericTestNode,
GraphMemberNode,
InjectedCTE,
ManifestNode,
Expand Down Expand Up @@ -181,7 +181,7 @@ def _create_node_context(
node, self.config, manifest
)
context.update(extra_context)
if isinstance(node, CompiledSchemaTestNode):
if isinstance(node, CompiledGenericTestNode):
# for test nodes, add a special keyword args value to the context
jinja.add_rendered_test_kwargs(context, node)

Expand Down
2 changes: 1 addition & 1 deletion core/dbt/contracts/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ParseFileType(StrEnum):
ParseFileType.Model: 'ModelParser',
ParseFileType.Snapshot: 'SnapshotParser',
ParseFileType.Analysis: 'AnalysisParser',
ParseFileType.Test: 'DataTestParser',
ParseFileType.Test: 'SingularTestParser',
ParseFileType.Seed: 'SeedParser',
ParseFileType.Documentation: 'DocumentationParser',
ParseFileType.Schema: 'SchemaParser',
Expand Down
28 changes: 14 additions & 14 deletions core/dbt/contracts/graph/compiled.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
HasTestMetadata,
ParsedNode,
ParsedAnalysisNode,
ParsedDataTestNode,
ParsedSingularTestNode,
ParsedHookNode,
ParsedModelNode,
ParsedExposure,
ParsedResource,
ParsedRPCNode,
ParsedSchemaTestNode,
ParsedGenericTestNode,
ParsedSeedNode,
ParsedSnapshotNode,
ParsedSourceDefinition,
Expand Down Expand Up @@ -107,16 +107,16 @@ class CompiledSnapshotNode(CompiledNode):


@dataclass
class CompiledDataTestNode(CompiledNode):
class CompiledSingularTestNode(CompiledNode):
resource_type: NodeType = field(metadata={'restrict': [NodeType.Test]})
# Was not able to make mypy happy and keep the code working. We need to
# refactor the various configs.
config: TestConfig = field(default_factory=TestConfig) # type:ignore


@dataclass
class CompiledSchemaTestNode(CompiledNode, HasTestMetadata):
# keep this in sync with ParsedSchemaTestNode!
class CompiledGenericTestNode(CompiledNode, HasTestMetadata):
# keep this in sync with ParsedGenericTestNode!
resource_type: NodeType = field(metadata={'restrict': [NodeType.Test]})
column_name: Optional[str] = None
# Was not able to make mypy happy and keep the code working. We need to
Expand All @@ -134,7 +134,7 @@ def same_contents(self, other) -> bool:
)


CompiledTestNode = Union[CompiledDataTestNode, CompiledSchemaTestNode]
CompiledTestNode = Union[CompiledSingularTestNode, CompiledGenericTestNode]


PARSED_TYPES: Dict[Type[CompiledNode], Type[ParsedResource]] = {
Expand All @@ -144,8 +144,8 @@ def same_contents(self, other) -> bool:
CompiledRPCNode: ParsedRPCNode,
CompiledSeedNode: ParsedSeedNode,
CompiledSnapshotNode: ParsedSnapshotNode,
CompiledDataTestNode: ParsedDataTestNode,
CompiledSchemaTestNode: ParsedSchemaTestNode,
CompiledSingularTestNode: ParsedSingularTestNode,
CompiledGenericTestNode: ParsedGenericTestNode,
}


Expand All @@ -156,8 +156,8 @@ def same_contents(self, other) -> bool:
ParsedRPCNode: CompiledRPCNode,
ParsedSeedNode: CompiledSeedNode,
ParsedSnapshotNode: CompiledSnapshotNode,
ParsedDataTestNode: CompiledDataTestNode,
ParsedSchemaTestNode: CompiledSchemaTestNode,
ParsedSingularTestNode: CompiledSingularTestNode,
ParsedGenericTestNode: CompiledGenericTestNode,
}


Expand Down Expand Up @@ -185,22 +185,22 @@ def parsed_instance_for(compiled: CompiledNode) -> ParsedResource:

NonSourceCompiledNode = Union[
CompiledAnalysisNode,
CompiledDataTestNode,
CompiledSingularTestNode,
CompiledModelNode,
CompiledHookNode,
CompiledRPCNode,
CompiledSchemaTestNode,
CompiledGenericTestNode,
CompiledSeedNode,
CompiledSnapshotNode,
]

NonSourceParsedNode = Union[
ParsedAnalysisNode,
ParsedDataTestNode,
ParsedSingularTestNode,
ParsedHookNode,
ParsedModelNode,
ParsedRPCNode,
ParsedSchemaTestNode,
ParsedGenericTestNode,
ParsedSeedNode,
ParsedSnapshotNode,
]
Expand Down
14 changes: 7 additions & 7 deletions core/dbt/contracts/graph/parsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ def _deserialize(cls, dct: Dict[str, int]):
return ParsedRPCNode.from_dict(dct)
elif resource_type == 'test':
if 'test_metadata' in dct:
return ParsedSchemaTestNode.from_dict(dct)
return ParsedGenericTestNode.from_dict(dct)
else:
return ParsedDataTestNode.from_dict(dct)
return ParsedSingularTestNode.from_dict(dct)
elif resource_type == 'operation':
return ParsedHookNode.from_dict(dct)
elif resource_type == 'seed':
Expand Down Expand Up @@ -412,16 +412,16 @@ class HasTestMetadata(dbtClassMixin):


@dataclass
class ParsedDataTestNode(ParsedNode):
class ParsedSingularTestNode(ParsedNode):
resource_type: NodeType = field(metadata={'restrict': [NodeType.Test]})
# Was not able to make mypy happy and keep the code working. We need to
# refactor the various configs.
config: TestConfig = field(default_factory=TestConfig) # type: ignore


@dataclass
class ParsedSchemaTestNode(ParsedNode, HasTestMetadata):
# keep this in sync with CompiledSchemaTestNode!
class ParsedGenericTestNode(ParsedNode, HasTestMetadata):
# keep this in sync with CompiledGenericTestNode!
resource_type: NodeType = field(metadata={'restrict': [NodeType.Test]})
column_name: Optional[str] = None
# Was not able to make mypy happy and keep the code working. We need to
Expand Down Expand Up @@ -773,11 +773,11 @@ def same_contents(self, old: Optional['ParsedExposure']) -> bool:

ManifestNodes = Union[
ParsedAnalysisNode,
ParsedDataTestNode,
ParsedSingularTestNode,
ParsedHookNode,
ParsedModelNode,
ParsedRPCNode,
ParsedSchemaTestNode,
ParsedGenericTestNode,
ParsedSeedNode,
ParsedSnapshotNode,
]
Expand Down
1 change: 0 additions & 1 deletion core/dbt/graph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
)
from .cli import ( # noqa: F401
parse_difference,
parse_test_selectors,
parse_from_selectors_definition,
)
from .queue import GraphQueue # noqa: F401
Expand Down
33 changes: 0 additions & 33 deletions core/dbt/graph/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@

DEFAULT_INCLUDES: List[str] = ['fqn:*', 'source:*', 'exposure:*']
DEFAULT_EXCLUDES: List[str] = []
DATA_TEST_SELECTOR: str = 'test_type:data'
SCHEMA_TEST_SELECTOR: str = 'test_type:schema'


def parse_union(
Expand Down Expand Up @@ -72,37 +70,6 @@ def parse_difference(
return SelectionDifference(components=[included, excluded])


def parse_test_selectors(
data: bool, schema: bool, base: SelectionSpec
) -> SelectionSpec:
union_components = []

if data:
union_components.append(
SelectionCriteria.from_single_spec(DATA_TEST_SELECTOR)
)
if schema:
union_components.append(
SelectionCriteria.from_single_spec(SCHEMA_TEST_SELECTOR)
)

intersect_with: SelectionSpec
if not union_components:
return base
elif len(union_components) == 1:
intersect_with = union_components[0]
else: # data and schema tests
intersect_with = SelectionUnion(
components=union_components,
expect_exists=True,
raw=[DATA_TEST_SELECTOR, SCHEMA_TEST_SELECTOR],
)

return SelectionIntersection(
components=[base, intersect_with], expect_exists=True
)


RawDefinition = Union[str, Dict[str, Any]]


Expand Down
21 changes: 11 additions & 10 deletions core/dbt/graph/selector_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
from .graph import UniqueId

from dbt.contracts.graph.compiled import (
CompiledDataTestNode,
CompiledSchemaTestNode,
CompiledSingularTestNode,
CompiledGenericTestNode,
CompileResultNode,
ManifestNode,
)
from dbt.contracts.graph.manifest import Manifest, WritableManifest
from dbt.contracts.graph.parsed import (
HasTestMetadata,
ParsedDataTestNode,
ParsedSingularTestNode,
ParsedExposure,
ParsedSchemaTestNode,
ParsedGenericTestNode,
ParsedSourceDefinition,
)
from dbt.contracts.state import PreviousState
Expand Down Expand Up @@ -361,14 +361,15 @@ def search(
self, included_nodes: Set[UniqueId], selector: str
) -> Iterator[UniqueId]:
search_types: Tuple[Type, ...]
if selector == 'schema':
search_types = (ParsedSchemaTestNode, CompiledSchemaTestNode)
elif selector == 'data':
search_types = (ParsedDataTestNode, CompiledDataTestNode)
# continue supporting 'schema' + 'data' for backwards compatibility
if selector in ('generic', 'schema'):
search_types = (ParsedGenericTestNode, CompiledGenericTestNode)
elif selector in ('singular', 'data'):
search_types = (ParsedSingularTestNode, CompiledSingularTestNode)
else:
raise RuntimeException(
f'Invalid test type selector {selector}: expected "data" or '
'"schema"'
f'Invalid test type selector {selector}: expected "generic" or '
'"singular"'
)

for node, real_node in self.parsed_nodes(included_nodes):
Expand Down
14 changes: 0 additions & 14 deletions core/dbt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,20 +723,6 @@ def _build_test_subparser(subparsers, base_subparser):
Runs tests on data in deployed models. Run this after `dbt run`
'''
)
sub.add_argument(
'--data',
action='store_true',
help='''
Run data tests defined in "tests" directory.
'''
)
sub.add_argument(
'--schema',
action='store_true',
help='''
Run constraint validations from schema.yml files
'''
)
sub.add_argument(
'-x',
'--fail-fast',
Expand Down
4 changes: 2 additions & 2 deletions core/dbt/parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .analysis import AnalysisParser # noqa
from .base import Parser, ConfiguredParser # noqa
from .data_test import DataTestParser # noqa
from .singular_test import SingularTestParser # noqa
from .docs import DocumentationParser # noqa
from .hooks import HookParser # noqa
from .macros import MacroParser # noqa
Expand All @@ -10,6 +10,6 @@
from .snapshots import SnapshotParser # noqa

from . import ( # noqa
analysis, base, data_test, docs, hooks, macros, models, schemas,
analysis, base, singular_test, docs, hooks, macros, models, schemas,
snapshots
)
26 changes: 0 additions & 26 deletions core/dbt/parser/data_test.py

This file was deleted.

Loading