package ingest import "testing" // The table this pins is the engine's shell contract, and every consumer in the zone reads the run's // fate through it: the reconciler that decides `paused` from `failed`, the intake that decides // whether a user's upload is deleted, the dev supervisor. Before D39.131 it knew 0/2/3 and mapped // everything else onto `failed`, which is how a ceiling stop became a failure (PD-113) and how an // operator's typo in a book.yaml became a deleted upload (PD-196). // // Mutation caught: dropping any case below back into the default, and widening the band by one at // either end. func TestOutcomeOfCoversTheWholeExitContract(t *testing.T) { for code, want := range map[int]Outcome{ 0: OutcomeClean, 1: OutcomeFailed, 2: OutcomeFlagged, 3: OutcomeBankStop, 4: OutcomeCeiling, 5: OutcomeStopped, // The band, including a class this build has no name for: it must still read as "refused" // rather than as "failed", because the consumers act on those two very differently. 10: OutcomeRefused, 11: OutcomeRefused, 12: OutcomeRefused, 13: OutcomeRefused, 19: OutcomeRefused, // Just outside it, on both sides. 9: OutcomeFailed, 20: OutcomeFailed, // Nothing the contract mentions at all. 7: OutcomeFailed, 127: OutcomeFailed, } { if got := OutcomeOf(code); got != want { t.Errorf("exit %d = %q, want %q", code, got, want) } } } func TestTheRefusalBandIsAllTenNumbersAndNothingElse(t *testing.T) { for code := range 30 { want := code >= 10 && code <= 19 if got := Refused(code); got != want { t.Errorf("Refused(%d) = %v, want %v", code, got, want) } } // The three named classes are inside their own band. Written as an assertion because the // numbers and the band are declared separately and a new class landing outside it would read as // "failed" to every consumer — the exact failure the band exists to make impossible. for _, code := range []int{ExitConfigInvalid, ExitSourceUnreadable, ExitProjectLocked, ExitRefusedOther} { if !Refused(code) { t.Errorf("exit %d is a refusal class but falls outside the band %d..%d", code, RefusalFirst, RefusalLast) } } }