From 1cdb4d1a2944d31090b582d373300ec43bc468f2 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 25 Oct 2026 15:27:23 +0100 Subject: [PATCH] Say a module found running on its own have again at the agent's start, so its health is this engine's and not an older engine's unknown xorg's have on g14 and shanks kept the unknown an engine before 958ccbd wrote: the baseline believed the have and never handed the module to the session, so no look rewrote its health, and the assigner held every module requiring x11-display back. --- internal/agent/agent.go | 4 ++++ internal/agent/agent_test.go | 34 ++++++++++++++++++++++++++++++++++ internal/link/have_test.go | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/internal/agent/agent.go b/internal/agent/agent.go index cefbd72..7c14c4a 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -671,6 +671,10 @@ func (a *Agent) baseline(ctx context.Context, module string, w wantNow, comp com a.mu.Lock() a.running[module] = delivery.Have{FP: h.FP, Composed: h.Composed, Phase: delivery.PhaseRunning} a.mu.Unlock() + // Said again, so the session holds the module and its key carries the health this engine judges, + // not the one an older engine left there (xorg's unknown on g14 and shanks, 2026-10-25). + a.env.Haves.Write(ctx, Have{Module: module, FP: h.FP, Composed: h.Composed, + Phase: string(delivery.PhaseRunning), Detail: h.Detail}) return true } return false diff --git a/internal/agent/agent_test.go b/internal/agent/agent_test.go index 7319982..8709ee6 100644 --- a/internal/agent/agent_test.go +++ b/internal/agent/agent_test.go @@ -313,6 +313,40 @@ func TestStartingOnItsOwnHaveAppliesNothing(t *testing.T) { } } +// A module found running on its own have after a restart is said again, once, through the haves: the session then holds +// it and writes the health this engine judges. Not said, its key kept the health an older engine wrote: xorg's have on +// g14 and shanks said unknown from before the engine said a module with nothing to judge ok, and the assigner held every +// module requiring x11-display back for it (2026-10-25). +func TestStartingOnItsOwnHaveSaysTheHaveAgainSoItsHealthIsThisEngines(t *testing.T) { + b := newBed(t) + fp := fpOf("a") + ck, craw, dig := composition(t, "xorg", fp, false, file("xorg", "x", "1")) + wk, wraw := wantFor(t, "xorg", fp, dig, "") + b.haves.stored = map[string]Have{"xorg": {Module: "xorg", FP: fp, Composed: dig, Phase: "running", Detail: "kept"}} + b.comps.before(ck, craw) + b.wants.before(wk, wraw) + stop := b.run() + defer stop() + eventually(t, "the have found running was not said again", func() bool { + b.haves.mu.Lock() + defer b.haves.mu.Unlock() + return len(b.haves.log) > 0 + }) + time.Sleep(50 * time.Millisecond) + b.haves.mu.Lock() + log := append([]Have(nil), b.haves.log...) + b.haves.mu.Unlock() + if len(log) != 1 { + t.Fatalf("the have was said %d times, want once: %+v", len(log), log) + } + if h := log[0]; h.Module != "xorg" || h.FP != fp || h.Composed != dig || h.Phase != string(delivery.PhaseRunning) || h.Detail != "kept" { + t.Fatalf("the have said again: %+v", h) + } + if got := b.appliedList(); len(got) != 0 { + t.Fatalf("a module that runs what the want names was applied: %v", got) + } +} + // A module whose kept resources differ from the composition is applied, and a failed apply is retried only by a change // of either key. func TestAFailedApplyIsRetriedOnlyByAChangeOfEitherKey(t *testing.T) { diff --git a/internal/link/have_test.go b/internal/link/have_test.go index a16b840..8101fd9 100644 --- a/internal/link/have_test.go +++ b/internal/link/have_test.go @@ -521,3 +521,25 @@ func TestAModuleWithNothingToJudgeIsOkOnceLookedAt(t *testing.T) { t.Fatalf("a failed module was said ok") } } + +// A have an older engine left unknown is written over with this engine's health once the module is said again, as the +// node agent says a module it finds running on its own have: a packages-only module (xorg, nothing long-running) is ok +// after a look, so the assigner no longer holds back what requires its provision (2026-10-25, g14 and shanks). +func TestAModuleSaidAgainOverAnOlderEnginesUnknownIsWrittenWithThisEnginesHealth(t *testing.T) { + l := newHaveLink() + fp := "src2:" + strings.Repeat("a", 64) + dig := "sha256:" + strings.Repeat("b", 64) + l.put(t, "n1.xorg", delivery.Have{V: delivery.Version, FP: fp, Composed: dig, Phase: delivery.PhaseRunning, + Health: delivery.HealthUnknown}) + q, _ := aHaveQueue(l) + if !q.SayHealth(context.Background(), *healthOf(map[string]string{"web": StateHealthy})) { + t.Fatal("not said") + } + if h := l.have(t, "n1.xorg"); h.Health != delivery.HealthUnknown { + t.Fatalf("a module the session does not hold was written: %+v", h) + } + q.NoteModule(context.Background(), ModuleFact{Module: "xorg", FP: fp, Composed: dig}) + if h := l.have(t, "n1.xorg"); h.Health != delivery.HealthOK || h.FP != fp || h.Composed != dig || h.Phase != delivery.PhaseRunning { + t.Fatalf("said again after a look: %+v", h) + } +}