zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/extensions/sync/references/references_internal_test.go (about)

     1  //go:build sync
     2  // +build sync
     3  
     4  package references
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"testing"
    10  
    11  	godigest "github.com/opencontainers/go-digest"
    12  	ispec "github.com/opencontainers/image-spec/specs-go/v1"
    13  	artifactspec "github.com/oras-project/artifacts-spec/specs-go/v1"
    14  	. "github.com/smartystreets/goconvey/convey"
    15  
    16  	zerr "zotregistry.io/zot/errors"
    17  	client "zotregistry.io/zot/pkg/extensions/sync/httpclient"
    18  	"zotregistry.io/zot/pkg/log"
    19  	"zotregistry.io/zot/pkg/storage"
    20  	"zotregistry.io/zot/pkg/test/mocks"
    21  )
    22  
    23  var errRef = errors.New("err")
    24  
    25  func TestCosign(t *testing.T) {
    26  	Convey("trigger errors", t, func() {
    27  		cfg := client.Config{
    28  			URL:       "url",
    29  			TLSVerify: false,
    30  		}
    31  
    32  		client, err := client.New(cfg, log.NewLogger("debug", ""))
    33  		So(err, ShouldBeNil)
    34  
    35  		cosign := NewCosignReference(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
    36  			GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
    37  				return []byte{}, "", "", errRef
    38  			},
    39  		}}, nil, log.NewLogger("debug", ""))
    40  
    41  		ok, err := cosign.canSkipReferences("repo", "tag", nil)
    42  		So(err, ShouldBeNil)
    43  		So(ok, ShouldBeTrue)
    44  
    45  		// trigger GetImageManifest err
    46  		ok, err = cosign.canSkipReferences("repo", "tag", &ispec.Manifest{MediaType: ispec.MediaTypeImageManifest})
    47  		So(err, ShouldNotBeNil)
    48  		So(ok, ShouldBeFalse)
    49  
    50  		cosign = NewCosignReference(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
    51  			GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
    52  				return []byte{}, "digest", "", nil
    53  			},
    54  		}}, nil, log.NewLogger("debug", ""))
    55  
    56  		// different digest
    57  		ok, err = cosign.canSkipReferences("repo", "tag", &ispec.Manifest{MediaType: ispec.MediaTypeImageManifest})
    58  		So(err, ShouldBeNil)
    59  		So(ok, ShouldBeFalse)
    60  	})
    61  }
    62  
    63  func TestOci(t *testing.T) {
    64  	Convey("trigger errors", t, func() {
    65  		cfg := client.Config{
    66  			URL:       "url",
    67  			TLSVerify: false,
    68  		}
    69  
    70  		client, err := client.New(cfg, log.NewLogger("debug", ""))
    71  		So(err, ShouldBeNil)
    72  
    73  		oci := NewOciReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
    74  			GetReferrersFn: func(repo string, digest godigest.Digest, artifactTypes []string) (ispec.Index, error) {
    75  				return ispec.Index{}, zerr.ErrManifestNotFound
    76  			},
    77  		}}, nil, log.NewLogger("debug", ""))
    78  
    79  		ok := oci.IsSigned(context.Background(), "repo", "")
    80  		So(ok, ShouldBeFalse)
    81  
    82  		// trigger GetReferrers err
    83  		ok, err = oci.canSkipReferences("repo", "tag", ispec.Index{Manifests: []ispec.Descriptor{{Digest: "digest1"}}})
    84  		So(err, ShouldBeNil)
    85  		So(ok, ShouldBeFalse)
    86  	})
    87  }
    88  
    89  func TestReferrersTag(t *testing.T) {
    90  	Convey("trigger errors", t, func() {
    91  		cfg := client.Config{
    92  			URL:       "url",
    93  			TLSVerify: false,
    94  		}
    95  
    96  		client, err := client.New(cfg, log.NewLogger("debug", ""))
    97  		So(err, ShouldBeNil)
    98  
    99  		referrersTag := NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
   100  			GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
   101  				return []byte{}, "", "", errRef
   102  			},
   103  		}}, nil, log.NewLogger("debug", ""))
   104  
   105  		ok := referrersTag.IsSigned(context.Background(), "repo", "")
   106  		So(ok, ShouldBeFalse)
   107  
   108  		// trigger GetImageManifest err
   109  		ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
   110  		So(err, ShouldNotBeNil)
   111  		So(ok, ShouldBeFalse)
   112  
   113  		referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
   114  			GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
   115  				return []byte{}, "", "", zerr.ErrManifestNotFound
   116  			},
   117  		}}, nil, log.NewLogger("debug", ""))
   118  
   119  		// trigger GetImageManifest err
   120  		ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
   121  		So(err, ShouldBeNil)
   122  		So(ok, ShouldBeFalse)
   123  
   124  		referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
   125  			GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
   126  				return []byte{}, "digest", "", nil
   127  			},
   128  		}}, nil, log.NewLogger("debug", ""))
   129  
   130  		// different digest
   131  		ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "newdigest")
   132  		So(err, ShouldBeNil)
   133  		So(ok, ShouldBeFalse)
   134  	})
   135  }
   136  
   137  func TestORAS(t *testing.T) {
   138  	Convey("trigger errors", t, func() {
   139  		cfg := client.Config{
   140  			URL:       "url",
   141  			TLSVerify: false,
   142  		}
   143  
   144  		client, err := client.New(cfg, log.NewLogger("debug", ""))
   145  		So(err, ShouldBeNil)
   146  
   147  		orasRefs := []artifactspec.Descriptor{
   148  			{
   149  				MediaType:    "oras",
   150  				ArtifactType: "oras",
   151  				Digest:       "digest1",
   152  			},
   153  		}
   154  
   155  		oras := NewORASReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
   156  			GetOrasReferrersFn: func(repo string, digest godigest.Digest, artifactType string) (
   157  				[]artifactspec.Descriptor, error,
   158  			) {
   159  				return orasRefs, nil
   160  			},
   161  		}}, nil, log.NewLogger("debug", ""))
   162  
   163  		// trigger artifactDescriptors not equal
   164  		ok, err := oras.canSkipReferences("repo", "tag", ReferenceList{[]artifactspec.Descriptor{
   165  			{
   166  				MediaType:    "oras",
   167  				ArtifactType: "oras",
   168  				Digest:       "digest2",
   169  			},
   170  		}})
   171  		So(err, ShouldBeNil)
   172  		So(ok, ShouldBeFalse)
   173  	})
   174  }
   175  
   176  func TestSyncManifest(t *testing.T) {
   177  	Convey("sync manifest not found err", t, func() {
   178  		cfg := client.Config{
   179  			URL:       "url",
   180  			TLSVerify: false,
   181  		}
   182  
   183  		client, err := client.New(cfg, log.NewLogger("debug", ""))
   184  		So(err, ShouldBeNil)
   185  
   186  		digest := godigest.FromString("test")
   187  
   188  		buf, refDigest, err := syncManifest(context.Background(), client, mocks.MockedImageStore{},
   189  			"repo", "repo", ispec.Descriptor{
   190  				Digest:    digest,
   191  				Size:      10,
   192  				MediaType: ispec.MediaTypeImageManifest,
   193  			}, digest.String(), log.Logger{})
   194  
   195  		So(buf, ShouldBeEmpty)
   196  		So(refDigest, ShouldBeEmpty)
   197  		So(err, ShouldNotBeNil)
   198  	})
   199  }
   200  
   201  func TestCompareManifest(t *testing.T) {
   202  	testCases := []struct {
   203  		manifest1 ispec.Manifest
   204  		manifest2 ispec.Manifest
   205  		expected  bool
   206  	}{
   207  		{
   208  			manifest1: ispec.Manifest{
   209  				Config: ispec.Descriptor{
   210  					Digest: "digest1",
   211  				},
   212  			},
   213  			manifest2: ispec.Manifest{
   214  				Config: ispec.Descriptor{
   215  					Digest: "digest2",
   216  				},
   217  			},
   218  			expected: false,
   219  		},
   220  		{
   221  			manifest1: ispec.Manifest{
   222  				Config: ispec.Descriptor{
   223  					Digest: "digest",
   224  				},
   225  			},
   226  			manifest2: ispec.Manifest{
   227  				Config: ispec.Descriptor{
   228  					Digest: "digest",
   229  				},
   230  			},
   231  			expected: true,
   232  		},
   233  		{
   234  			manifest1: ispec.Manifest{
   235  				Layers: []ispec.Descriptor{{
   236  					Digest: "digest",
   237  					Size:   1,
   238  				}},
   239  			},
   240  			manifest2: ispec.Manifest{
   241  				Layers: []ispec.Descriptor{{
   242  					Digest: "digest",
   243  					Size:   1,
   244  				}},
   245  			},
   246  			expected: true,
   247  		},
   248  		{
   249  			manifest1: ispec.Manifest{
   250  				Layers: []ispec.Descriptor{{
   251  					Digest: "digest1",
   252  					Size:   1,
   253  				}},
   254  			},
   255  			manifest2: ispec.Manifest{
   256  				Layers: []ispec.Descriptor{{
   257  					Digest: "digest2",
   258  					Size:   2,
   259  				}},
   260  			},
   261  			expected: false,
   262  		},
   263  		{
   264  			manifest1: ispec.Manifest{
   265  				Layers: []ispec.Descriptor{
   266  					{
   267  						Digest: "digest",
   268  						Size:   1,
   269  					},
   270  					{
   271  						Digest: "digest1",
   272  						Size:   1,
   273  					},
   274  				},
   275  			},
   276  			manifest2: ispec.Manifest{
   277  				Layers: []ispec.Descriptor{{
   278  					Digest: "digest",
   279  					Size:   1,
   280  				}},
   281  			},
   282  			expected: false,
   283  		},
   284  		{
   285  			manifest1: ispec.Manifest{
   286  				Layers: []ispec.Descriptor{
   287  					{
   288  						Digest: "digest1",
   289  						Size:   1,
   290  					},
   291  					{
   292  						Digest: "digest2",
   293  						Size:   2,
   294  					},
   295  				},
   296  			},
   297  			manifest2: ispec.Manifest{
   298  				Layers: []ispec.Descriptor{
   299  					{
   300  						Digest: "digest1",
   301  						Size:   1,
   302  					},
   303  					{
   304  						Digest: "digest2",
   305  						Size:   2,
   306  					},
   307  				},
   308  			},
   309  			expected: true,
   310  		},
   311  		{
   312  			manifest1: ispec.Manifest{
   313  				Layers: []ispec.Descriptor{
   314  					{
   315  						Digest: "digest",
   316  						Size:   1,
   317  					},
   318  					{
   319  						Digest: "digest1",
   320  						Size:   1,
   321  					},
   322  				},
   323  			},
   324  			manifest2: ispec.Manifest{
   325  				Layers: []ispec.Descriptor{
   326  					{
   327  						Digest: "digest",
   328  						Size:   1,
   329  					},
   330  					{
   331  						Digest: "digest2",
   332  						Size:   2,
   333  					},
   334  				},
   335  			},
   336  			expected: false,
   337  		},
   338  	}
   339  
   340  	Convey("Test manifestsEqual()", t, func() {
   341  		for _, test := range testCases {
   342  			actualResult := manifestsEqual(test.manifest1, test.manifest2)
   343  			So(actualResult, ShouldEqual, test.expected)
   344  		}
   345  	})
   346  }
   347  
   348  func TestCompareArtifactRefs(t *testing.T) {
   349  	testCases := []struct {
   350  		refs1    []artifactspec.Descriptor
   351  		refs2    []artifactspec.Descriptor
   352  		expected bool
   353  	}{
   354  		{
   355  			refs1: []artifactspec.Descriptor{
   356  				{
   357  					Digest: "digest1",
   358  				},
   359  			},
   360  			refs2: []artifactspec.Descriptor{
   361  				{
   362  					Digest: "digest2",
   363  				},
   364  			},
   365  			expected: false,
   366  		},
   367  		{
   368  			refs1: []artifactspec.Descriptor{
   369  				{
   370  					Digest: "digest",
   371  				},
   372  			},
   373  			refs2: []artifactspec.Descriptor{
   374  				{
   375  					Digest: "digest",
   376  				},
   377  			},
   378  			expected: true,
   379  		},
   380  		{
   381  			refs1: []artifactspec.Descriptor{
   382  				{
   383  					Digest: "digest",
   384  				},
   385  				{
   386  					Digest: "digest2",
   387  				},
   388  			},
   389  			refs2: []artifactspec.Descriptor{
   390  				{
   391  					Digest: "digest",
   392  				},
   393  			},
   394  			expected: false,
   395  		},
   396  		{
   397  			refs1: []artifactspec.Descriptor{
   398  				{
   399  					Digest: "digest1",
   400  				},
   401  				{
   402  					Digest: "digest2",
   403  				},
   404  			},
   405  			refs2: []artifactspec.Descriptor{
   406  				{
   407  					Digest: "digest1",
   408  				},
   409  				{
   410  					Digest: "digest2",
   411  				},
   412  			},
   413  			expected: true,
   414  		},
   415  		{
   416  			refs1: []artifactspec.Descriptor{
   417  				{
   418  					Digest: "digest",
   419  				},
   420  				{
   421  					Digest: "digest1",
   422  				},
   423  			},
   424  			refs2: []artifactspec.Descriptor{
   425  				{
   426  					Digest: "digest1",
   427  				},
   428  				{
   429  					Digest: "digest2",
   430  				},
   431  			},
   432  			expected: false,
   433  		},
   434  	}
   435  
   436  	Convey("Test manifestsEqual()", t, func() {
   437  		for _, test := range testCases {
   438  			actualResult := artifactDescriptorsEqual(test.refs1, test.refs2)
   439  			So(actualResult, ShouldEqual, test.expected)
   440  		}
   441  	})
   442  }