| 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)) |
| }) |
| } |