The registry's answer was cached and served as-is, so the stack view and the machine-wide list kept calling an image behind after an update had pulled it. The cache now keeps the digest the registry named, and an image marked behind is re-checked locally on every read: once this machine holds that digest it is current, at no registry cost. The page re-reads the machine-wide answer after a stack task, a queued update, or a schedule run. Also: stack keys can no longer collide with the machine key, and the dead "/"+stack forget in the schedule runner is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
1.4 KiB
Go
48 lines
1.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// fakeDocker puts a `docker` on PATH whose `image inspect` answers with the given RepoDigests.
|
|
func fakeDocker(t *testing.T, digests string) {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
script := "#!/bin/sh\necho '" + digests + "'\n"
|
|
if err := os.WriteFile(filepath.Join(dir, "docker"), []byte(script), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Setenv("PATH", dir)
|
|
}
|
|
|
|
// An update pulls the newer image: the cached registry answer must not keep calling it behind.
|
|
func TestSettledSeesAPulledImage(t *testing.T) {
|
|
cached := []imageCheck{
|
|
{Image: "nginx:alpine", State: "update", remote: "sha256:new"},
|
|
{Image: "redis:7", State: "current", remote: "sha256:r"},
|
|
{Image: "local/thing", State: "unknown"},
|
|
}
|
|
fakeDocker(t, `["nginx@sha256:new"]`)
|
|
got := settled(context.Background(), cached)
|
|
if got[0].State != "current" {
|
|
t.Fatalf("pulled image still marked %q", got[0].State)
|
|
}
|
|
if got[1].State != "current" || got[2].State != "unknown" {
|
|
t.Fatalf("others changed: %+v", got)
|
|
}
|
|
if cached[0].State != "update" {
|
|
t.Fatal("settled wrote through to the cache")
|
|
}
|
|
}
|
|
|
|
func TestSettledKeepsAnImageStillBehind(t *testing.T) {
|
|
fakeDocker(t, `["nginx@sha256:old"]`)
|
|
got := settled(context.Background(), []imageCheck{{Image: "nginx:alpine", State: "update", remote: "sha256:new"}})
|
|
if got[0].State != "update" {
|
|
t.Fatalf("image not yet pulled marked %q", got[0].State)
|
|
}
|
|
}
|