Skip to content

Commit 128c745

Browse files
authored
Chore: detect invalid audit refs and raise early (#4323)
1 parent 57f0baa commit 128c745

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

sqlmesh/core/model/definition.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,14 @@ def _create_model(
24782478

24792479
model.audit_definitions.update(audit_definitions)
24802480

2481+
from sqlmesh.core.audit.builtin import BUILT_IN_AUDITS
2482+
2483+
# Ensure that all audits referenced in the model are defined
2484+
available_audits = BUILT_IN_AUDITS.keys() | model.audit_definitions.keys()
2485+
for referenced_audit, *_ in model.audits:
2486+
if referenced_audit not in available_audits:
2487+
raise_config_error(f"Audit '{referenced_audit}' is undefined", location=path)
2488+
24812489
# Any macro referenced in audits or signals needs to be treated as metadata-only
24822490
statements.extend((audit.query, True) for audit in audit_definitions.values())
24832491
for _, audit_args in model.audits:

tests/core/test_model.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,18 @@ def test_audits():
13421342
"""
13431343
)
13441344

1345-
model = load_sql_based_model(expressions, path=Path("./examples/sushi/models/test_model.sql"))
1345+
audit_definitions = {
1346+
audit_name: load_audit(
1347+
d.parse(f"AUDIT (name {audit_name}); SELECT 1 WHERE FALSE"), dialect="duckdb"
1348+
)
1349+
for audit_name in ("audit_a", "audit_b", "audit_c")
1350+
}
1351+
1352+
model = load_sql_based_model(
1353+
expressions,
1354+
path=Path("./examples/sushi/models/test_model.sql"),
1355+
audit_definitions=audit_definitions,
1356+
)
13461357
assert model.audits == [
13471358
("audit_a", {}),
13481359
("audit_b", {"key": exp.Literal.string("value")}),
@@ -9635,3 +9646,19 @@ def test_semicolon_is_not_included_in_model_state(tmp_path, assert_exp_eq):
96359646
plan = ctx.plan(no_prompts=True, auto_apply=True)
96369647

96379648
assert not plan.context_diff.modified_snapshots
9649+
9650+
9651+
def test_invalid_audit_reference():
9652+
sql = """
9653+
MODEL (
9654+
name test,
9655+
audits (not_nulll (columns := (id)))
9656+
);
9657+
9658+
SELECT
9659+
1 AS id
9660+
"""
9661+
expressions = d.parse(sql)
9662+
9663+
with pytest.raises(ConfigError, match="Audit 'not_nulll' is undefined"):
9664+
load_sql_based_model(expressions)

0 commit comments

Comments
 (0)