automation-tests/common/libimage/manifests/manifests_test.go

338 lines
12 KiB
Go

package manifests
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/containers/common/pkg/manifests"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
digest "github.com/opencontainers/go-digest"
"github.com/stretchr/testify/assert"
)
var (
_ List = &list{}
sys = &types.SystemContext{
SystemRegistriesConfPath: "../../tests/registries.conf",
SignaturePolicyPath: "../../tests/policy.json",
}
amd64sys = &types.SystemContext{ArchitectureChoice: "amd64"}
arm64sys = &types.SystemContext{ArchitectureChoice: "arm64"}
ppc64sys = &types.SystemContext{ArchitectureChoice: "ppc64le"}
)
const (
listImageName = "foo"
otherListImage = "docker://k8s.gcr.io/pause:3.1"
otherListDigest = "sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea"
otherListAmd64Digest = "sha256:59eec8837a4d942cc19a52b8c09ea75121acc38114a2c68b98983ce9356b8610"
otherListArm64Digest = "sha256:f365626a556e58189fc21d099fc64603db0f440bff07f77c740989515c544a39"
otherListPpc64Digest = "sha256:bcf9771c0b505e68c65440474179592ffdfa98790eb54ffbf129969c5e429990"
otherListInstanceDigest = "docker://k8s.gcr.io/pause@sha256:f365626a556e58189fc21d099fc64603db0f440bff07f77c740989515c544a39"
)
func TestSaveLoad(t *testing.T) {
if unshare.IsRootless() {
t.Skip("Test can only run as root")
}
dir, err := ioutil.TempDir("", "manifests")
assert.Nilf(t, err, "error creating temporary directory")
defer os.RemoveAll(dir)
storeOptions := storage.StoreOptions{
GraphRoot: filepath.Join(dir, "root"),
RunRoot: filepath.Join(dir, "runroot"),
GraphDriverName: "vfs",
}
store, err := storage.GetStore(storeOptions)
assert.Nilf(t, err, "error opening store")
if store == nil {
return
}
defer func() {
if _, err := store.Shutdown(true); err != nil {
assert.Nilf(t, err, "error closing store")
}
}()
list := Create()
assert.NotNil(t, list, "Create() returned nil?")
image, err := list.SaveToImage(store, "", []string{listImageName}, manifest.DockerV2ListMediaType)
assert.Nilf(t, err, "SaveToImage(1)")
locker, err := LockerForImage(store, image)
assert.Nilf(t, err, "LockerForImage()")
locker.Lock()
defer locker.Unlock()
imageReused, err := list.SaveToImage(store, image, nil, manifest.DockerV2ListMediaType)
assert.Nilf(t, err, "SaveToImage(2)")
_, list, err = LoadFromImage(store, image)
assert.Nilf(t, err, "LoadFromImage(1)")
assert.NotNilf(t, list, "LoadFromImage(1)")
_, list, err = LoadFromImage(store, imageReused)
assert.Nilf(t, err, "LoadFromImage(2)")
assert.NotNilf(t, list, "LoadFromImage(2)")
_, list, err = LoadFromImage(store, listImageName)
assert.Nilf(t, err, "LoadFromImage(3)")
assert.NotNilf(t, list, "LoadFromImage(3)")
}
func TestAddRemove(t *testing.T) {
if unshare.IsRootless() {
t.Skip("Test can only run as root")
}
ctx := context.TODO()
ref, err := alltransports.ParseImageName(otherListImage)
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
src, err := ref.NewImageSource(ctx, sys)
assert.Nilf(t, err, "NewImageSource(%q)", otherListImage)
defer assert.Nilf(t, src.Close(), "ImageSource.Close()")
m, _, err := src.GetManifest(ctx, nil)
assert.Nilf(t, err, "ImageSource.GetManifest()")
assert.Nilf(t, src.Close(), "ImageSource.GetManifest()")
listDigest, err := manifest.Digest(m)
assert.Nilf(t, err, "manifest.Digest()")
assert.Equalf(t, listDigest.String(), otherListDigest, "digest for image %q changed?", otherListImage)
l, err := manifests.FromBlob(m)
assert.Nilf(t, err, "manifests.FromBlob()")
assert.NotNilf(t, l, "manifests.FromBlob()")
assert.Equalf(t, len(l.Instances()), 5, "image %q had an arch added?", otherListImage)
list := Create()
instanceDigest, err := list.Add(ctx, amd64sys, ref, false)
assert.Nilf(t, err, "list.Add(all=false)")
assert.Equal(t, instanceDigest.String(), otherListAmd64Digest)
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
list = Create()
instanceDigest, err = list.Add(ctx, arm64sys, ref, false)
assert.Nilf(t, err, "list.Add(all=false)")
assert.Equal(t, instanceDigest.String(), otherListArm64Digest)
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
list = Create()
instanceDigest, err = list.Add(ctx, ppc64sys, ref, false)
assert.Nilf(t, err, "list.Add(all=false)")
assert.Equal(t, instanceDigest.String(), otherListPpc64Digest)
assert.Equalf(t, len(list.Instances()), 1, "too many instances added")
_, err = list.Add(ctx, sys, ref, true)
assert.Nilf(t, err, "list.Add(all=true)")
assert.Equalf(t, len(list.Instances()), 5, "too many instances added")
list = Create()
_, err = list.Add(ctx, sys, ref, true)
assert.Nilf(t, err, "list.Add(all=true)")
assert.Equalf(t, len(list.Instances()), 5, "too many instances added", otherListImage)
for _, instance := range list.Instances() {
assert.Nilf(t, list.Remove(instance), "error removing instance %q", instance)
}
assert.Equalf(t, len(list.Instances()), 0, "should have removed all instances")
ref, err = alltransports.ParseImageName(otherListInstanceDigest)
assert.Nilf(t, err, "ParseImageName(%q)", otherListInstanceDigest)
list = Create()
_, err = list.Add(ctx, sys, ref, false)
assert.Nilf(t, err, "list.Add(all=false)")
assert.Equalf(t, len(list.Instances()), 1, "too many instances added", otherListInstanceDigest)
list = Create()
_, err = list.Add(ctx, sys, ref, true)
assert.Nilf(t, err, "list.Add(all=true)")
assert.Equalf(t, len(list.Instances()), 1, "too many instances added", otherListInstanceDigest)
}
func TestReference(t *testing.T) {
if unshare.IsRootless() {
t.Skip("Test can only run as root")
}
ctx := context.TODO()
dir, err := ioutil.TempDir("", "manifests")
assert.Nilf(t, err, "error creating temporary directory")
defer os.RemoveAll(dir)
storeOptions := storage.StoreOptions{
GraphRoot: filepath.Join(dir, "root"),
RunRoot: filepath.Join(dir, "runroot"),
GraphDriverName: "vfs",
}
store, err := storage.GetStore(storeOptions)
assert.Nilf(t, err, "error opening store")
if store == nil {
return
}
defer func() {
if _, err := store.Shutdown(true); err != nil {
assert.Nilf(t, err, "error closing store")
}
}()
ref, err := alltransports.ParseImageName(otherListImage)
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
list := Create()
_, err = list.Add(ctx, ppc64sys, ref, false)
assert.Nilf(t, err, "list.Add(all=false)")
listRef, err := list.Reference(store, cp.CopyAllImages, nil)
assert.NotNilf(t, err, "list.Reference(never saved)")
assert.Nilf(t, listRef, "list.Reference(never saved)")
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
assert.NotNilf(t, err, "list.Reference(never saved)")
assert.Nilf(t, listRef, "list.Reference(never saved)")
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
assert.NotNilf(t, err, "list.Reference(never saved)")
assert.Nilf(t, listRef, "list.Reference(never saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
assert.NotNilf(t, err, "list.Reference(never saved)")
assert.Nilf(t, listRef, "list.Reference(never saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
assert.NotNilf(t, err, "list.Reference(never saved)")
assert.Nilf(t, listRef, "list.Reference(never saved)")
_, err = list.SaveToImage(store, "", []string{listImageName}, "")
assert.Nilf(t, err, "SaveToImage")
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
_, err = list.Add(ctx, sys, ref, true)
assert.Nilf(t, err, "list.Add(all=true)")
listRef, err = list.Reference(store, cp.CopyAllImages, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySystemImage, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, nil)
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest})
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
listRef, err = list.Reference(store, cp.CopySpecificImages, []digest.Digest{otherListAmd64Digest, otherListArm64Digest})
assert.Nilf(t, err, "list.Reference(saved)")
assert.NotNilf(t, listRef, "list.Reference(saved)")
}
func TestPush(t *testing.T) {
if unshare.IsRootless() {
t.Skip("Test can only run as root")
}
ctx := context.TODO()
dir, err := ioutil.TempDir("", "manifests")
assert.Nilf(t, err, "error creating temporary directory")
defer os.RemoveAll(dir)
storeOptions := storage.StoreOptions{
GraphRoot: filepath.Join(dir, "root"),
RunRoot: filepath.Join(dir, "runroot"),
GraphDriverName: "vfs",
}
store, err := storage.GetStore(storeOptions)
assert.Nilf(t, err, "error opening store")
if store == nil {
return
}
defer func() {
if _, err := store.Shutdown(true); err != nil {
assert.Nilf(t, err, "error closing store")
}
}()
dest, err := ioutil.TempDir("", "manifests")
assert.Nilf(t, err, "error creating temporary directory")
defer os.RemoveAll(dest)
destRef, err := alltransports.ParseImageName(fmt.Sprintf("dir:%s", dest))
assert.Nilf(t, err, "ParseImageName()")
ref, err := alltransports.ParseImageName(otherListImage)
assert.Nilf(t, err, "ParseImageName(%q)", otherListImage)
list := Create()
_, err = list.Add(ctx, sys, ref, true)
assert.Nilf(t, err, "list.Add(all=true)")
_, err = list.SaveToImage(store, "", []string{listImageName}, "")
assert.Nilf(t, err, "SaveToImage")
options := PushOptions{
Store: store,
SystemContext: sys,
ImageListSelection: cp.CopyAllImages,
Instances: nil,
}
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(all)")
options.ImageListSelection = cp.CopySystemImage
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(local)")
options.ImageListSelection = cp.CopySpecificImages
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(none specified)")
options.Instances = []digest.Digest{otherListAmd64Digest}
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(one specified)")
options.Instances = append(options.Instances, otherListArm64Digest)
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(two specified)")
options.Instances = append(options.Instances, otherListPpc64Digest)
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(three specified)")
options.Instances = append(options.Instances, otherListDigest)
_, _, err = list.Push(ctx, destRef, options)
assert.Nilf(t, err, "list.Push(four specified)")
}