test(materialization): GC + scheduler state-machine transition coverage - #902
girishjeswani merged 5 commits into
Conversation
…cords-only cascade deletes Hardens garbage-collection coverage for the materialization service (fast-follow to malloydata#888, split out per review as malloydata#895): - deleteMaterialization telemetry: a successful physical-table drop meters outcome=success; a failed drop meters outcome=failure and still deletes the record, so a best-effort drop failure never surfaces to the caller. - buildOneSource staging cleanup: the original build error propagates when the staging-cleanup drop itself fails (leak logged), and a cancelled mid-run build drops its staging table like a failure — no _staging orphan. - Cascade deletes are records-only: deleteByEnvironmentId / deleteByPackage issue a single DELETE and no DDL, documenting that physical-table GC is the caller's responsibility so a materialized table intentionally outlives its record on an env/package delete. Contract comment added on both repo methods. Covers items 1-3 of malloydata#895; the state-machine transition tests (item 4) follow once malloydata#888's scheduler lands on main. Signed-off-by: Girish Jeswani <[email protected]>
…ne transitions Drives the scheduler's transitions end to end against the real store (malloydata#895, item 4), complementing the per-tick unit guards: - a cron edit between ticks re-arms from now (no stale fire from the old cadence) - a package unload/reload prunes arming state and re-anchors without a spurious fire - a fired occurrence advances to the next occurrence (fires once per occurrence, not every tick; the advance is outcome-independent, so the FAILED-fire isolation stays unit-covered) - maxFiresPerTick caps a tick and the capped package fires on the next tick Each test uses its own environment and tears it down in afterEach, since the scheduler sweeps every loaded environment. Signed-off-by: Girish Jeswani <[email protected]>
The integration version drove the prune + re-anchor transition via a package delete + same-name re-add, which races the package-install staging rename on Windows (ENOENT on the staging->final rename; POSIX handles it) — unrelated to the scheduler logic under test. The transition is pure in-memory arming state, so it's now a deterministic unit test in materialization_scheduler.spec.ts (mutating the fake loaded set). The other three transitions stay as integration tests. Signed-off-by: Girish Jeswani <[email protected]>
|
@girishjeswani Reviewed thoroughly, including running everything locally: full root gate on the PR head (unit 1166 pass / 0 fail, integration 225 / 0) and again on a local merge with current main (1205 / 0 unit, 225 / 0 integration, no conflicts and no interaction with #904's quoting change, which is confined to manifest-bind sites the failure-path tests never reach). Behavior-change claim verified: the only non-test hunk is the comment block in Description is stale after 842ee44. The body still lists unload/reload under "State-machine transitions (integration, real store)" and implies 4 integration transition tests; the final diff has 3, with unload/reload moved to a deterministic unit test (a good trade for the Windows staging-rename race, and the moved test genuinely covers prune, fresh re-anchor, and re-armed liveness). Also "contract comment on both repo methods" is one block above The cancelled-mid-run staging test does not exercise cancellation ( Optional hardening, take or leave:
|
|
Nice, well-scoped coverage. One small note on the records-only cascade test + contract comment: they pin "no DDL in Could the test/comment reference #901, so a future best-effort drop-before-teardown (the fix #901 already sketches) reads as completing the design rather than violating a green "no DDL here" test? Purely about keeping the follow-up visible at the code site; the behavior in this PR is correct as-is. |
…de contract The records-only cascade-delete comment and its guard test pin "no DDL in deleteByEnvironmentId / deleteByPackage". Note the standalone GC gap (malloydata#901) at both code sites so the behavior reads as an intentional-for-now contract with an open follow-up, not a settled one: malloydata#901's best-effort drop-before-teardown lives above these methods, so adding it completes the design and leaves this test green. Comment-only; no behavior change. Signed-off-by: Girish Jeswani <[email protected]>
Summary
Closes #895 — the GC + state-machine-transition coverage split out of #888. All additive tests plus one documenting comment; no behavior change.
Garbage collection
deleteMaterialization({ dropTables })metersrecordDropTables("success")on a successful physical-table drop and("failure")when the drop throws — and the record is still deleted (a best-effort drop failure never surfaces to the caller). Asserted via the OTel in-memory harness._stagingorphan. (Build-SQL failure was already covered.)deleteByEnvironmentId/deleteByPackageissue a singleDELETEand no DDL. A materialized table intentionally outlives its record on env/package delete — physical GC is the caller's responsibility (same contract asdeleteMaterialization's default). Locked in with SQL-shape tests + a contract comment on both repo methods, so a future refactor can't silently add aDROPthere. This is the "explicit decision, not silent" the feat(materialization): standalone scheduler, environment-scoped listing, and schedule management UI #888 review asked to keep visible; the optional standalone cascade-drop is tracked in Optional: standalone cascade-drop of materialized tables on env/package delete #901.State-machine transitions (integration, real store)
Complements the per-tick unit guards by driving each transition end to end through REST-created packages the scheduler sweeps:
now(no stale fire from the old cadence)FAILED-fire isolation stays unit-covered — a genuine failed build isn't reliably reproducible without a brittle fixture)maxFiresPerTickcaps a tick and the capped package fires on the next tickEach transition test uses its own environment and tears it down in
afterEach, since the scheduler sweeps every loaded environment.Testing
typecheck+eslintclean on changed files.Notes