fix(s3/lifecycle): wire ExpirationDate dispatch through bootstrap walker

The walker explicitly skipped ModeScanAtDate actions on the comment
"SCAN_AT_DATE runs its own date-triggered bootstrap" — but no such
bootstrap exists in the scheduler or shell layer. The result: rules
with Expiration{Date: ...} compiled correctly, populated the
snapshot's dateActions map, and were never dispatched.
ExpirationDate is silently a no-op in production.

EvaluateAction already handles ActionKindExpirationDate correctly
(rejects when now.Before(rule.ExpirationDate), otherwise emits
ActionDeleteObject). The walker just needed to fall through instead
of skipping. Pre-date walks become no-ops via EvaluateAction's date
check; post-date walks expire eligible objects.

Un-skip TestLifecycleExpirationDateInThePast — it now exercises the
fixed path end-to-end.
This commit is contained in:
Chris Lu committed 2026-05-09 23:30:47 -07:00
1 parent 60bee61189
commit e785f59d6f
2 files changed
+10 -13

No files matched your search

@@ -20,15 +20,6 @@ import (
// separate compile + dispatch branch (engine.decideMode case
// ActionKindExpirationDate) that wouldn't be exercised otherwise.
func TestLifecycleExpirationDateInThePast(t *testing.T) {
// SCAN_AT_DATE is a documented mode in engine.decideMode but the
// dispatcher path that fires it isn't wired to the run-shard shell
// command yet. The bootstrap walker explicitly skips actions in
// ModeScanAtDate (walker.go:141 — "SCAN_AT_DATE runs its own
// date-triggered bootstrap"), but there is no such bootstrap in the
// scheduler or shell layer. Until that lands, this test would
// always time out. Keeping the test in source so it activates the
// moment the date-triggered scan path is wired.
t.Skip("ScanAtDate dispatch path not yet wired to run-shard; activate when the date-bootstrap lands")
c := s3Client(t)
fc, fcClose := filerClient(t)
defer fcClose()