feat(repodb): add user related information to repodb (#1317)

Initial code was contributed by Bogdan BIVOLARU <104334+bogdanbiv@users.noreply.github.com>
Moved implementation from a separate db to repodb by Andrei Aaron <aaaron@luxoft.com>

Not done yet:
- run/test dynamodb implementation, only boltdb was tested
- add additional coverage for existing functionality
- add web-based APIs to toggle the stars/bookmarks on/off

Initially graphql mutation was discussed for the missing API but
we decided REST endpoints would be better suited for configuration



feat(userdb): complete functionality for userdb integration

- dynamodb rollback changes to user starred repos in case increasing the total star count fails
- dynamodb increment/decrement repostars in repometa when user stars/unstars a repo
- dynamodb check anonymous user permissions are working as intendend
- common test handle anonymous users
- RepoMeta2RepoSummary set IsStarred and IsBookmarked



feat(userdb): rest api calls for toggling stars/bookmarks on/off



test(userdb): blackbox tests



test(userdb): move preferences tests in a different file with specific build tags



feat(repodb): add is-starred and is-bookmarked fields to repo-meta

- removed duplicated logic for determining if a repo is starred/bookmarked

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
Co-authored-by: Andrei Aaron <aaaron@luxoft.com>
This commit is contained in:
LaurentiuNiculae
2023-04-24 21:13:15 +03:00
committed by GitHub
parent ef51fd692d
commit 9cc990d7ca
50 changed files with 4357 additions and 648 deletions
+130
View File
@@ -1,15 +1,21 @@
package common_test
import (
"errors"
"testing"
"time"
"github.com/opencontainers/go-digest"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
. "github.com/smartystreets/goconvey/convey"
"zotregistry.io/zot/pkg/meta/common"
"zotregistry.io/zot/pkg/meta/repodb"
"zotregistry.io/zot/pkg/test/mocks"
)
var ErrTestError = errors.New("test error")
func TestUtils(t *testing.T) {
Convey("GetReferredSubject", t, func() {
_, err := common.GetReferredSubject([]byte("bad json"))
@@ -94,4 +100,128 @@ func TestUtils(t *testing.T) {
So(noImageChecked, ShouldEqual, false)
})
})
Convey("SignatureAlreadyExists", t, func() {
res := common.SignatureAlreadyExists(
[]repodb.SignatureInfo{{SignatureManifestDigest: "digest"}},
repodb.SignatureMetadata{SignatureDigest: "digest"},
)
So(res, ShouldEqual, true)
res = common.SignatureAlreadyExists(
[]repodb.SignatureInfo{{SignatureManifestDigest: "digest"}},
repodb.SignatureMetadata{SignatureDigest: "digest2"},
)
So(res, ShouldEqual, false)
})
Convey("FilterDataByRepo", t, func() {
Convey("Errors", func() {
// Unmarshal index data error
_, _, err := common.FilterDataByRepo(
[]repodb.RepoMetadata{{
Tags: map[string]repodb.Descriptor{
"tag": {
Digest: "indexDigest",
MediaType: ispec.MediaTypeImageIndex,
},
},
}},
map[string]repodb.ManifestMetadata{},
map[string]repodb.IndexData{
"indexDigest": {
IndexBlob: []byte("bad blob"),
},
},
)
So(err, ShouldNotBeNil)
})
})
Convey("FetchDataForRepos", t, func() {
Convey("Errors", func() {
// Unmarshal index data error
_, _, err := common.FetchDataForRepos(
mocks.RepoDBMock{
GetIndexDataFn: func(indexDigest digest.Digest) (repodb.IndexData, error) {
return repodb.IndexData{
IndexBlob: []byte("bad blob"),
}, nil
},
},
[]repodb.RepoMetadata{{
Tags: map[string]repodb.Descriptor{
"tag": {
Digest: "indexDigest",
MediaType: ispec.MediaTypeImageIndex,
},
},
}},
)
So(err, ShouldNotBeNil)
})
})
}
func TestFetchDataForRepos(t *testing.T) {
Convey("GetReferredSubject", t, func() {
mockRepoDB := mocks.RepoDBMock{}
Convey("GetManifestData errors", func() {
mockRepoDB.GetManifestDataFn = func(manifestDigest digest.Digest) (repodb.ManifestData, error) {
return repodb.ManifestData{}, ErrTestError
}
_, _, err := common.FetchDataForRepos(mockRepoDB, []repodb.RepoMetadata{
{
Tags: map[string]repodb.Descriptor{
"tag1": {Digest: "dig1", MediaType: ispec.MediaTypeImageManifest},
},
},
})
So(err, ShouldNotBeNil)
})
Convey("GetIndexData errors", func() {
mockRepoDB.GetIndexDataFn = func(indexDigest digest.Digest) (repodb.IndexData, error) {
return repodb.IndexData{}, ErrTestError
}
_, _, err := common.FetchDataForRepos(mockRepoDB, []repodb.RepoMetadata{
{
Tags: map[string]repodb.Descriptor{
"tag1": {Digest: "dig1", MediaType: ispec.MediaTypeImageIndex},
},
},
})
So(err, ShouldNotBeNil)
})
Convey("GetIndexData ok, GetManifestData errors", func() {
mockRepoDB.GetIndexDataFn = func(indexDigest digest.Digest) (repodb.IndexData, error) {
return repodb.IndexData{
IndexBlob: []byte(`{
"manifests": [
{"digest": "dig1"}
]
}`),
}, nil
}
mockRepoDB.GetManifestDataFn = func(manifestDigest digest.Digest) (repodb.ManifestData, error) {
return repodb.ManifestData{}, ErrTestError
}
_, _, err := common.FetchDataForRepos(mockRepoDB, []repodb.RepoMetadata{
{
Tags: map[string]repodb.Descriptor{
"tag1": {Digest: "dig1", MediaType: ispec.MediaTypeImageIndex},
},
},
})
So(err, ShouldNotBeNil)
})
})
}