Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -89,6 +89,76 @@ func BenchmarkImageList(b *testing.B) {
|
| 89 | 89 |
} |
| 90 | 90 |
} |
| 91 | 91 |
|
| 92 |
+func TestImageListCheckTotalSize(t *testing.T) {
|
|
| 93 |
+ ctx := namespaces.WithNamespace(context.TODO(), "testing") |
|
| 94 |
+ |
|
| 95 |
+ blobsDir := t.TempDir() |
|
| 96 |
+ cs := &blobsDirContentStore{blobs: filepath.Join(blobsDir, "blobs/sha256")}
|
|
| 97 |
+ |
|
| 98 |
+ twoplatform, mfstsDescs, err := specialimage.MultiPlatform(blobsDir, "test:latest", []ocispec.Platform{
|
|
| 99 |
+ {OS: "linux", Architecture: "arm64"},
|
|
| 100 |
+ {OS: "linux", Architecture: "amd64"},
|
|
| 101 |
+ }) |
|
| 102 |
+ assert.NilError(t, err) |
|
| 103 |
+ |
|
| 104 |
+ ctx = logtest.WithT(ctx, t) |
|
| 105 |
+ service := fakeImageService(t, ctx, cs) |
|
| 106 |
+ |
|
| 107 |
+ _, err = service.images.Create(ctx, imagesFromIndex(twoplatform)[0]) |
|
| 108 |
+ assert.NilError(t, err) |
|
| 109 |
+ |
|
| 110 |
+ all, err := service.Images(ctx, imagetypes.ListOptions{Manifests: true})
|
|
| 111 |
+ assert.NilError(t, err) |
|
| 112 |
+ |
|
| 113 |
+ assert.Check(t, is.Len(all, 1)) |
|
| 114 |
+ assert.Check(t, is.Len(all[0].Manifests, 2)) |
|
| 115 |
+ |
|
| 116 |
+ // TODO: The test snapshotter doesn't do anything, so the size is always 0. |
|
| 117 |
+ assert.Check(t, is.Equal(all[0].Manifests[0].ImageData.Size.Unpacked, int64(0))) |
|
| 118 |
+ assert.Check(t, is.Equal(all[0].Manifests[1].ImageData.Size.Unpacked, int64(0))) |
|
| 119 |
+ |
|
| 120 |
+ mfstArm64 := mfstsDescs[0] |
|
| 121 |
+ mfstAmd64 := mfstsDescs[1] |
|
| 122 |
+ |
|
| 123 |
+ indexSize := blobSize(t, ctx, cs, twoplatform.Manifests[0].Digest) |
|
| 124 |
+ arm64ManifestSize := blobSize(t, ctx, cs, mfstArm64.Digest) |
|
| 125 |
+ amd64ManifestSize := blobSize(t, ctx, cs, mfstAmd64.Digest) |
|
| 126 |
+ |
|
| 127 |
+ var arm64Mfst, amd64Mfst ocispec.Manifest |
|
| 128 |
+ assert.NilError(t, readConfig(ctx, cs, mfstArm64, &arm64Mfst)) |
|
| 129 |
+ assert.NilError(t, readConfig(ctx, cs, mfstAmd64, &amd64Mfst)) |
|
| 130 |
+ |
|
| 131 |
+ // MultiPlatform should produce a single layer. If these fail, the test needs to be adjusted. |
|
| 132 |
+ assert.Assert(t, is.Len(arm64Mfst.Layers, 1)) |
|
| 133 |
+ assert.Assert(t, is.Len(amd64Mfst.Layers, 1)) |
|
| 134 |
+ |
|
| 135 |
+ arm64ConfigSize := blobSize(t, ctx, cs, arm64Mfst.Config.Digest) |
|
| 136 |
+ amd64ConfigSize := blobSize(t, ctx, cs, amd64Mfst.Config.Digest) |
|
| 137 |
+ |
|
| 138 |
+ arm64LayerSize := blobSize(t, ctx, cs, arm64Mfst.Layers[0].Digest) |
|
| 139 |
+ amd64LayerSize := blobSize(t, ctx, cs, amd64Mfst.Layers[0].Digest) |
|
| 140 |
+ |
|
| 141 |
+ allTotalSize := indexSize + |
|
| 142 |
+ arm64ManifestSize + amd64ManifestSize + |
|
| 143 |
+ arm64ConfigSize + amd64ConfigSize + |
|
| 144 |
+ arm64LayerSize + amd64LayerSize |
|
| 145 |
+ |
|
| 146 |
+ assert.Check(t, is.Equal(all[0].Size, allTotalSize-indexSize)) |
|
| 147 |
+ |
|
| 148 |
+ assert.Check(t, is.Equal(all[0].Manifests[0].Size.Content, arm64ManifestSize+arm64ConfigSize+arm64LayerSize)) |
|
| 149 |
+ assert.Check(t, is.Equal(all[0].Manifests[1].Size.Content, amd64ManifestSize+amd64ConfigSize+amd64LayerSize)) |
|
| 150 |
+ |
|
| 151 |
+ // TODO: This should also include the Size.Unpacked, but the test snapshotter doesn't do anything yet |
|
| 152 |
+ assert.Check(t, is.Equal(all[0].Manifests[0].Size.Total, amd64ManifestSize+amd64ConfigSize+amd64LayerSize)) |
|
| 153 |
+ assert.Check(t, is.Equal(all[0].Manifests[1].Size.Total, amd64ManifestSize+amd64ConfigSize+amd64LayerSize)) |
|
| 154 |
+} |
|
| 155 |
+ |
|
| 156 |
+func blobSize(t *testing.T, ctx context.Context, cs content.Store, dgst digest.Digest) int64 {
|
|
| 157 |
+ info, err := cs.Info(ctx, dgst) |
|
| 158 |
+ assert.NilError(t, err) |
|
| 159 |
+ return info.Size |
|
| 160 |
+} |
|
| 161 |
+ |
|
| 92 | 162 |
func TestImageList(t *testing.T) {
|
| 93 | 163 |
ctx := namespaces.WithNamespace(context.TODO(), "testing") |
| 94 | 164 |
|
| ... | ... |
@@ -204,7 +204,7 @@ func TestImagePushIndex(t *testing.T) {
|
| 204 | 204 |
imgSvc.defaultPlatformOverride = platforms.Only(defaultDaemonPlatform) |
| 205 | 205 |
} |
| 206 | 206 |
|
| 207 |
- idx, err := specialimage.MultiPlatform(csDir, "multiplatform:latest", tc.indexPlatforms) |
|
| 207 |
+ idx, _, err := specialimage.MultiPlatform(csDir, "multiplatform:latest", tc.indexPlatforms) |
|
| 208 | 208 |
assert.NilError(t, err) |
| 209 | 209 |
|
| 210 | 210 |
imgs := imagesFromIndex(idx) |
| ... | ... |
@@ -251,7 +251,8 @@ func TestAPIImagesListManifests(t *testing.T) {
|
| 251 | 251 |
{OS: "darwin", Architecture: "arm64"},
|
| 252 | 252 |
} |
| 253 | 253 |
specialimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) {
|
| 254 |
- return specialimage.MultiPlatform(dir, "multiplatform:latest", testPlatforms) |
|
| 254 |
+ idx, _, err := specialimage.MultiPlatform(dir, "multiplatform:latest", testPlatforms) |
|
| 255 |
+ return idx, err |
|
| 255 | 256 |
}) |
| 256 | 257 |
|
| 257 | 258 |
t.Run("unsupported before 1.47", func(t *testing.T) {
|
| ... | ... |
@@ -7,10 +7,10 @@ import ( |
| 7 | 7 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
-func MultiPlatform(dir string, imageRef string, imagePlatforms []ocispec.Platform) (*ocispec.Index, error) {
|
|
| 10 |
+func MultiPlatform(dir string, imageRef string, imagePlatforms []ocispec.Platform) (*ocispec.Index, []ocispec.Descriptor, error) {
|
|
| 11 | 11 |
ref, err := reference.ParseNormalizedNamed(imageRef) |
| 12 | 12 |
if err != nil {
|
| 13 |
- return nil, err |
|
| 13 |
+ return nil, nil, err |
|
| 14 | 14 |
} |
| 15 | 15 |
|
| 16 | 16 |
var descs []ocispec.Descriptor |
| ... | ... |
@@ -19,14 +19,15 @@ func MultiPlatform(dir string, imageRef string, imagePlatforms []ocispec.Platfor |
| 19 | 19 |
ps := platforms.Format(platform) |
| 20 | 20 |
manifestDesc, err := oneLayerPlatformManifest(dir, platform, FileInLayer{Path: "bash", Content: []byte("layer-" + ps)})
|
| 21 | 21 |
if err != nil {
|
| 22 |
- return nil, err |
|
| 22 |
+ return nil, nil, err |
|
| 23 | 23 |
} |
| 24 | 24 |
descs = append(descs, manifestDesc) |
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 |
- return multiPlatformImage(dir, ref, ocispec.Index{
|
|
| 27 |
+ idx, err := multiPlatformImage(dir, ref, ocispec.Index{
|
|
| 28 | 28 |
Versioned: specs.Versioned{SchemaVersion: 2},
|
| 29 | 29 |
MediaType: ocispec.MediaTypeImageIndex, |
| 30 | 30 |
Manifests: descs, |
| 31 | 31 |
}) |
| 32 |
+ return idx, descs, err |
|
| 32 | 33 |
} |