|
| 1 | +import typing as t |
1 | 2 | from pathlib import Path |
2 | 3 | import pytest |
3 | 4 | from sqlmesh_dbt.operations import create |
4 | 5 | from sqlmesh.utils import yaml |
5 | 6 | from sqlmesh.utils.errors import SQLMeshError |
6 | 7 | import time_machine |
| 8 | +from sqlmesh.core.console import NoopConsole |
| 9 | +from sqlmesh.core.plan import PlanBuilder |
7 | 10 |
|
8 | 11 | pytestmark = pytest.mark.slow |
9 | 12 |
|
10 | 13 |
|
| 14 | +class PlanCapturingConsole(NoopConsole): |
| 15 | + def plan( |
| 16 | + self, |
| 17 | + plan_builder: PlanBuilder, |
| 18 | + auto_apply: bool, |
| 19 | + default_catalog: t.Optional[str], |
| 20 | + no_diff: bool = False, |
| 21 | + no_prompts: bool = False, |
| 22 | + ) -> None: |
| 23 | + self.plan_builder = plan_builder |
| 24 | + self.auto_apply = auto_apply |
| 25 | + self.default_catalog = default_catalog |
| 26 | + self.no_diff = no_diff |
| 27 | + self.no_prompts = no_prompts |
| 28 | + |
| 29 | + # normal console starts applying the plan here; we dont because we just want to capture the parameters |
| 30 | + # and check they were set correctly |
| 31 | + |
| 32 | + |
11 | 33 | def test_create_sets_and_persists_default_start_date(jaffle_shop_duckdb: Path): |
12 | 34 | with time_machine.travel("2020-01-02 00:00:00 UTC"): |
13 | 35 | from sqlmesh.utils.date import yesterday_ds, to_ds |
@@ -83,3 +105,136 @@ def test_create_can_set_project_variables(jaffle_shop_duckdb: Path): |
83 | 105 | query = test_model.render_query() |
84 | 106 | assert query is not None |
85 | 107 | assert query.sql() == "SELECT 'bar' AS \"a\"" |
| 108 | + |
| 109 | + |
| 110 | +def test_run_option_mapping(jaffle_shop_duckdb: Path): |
| 111 | + operations = create(project_dir=jaffle_shop_duckdb) |
| 112 | + console = PlanCapturingConsole() |
| 113 | + operations.context.console = console |
| 114 | + |
| 115 | + plan = operations.run() |
| 116 | + assert plan.environment.name == "prod" |
| 117 | + assert console.no_prompts is True |
| 118 | + assert console.no_diff is True |
| 119 | + assert console.auto_apply is True |
| 120 | + assert plan.end_bounded is False |
| 121 | + assert plan.ignore_cron is True |
| 122 | + assert plan.skip_backfill is False |
| 123 | + assert plan.selected_models_to_backfill is None |
| 124 | + assert {s.name for s in plan.snapshots} == {k for k in operations.context.snapshots} |
| 125 | + |
| 126 | + plan = operations.run(select=["main.stg_orders+"]) |
| 127 | + assert plan.environment.name == "prod" |
| 128 | + assert console.no_prompts is True |
| 129 | + assert console.no_diff is True |
| 130 | + assert console.auto_apply is True |
| 131 | + assert plan.end_bounded is False |
| 132 | + assert plan.ignore_cron is True |
| 133 | + assert plan.skip_backfill is False |
| 134 | + assert plan.selected_models_to_backfill == { |
| 135 | + '"jaffle_shop"."main"."customers"', |
| 136 | + '"jaffle_shop"."main"."orders"', |
| 137 | + '"jaffle_shop"."main"."stg_orders"', |
| 138 | + } |
| 139 | + assert {s.name for s in plan.snapshots} == plan.selected_models_to_backfill |
| 140 | + |
| 141 | + plan = operations.run(select=["main.stg_orders+"], exclude=["main.customers"]) |
| 142 | + assert plan.environment.name == "prod" |
| 143 | + assert console.no_prompts is True |
| 144 | + assert console.no_diff is True |
| 145 | + assert console.auto_apply is True |
| 146 | + assert plan.end_bounded is False |
| 147 | + assert plan.ignore_cron is True |
| 148 | + assert plan.skip_backfill is False |
| 149 | + assert plan.selected_models_to_backfill == { |
| 150 | + '"jaffle_shop"."main"."orders"', |
| 151 | + '"jaffle_shop"."main"."stg_orders"', |
| 152 | + } |
| 153 | + assert {s.name for s in plan.snapshots} == plan.selected_models_to_backfill |
| 154 | + |
| 155 | + plan = operations.run(exclude=["main.customers"]) |
| 156 | + assert plan.environment.name == "prod" |
| 157 | + assert console.no_prompts is True |
| 158 | + assert console.no_diff is True |
| 159 | + assert console.auto_apply is True |
| 160 | + assert plan.end_bounded is False |
| 161 | + assert plan.ignore_cron is True |
| 162 | + assert plan.skip_backfill is False |
| 163 | + assert plan.selected_models_to_backfill == {k for k in operations.context.snapshots} - { |
| 164 | + '"jaffle_shop"."main"."customers"' |
| 165 | + } |
| 166 | + assert {s.name for s in plan.snapshots} == plan.selected_models_to_backfill |
| 167 | + |
| 168 | + plan = operations.run(empty=True) |
| 169 | + assert plan.environment.name == "prod" |
| 170 | + assert console.no_prompts is True |
| 171 | + assert console.no_diff is True |
| 172 | + assert console.auto_apply is True |
| 173 | + assert plan.end_bounded is False |
| 174 | + assert plan.ignore_cron is True |
| 175 | + assert plan.skip_backfill is True |
| 176 | + assert plan.selected_models_to_backfill is None |
| 177 | + assert {s.name for s in plan.snapshots} == {k for k in operations.context.snapshots} |
| 178 | + |
| 179 | + |
| 180 | +def test_run_option_mapping_dev(jaffle_shop_duckdb: Path): |
| 181 | + # create prod so that dev has something to compare against |
| 182 | + operations = create(project_dir=jaffle_shop_duckdb) |
| 183 | + operations.run() |
| 184 | + |
| 185 | + (jaffle_shop_duckdb / "models" / "new_model.sql").write_text("select 1") |
| 186 | + |
| 187 | + operations = create(project_dir=jaffle_shop_duckdb) |
| 188 | + |
| 189 | + console = PlanCapturingConsole() |
| 190 | + operations.context.console = console |
| 191 | + |
| 192 | + plan = operations.run(environment="dev") |
| 193 | + assert plan.environment.name == "dev" |
| 194 | + assert console.no_prompts is True |
| 195 | + assert console.no_diff is True |
| 196 | + assert console.auto_apply is True |
| 197 | + assert plan.include_unmodified is False |
| 198 | + assert plan.context_diff.create_from == "prod" |
| 199 | + assert plan.context_diff.is_new_environment is True |
| 200 | + assert ( |
| 201 | + console.plan_builder._enable_preview is False |
| 202 | + ) # duckdb doesnt support cloning so dev previews are not enabled for dbt projects |
| 203 | + assert plan.end_bounded is True |
| 204 | + assert plan.ignore_cron is False |
| 205 | + assert plan.skip_backfill is False |
| 206 | + assert plan.selected_models_to_backfill == {'"jaffle_shop"."main"."new_model"'} |
| 207 | + |
| 208 | + plan = operations.run(environment="dev", empty=True) |
| 209 | + assert plan.environment.name == "dev" |
| 210 | + assert console.no_prompts is True |
| 211 | + assert console.no_diff is True |
| 212 | + assert console.auto_apply is True |
| 213 | + assert plan.include_unmodified is False |
| 214 | + assert plan.context_diff.create_from == "prod" |
| 215 | + assert plan.context_diff.is_new_environment is True |
| 216 | + assert console.plan_builder._enable_preview is False |
| 217 | + assert plan.end_bounded is True |
| 218 | + assert plan.ignore_cron is False |
| 219 | + assert plan.skip_backfill is True |
| 220 | + assert plan.selected_models_to_backfill == {'"jaffle_shop"."main"."new_model"'} |
| 221 | + |
| 222 | + plan = operations.run(environment="dev", select=["main.stg_orders+"]) |
| 223 | + assert plan.environment.name == "dev" |
| 224 | + assert console.no_prompts is True |
| 225 | + assert console.no_diff is True |
| 226 | + assert console.auto_apply is True |
| 227 | + assert plan.include_unmodified is False |
| 228 | + assert plan.context_diff.create_from == "prod" |
| 229 | + assert plan.context_diff.is_new_environment is True |
| 230 | + assert console.plan_builder._enable_preview is False |
| 231 | + # dev plans with --select have run=True, ignore_cron=True set |
| 232 | + assert plan.end_bounded is False |
| 233 | + assert plan.ignore_cron is True |
| 234 | + assert plan.skip_backfill is False |
| 235 | + # note: the new model in the dev environment is ignored in favour of the explicitly selected ones |
| 236 | + assert plan.selected_models_to_backfill == { |
| 237 | + '"jaffle_shop"."main"."customers"', |
| 238 | + '"jaffle_shop"."main"."orders"', |
| 239 | + '"jaffle_shop"."main"."stg_orders"', |
| 240 | + } |
0 commit comments