package containerd import ( "io" "path/filepath" "testing" "github.com/containerd/containerd/v2/pkg/namespaces" cerrdefs "github.com/containerd/errdefs" "github.com/containerd/platforms" "github.com/moby/moby/v2/internal/testutil/specialimage" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) func TestImageMultiplatformSaveShallowWithNative(t *testing.T) { ctx := namespaces.WithNamespace(t.Context(), "testing-"+t.Name()) contentDir := t.TempDir() store := &blobsDirContentStore{blobs: filepath.Join(contentDir, "blobs/sha256")} native := platforms.Platform{ OS: "linux", Architecture: "amd64", } arm64 := platforms.Platform{ OS: "linux", Architecture: "arm64", } riscv64 := platforms.Platform{ OS: "linux", Architecture: "riscv64", } imgSvc := fakeImageService(t, ctx, store) // Mock the native platform. imgSvc.defaultPlatformOverride = platforms.Only(native) idx, _, err := specialimage.PartialMultiPlatform(contentDir, "partial-with-native:latest", specialimage.PartialOpts{ Stored: []ocispec.Platform{native, riscv64}, Missing: []ocispec.Platform{arm64}, }) assert.NilError(t, err) img, err := imgSvc.images.Create(ctx, imagesFromIndex(idx)[0]) assert.NilError(t, err) t.Run("export without specific platform", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, nil, io.Discard) assert.NilError(t, err) }) t.Run("export native", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{native}, io.Discard) assert.NilError(t, err) }) t.Run("export multiple platforms", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{native, riscv64}, io.Discard) assert.NilError(t, err) }) t.Run("export missing", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{arm64}, io.Discard) assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) }) t.Run("export multiple platforms with some missing", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{arm64, riscv64}, io.Discard) assert.NilError(t, err) }) } func TestImageMultiplatformSaveShallowWithoutNative(t *testing.T) { ctx := namespaces.WithNamespace(t.Context(), "testing-"+t.Name()) contentDir := t.TempDir() store := &blobsDirContentStore{blobs: filepath.Join(contentDir, "blobs/sha256")} native := platforms.Platform{ OS: "linux", Architecture: "amd64", } arm64 := platforms.Platform{ OS: "linux", Architecture: "arm64", } riscv64 := platforms.Platform{ OS: "linux", Architecture: "riscv64", } s390x := platforms.Platform{ OS: "linux", Architecture: "s390x", } imgSvc := fakeImageService(t, ctx, store) // Mock the native platform. imgSvc.defaultPlatformOverride = platforms.Only(native) idx, _, err := specialimage.PartialMultiPlatform(contentDir, "partial-without-native:latest", specialimage.PartialOpts{ Stored: []ocispec.Platform{arm64, riscv64}, Missing: []ocispec.Platform{native}, }) assert.NilError(t, err) img, err := imgSvc.images.Create(ctx, imagesFromIndex(idx)[0]) assert.NilError(t, err) t.Run("export without specific platform", func(t *testing.T) { t.Skip("TODO(vvoland): https://github.com/docker/cli/issues/5476") err = imgSvc.ExportImage(ctx, []string{img.Name}, nil, io.Discard) assert.NilError(t, err) }) t.Run("export native", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{native}, io.Discard) assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) }) t.Run("export arm64", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{arm64}, io.Discard) assert.NilError(t, err) }) t.Run("export multiple platforms", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{arm64, riscv64}, io.Discard) assert.NilError(t, err) }) t.Run("export multiple platforms with some missing", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{arm64, native}, io.Discard) assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) }) t.Run("export non existing platform", func(t *testing.T) { err = imgSvc.ExportImage(ctx, []string{img.Name}, []ocispec.Platform{s390x}, io.Discard) assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) }) }