hub v0.140.0: a failed operator mail is retried (1, 5, 15 min); a Docker set needs a passing memory-kill check on every ring-0 box (decision 157)
gates / gates (push) Successful in 2m40s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 19:14:00 +02:00
parent 2441c86a89
commit eed1dbd80c
8 changed files with 298 additions and 17 deletions
+36 -8
View File
@@ -1,6 +1,8 @@
package web
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
@@ -80,19 +82,45 @@ func TestSystemPage_DockerButtonOnlyWhenReady(t *testing.T) {
// and drop it (the flake seen 2026-10-05 under full-suite load).
clock := time.Date(2026, 10, 5, 3, 0, 0, 0, time.UTC)
svc.Now = func() time.Time { return clock }
night := func() {
if err := svc.Ingest("full-1", osupdates.Report{RunID: time.Now().String(), Layer: "docker", Trigger: "night", Mode: "apply",
nightOOM := func(oom string) {
r := osupdates.Report{RunID: time.Now().String(), Layer: "docker", Trigger: "night", Mode: "apply",
Outcome: "nothing", Healthy: true, Installed: []osupdates.Package{{Name: "docker-ce", Version: "5:29.8.2-1", Origin: "Docker"}}}
if oom != "" {
r.OOMCheck = json.RawMessage(oom)
}
if err := svc.Ingest("full-1", r); err != nil {
t.Fatal(err)
}
}
pass := `{"result":"pass","oom_killed":true,"oom_event":true,"exit_code":137,"image":"felhom-controller","detail":""}`
nightOOM(pass)
if strings.Contains(getSystem(t, s), `action="/os/approve-docker"`) {
t.Fatal("button shown after ONE night")
}
nightOOM(pass)
if !strings.Contains(getSystem(t, s), `action="/os/approve-docker"`) {
t.Fatal("button missing after two healthy nights")
}
}
// Decision 157: two healthy nights WITHOUT the memory-kill check (an older agent) show no button, and the page says why.
func TestSystemPage_DockerButtonHiddenWithoutTheMemoryKillCheck(t *testing.T) {
s, st, svc := systemServer(t)
_ = st.SetOSRing("full-1", 0)
clock := time.Date(2026, 10, 5, 3, 0, 0, 0, time.UTC)
svc.Now = func() time.Time { return clock }
for i := 0; i < 2; i++ {
if err := svc.Ingest("full-1", osupdates.Report{RunID: time.Now().String() + fmt.Sprint(i), Layer: "docker", Trigger: "night", Mode: "apply",
Outcome: "nothing", Healthy: true, Installed: []osupdates.Package{{Name: "docker-ce", Version: "5:29.8.2-1", Origin: "Docker"}}}); err != nil {
t.Fatal(err)
}
}
night()
if strings.Contains(getSystem(t, s), `action="/os/approve-docker"`) {
t.Fatal("button shown after ONE night")
page := getSystem(t, s)
if strings.Contains(page, `action="/os/approve-docker"`) {
t.Fatal("button shown although no ring-0 box reported the memory-kill check")
}
night()
if !strings.Contains(getSystem(t, s), `action="/os/approve-docker"`) {
t.Fatal("button missing after two healthy nights")
if !strings.Contains(page, "memory-kill check") {
t.Fatal("the page does not say why the button is missing")
}
}