zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/meta/boltdb/boltdb_test.go (about)

     1  package boltdb_test
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"encoding/base64"
     7  	"math"
     8  	"testing"
     9  	"time"
    10  
    11  	godigest "github.com/opencontainers/go-digest"
    12  	ispec "github.com/opencontainers/image-spec/specs-go/v1"
    13  	. "github.com/smartystreets/goconvey/convey"
    14  	"go.etcd.io/bbolt"
    15  	"google.golang.org/protobuf/proto"
    16  
    17  	zerr "zotregistry.io/zot/errors"
    18  	"zotregistry.io/zot/pkg/log"
    19  	"zotregistry.io/zot/pkg/meta/boltdb"
    20  	proto_go "zotregistry.io/zot/pkg/meta/proto/gen"
    21  	mTypes "zotregistry.io/zot/pkg/meta/types"
    22  	reqCtx "zotregistry.io/zot/pkg/requestcontext"
    23  	. "zotregistry.io/zot/pkg/test/image-utils"
    24  )
    25  
    26  type imgTrustStore struct{}
    27  
    28  func (its imgTrustStore) VerifySignature(
    29  	signatureType string, rawSignature []byte, sigKey string, manifestDigest godigest.Digest, imageMeta mTypes.ImageMeta,
    30  	repo string,
    31  ) (string, time.Time, bool, error) {
    32  	return "", time.Time{}, false, nil
    33  }
    34  
    35  func TestWrapperErrors(t *testing.T) {
    36  	image := CreateDefaultImage()
    37  	imageMeta := image.AsImageMeta()
    38  	multiarchImageMeta := CreateMultiarchWith().Images([]Image{image}).Build().AsImageMeta()
    39  
    40  	badProtoBlob := []byte("bad-repo-meta")
    41  
    42  	goodRepoMetaBlob, err := proto.Marshal(&proto_go.RepoMeta{Name: "repo"})
    43  	if err != nil {
    44  		t.FailNow()
    45  	}
    46  
    47  	Convey("Errors", t, func() {
    48  		tmpDir := t.TempDir()
    49  		boltDBParams := boltdb.DBParameters{RootDir: tmpDir}
    50  		boltDriver, err := boltdb.GetBoltDriver(boltDBParams)
    51  		So(err, ShouldBeNil)
    52  
    53  		log := log.NewLogger("debug", "")
    54  
    55  		boltdbWrapper, err := boltdb.New(boltDriver, log)
    56  		So(boltdbWrapper, ShouldNotBeNil)
    57  		So(err, ShouldBeNil)
    58  
    59  		boltdbWrapper.SetImageTrustStore(imgTrustStore{})
    60  
    61  		userAc := reqCtx.NewUserAccessControl()
    62  		userAc.SetUsername("test")
    63  
    64  		ctx := userAc.DeriveContext(context.Background())
    65  
    66  		Convey("RemoveRepoReference", func() {
    67  			Convey("getProtoRepoMeta errors", func() {
    68  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
    69  				So(err, ShouldBeNil)
    70  
    71  				err = boltdbWrapper.RemoveRepoReference("repo", "ref", imageMeta.Digest)
    72  				So(err, ShouldNotBeNil)
    73  			})
    74  
    75  			Convey("getProtoImageMeta errors", func() {
    76  				err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
    77  					Name: "repo",
    78  					Tags: map[string]mTypes.Descriptor{
    79  						"tag": {
    80  							MediaType: ispec.MediaTypeImageManifest,
    81  							Digest:    imageMeta.Digest.String(),
    82  						},
    83  					},
    84  				})
    85  				So(err, ShouldBeNil)
    86  
    87  				err = setImageMeta(imageMeta.Digest, badProtoBlob, boltdbWrapper.DB)
    88  				So(err, ShouldBeNil)
    89  
    90  				err = boltdbWrapper.RemoveRepoReference("repo", "ref", imageMeta.Digest)
    91  				So(err, ShouldNotBeNil)
    92  			})
    93  
    94  			Convey("unmarshalProtoRepoBlobs errors", func() {
    95  				err := boltdbWrapper.SetRepoReference(ctx, "repo", "tag", imageMeta)
    96  				So(err, ShouldBeNil)
    97  
    98  				err = setRepoBlobInfo("repo", badProtoBlob, boltdbWrapper.DB)
    99  				So(err, ShouldBeNil)
   100  
   101  				err = boltdbWrapper.RemoveRepoReference("repo", "ref", imageMeta.Digest)
   102  				So(err, ShouldNotBeNil)
   103  			})
   104  		})
   105  
   106  		Convey("UpdateSignaturesValidity", func() {
   107  			boltdbWrapper.SetImageTrustStore(imgTrustStore{})
   108  			digest := image.Digest()
   109  
   110  			ctx := context.Background()
   111  
   112  			Convey("image meta blob not found", func() {
   113  				err := boltdbWrapper.UpdateSignaturesValidity(ctx, "repo", digest)
   114  				So(err, ShouldBeNil)
   115  			})
   116  
   117  			Convey("image meta unmarshal fail", func() {
   118  				err := setImageMeta(digest, badProtoBlob, boltdbWrapper.DB)
   119  				So(err, ShouldBeNil)
   120  
   121  				err = boltdbWrapper.UpdateSignaturesValidity(ctx, "repo", digest)
   122  				So(err, ShouldNotBeNil)
   123  			})
   124  
   125  			Convey("repo meta blob not found", func() {
   126  				err := boltdbWrapper.SetImageMeta(digest, imageMeta)
   127  				So(err, ShouldBeNil)
   128  
   129  				err = boltdbWrapper.UpdateSignaturesValidity(ctx, "repo", digest)
   130  				So(err, ShouldNotBeNil)
   131  			})
   132  
   133  			Convey("repo meta unmarshal fail", func() {
   134  				err := boltdbWrapper.SetImageMeta(digest, imageMeta)
   135  				So(err, ShouldBeNil)
   136  
   137  				err = setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   138  				So(err, ShouldBeNil)
   139  
   140  				err = boltdbWrapper.UpdateSignaturesValidity(ctx, "repo", digest)
   141  				So(err, ShouldNotBeNil)
   142  			})
   143  		})
   144  
   145  		Convey("GetRepoLastUpdated", func() {
   146  			Convey("bad blob in db", func() {
   147  				err := boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   148  					repoBlobsBuck := tx.Bucket([]byte(boltdb.RepoBlobsBuck))
   149  					lastUpdatedBuck := repoBlobsBuck.Bucket([]byte(boltdb.RepoLastUpdatedBuck))
   150  
   151  					return lastUpdatedBuck.Put([]byte("repo"), []byte("bad-blob"))
   152  				})
   153  				So(err, ShouldBeNil)
   154  
   155  				lastUpdated := boltdbWrapper.GetRepoLastUpdated("repo")
   156  				So(lastUpdated, ShouldEqual, time.Time{})
   157  			})
   158  		})
   159  
   160  		Convey("UpdateStatsOnDownload", func() {
   161  			Convey("repo meta not found", func() {
   162  				err = boltdbWrapper.UpdateStatsOnDownload("repo", "ref")
   163  				So(err, ShouldNotBeNil)
   164  			})
   165  
   166  			Convey("unmarshalProtoRepoMeta error", func() {
   167  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   168  				So(err, ShouldBeNil)
   169  
   170  				err = boltdbWrapper.UpdateStatsOnDownload("repo", "ref")
   171  				So(err, ShouldNotBeNil)
   172  			})
   173  
   174  			Convey("ref is tag and tag is not found", func() {
   175  				err := boltdbWrapper.SetRepoReference(ctx, "repo", "tag", imageMeta)
   176  				So(err, ShouldBeNil)
   177  
   178  				err = boltdbWrapper.UpdateStatsOnDownload("repo", "not-found-tag")
   179  				So(err, ShouldNotBeNil)
   180  			})
   181  
   182  			Convey("digest not found in statistics", func() {
   183  				err := boltdbWrapper.SetRepoReference(ctx, "repo", "tag", imageMeta)
   184  				So(err, ShouldBeNil)
   185  
   186  				err = boltdbWrapper.UpdateStatsOnDownload("repo", godigest.FromString("not-found").String())
   187  				So(err, ShouldNotBeNil)
   188  			})
   189  		})
   190  
   191  		Convey("GetReferrersInfo", func() {
   192  			Convey("unmarshalProtoRepoMeta error", func() {
   193  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   194  				So(err, ShouldBeNil)
   195  
   196  				_, err = boltdbWrapper.GetReferrersInfo("repo", "refDig", []string{})
   197  				So(err, ShouldNotBeNil)
   198  			})
   199  		})
   200  
   201  		Convey("ResetRepoReferences", func() {
   202  			Convey("unmarshalProtoRepoMeta error", func() {
   203  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   204  				So(err, ShouldBeNil)
   205  
   206  				err = boltdbWrapper.ResetRepoReferences("repo")
   207  				So(err, ShouldNotBeNil)
   208  			})
   209  		})
   210  
   211  		Convey("DecrementRepoStars", func() {
   212  			Convey("unmarshalProtoRepoMeta error", func() {
   213  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   214  				So(err, ShouldBeNil)
   215  
   216  				err = boltdbWrapper.DecrementRepoStars("repo")
   217  				So(err, ShouldNotBeNil)
   218  			})
   219  		})
   220  
   221  		Convey("IncrementRepoStars", func() {
   222  			Convey("unmarshalProtoRepoMeta error", func() {
   223  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   224  				So(err, ShouldBeNil)
   225  
   226  				err = boltdbWrapper.IncrementRepoStars("repo")
   227  				So(err, ShouldNotBeNil)
   228  			})
   229  		})
   230  
   231  		Convey("DeleteSignature", func() {
   232  			Convey("repo meta not found", func() {
   233  				err = boltdbWrapper.DeleteSignature("repo", godigest.FromString("dig"), mTypes.SignatureMetadata{})
   234  				So(err, ShouldNotBeNil)
   235  			})
   236  
   237  			Convey("unmarshalProtoRepoMeta error", func() {
   238  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   239  				So(err, ShouldBeNil)
   240  
   241  				err = boltdbWrapper.DeleteSignature("repo", godigest.FromString("dig"), mTypes.SignatureMetadata{})
   242  				So(err, ShouldNotBeNil)
   243  			})
   244  		})
   245  
   246  		Convey("AddManifestSignature", func() {
   247  			Convey("unmarshalProtoRepoMeta error", func() {
   248  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   249  				So(err, ShouldBeNil)
   250  
   251  				err = boltdbWrapper.AddManifestSignature("repo", godigest.FromString("dig"), mTypes.SignatureMetadata{})
   252  				So(err, ShouldNotBeNil)
   253  			})
   254  		})
   255  
   256  		Convey("GetMultipleRepoMeta", func() {
   257  			Convey("unmarshalProtoRepoMeta error", func() {
   258  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   259  				So(err, ShouldBeNil)
   260  
   261  				_, err = boltdbWrapper.GetMultipleRepoMeta(ctx, func(repoMeta mTypes.RepoMeta) bool { return true })
   262  				So(err, ShouldNotBeNil)
   263  			})
   264  		})
   265  
   266  		Convey("GetFullImageMeta", func() {
   267  			Convey("repo meta not found", func() {
   268  				_, err := boltdbWrapper.GetFullImageMeta(ctx, "repo", "tag")
   269  				So(err, ShouldNotBeNil)
   270  			})
   271  
   272  			Convey("unmarshalProtoRepoMeta fails", func() {
   273  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   274  				So(err, ShouldBeNil)
   275  
   276  				_, err = boltdbWrapper.GetFullImageMeta(ctx, "repo", "tag")
   277  				So(err, ShouldNotBeNil)
   278  			})
   279  
   280  			Convey("tag not found", func() {
   281  				err := setRepoMeta("repo", goodRepoMetaBlob, boltdbWrapper.DB)
   282  				So(err, ShouldBeNil)
   283  
   284  				_, err = boltdbWrapper.GetFullImageMeta(ctx, "repo", "tag-not-found")
   285  				So(err, ShouldNotBeNil)
   286  			})
   287  
   288  			Convey("getProtoImageMeta fails", func() {
   289  				err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   290  					Name: "repo",
   291  					Tags: map[string]mTypes.Descriptor{
   292  						"tag": {
   293  							MediaType: ispec.MediaTypeImageManifest,
   294  							Digest:    godigest.FromString("not-found").String(),
   295  						},
   296  					},
   297  				})
   298  				So(err, ShouldBeNil)
   299  
   300  				_, err = boltdbWrapper.GetFullImageMeta(ctx, "repo", "tag")
   301  				So(err, ShouldNotBeNil)
   302  			})
   303  
   304  			Convey("image is index, fail to get manifests", func() {
   305  				err := boltdbWrapper.SetImageMeta(multiarchImageMeta.Digest, multiarchImageMeta)
   306  				So(err, ShouldBeNil)
   307  
   308  				err = boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   309  					Name: "repo",
   310  					Tags: map[string]mTypes.Descriptor{
   311  						"tag": {
   312  							MediaType: ispec.MediaTypeImageIndex,
   313  							Digest:    multiarchImageMeta.Digest.String(),
   314  						},
   315  					},
   316  				})
   317  				So(err, ShouldBeNil)
   318  
   319  				_, err = boltdbWrapper.GetFullImageMeta(ctx, "repo", "tag")
   320  				So(err, ShouldNotBeNil)
   321  			})
   322  		})
   323  
   324  		Convey("FilterRepos", func() {
   325  			err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   326  			So(err, ShouldBeNil)
   327  
   328  			_, err = boltdbWrapper.FilterRepos(ctx, mTypes.AcceptAllRepoNames, mTypes.AcceptAllRepoMeta)
   329  			So(err, ShouldNotBeNil)
   330  		})
   331  
   332  		Convey("SearchTags", func() {
   333  			Convey("unmarshalProtoRepoMeta fails", func() {
   334  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   335  				So(err, ShouldBeNil)
   336  
   337  				// manifests are missing
   338  				_, err = boltdbWrapper.SearchTags(ctx, "repo:")
   339  				So(err, ShouldNotBeNil)
   340  			})
   341  
   342  			Convey("found repo meta", func() {
   343  				Convey("bad image manifest", func() {
   344  					badImageDigest := godigest.FromString("bad-image-manifest")
   345  					err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   346  						Name: "repo",
   347  						Tags: map[string]mTypes.Descriptor{
   348  							"bad-image-manifest": {
   349  								MediaType: ispec.MediaTypeImageManifest,
   350  								Digest:    badImageDigest.String(),
   351  							},
   352  						},
   353  					})
   354  					So(err, ShouldBeNil)
   355  
   356  					err = setImageMeta(badImageDigest, badProtoBlob, boltdbWrapper.DB)
   357  					So(err, ShouldBeNil)
   358  
   359  					_, err = boltdbWrapper.SearchTags(ctx, "repo:")
   360  					So(err, ShouldNotBeNil)
   361  				})
   362  				Convey("bad image index", func() {
   363  					badIndexDigest := godigest.FromString("bad-image-manifest")
   364  					err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   365  						Name: "repo",
   366  						Tags: map[string]mTypes.Descriptor{
   367  							"bad-image-index": {
   368  								MediaType: ispec.MediaTypeImageIndex,
   369  								Digest:    badIndexDigest.String(),
   370  							},
   371  						},
   372  					})
   373  					So(err, ShouldBeNil)
   374  
   375  					err = setImageMeta(badIndexDigest, badProtoBlob, boltdbWrapper.DB)
   376  					So(err, ShouldBeNil)
   377  
   378  					_, err = boltdbWrapper.SearchTags(ctx, "repo:")
   379  					So(err, ShouldNotBeNil)
   380  				})
   381  				Convey("good image index, bad inside manifest", func() {
   382  					goodIndexBadManifestDigest := godigest.FromString("good-index-bad-manifests")
   383  					err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   384  						Name: "repo",
   385  						Tags: map[string]mTypes.Descriptor{
   386  							"good-index-bad-manifests": {
   387  								MediaType: ispec.MediaTypeImageIndex,
   388  								Digest:    goodIndexBadManifestDigest.String(),
   389  							},
   390  						},
   391  					})
   392  					So(err, ShouldBeNil)
   393  
   394  					err = boltdbWrapper.SetImageMeta(goodIndexBadManifestDigest, multiarchImageMeta)
   395  					So(err, ShouldBeNil)
   396  
   397  					err = setImageMeta(image.Digest(), badProtoBlob, boltdbWrapper.DB)
   398  					So(err, ShouldBeNil)
   399  
   400  					_, err = boltdbWrapper.SearchTags(ctx, "repo:")
   401  					So(err, ShouldNotBeNil)
   402  				})
   403  				Convey("bad media type", func() {
   404  					err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   405  						Name: "repo",
   406  						Tags: map[string]mTypes.Descriptor{
   407  							"mad-media-type": {
   408  								MediaType: "bad media type",
   409  								Digest:    godigest.FromString("dig").String(),
   410  							},
   411  						},
   412  					})
   413  					So(err, ShouldBeNil)
   414  
   415  					_, err = boltdbWrapper.SearchTags(ctx, "repo:")
   416  					So(err, ShouldBeNil)
   417  				})
   418  			})
   419  		})
   420  
   421  		Convey("FilterTags", func() {
   422  			Convey("unmarshalProtoRepoMeta fails", func() {
   423  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   424  				So(err, ShouldBeNil)
   425  
   426  				_, err = boltdbWrapper.FilterTags(ctx, mTypes.AcceptAllRepoTag, mTypes.AcceptAllImageMeta)
   427  				So(err, ShouldNotBeNil)
   428  			})
   429  
   430  			Convey("bad media Type fails", func() {
   431  				err := boltdbWrapper.SetRepoMeta("repo", mTypes.RepoMeta{
   432  					Name: "repo",
   433  					Tags: map[string]mTypes.Descriptor{
   434  						"bad-repo-meta": {
   435  							MediaType: "bad media type",
   436  							Digest:    godigest.FromString("dig").String(),
   437  						},
   438  					},
   439  				})
   440  				So(err, ShouldBeNil)
   441  
   442  				_, err = boltdbWrapper.FilterTags(ctx, mTypes.AcceptAllRepoTag, mTypes.AcceptAllImageMeta)
   443  				So(err, ShouldBeNil)
   444  			})
   445  		})
   446  
   447  		Convey("SearchRepos", func() {
   448  			Convey("unmarshalProtoRepoMeta fails", func() {
   449  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   450  				So(err, ShouldBeNil)
   451  
   452  				// manifests are missing
   453  				_, err = boltdbWrapper.SearchRepos(ctx, "repo")
   454  				So(err, ShouldNotBeNil)
   455  			})
   456  		})
   457  
   458  		Convey("FilterImageMeta", func() {
   459  			Convey("MediaType ImageIndex, getProtoImageMeta fails", func() {
   460  				err := boltdbWrapper.SetImageMeta(multiarchImageMeta.Digest, multiarchImageMeta)
   461  				So(err, ShouldBeNil)
   462  
   463  				err = setImageMeta(image.Digest(), badProtoBlob, boltdbWrapper.DB)
   464  				So(err, ShouldBeNil)
   465  
   466  				// manifests are missing
   467  				_, err = boltdbWrapper.FilterImageMeta(ctx, []string{multiarchImageMeta.Digest.String()})
   468  				So(err, ShouldNotBeNil)
   469  			})
   470  		})
   471  
   472  		Convey("SetRepoReference", func() {
   473  			Convey("getProtoRepoMeta errors", func() {
   474  				err := setRepoMeta("repo", badProtoBlob, boltdbWrapper.DB)
   475  				So(err, ShouldBeNil)
   476  
   477  				err = boltdbWrapper.SetRepoReference(ctx, "repo", "tag", imageMeta)
   478  				So(err, ShouldNotBeNil)
   479  			})
   480  
   481  			Convey("unmarshalProtoRepoBlobs errors", func() {
   482  				err := setRepoMeta("repo", goodRepoMetaBlob, boltdbWrapper.DB)
   483  				So(err, ShouldBeNil)
   484  
   485  				err = setRepoBlobInfo("repo", badProtoBlob, boltdbWrapper.DB)
   486  				So(err, ShouldBeNil)
   487  
   488  				err = boltdbWrapper.SetRepoReference(ctx, "repo", "tag", imageMeta)
   489  				So(err, ShouldNotBeNil)
   490  			})
   491  		})
   492  
   493  		Convey("AddUserAPIKey", func() {
   494  			Convey("no userid found", func() {
   495  				userAc := reqCtx.NewUserAccessControl()
   496  				ctx := userAc.DeriveContext(context.Background())
   497  
   498  				err = boltdbWrapper.AddUserAPIKey(ctx, "", &mTypes.APIKeyDetails{})
   499  				So(err, ShouldNotBeNil)
   500  			})
   501  
   502  			err = boltdbWrapper.AddUserAPIKey(ctx, "", &mTypes.APIKeyDetails{})
   503  			So(err, ShouldNotBeNil)
   504  
   505  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   506  				return tx.DeleteBucket([]byte(boltdb.UserDataBucket))
   507  			})
   508  			So(err, ShouldBeNil)
   509  
   510  			err = boltdbWrapper.AddUserAPIKey(ctx, "test", &mTypes.APIKeyDetails{})
   511  			So(err, ShouldNotBeNil)
   512  
   513  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   514  				return tx.DeleteBucket([]byte(boltdb.UserAPIKeysBucket))
   515  			})
   516  
   517  			So(err, ShouldBeNil)
   518  
   519  			err = boltdbWrapper.AddUserAPIKey(ctx, "", &mTypes.APIKeyDetails{})
   520  			So(err, ShouldEqual, zerr.ErrBucketDoesNotExist)
   521  		})
   522  
   523  		Convey("UpdateUserAPIKey", func() {
   524  			err = boltdbWrapper.UpdateUserAPIKeyLastUsed(ctx, "")
   525  			So(err, ShouldNotBeNil)
   526  
   527  			userAc := reqCtx.NewUserAccessControl()
   528  			ctx := userAc.DeriveContext(context.Background())
   529  
   530  			err = boltdbWrapper.UpdateUserAPIKeyLastUsed(ctx, "") //nolint: contextcheck
   531  			So(err, ShouldNotBeNil)
   532  		})
   533  
   534  		Convey("DeleteUserAPIKey", func() {
   535  			err = boltdbWrapper.SetUserData(ctx, mTypes.UserData{})
   536  			So(err, ShouldBeNil)
   537  
   538  			err = boltdbWrapper.AddUserAPIKey(ctx, "hashedKey", &mTypes.APIKeyDetails{})
   539  			So(err, ShouldBeNil)
   540  
   541  			Convey("no such bucket", func() {
   542  				err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   543  					return tx.DeleteBucket([]byte(boltdb.UserAPIKeysBucket))
   544  				})
   545  				So(err, ShouldBeNil)
   546  
   547  				userAc := reqCtx.NewUserAccessControl()
   548  				userAc.SetUsername("test")
   549  				ctx := userAc.DeriveContext(context.Background())
   550  
   551  				err = boltdbWrapper.DeleteUserAPIKey(ctx, "")
   552  				So(err, ShouldEqual, zerr.ErrBucketDoesNotExist)
   553  			})
   554  
   555  			Convey("userdata not found", func() {
   556  				userAc := reqCtx.NewUserAccessControl()
   557  				userAc.SetUsername("test")
   558  				ctx := userAc.DeriveContext(context.Background())
   559  
   560  				err := boltdbWrapper.DeleteUserData(ctx)
   561  				So(err, ShouldBeNil)
   562  
   563  				err = boltdbWrapper.DeleteUserAPIKey(ctx, "")
   564  				So(err, ShouldNotBeNil)
   565  			})
   566  
   567  			userAc := reqCtx.NewUserAccessControl()
   568  			ctx := userAc.DeriveContext(context.Background())
   569  
   570  			err = boltdbWrapper.DeleteUserAPIKey(ctx, "test") //nolint: contextcheck
   571  			So(err, ShouldNotBeNil)
   572  
   573  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   574  				return tx.DeleteBucket([]byte(boltdb.UserDataBucket))
   575  			})
   576  			So(err, ShouldBeNil)
   577  
   578  			err = boltdbWrapper.DeleteUserAPIKey(ctx, "") //nolint: contextcheck
   579  			So(err, ShouldNotBeNil)
   580  		})
   581  
   582  		Convey("GetUserAPIKeyInfo", func() {
   583  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   584  				return tx.DeleteBucket([]byte(boltdb.UserAPIKeysBucket))
   585  			})
   586  			So(err, ShouldBeNil)
   587  
   588  			_, err = boltdbWrapper.GetUserAPIKeyInfo("")
   589  			So(err, ShouldNotBeNil)
   590  		})
   591  
   592  		Convey("GetUserData", func() {
   593  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   594  				buck := tx.Bucket([]byte(boltdb.UserDataBucket))
   595  				So(buck, ShouldNotBeNil)
   596  
   597  				return buck.Put([]byte("test"), []byte("dsa8"))
   598  			})
   599  
   600  			So(err, ShouldBeNil)
   601  
   602  			_, err = boltdbWrapper.GetUserData(ctx)
   603  			So(err, ShouldNotBeNil)
   604  
   605  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   606  				return tx.DeleteBucket([]byte(boltdb.UserAPIKeysBucket))
   607  			})
   608  			So(err, ShouldBeNil)
   609  
   610  			_, err = boltdbWrapper.GetUserData(ctx)
   611  			So(err, ShouldNotBeNil)
   612  		})
   613  
   614  		Convey("SetUserData", func() {
   615  			userAc := reqCtx.NewUserAccessControl()
   616  			ctx := userAc.DeriveContext(context.Background())
   617  
   618  			err = boltdbWrapper.SetUserData(ctx, mTypes.UserData{})
   619  			So(err, ShouldNotBeNil)
   620  
   621  			buff := make([]byte, int(math.Ceil(float64(1000000)/float64(1.33333333333))))
   622  			_, err := rand.Read(buff)
   623  			So(err, ShouldBeNil)
   624  
   625  			longString := base64.RawURLEncoding.EncodeToString(buff)
   626  
   627  			userAc = reqCtx.NewUserAccessControl()
   628  			userAc.SetUsername(longString)
   629  			ctx = userAc.DeriveContext(context.Background())
   630  
   631  			err = boltdbWrapper.SetUserData(ctx, mTypes.UserData{}) //nolint: contextcheck
   632  			So(err, ShouldNotBeNil)
   633  
   634  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   635  				return tx.DeleteBucket([]byte(boltdb.UserDataBucket))
   636  			})
   637  			So(err, ShouldBeNil)
   638  
   639  			userAc = reqCtx.NewUserAccessControl()
   640  			userAc.SetUsername("test")
   641  			ctx = userAc.DeriveContext(context.Background())
   642  
   643  			err = boltdbWrapper.SetUserData(ctx, mTypes.UserData{}) //nolint: contextcheck
   644  			So(err, ShouldNotBeNil)
   645  		})
   646  
   647  		Convey("DeleteUserData", func() {
   648  			userAc = reqCtx.NewUserAccessControl()
   649  			ctx = userAc.DeriveContext(context.Background())
   650  
   651  			err = boltdbWrapper.DeleteUserData(ctx)
   652  			So(err, ShouldNotBeNil)
   653  
   654  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   655  				return tx.DeleteBucket([]byte(boltdb.UserDataBucket))
   656  			})
   657  			So(err, ShouldBeNil)
   658  
   659  			userAc = reqCtx.NewUserAccessControl()
   660  			userAc.SetUsername("test")
   661  			ctx = userAc.DeriveContext(context.Background())
   662  
   663  			err = boltdbWrapper.DeleteUserData(ctx)
   664  			So(err, ShouldNotBeNil)
   665  		})
   666  
   667  		Convey("GetUserGroups and SetUserGroups", func() {
   668  			userAc = reqCtx.NewUserAccessControl()
   669  			ctx = userAc.DeriveContext(context.Background())
   670  
   671  			_, err := boltdbWrapper.GetUserGroups(ctx)
   672  			So(err, ShouldNotBeNil)
   673  
   674  			err = boltdbWrapper.SetUserGroups(ctx, []string{})
   675  			So(err, ShouldNotBeNil)
   676  		})
   677  
   678  		Convey("ToggleStarRepo bad context errors", func() {
   679  			uacKey := reqCtx.GetContextKey()
   680  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   681  
   682  			_, err := boltdbWrapper.ToggleStarRepo(ctx, "repo")
   683  			So(err, ShouldNotBeNil)
   684  		})
   685  
   686  		Convey("ToggleStarRepo, no repoMeta found", func() {
   687  			userAc := reqCtx.NewUserAccessControl()
   688  			userAc.SetUsername("username")
   689  			userAc.SetGlobPatterns("read", map[string]bool{
   690  				"repo": true,
   691  			})
   692  			ctx := userAc.DeriveContext(context.Background())
   693  
   694  			err := boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   695  				repoBuck := tx.Bucket([]byte(boltdb.RepoMetaBuck))
   696  
   697  				err := repoBuck.Put([]byte("repo"), []byte("bad repo"))
   698  				So(err, ShouldBeNil)
   699  
   700  				return nil
   701  			})
   702  			So(err, ShouldBeNil)
   703  
   704  			_, err = boltdbWrapper.ToggleStarRepo(ctx, "repo")
   705  			So(err, ShouldNotBeNil)
   706  		})
   707  
   708  		Convey("ToggleStarRepo, bad repoMeta found", func() {
   709  			userAc := reqCtx.NewUserAccessControl()
   710  			userAc.SetUsername("username")
   711  			userAc.SetGlobPatterns("read", map[string]bool{
   712  				"repo": true,
   713  			})
   714  			ctx := userAc.DeriveContext(context.Background())
   715  
   716  			_, err = boltdbWrapper.ToggleStarRepo(ctx, "repo")
   717  			So(err, ShouldNotBeNil)
   718  		})
   719  
   720  		Convey("ToggleBookmarkRepo bad context errors", func() {
   721  			uacKey := reqCtx.GetContextKey()
   722  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   723  
   724  			_, err := boltdbWrapper.ToggleBookmarkRepo(ctx, "repo")
   725  			So(err, ShouldNotBeNil)
   726  		})
   727  
   728  		Convey("GetUserData bad context errors", func() {
   729  			uacKey := reqCtx.GetContextKey()
   730  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   731  
   732  			_, err := boltdbWrapper.GetUserData(ctx)
   733  			So(err, ShouldNotBeNil)
   734  		})
   735  
   736  		Convey("SetUserData bad context errors", func() {
   737  			uacKey := reqCtx.GetContextKey()
   738  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   739  
   740  			err := boltdbWrapper.SetUserData(ctx, mTypes.UserData{})
   741  			So(err, ShouldNotBeNil)
   742  		})
   743  
   744  		Convey("GetUserGroups bad context errors", func() {
   745  			_, err := boltdbWrapper.GetUserGroups(ctx)
   746  			So(err, ShouldNotBeNil)
   747  
   748  			uacKey := reqCtx.GetContextKey()
   749  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   750  
   751  			_, err = boltdbWrapper.GetUserGroups(ctx) //nolint: contextcheck
   752  			So(err, ShouldNotBeNil)
   753  		})
   754  
   755  		Convey("SetUserGroups bad context errors", func() {
   756  			uacKey := reqCtx.GetContextKey()
   757  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   758  
   759  			err := boltdbWrapper.SetUserGroups(ctx, []string{})
   760  			So(err, ShouldNotBeNil)
   761  		})
   762  
   763  		Convey("AddUserAPIKey bad context errors", func() {
   764  			uacKey := reqCtx.GetContextKey()
   765  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   766  
   767  			err := boltdbWrapper.AddUserAPIKey(ctx, "", &mTypes.APIKeyDetails{})
   768  			So(err, ShouldNotBeNil)
   769  		})
   770  
   771  		Convey("DeleteUserAPIKey bad context errors", func() {
   772  			uacKey := reqCtx.GetContextKey()
   773  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   774  
   775  			err := boltdbWrapper.DeleteUserAPIKey(ctx, "")
   776  			So(err, ShouldNotBeNil)
   777  		})
   778  
   779  		Convey("UpdateUserAPIKeyLastUsed bad context errors", func() {
   780  			uacKey := reqCtx.GetContextKey()
   781  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   782  
   783  			err := boltdbWrapper.UpdateUserAPIKeyLastUsed(ctx, "")
   784  			So(err, ShouldNotBeNil)
   785  		})
   786  
   787  		Convey("DeleteUserData bad context errors", func() {
   788  			uacKey := reqCtx.GetContextKey()
   789  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   790  
   791  			err := boltdbWrapper.DeleteUserData(ctx)
   792  			So(err, ShouldNotBeNil)
   793  		})
   794  
   795  		Convey("GetStarredRepos bad context errors", func() {
   796  			uacKey := reqCtx.GetContextKey()
   797  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   798  
   799  			_, err := boltdbWrapper.GetStarredRepos(ctx)
   800  			So(err, ShouldNotBeNil)
   801  		})
   802  
   803  		Convey("GetBookmarkedRepos bad context errors", func() {
   804  			uacKey := reqCtx.GetContextKey()
   805  			ctx := context.WithValue(context.Background(), uacKey, "bad context")
   806  
   807  			_, err := boltdbWrapper.GetBookmarkedRepos(ctx)
   808  			So(err, ShouldNotBeNil)
   809  		})
   810  
   811  		Convey("GetUserRepoMeta unmarshal error", func() {
   812  			userAc := reqCtx.NewUserAccessControl()
   813  			userAc.SetUsername("username")
   814  			userAc.SetGlobPatterns("read", map[string]bool{
   815  				"repo": true,
   816  			})
   817  			ctx := userAc.DeriveContext(context.Background())
   818  
   819  			err = boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
   820  				repoBuck := tx.Bucket([]byte(boltdb.RepoMetaBuck))
   821  
   822  				err := repoBuck.Put([]byte("repo"), []byte("bad repo"))
   823  				So(err, ShouldBeNil)
   824  
   825  				return nil
   826  			})
   827  			So(err, ShouldBeNil)
   828  
   829  			_, err := boltdbWrapper.GetRepoMeta(ctx, "repo")
   830  			So(err, ShouldNotBeNil)
   831  		})
   832  	})
   833  }
   834  
   835  func setRepoMeta(repo string, blob []byte, db *bbolt.DB) error { //nolint: unparam
   836  	err := db.Update(func(tx *bbolt.Tx) error {
   837  		buck := tx.Bucket([]byte(boltdb.RepoMetaBuck))
   838  
   839  		return buck.Put([]byte(repo), blob)
   840  	})
   841  
   842  	return err
   843  }
   844  
   845  func setImageMeta(digest godigest.Digest, blob []byte, db *bbolt.DB) error {
   846  	err := db.Update(func(tx *bbolt.Tx) error {
   847  		buck := tx.Bucket([]byte(boltdb.ImageMetaBuck))
   848  
   849  		return buck.Put([]byte(digest.String()), blob)
   850  	})
   851  
   852  	return err
   853  }
   854  
   855  func setRepoBlobInfo(repo string, blob []byte, db *bbolt.DB) error {
   856  	err := db.Update(func(tx *bbolt.Tx) error {
   857  		buck := tx.Bucket([]byte(boltdb.RepoBlobsBuck))
   858  
   859  		return buck.Put([]byte(repo), blob)
   860  	})
   861  
   862  	return err
   863  }