mirror of
https://github.com/project-zot/zot.git
synced 2025-01-06 22:40:28 -05:00
1df743f173
fix(gc): fix cleaning deduped blobs because they have the modTime of the original blobs, fixed by updating the modTime when hard linking the blobs. fix(gc): failing to parse rootDir at zot startup when using s3 storage because there are no files under rootDir and we can not create empty dirs on s3, fixed by creating an empty file under rootDir. Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
288 lines
9.1 KiB
Go
288 lines
9.1 KiB
Go
package meta_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
|
|
notreg "github.com/notaryproject/notation-go/registry"
|
|
godigest "github.com/opencontainers/go-digest"
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
zerr "zotregistry.io/zot/errors"
|
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
|
"zotregistry.io/zot/pkg/log"
|
|
"zotregistry.io/zot/pkg/meta"
|
|
"zotregistry.io/zot/pkg/meta/boltdb"
|
|
mTypes "zotregistry.io/zot/pkg/meta/types"
|
|
"zotregistry.io/zot/pkg/storage"
|
|
"zotregistry.io/zot/pkg/storage/local"
|
|
"zotregistry.io/zot/pkg/test"
|
|
. "zotregistry.io/zot/pkg/test/image-utils"
|
|
"zotregistry.io/zot/pkg/test/mocks"
|
|
)
|
|
|
|
var ErrTestError = errors.New("test error")
|
|
|
|
func TestOnUpdateManifest(t *testing.T) {
|
|
Convey("On UpdateManifest", t, func() {
|
|
rootDir := t.TempDir()
|
|
storeController := storage.StoreController{}
|
|
log := log.NewLogger("debug", "")
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
storeController.DefaultStore = local.NewImageStore(rootDir, true, true, log, metrics, nil, nil)
|
|
|
|
params := boltdb.DBParameters{
|
|
RootDir: rootDir,
|
|
}
|
|
boltDriver, err := boltdb.GetBoltDriver(params)
|
|
So(err, ShouldBeNil)
|
|
|
|
metaDB, err := boltdb.New(boltDriver, log)
|
|
So(err, ShouldBeNil)
|
|
|
|
config, layers, manifest, err := test.GetRandomImageComponents(100) //nolint:staticcheck
|
|
So(err, ShouldBeNil)
|
|
|
|
err = test.WriteImageToFileSystem(
|
|
Image{
|
|
Config: config, Manifest: manifest, Layers: layers,
|
|
}, "repo", "tag1", storeController)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestBlob, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
digest := godigest.FromBytes(manifestBlob)
|
|
|
|
err = meta.OnUpdateManifest("repo", "tag1", "", digest, manifestBlob, storeController, metaDB, log)
|
|
So(err, ShouldBeNil)
|
|
|
|
repoMeta, err := metaDB.GetRepoMeta("repo")
|
|
So(err, ShouldBeNil)
|
|
|
|
So(repoMeta.Tags, ShouldContainKey, "tag1")
|
|
})
|
|
|
|
Convey("metadataSuccessfullySet is false", t, func() {
|
|
rootDir := t.TempDir()
|
|
storeController := storage.StoreController{}
|
|
log := log.NewLogger("debug", "")
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
storeController.DefaultStore = local.NewImageStore(rootDir, true, true, log, metrics, nil, nil)
|
|
|
|
metaDB := mocks.MetaDBMock{
|
|
SetManifestDataFn: func(manifestDigest godigest.Digest, mm mTypes.ManifestData) error {
|
|
return ErrTestError
|
|
},
|
|
}
|
|
|
|
err := meta.OnUpdateManifest("repo", "tag1", ispec.MediaTypeImageManifest, "digest",
|
|
[]byte("{}"), storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
}
|
|
|
|
func TestUpdateErrors(t *testing.T) {
|
|
Convey("Update operations", t, func() {
|
|
Convey("On UpdateManifest", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
storeController := storage.StoreController{DefaultStore: &imageStore}
|
|
metaDB := mocks.MetaDBMock{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
Convey("CheckIsImageSignature errors", func() {
|
|
badManifestBlob := []byte("bad")
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return []byte{}, "", "", zerr.ErrManifestNotFound
|
|
}
|
|
|
|
imageStore.DeleteImageManifestFn = func(repo, reference string, detectCollision bool) error {
|
|
return nil
|
|
}
|
|
|
|
err := meta.OnUpdateManifest("repo", "tag1", "digest", "media", badManifestBlob,
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("GetSignatureLayersInfo errors", func() {
|
|
// get notation signature layers info
|
|
badNotationManifestContent := ispec.Manifest{
|
|
Subject: &ispec.Descriptor{
|
|
Digest: "123",
|
|
},
|
|
Config: ispec.Descriptor{MediaType: notreg.ArtifactTypeNotation},
|
|
}
|
|
|
|
badNotationManifestBlob, err := json.Marshal(badNotationManifestContent)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return badNotationManifestBlob, "", "", nil
|
|
}
|
|
|
|
err = meta.OnUpdateManifest("repo", "tag1", "", "digest", badNotationManifestBlob,
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("UpdateSignaturesValidity", func() {
|
|
notationManifestContent := ispec.Manifest{
|
|
Subject: &ispec.Descriptor{
|
|
Digest: "123",
|
|
},
|
|
Config: ispec.Descriptor{MediaType: notreg.ArtifactTypeNotation},
|
|
Layers: []ispec.Descriptor{{
|
|
MediaType: ispec.MediaTypeImageLayer,
|
|
Digest: godigest.FromString("blob digest"),
|
|
}},
|
|
}
|
|
|
|
notationManifestBlob, err := json.Marshal(notationManifestContent)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return notationManifestBlob, "", "", nil
|
|
}
|
|
|
|
imageStore.GetBlobContentFn = func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
return []byte{}, nil
|
|
}
|
|
|
|
metaDB.UpdateSignaturesValidityFn = func(repo string, manifestDigest godigest.Digest) error {
|
|
return ErrTestError
|
|
}
|
|
|
|
err = meta.OnUpdateManifest("repo", "tag1", "", "digest", notationManifestBlob,
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
})
|
|
|
|
Convey("On DeleteManifest", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
storeController := storage.StoreController{DefaultStore: &imageStore}
|
|
metaDB := mocks.MetaDBMock{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
Convey("CheckIsImageSignature errors", func() {
|
|
badManifestBlob := []byte("bad")
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return []byte{}, "", "", zerr.ErrManifestNotFound
|
|
}
|
|
|
|
err := meta.OnDeleteManifest("repo", "tag1", "digest", "media", badManifestBlob,
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("DeleteReferrers errors", func() {
|
|
metaDB.DeleteReferrerFn = func(repo string, referredDigest, referrerDigest godigest.Digest) error {
|
|
return ErrTestError
|
|
}
|
|
|
|
err := meta.OnDeleteManifest("repo", "tag1", "digest", "media",
|
|
[]byte(`{"subject": {"digest": "dig"}}`),
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
})
|
|
|
|
Convey("On GetManifest", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
storeController := storage.StoreController{DefaultStore: &imageStore}
|
|
metaDB := mocks.MetaDBMock{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
Convey("CheckIsImageSignature errors", func() {
|
|
badManifestBlob := []byte("bad")
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return []byte{}, "", "", zerr.ErrManifestNotFound
|
|
}
|
|
|
|
err := meta.OnGetManifest("repo", "tag1", badManifestBlob,
|
|
storeController, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
})
|
|
|
|
Convey("SetImageMetaFromInput", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
metaDB := mocks.MetaDBMock{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
err := meta.SetImageMetaFromInput("repo", "ref", ispec.MediaTypeImageManifest, "digest",
|
|
[]byte("BadManifestBlob"), imageStore, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
|
|
// reference is digest
|
|
|
|
manifestContent := ispec.Manifest{}
|
|
manifestBlob, err := json.Marshal(manifestContent)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageStore.GetImageManifestFn = func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
|
return manifestBlob, "", "", nil
|
|
}
|
|
imageStore.GetBlobContentFn = func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
return []byte("{}"), nil
|
|
}
|
|
|
|
err = meta.SetImageMetaFromInput("repo", string(godigest.FromString("reference")), "", "digest",
|
|
manifestBlob, imageStore, metaDB, log)
|
|
So(err, ShouldBeNil)
|
|
})
|
|
|
|
Convey("SetImageMetaFromInput SetData errors", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
metaDB := mocks.MetaDBMock{
|
|
SetManifestDataFn: func(manifestDigest godigest.Digest, mm mTypes.ManifestData) error {
|
|
return ErrTestError
|
|
},
|
|
}
|
|
err := meta.SetImageMetaFromInput("repo", "ref", ispec.MediaTypeImageManifest, "digest",
|
|
[]byte("{}"), imageStore, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("SetImageMetaFromInput SetIndexData errors", func() {
|
|
imageStore := mocks.MockedImageStore{}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
metaDB := mocks.MetaDBMock{
|
|
SetIndexDataFn: func(digest godigest.Digest, indexData mTypes.IndexData) error {
|
|
return ErrTestError
|
|
},
|
|
}
|
|
err := meta.SetImageMetaFromInput("repo", "ref", ispec.MediaTypeImageIndex, "digest",
|
|
[]byte("{}"), imageStore, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("SetImageMetaFromInput SetReferrer errors", func() {
|
|
imageStore := mocks.MockedImageStore{
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
return []byte("{}"), nil
|
|
},
|
|
}
|
|
log := log.NewLogger("debug", "")
|
|
|
|
metaDB := mocks.MetaDBMock{
|
|
SetReferrerFn: func(repo string, referredDigest godigest.Digest, referrer mTypes.ReferrerInfo) error {
|
|
return ErrTestError
|
|
},
|
|
}
|
|
|
|
err := meta.SetImageMetaFromInput("repo", "ref", ispec.MediaTypeImageManifest, "digest",
|
|
[]byte(`{"subject": {"digest": "subjDigest"}}`), imageStore, metaDB, log)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
})
|
|
}
|