|
19 | 19 | from sqlglot import exp |
20 | 20 | from sqlglot.expressions import DataType |
21 | 21 | import re |
| 22 | +from IPython.utils.capture import capture_output |
| 23 | + |
22 | 24 |
|
23 | 25 | from sqlmesh import CustomMaterialization |
24 | 26 | from sqlmesh.cli.example_project import init_example_project |
|
62 | 64 | SnapshotTableInfo, |
63 | 65 | ) |
64 | 66 | from sqlmesh.utils.date import TimeLike, now, to_date, to_datetime, to_timestamp |
65 | | -from sqlmesh.utils.errors import NoChangesPlanError, SQLMeshError |
| 67 | +from sqlmesh.utils.errors import NoChangesPlanError, SQLMeshError, PlanError |
66 | 68 | from sqlmesh.utils.pydantic import validate_string |
67 | 69 | from tests.conftest import DuckDBMetadata, SushiDataValidator |
68 | 70 | from tests.utils.test_helpers import use_terminal_console |
| 71 | +from tests.utils.test_filesystem import create_temp_file |
69 | 72 |
|
70 | 73 | if t.TYPE_CHECKING: |
71 | 74 | from sqlmesh import QueryOrDF |
@@ -5922,3 +5925,42 @@ def setup_scenario(): |
5922 | 5925 |
|
5923 | 5926 | # - Check that the environment record does not exist in the state sync anymore |
5924 | 5927 | assert not ctx.state_sync.get_environment("dev") |
| 5928 | + |
| 5929 | + |
| 5930 | +@use_terminal_console |
| 5931 | +def test_audits_running_on_metadata_changes(tmp_path: Path): |
| 5932 | + def setup_senario(model_before: str, model_after: str): |
| 5933 | + models_dir = Path("models") |
| 5934 | + create_temp_file(tmp_path, models_dir / "test.sql", model_before) |
| 5935 | + |
| 5936 | + # Create first snapshot |
| 5937 | + context = Context(paths=tmp_path, config=Config()) |
| 5938 | + context.plan("prod", no_prompts=True, auto_apply=True) |
| 5939 | + |
| 5940 | + # Create second (metadata) snapshot |
| 5941 | + create_temp_file(tmp_path, models_dir / "test.sql", model_after) |
| 5942 | + context.load() |
| 5943 | + |
| 5944 | + with capture_output() as output: |
| 5945 | + with pytest.raises(PlanError): |
| 5946 | + context.plan("prod", no_prompts=True, auto_apply=True) |
| 5947 | + |
| 5948 | + assert 'Failed models\n\n "model"' in output.stdout |
| 5949 | + |
| 5950 | + return output |
| 5951 | + |
| 5952 | + # Ensure incorrect audits (bad data, incorrect definition etc) are evaluated immediately |
| 5953 | + output = setup_senario( |
| 5954 | + "MODEL (name model); SELECT NULL AS col", |
| 5955 | + "MODEL (name model, audits (not_null(columns=[col]))); SELECT NULL AS col", |
| 5956 | + ) |
| 5957 | + assert "'not_null' audit error: 1 row failed" in output.stdout |
| 5958 | + |
| 5959 | + output = setup_senario( |
| 5960 | + "MODEL (name model); SELECT NULL AS col", |
| 5961 | + "MODEL (name model, audits (not_null(columns=[this_col_does_not_exist]))); SELECT NULL AS col", |
| 5962 | + ) |
| 5963 | + assert ( |
| 5964 | + 'Binder Error: Referenced column "this_col_does_not_exist" not found in \nFROM clause!' |
| 5965 | + in output.stdout |
| 5966 | + ) |
0 commit comments