mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-23 20:25:56 +00:00
test(docker): cover multi-RepoDigest update comparison
Restore the remaining focused regressions for the all-local-RepoDigests update comparison carried on the earlier core-runtime candidate: multi-digest resolution in getImageRepoDigests, false-update suppression in CheckImageUpdate, and the DigestsDiffer multi-digest cases. Test-only additions; the runtime change and contract sections are in the preceding fix(docker) commit. Change-source: pulse-maintainer
This commit is contained in:
@@ -77,6 +77,42 @@ func TestAgent_getImageRepoDigest_FallbackToFirst(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgent_getImageRepoDigests_MultipleDigestsForOneImage(t *testing.T) {
|
||||
agent := &Agent{
|
||||
docker: &fakeDockerClient{
|
||||
imageInspectWithRawFn: func(ctx context.Context, imageID string) (image.InspectResponse, []byte, error) {
|
||||
return image.InspectResponse{
|
||||
RepoDigests: []string{
|
||||
"docker.io/library/postgres@sha256:44c4",
|
||||
"docker.io/library/postgres@sha256:cf78",
|
||||
"docker.io/other/postgres@sha256:beef",
|
||||
},
|
||||
Architecture: "amd64",
|
||||
Os: "linux",
|
||||
}, nil, nil
|
||||
},
|
||||
},
|
||||
logger: zerolog.New(io.Discard),
|
||||
}
|
||||
|
||||
digests, arch, os, variant := agent.getImageRepoDigests(context.Background(), "image-id", "postgres:16.15-alpine3.24")
|
||||
want := []string{"sha256:44c4", "sha256:cf78", "sha256:beef"}
|
||||
if len(digests) != len(want) {
|
||||
t.Fatalf("digests = %v, want %v", digests, want)
|
||||
}
|
||||
for i := range want {
|
||||
if digests[i] != want[i] {
|
||||
t.Fatalf("digests = %v, want %v", digests, want)
|
||||
}
|
||||
}
|
||||
if arch != "amd64" || os != "linux" || variant != "" {
|
||||
t.Fatalf("platform = %q/%q/%q, want amd64/linux/", arch, os, variant)
|
||||
}
|
||||
if got, _, _, _ := agent.getImageRepoDigest(context.Background(), "image-id", "postgres:16.15-alpine3.24"); got != "sha256:44c4" {
|
||||
t.Fatalf("primary digest = %q, want sha256:44c4", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgent_getImageRepoDigest_InvalidRepoDigest(t *testing.T) {
|
||||
agent := &Agent{
|
||||
docker: &fakeDockerClient{
|
||||
|
||||
@@ -123,3 +123,43 @@ func TestRegistryChecker_MultiArchDigestLayersStayConsistentAcrossCache(t *testi
|
||||
t.Fatalf("expected one HEAD and one GET before the cache hit, got %d requests", requestCount)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2110: a local image can carry several RepoDigests, for example the
|
||||
// tag's manifest digest and a platform manifest digest. The update check must
|
||||
// treat any of them as the current image rather than reporting a false update
|
||||
// just because the first entry differs from the registry digest.
|
||||
func TestRegistryChecker_MultipleLocalRepoDigestsSuppressFalseUpdate(t *testing.T) {
|
||||
checker := NewRegistryChecker(zerolog.Nop())
|
||||
checker.httpClient = &http.Client{
|
||||
Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
|
||||
if req.Method == http.MethodHead {
|
||||
return newStringResponse(http.StatusOK, map[string]string{
|
||||
"Content-Type": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"Docker-Content-Digest": "sha256:cf78",
|
||||
}, ""), nil
|
||||
}
|
||||
return newStringResponse(http.StatusOK, nil, "{}"), nil
|
||||
}),
|
||||
}
|
||||
|
||||
result := checker.CheckImageUpdate(
|
||||
context.Background(),
|
||||
"example.test/postgres:16.15-alpine3.24",
|
||||
"sha256:44c4,sha256:cf78",
|
||||
"amd64",
|
||||
"linux",
|
||||
"",
|
||||
)
|
||||
if result == nil {
|
||||
t.Fatal("expected an update result")
|
||||
}
|
||||
if result.UpdateAvailable {
|
||||
t.Fatalf("a local RepoDigest matching the registry digest must suppress the update: %#v", result)
|
||||
}
|
||||
if result.CurrentDigest != "sha256:44c4" {
|
||||
t.Fatalf("primary current digest = %q, want %q", result.CurrentDigest, "sha256:44c4")
|
||||
}
|
||||
if result.LatestDigest != "sha256:cf78" {
|
||||
t.Fatalf("latest digest = %q, want %q", result.LatestDigest, "sha256:cf78")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +207,24 @@ func TestRegistryChecker_DigestsDiffer(t *testing.T) {
|
||||
latest: "def456,abc123",
|
||||
want: true, // No match found
|
||||
},
|
||||
{
|
||||
name: "multiple current digests match second latest",
|
||||
current: "sha256:44c4,sha256:cf78",
|
||||
latest: "sha256:cf78",
|
||||
want: false, // One local RepoDigest is current
|
||||
},
|
||||
{
|
||||
name: "multiple current digests no match",
|
||||
current: "sha256:44c4,sha256:aaaa",
|
||||
latest: "sha256:cf78",
|
||||
want: true, // No local RepoDigest is current
|
||||
},
|
||||
{
|
||||
name: "empty entries in current set are ignored",
|
||||
current: " ,sha256:cf78",
|
||||
latest: "sha256:cf78",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user