From b90d59a2e9f200b8c18b1f942476d0f95e13db7d Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 10 Mar 2026 21:01:48 -0700 Subject: [PATCH] tests: cover imagetools append Add integration coverage for imagetools create --append and verify the target is rewritten as a two-platform manifest list. Signed-off-by: Tonis Tiigi --- tests/imagetools.go | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/imagetools.go b/tests/imagetools.go index 0691b909c..e5a4b81d1 100644 --- a/tests/imagetools.go +++ b/tests/imagetools.go @@ -31,6 +31,7 @@ var imagetoolsTests = []func(t *testing.T, sb integration.Sandbox){ testImagetoolsCopyIndex, testImagetoolsInspectAndFilter, testImagetoolsCreatePlatformFilter, + testImagetoolsAppend, testImagetoolsAnnotation, testImagetoolsMergeSources, testImagetoolsMergeSourcesWithAttestations, @@ -332,6 +333,71 @@ func testImagetoolsCreatePlatformFilter(t *testing.T, sb integration.Sandbox) { require.Equal(t, 1, attestationCount) } +// testImagetoolsAppend verifies create --append adds a new source onto an +// existing target image and rewrites it as a combined index. +func testImagetoolsAppend(t *testing.T, sb integration.Sandbox) { + if !isDockerContainerWorker(sb) { + t.Skip("only testing with docker-container worker, imagetools only runs on docker-container") + } + + dir := createDockerfileWithArches(t, "amd64", "arm64") + registry, err := sb.NewRegistry() + if errors.Is(err, integration.ErrRequirements) { + t.Skip(err.Error()) + } + require.NoError(t, err) + + target := registry + "/buildx/imtools-append-target:latest" + out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64", "--provenance=false", dir)) + require.NoError(t, err, string(out)) + + cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw")) + dt, err := cmd.CombinedOutput() + require.NoError(t, err, string(dt)) + + var amd64Manifest ocispecs.Manifest + err = json.Unmarshal(dt, &amd64Manifest) + require.NoError(t, err) + require.Equal(t, images.MediaTypeDockerSchema2Manifest, amd64Manifest.MediaType) + amd64Digest := digest.FromBytes(dt) + + source := registry + "/buildx/imtools-append-source:latest" + out, err = buildCmd(sb, withArgs("-t", source, "--push", "--platform=linux/arm64", "--provenance=false", dir)) + require.NoError(t, err, string(out)) + + cmd = buildxCmd(sb, withArgs("imagetools", "inspect", source, "--raw")) + dt, err = cmd.CombinedOutput() + require.NoError(t, err, string(dt)) + + var arm64Manifest ocispecs.Manifest + err = json.Unmarshal(dt, &arm64Manifest) + require.NoError(t, err) + require.Equal(t, images.MediaTypeDockerSchema2Manifest, arm64Manifest.MediaType) + arm64Digest := digest.FromBytes(dt) + + cmd = buildxCmd(sb, withArgs("imagetools", "create", "--append", "-t", target, source)) + dt, err = cmd.CombinedOutput() + require.NoError(t, err, string(dt)) + + cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw")) + dt, err = cmd.CombinedOutput() + require.NoError(t, err, string(dt)) + + var idx ocispecs.Index + err = json.Unmarshal(dt, &idx) + require.NoError(t, err) + require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx.MediaType) + require.Len(t, idx.Manifests, 2) + + platformsByDigest := map[digest.Digest]string{} + for _, desc := range idx.Manifests { + require.NotNil(t, desc.Platform) + platformsByDigest[desc.Digest] = platforms.Format(*desc.Platform) + } + require.Equal(t, "linux/amd64", platformsByDigest[amd64Digest]) + require.Equal(t, "linux/arm64", platformsByDigest[arm64Digest]) +} + // testImagetoolsAnnotation verifies index and manifest annotations added by imagetools create. func testImagetoolsAnnotation(t *testing.T, sb integration.Sandbox) { if !isDockerContainerWorker(sb) {