test(cascade): pin part-integrity paths (rollback, empty-materialization, U3 arm)#1485
test(cascade): pin part-integrity paths (rollback, empty-materialization, U3 arm)#1485dimitri-yatsenko wants to merge 2 commits into
Conversation
…erage gaps Locks the behaviors the post-2.3 audit verified, so regressions in either direction — a documented bypass silently closing, or a blocking path silently opening — become visible. test_strict_provenance_limits.py: len/bool and query-expression 'in' bypass (documented); CLASS-form 'in' RAISES (gated __iter__); restriction-by-table bypasses; join with undeclared operand RAISES (the one gated read path, previously untested); Aggregation __len__ bypasses while its fetch RAISES; delete_quick ungated (documented); INSERT...SELECT skips per-row key consistency (documented exception); self.upstream[SelfPart] raises while direct self.PartName read is allowed; context cleared after raising make(); nested push/pop token restore. test_cascade_integrity.py: enforce post-check raises 'before its master' AND rolls back; empty-materialization sentinel previews master at 0 and deletes cleanly; U3 upward arm with SECONDARY -> master FK restricts only the correct master (bare proj() would restrict both). Also corrects the provenance.py module docstring (audit item B6): context is pushed/popped inside _populate_one in whichever process/thread runs make() — the old across-threads/fork-inheritance rationale was inaccurate. Behavior unchanged. New files only — no conflicts with the open #1480/#1484 branches.
MilagrosMarin
left a comment
There was a problem hiding this comment.
Thanks @dimitri-yatsenko — three clean pins.
The enforce post-check + rollback test finally covers the data-driven path (cascade reaches Part but not Master → raise + rollback); previously only the direct Part.delete pre-guard had coverage.
The empty-materialization sentinel uses counts.get(Master.full_table_name, 1) == 0 — the 1 default cleanly distinguishes "Master present with zero matches" (the intended [False] sentinel from #1468) from "Master not in counts at all". Both would pass a naïve > 0 check, so the specificity here matters.
The U3 arm with secondary master FK is the isolated non-primary-FK direct-hit test I flagged as a follow-up during #1471. The topology forces U3 exactly, and asserting only master 1 is restricted genuinely distinguishes the fix — a bare proj() would fall to a cross-join and restrict both masters.
Dropping the strict_provenance limits to align with the guardrail removal in #1489 was the right call.
Approving.
Adds integration coverage for the cascade part-integrity paths hardened in #1484, so a regression in either direction becomes visible.
test_cascade_integrity.py"before its master"and rolls back completely (previously only thePart.deletepre-guard had a test).-> masterFK —proj(*attr_map.keys())correctly restricts only the right master; a bareproj()would have restricted both (pins the exact fix(#1429): cascade through FK chain for part_integrity="cascade" #1468 code path).New file only — no conflicts. Tests green locally on MySQL + PostgreSQL. Companion to the cascade fix in #1484.
Scope note
This PR originally also pinned the
strict_provenanceread/write-gate limits. That surface is being retired in #1489 (which deletesprovenance.py), so those tests and the now-mootprovenance.pydocstring edit were dropped to keep this PR coherent with the guardrail removal. What remains is the cascade-integrity coverage, which is independent ofstrict_provenance.