Skip to content

Commit d4f2ec0

Browse files
committed
Verify catalog before failed import audits
1 parent d871658 commit d4f2ec0

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

‎src/openstatspec/sql/wide.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def _record_failed_preflight(
9797
audit_relations={normative.operation.name, normative.fidelity_event.name},
9898
phase="import preflight failure",
9999
) as connection:
100-
_verify_normative_catalog(connection, normative)
100+
require_verified_catalog(connection)
101101
failed_at = datetime.now(UTC).replace(tzinfo=None)
102102
record_normative_operation(
103103
connection, normative, operation_id=operation_id,

‎tests/test_catalog_persistence_review.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,46 @@ def observe(**kwargs):
124124
assert phases == ["catalog initialization", "import preflight failure"]
125125

126126

127+
def test_failed_import_preflight_rejects_catalog_drift_before_audit(
128+
tmp_path, monkeypatch,
129+
):
130+
path = tmp_path / "failed-preflight-drift.sqlite"
131+
database_url = f"sqlite:///{path}"
132+
real_bound_transaction = wide._bound_catalog_transaction
133+
134+
@contextmanager
135+
def inject_drift(**kwargs):
136+
if kwargs["phase"] == "import preflight failure":
137+
connection = sqlite3.connect(path)
138+
connection.execute("create view foreign_view as select 1 as value")
139+
connection.commit()
140+
connection.close()
141+
with real_bound_transaction(**kwargs) as connection:
142+
yield connection
143+
144+
monkeypatch.setattr(wide, "_bound_catalog_transaction", inject_drift)
145+
variables = _variables()
146+
variables[0].update({
147+
"storage_kind": "numeric", "string_width": None,
148+
"format": "F8.2", "alignment": "right",
149+
})
150+
151+
with pytest.raises(UnsupportedOperationError, match="foreign"):
152+
wide.create_wide_dataset(
153+
database_url=database_url,
154+
dataset_id="invalid",
155+
source_name="invalid.sav",
156+
source_format="SAV",
157+
rows=[{"name": "not-a-number"}],
158+
variables=variables,
159+
)
160+
161+
connection = sqlite3.connect(path)
162+
assert connection.execute("select count(*) from operation").fetchone() == (0,)
163+
assert connection.execute("select count(*) from fidelity_event").fetchone() == (0,)
164+
connection.close()
165+
166+
127167
def test_export_audit_mutations_route_through_binding_guard(tmp_path, monkeypatch):
128168
database_url = f"sqlite:///{tmp_path / 'bound-export.sqlite'}"
129169
_create(database_url)

0 commit comments

Comments
 (0)