mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
c8d/save: Add tests
Test saving a shallow/partial image Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
103
daemon/containerd/image_save_test.go
Normal file
103
daemon/containerd/image_save_test.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package containerd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/testutils/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(context.TODO(), "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",
|
||||
}
|
||||
|
||||
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},
|
||||
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}, &native, io.Discard)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
t.Run("export missing", func(t *testing.T) {
|
||||
err = imgSvc.ExportImage(ctx, []string{img.Name}, &arm64, io.Discard)
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
})
|
||||
}
|
||||
|
||||
func TestImageMultiplatformSaveShallowWithoutNative(t *testing.T) {
|
||||
ctx := namespaces.WithNamespace(context.TODO(), "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",
|
||||
}
|
||||
|
||||
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},
|
||||
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}, &native, io.Discard)
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
})
|
||||
t.Run("export arm64", func(t *testing.T) {
|
||||
err = imgSvc.ExportImage(ctx, []string{img.Name}, &arm64, io.Discard)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
}
|
||||
56
internal/testutils/specialimage/partial.go
Normal file
56
internal/testutils/specialimage/partial.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package specialimage
|
||||
|
||||
import (
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type PartialOpts struct {
|
||||
Stored []ocispec.Platform
|
||||
Missing []ocispec.Platform
|
||||
}
|
||||
|
||||
// PartialMultiPlatform creates an index with all platforms in storedPlatforms
|
||||
// and missingPlatforms. However, only the blobs of the storedPlatforms are
|
||||
// created and stored, while the missingPlatforms are only referenced in the
|
||||
// index.
|
||||
func PartialMultiPlatform(dir string, imageRef string, opts PartialOpts) (*ocispec.Index, []ocispec.Descriptor, error) {
|
||||
ref, err := reference.ParseNormalizedNamed(imageRef)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var descs []ocispec.Descriptor
|
||||
|
||||
for _, platform := range opts.Stored {
|
||||
ps := platforms.Format(platform)
|
||||
manifestDesc, err := oneLayerPlatformManifest(dir, platform, FileInLayer{Path: "bash", Content: []byte("layer-" + ps)})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
descs = append(descs, manifestDesc)
|
||||
}
|
||||
|
||||
for _, platform := range opts.Missing {
|
||||
platformStr := platforms.FormatAll(platform)
|
||||
dgst := digest.FromBytes([]byte(platformStr))
|
||||
|
||||
platform := platform
|
||||
descs = append(descs, ocispec.Descriptor{
|
||||
MediaType: ocispec.MediaTypeImageManifest,
|
||||
Size: 128,
|
||||
Platform: &platform,
|
||||
Digest: dgst,
|
||||
})
|
||||
}
|
||||
|
||||
idx, err := multiPlatformImage(dir, ref, ocispec.Index{
|
||||
Versioned: specs.Versioned{SchemaVersion: 2},
|
||||
MediaType: ocispec.MediaTypeImageIndex,
|
||||
Manifests: descs,
|
||||
})
|
||||
return idx, descs, err
|
||||
}
|
||||
Reference in New Issue
Block a user