diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e6e472425..3702cb56594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Add support for impersonating a service account using `impersonate_service_account` in the BigQuery profile configuration ([#2677](https://github.com/fishtown-analytics/dbt/issues/2677)) ([docs](https://docs.getdbt.com/reference/warehouse-profiles/bigquery-profile#service-account-impersonation)) - Macros in the current project can override internal dbt macros that are called through `execute_macros`. ([#2301](https://github.com/fishtown-analytics/dbt/issues/2301), [#2686](https://github.com/fishtown-analytics/dbt/pull/2686)) - Add state:modified and state:new selectors ([#2641](https://github.com/fishtown-analytics/dbt/issues/2641), [#2695](https://github.com/fishtown-analytics/dbt/pull/2695)) +- Added `--defer` flag for `dbt test` as well. ([#2701](https://github.com/fishtown-analytics/dbt/issues/2701), [#2706](https://github.com/fishtown-analytics/dbt/pull/2706)) Contributors: - [@bbhoss](https://github.com/bbhoss) ([#2677](https://github.com/fishtown-analytics/dbt/pull/2677)) diff --git a/core/dbt/main.py b/core/dbt/main.py index 3efdc46d667..6653ee74c53 100644 --- a/core/dbt/main.py +++ b/core/dbt/main.py @@ -444,6 +444,21 @@ def _build_snapshot_subparser(subparsers, base_subparser): return sub +def _add_defer_argument(*subparsers): + for sub in subparsers: + sub.add_optional_argument_inverse( + '--defer', + enable_help=''' + If set, defer to the state variable for resolving unselected nodes. + ''', + disable_help=''' + If set, do not defer to the state variable for resolving unselected + nodes. + ''', + default=flags.DEFER_MODE, + ) + + def _build_run_subparser(subparsers, base_subparser): run_sub = subparsers.add_parser( 'run', @@ -461,19 +476,6 @@ def _build_run_subparser(subparsers, base_subparser): ''' ) - # this is a "dbt run"-only thing, for now - run_sub.add_optional_argument_inverse( - '--defer', - enable_help=''' - If set, defer to the state variable for resolving unselected nodes. - ''', - disable_help=''' - If set, do not defer to the state variable for resolving unselected - nodes. - ''', - default=flags.DEFER_MODE, - ) - run_sub.set_defaults(cls=run_task.RunTask, which='run', rpc_method='run') return run_sub @@ -987,6 +989,8 @@ def parse_args(args, cls=DBTArgumentParser): # list_sub sets up its own arguments. _add_selection_arguments(run_sub, compile_sub, generate_sub, test_sub) _add_selection_arguments(snapshot_sub, seed_sub, models_name='select') + # --defer + _add_defer_argument(run_sub, test_sub) # --full-refresh _add_table_mutability_arguments(run_sub, compile_sub) diff --git a/core/dbt/task/seed.py b/core/dbt/task/seed.py index 47a89d1a5db..fdc9c71fce8 100644 --- a/core/dbt/task/seed.py +++ b/core/dbt/task/seed.py @@ -37,6 +37,10 @@ def print_result_line(self, result): class SeedTask(RunTask): + def defer_to_manifest(self, selected_uids): + # seeds don't defer + return + def raise_on_first_error(self): return False diff --git a/core/dbt/task/snapshot.py b/core/dbt/task/snapshot.py index edc5ba9b277..863dba99fbe 100644 --- a/core/dbt/task/snapshot.py +++ b/core/dbt/task/snapshot.py @@ -22,6 +22,10 @@ class SnapshotTask(RunTask): def raise_on_first_error(self): return False + def defer_to_manifest(self, selected_uids): + # snapshots don't defer + return + def get_node_selector(self): if self.manifest is None or self.graph is None: raise InternalException( diff --git a/test/integration/062_defer_state_test/test_defer_state.py b/test/integration/062_defer_state_test/test_defer_state.py index 892ef863ee9..09a1671aa74 100644 --- a/test/integration/062_defer_state_test/test_defer_state.py +++ b/test/integration/062_defer_state_test/test_defer_state.py @@ -55,13 +55,22 @@ def run_and_defer(self): results = self.run_dbt(['run']) assert len(results) == 2 assert not any(r.node.deferred for r in results) + results = self.run_dbt(['test']) + assert len(results) == 2 # copy files over from the happy times when we had a good target self.copy_state() - # no state, still fails + # test tests first, because run will change things + # no state, wrong schema, failure. + self.run_dbt(['test', '--target', 'otherschema'], expect_pass=False) + + # no state, run also fails self.run_dbt(['run', '--target', 'otherschema'], expect_pass=False) + # defer test, it succeeds + results = self.run_dbt(['test', '-m', 'view_model+', '--state', 'state', '--defer', '--target', 'otherschema']) + # with state it should work though results = self.run_dbt(['run', '-m', 'view_model', '--state', 'state', '--defer', '--target', 'otherschema']) assert self.other_schema not in results[0].node.injected_sql @@ -106,14 +115,11 @@ def run_switchdirs_defer(self): def test_postgres_state_changetarget(self): self.run_and_defer() # these should work without --defer! - self.run_dbt(['test']) self.run_dbt(['snapshot']) # make sure these commands don't work with --defer with pytest.raises(SystemExit): self.run_dbt(['seed', '--defer']) - with pytest.raises(SystemExit): - self.run_dbt(['test', '--defer']) with pytest.raises(SystemExit): self.run_dbt(['snapshot', '--defer'])