Make runner persistence session-only
This commit is contained in:
@@ -31,54 +31,30 @@ func (s *terminalSessionStore) Save(_ context.Context, _ string, m *manifest.Man
|
||||
return s.saveErr
|
||||
}
|
||||
|
||||
type terminalRunStore struct {
|
||||
events []string
|
||||
saveErr error
|
||||
saved *manifest.RunManifest
|
||||
}
|
||||
|
||||
func (s *terminalRunStore) CreateRun(_ context.Context, sessionID, campaign, runID string, force bool, requestedStages []string) (*manifest.RunManifest, error) {
|
||||
return manifest.NewRun(sessionID, campaign, runID, force, requestedStages, time.Now().UTC()), nil
|
||||
}
|
||||
|
||||
func (s *terminalRunStore) SaveRun(_ context.Context, _ string, m *manifest.RunManifest) error {
|
||||
s.events = append(s.events, "run")
|
||||
s.saved = m
|
||||
return s.saveErr
|
||||
}
|
||||
|
||||
func TestPersistTerminalFailureKeepsSessionAuthorityBeforeRunAudit(t *testing.T) {
|
||||
func TestPersistSessionTerminalFailurePreservesCauseAndSessionAuthority(t *testing.T) {
|
||||
cause := errors.New("stage failed")
|
||||
sessionFailure := errors.New("session unavailable")
|
||||
runFailure := errors.New("run unavailable")
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
sessionErr error
|
||||
runErr error
|
||||
cause error
|
||||
alreadyTerminal bool
|
||||
}{
|
||||
{name: "both ledgers saved", cause: cause},
|
||||
{name: "session saved", cause: cause},
|
||||
{name: "session save fails", sessionErr: sessionFailure, cause: cause},
|
||||
{name: "run save fails", runErr: runFailure, cause: cause},
|
||||
{name: "both saves fail", sessionErr: sessionFailure, runErr: runFailure, cause: cause},
|
||||
{name: "cancellation", cause: context.Canceled},
|
||||
{name: "already terminal run", cause: cause, alreadyTerminal: true},
|
||||
{name: "already terminal session", cause: cause, alreadyTerminal: true},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
sessionStore := &terminalSessionStore{saveErr: tc.sessionErr}
|
||||
runStore := &terminalRunStore{saveErr: tc.runErr}
|
||||
sessionManifest := manifest.New("2026-05-03", time.Now().UTC())
|
||||
runManifest := manifest.NewRun("2026-05-03", "sample-campaign", "20260503T010203Z-a1b2c3d4", false, nil, time.Now().UTC())
|
||||
if tc.alreadyTerminal {
|
||||
sessionManifest.RecordFailure(time.Now().UTC(), "earlier failure")
|
||||
runManifest.MarkFailed(time.Now().UTC(), "earlier failure")
|
||||
}
|
||||
|
||||
err := persistTerminalFailure(
|
||||
context.Background(), sessionStore, "session.json", sessionManifest,
|
||||
runStore, "run.json", runManifest, tc.cause,
|
||||
err := persistSessionTerminalFailure(
|
||||
context.Background(), sessionStore, "session.json", sessionManifest, tc.cause,
|
||||
)
|
||||
if !errors.Is(err, tc.cause) {
|
||||
t.Fatalf("error = %v, want original cause %v", err, tc.cause)
|
||||
@@ -86,35 +62,25 @@ func TestPersistTerminalFailureKeepsSessionAuthorityBeforeRunAudit(t *testing.T)
|
||||
if tc.sessionErr != nil && !errors.Is(err, tc.sessionErr) {
|
||||
t.Fatalf("error = %v, want session failure %v", err, tc.sessionErr)
|
||||
}
|
||||
if tc.runErr != nil && !errors.Is(err, tc.runErr) {
|
||||
t.Fatalf("error = %v, want run failure %v", err, tc.runErr)
|
||||
}
|
||||
if got := append(sessionStore.events, runStore.events...); len(got) != 2 || got[0] != "session" || got[1] != "run" {
|
||||
t.Fatalf("save order = %v, want [session run]", got)
|
||||
if got := sessionStore.events; len(got) != 1 || got[0] != "session" {
|
||||
t.Fatalf("save calls = %v, want [session]", got)
|
||||
}
|
||||
if sessionStore.saved == nil || sessionStore.saved.LastError == nil || sessionStore.saved.LastError.Message != tc.cause.Error() {
|
||||
t.Fatalf("session terminal error = %#v, want %q", sessionStore.saved, tc.cause)
|
||||
}
|
||||
if runStore.saved == nil || runStore.saved.Status != manifest.RunManifestStatusFailed || runStore.saved.LastError == nil || runStore.saved.LastError.Message != tc.cause.Error() {
|
||||
t.Fatalf("run terminal record = %#v, want failed with %q", runStore.saved, tc.cause)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecuteStagesTerminalizesCancelledStage(t *testing.T) {
|
||||
cfg := testConfig(t)
|
||||
runStore := &terminalRunStore{}
|
||||
|
||||
_, err := executeStages(context.Background(), cfg, []stage.Stage{
|
||||
failingStage{name: "prepare", err: context.Canceled},
|
||||
}, RunOptions{RunManifestStore: runStore})
|
||||
}, RunOptions{})
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("executeStages() error = %v, want context cancellation", err)
|
||||
}
|
||||
if runStore.saved == nil || runStore.saved.Status != manifest.RunManifestStatusFailed {
|
||||
t.Fatalf("run terminal record = %#v, want failed", runStore.saved)
|
||||
}
|
||||
store := &manifest.LocalStore{}
|
||||
sessionManifest, loadErr := store.Load(context.Background(), manifestPathFor(cfg))
|
||||
if loadErr != nil {
|
||||
@@ -125,7 +91,7 @@ func TestExecuteStagesTerminalizesCancelledStage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecuteStagesResumeValidationFailureTerminalizesRunRecord(t *testing.T) {
|
||||
func TestExecuteStagesResumeValidationFailureRecordsSessionFailure(t *testing.T) {
|
||||
cfg := testConfig(t)
|
||||
store := &manifest.LocalStore{}
|
||||
seed := manifest.New(cfg.Session.SessionID, time.Now().UTC())
|
||||
@@ -133,16 +99,11 @@ func TestExecuteStagesResumeValidationFailureTerminalizesRunRecord(t *testing.T)
|
||||
if err := store.Save(context.Background(), manifestPathFor(cfg), seed); err != nil {
|
||||
t.Fatalf("save session manifest: %v", err)
|
||||
}
|
||||
runStore := &terminalRunStore{}
|
||||
|
||||
_, err := executeStages(context.Background(), cfg, []stage.Stage{
|
||||
resumeCheckingStage{name: "checked", validateErr: errors.New("inspection unavailable"), runs: new(int)},
|
||||
}, RunOptions{RunManifestStore: runStore})
|
||||
if err == nil || !strings.Contains(err.Error(), "inspection unavailable") || runStore.saved == nil {
|
||||
t.Fatalf("executeStages() error = %v, want resume validation failure and terminal run", err)
|
||||
}
|
||||
if runStore.saved.Status != manifest.RunManifestStatusFailed {
|
||||
t.Fatalf("run manifest status = %q, want failed", runStore.saved.Status)
|
||||
}, RunOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "inspection unavailable") {
|
||||
t.Fatalf("executeStages() error = %v, want resume validation failure", err)
|
||||
}
|
||||
persisted, loadErr := store.Load(context.Background(), manifestPathFor(cfg))
|
||||
if loadErr != nil {
|
||||
|
||||
Reference in New Issue
Block a user