mirror of
https://github.com/goharbor/harbor
synced 2025-04-19 20:44:33 +00:00

add suject_artifact_repo column in the table artifact_accessory Signed-off-by: Wang Yan <wangyan@vmware.com>
670 lines
21 KiB
Go
670 lines
21 KiB
Go
// Copyright Project Harbor Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package artifact
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/goharbor/harbor/src/controller/artifact/processor/chart"
|
|
"github.com/goharbor/harbor/src/controller/artifact/processor/cnab"
|
|
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
|
|
"github.com/goharbor/harbor/src/controller/tag"
|
|
"github.com/goharbor/harbor/src/lib"
|
|
"github.com/goharbor/harbor/src/lib/errors"
|
|
"github.com/goharbor/harbor/src/lib/icon"
|
|
"github.com/goharbor/harbor/src/lib/orm"
|
|
"github.com/goharbor/harbor/src/lib/q"
|
|
accessorymodel "github.com/goharbor/harbor/src/pkg/accessory/model"
|
|
basemodel "github.com/goharbor/harbor/src/pkg/accessory/model/base"
|
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
|
"github.com/goharbor/harbor/src/pkg/label/model"
|
|
repomodel "github.com/goharbor/harbor/src/pkg/repository/model"
|
|
model_tag "github.com/goharbor/harbor/src/pkg/tag/model/tag"
|
|
tagtesting "github.com/goharbor/harbor/src/testing/controller/tag"
|
|
ormtesting "github.com/goharbor/harbor/src/testing/lib/orm"
|
|
"github.com/goharbor/harbor/src/testing/pkg/accessory"
|
|
accessorytesting "github.com/goharbor/harbor/src/testing/pkg/accessory"
|
|
arttesting "github.com/goharbor/harbor/src/testing/pkg/artifact"
|
|
artrashtesting "github.com/goharbor/harbor/src/testing/pkg/artifactrash"
|
|
"github.com/goharbor/harbor/src/testing/pkg/blob"
|
|
"github.com/goharbor/harbor/src/testing/pkg/immutable"
|
|
"github.com/goharbor/harbor/src/testing/pkg/label"
|
|
"github.com/goharbor/harbor/src/testing/pkg/registry"
|
|
repotesting "github.com/goharbor/harbor/src/testing/pkg/repository"
|
|
)
|
|
|
|
// TODO find another way to test artifact controller, it's hard to maintain currently
|
|
|
|
type fakeAbstractor struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (f *fakeAbstractor) AbstractMetadata(ctx context.Context, artifact *artifact.Artifact) error {
|
|
args := f.Called()
|
|
return args.Error(0)
|
|
}
|
|
|
|
type controllerTestSuite struct {
|
|
suite.Suite
|
|
ctl *controller
|
|
repoMgr *repotesting.Manager
|
|
artMgr *arttesting.Manager
|
|
artrashMgr *artrashtesting.FakeManager
|
|
blobMgr *blob.Manager
|
|
tagCtl *tagtesting.FakeController
|
|
labelMgr *label.Manager
|
|
abstractor *fakeAbstractor
|
|
immutableMtr *immutable.FakeMatcher
|
|
regCli *registry.Client
|
|
accMgr *accessory.Manager
|
|
}
|
|
|
|
func (c *controllerTestSuite) SetupTest() {
|
|
c.repoMgr = &repotesting.Manager{}
|
|
c.artMgr = &arttesting.Manager{}
|
|
c.artrashMgr = &artrashtesting.FakeManager{}
|
|
c.blobMgr = &blob.Manager{}
|
|
c.tagCtl = &tagtesting.FakeController{}
|
|
c.labelMgr = &label.Manager{}
|
|
c.abstractor = &fakeAbstractor{}
|
|
c.immutableMtr = &immutable.FakeMatcher{}
|
|
c.accMgr = &accessorytesting.Manager{}
|
|
c.regCli = ®istry.Client{}
|
|
c.ctl = &controller{
|
|
repoMgr: c.repoMgr,
|
|
artMgr: c.artMgr,
|
|
artrashMgr: c.artrashMgr,
|
|
blobMgr: c.blobMgr,
|
|
tagCtl: c.tagCtl,
|
|
labelMgr: c.labelMgr,
|
|
abstractor: c.abstractor,
|
|
immutableMtr: c.immutableMtr,
|
|
regCli: c.regCli,
|
|
accessoryMgr: c.accMgr,
|
|
}
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestAssembleArtifact() {
|
|
art := &artifact.Artifact{
|
|
ID: 1,
|
|
Digest: "sha256:123",
|
|
RepositoryName: "library/hello-world",
|
|
}
|
|
option := &Option{
|
|
WithTag: true,
|
|
TagOption: &tag.Option{
|
|
WithImmutableStatus: false,
|
|
},
|
|
WithLabel: true,
|
|
WithAccessory: true,
|
|
}
|
|
tg := &tag.Tag{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
ArtifactID: 1,
|
|
Name: "latest",
|
|
PushTime: time.Now(),
|
|
PullTime: time.Now(),
|
|
},
|
|
}
|
|
c.tagCtl.On("List").Return([]*tag.Tag{tg}, nil)
|
|
ctx := lib.WithAPIVersion(nil, "2.0")
|
|
lb := &model.Label{
|
|
ID: 1,
|
|
Name: "label",
|
|
}
|
|
c.labelMgr.On("ListByArtifact", mock.Anything, mock.Anything).Return([]*model.Label{
|
|
lb,
|
|
}, nil)
|
|
acc := &basemodel.Default{
|
|
Data: accessorymodel.AccessoryData{
|
|
ID: 1,
|
|
ArtifactID: 2,
|
|
SubArtifactDigest: "sha256:123",
|
|
Type: accessorymodel.TypeCosignSignature,
|
|
},
|
|
}
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{
|
|
acc,
|
|
}, nil)
|
|
artifact := c.ctl.assembleArtifact(ctx, art, option)
|
|
c.Require().NotNil(artifact)
|
|
c.Equal(art.ID, artifact.ID)
|
|
c.Equal(icon.DigestOfIconDefault, artifact.Icon)
|
|
c.Contains(artifact.Tags, tg)
|
|
c.Contains(artifact.Labels, lb)
|
|
c.Contains(artifact.Accessories, acc)
|
|
// TODO check other fields of option
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestPopulateIcon() {
|
|
cases := []struct {
|
|
art *artifact.Artifact
|
|
ico string
|
|
}{
|
|
{
|
|
art: &artifact.Artifact{
|
|
ID: 1,
|
|
Digest: "sha256:123",
|
|
Type: image.ArtifactTypeImage,
|
|
},
|
|
ico: icon.DigestOfIconImage,
|
|
},
|
|
{
|
|
art: &artifact.Artifact{
|
|
ID: 2,
|
|
Digest: "sha256:456",
|
|
Type: cnab.ArtifactTypeCNAB,
|
|
},
|
|
ico: icon.DigestOfIconCNAB,
|
|
},
|
|
{
|
|
art: &artifact.Artifact{
|
|
ID: 3,
|
|
Digest: "sha256:1234",
|
|
Type: chart.ArtifactTypeChart,
|
|
},
|
|
ico: icon.DigestOfIconChart,
|
|
},
|
|
{
|
|
art: &artifact.Artifact{
|
|
ID: 4,
|
|
Digest: "sha256:1234",
|
|
Type: "other",
|
|
},
|
|
ico: icon.DigestOfIconDefault,
|
|
},
|
|
{
|
|
art: &artifact.Artifact{
|
|
ID: 5,
|
|
Digest: "sha256:2345",
|
|
Type: image.ArtifactTypeImage,
|
|
Icon: "sha256:abcd",
|
|
},
|
|
ico: "sha256:abcd",
|
|
},
|
|
}
|
|
for _, cs := range cases {
|
|
a := &Artifact{
|
|
Artifact: *cs.art,
|
|
}
|
|
c.ctl.populateIcon(a)
|
|
c.Equal(cs.ico, a.Icon)
|
|
}
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestEnsureArtifact() {
|
|
digest := "sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180"
|
|
|
|
// the artifact already exists
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
}, nil)
|
|
created, art, err := c.ctl.ensureArtifact(orm.NewContext(nil, &ormtesting.FakeOrmer{}), "library/hello-world", digest)
|
|
c.Require().Nil(err)
|
|
c.False(created)
|
|
c.Equal(int64(1), art.ID)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// the artifact doesn't exist
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
ProjectID: 1,
|
|
}, nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
c.artMgr.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
|
c.abstractor.On("AbstractMetadata").Return(nil)
|
|
created, art, err = c.ctl.ensureArtifact(orm.NewContext(nil, &ormtesting.FakeOrmer{}), "library/hello-world", digest)
|
|
c.Require().Nil(err)
|
|
c.True(created)
|
|
c.Equal(int64(1), art.ID)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestEnsure() {
|
|
digest := "sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180"
|
|
|
|
// both the artifact and the tag don't exist
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
ProjectID: 1,
|
|
}, nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
c.artMgr.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
|
c.abstractor.On("AbstractMetadata").Return(nil)
|
|
c.tagCtl.On("Ensure").Return(nil)
|
|
c.accMgr.On("Ensure").Return(nil)
|
|
_, id, err := c.ctl.Ensure(orm.NewContext(nil, &ormtesting.FakeOrmer{}), "library/hello-world", digest, &ArtOption{
|
|
Tags: []string{"latest"},
|
|
})
|
|
c.Require().Nil(err)
|
|
c.repoMgr.AssertExpectations(c.T())
|
|
c.artMgr.AssertExpectations(c.T())
|
|
c.tagCtl.AssertExpectations(c.T())
|
|
c.abstractor.AssertExpectations(c.T())
|
|
c.Equal(int64(1), id)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestCount() {
|
|
c.artMgr.On("Count", mock.Anything, mock.Anything).Return(int64(1), nil)
|
|
total, err := c.ctl.Count(nil, nil)
|
|
c.Require().Nil(err)
|
|
c.Equal(int64(1), total)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestList() {
|
|
query := &q.Query{}
|
|
option := &Option{
|
|
WithTag: true,
|
|
WithAccessory: true,
|
|
}
|
|
c.artMgr.On("List", mock.Anything, mock.Anything).Return([]*artifact.Artifact{
|
|
{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
},
|
|
}, nil)
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
ArtifactID: 1,
|
|
Name: "latest",
|
|
},
|
|
},
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
Name: "library/hello-world",
|
|
}, nil)
|
|
c.repoMgr.On("List", mock.Anything, mock.Anything).Return([]*repomodel.RepoRecord{
|
|
{RepositoryID: 1, Name: "library/hello-world"},
|
|
}, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
artifacts, err := c.ctl.List(nil, query, option)
|
|
c.Require().Nil(err)
|
|
c.Require().Len(artifacts, 1)
|
|
c.Equal(int64(1), artifacts[0].ID)
|
|
c.Require().Len(artifacts[0].Tags, 1)
|
|
c.Equal(int64(1), artifacts[0].Tags[0].ID)
|
|
c.Equal(0, len(artifacts[0].Accessories))
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestGet() {
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
art, err := c.ctl.Get(nil, 1, nil)
|
|
c.Require().Nil(err)
|
|
c.Require().NotNil(art)
|
|
c.Equal(int64(1), art.ID)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestGetByDigest() {
|
|
// not found
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
art, err := c.ctl.getByDigest(nil, "library/hello-world",
|
|
"sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180", nil)
|
|
c.Require().NotNil(err)
|
|
c.True(errors.IsErr(err, errors.NotFoundCode))
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// success
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
art, err = c.ctl.getByDigest(nil, "library/hello-world",
|
|
"sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180", nil)
|
|
c.Require().Nil(err)
|
|
c.Require().NotNil(art)
|
|
c.Equal(int64(1), art.ID)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestGetByTag() {
|
|
// not found
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.tagCtl.On("List").Return(nil, nil)
|
|
art, err := c.ctl.getByTag(nil, "library/hello-world", "latest", nil)
|
|
c.Require().NotNil(err)
|
|
c.True(errors.IsErr(err, errors.NotFoundCode))
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// success
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
Name: "latest",
|
|
ArtifactID: 1,
|
|
},
|
|
},
|
|
}, nil)
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
art, err = c.ctl.getByTag(nil, "library/hello-world", "latest", nil)
|
|
c.Require().Nil(err)
|
|
c.Require().NotNil(art)
|
|
c.Equal(int64(1), art.ID)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestGetByReference() {
|
|
// reference is digest
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
art, err := c.ctl.GetByReference(nil, "library/hello-world",
|
|
"sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180", nil)
|
|
c.Require().Nil(err)
|
|
c.Require().NotNil(art)
|
|
c.Equal(int64(1), art.ID)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// reference is tag
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
}, nil)
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
RepositoryID: 1,
|
|
Name: "latest",
|
|
ArtifactID: 1,
|
|
},
|
|
},
|
|
}, nil)
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
art, err = c.ctl.GetByReference(nil, "library/hello-world", "latest", nil)
|
|
c.Require().Nil(err)
|
|
c.Require().NotNil(art)
|
|
c.Equal(int64(1), art.ID)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestDeleteDeeply() {
|
|
// root artifact and doesn't exist
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
err := c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, false)
|
|
c.Require().NotNil(err)
|
|
c.Assert().True(errors.IsErr(err, errors.NotFoundCode))
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// child artifact and doesn't exist
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false, false)
|
|
c.Require().Nil(err)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// child artifact and contains tags
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{ID: 1}, nil)
|
|
c.artMgr.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
},
|
|
},
|
|
}, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
c.artrashMgr.On("Create").Return(0, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false, false)
|
|
c.Require().Nil(err)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// root artifact is referenced by other artifacts
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{ID: 1}, nil)
|
|
c.tagCtl.On("List").Return(nil, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
c.artMgr.On("ListReferences", mock.Anything, mock.Anything).Return([]*artifact.Reference{
|
|
{
|
|
ID: 1,
|
|
},
|
|
}, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, false)
|
|
c.Require().NotNil(err)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// child artifact contains no tag but referenced by other artifacts
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{ID: 1}, nil)
|
|
c.tagCtl.On("List").Return(nil, nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
c.artMgr.On("ListReferences", mock.Anything, mock.Anything).Return([]*artifact.Reference{
|
|
{
|
|
ID: 1,
|
|
},
|
|
}, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
err = c.ctl.deleteDeeply(nil, 1, false, false)
|
|
c.Require().Nil(err)
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// accessory contains tag
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{ID: 1}, nil)
|
|
c.artMgr.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
},
|
|
},
|
|
}, nil)
|
|
c.tagCtl.On("DeleteTags", mock.Anything, mock.Anything).Return(nil)
|
|
c.labelMgr.On("RemoveAllFrom", mock.Anything, mock.Anything).Return(nil)
|
|
c.artMgr.On("ListReferences", mock.Anything, mock.Anything).Return([]*artifact.Reference{}, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
c.accMgr.On("DeleteAccessories", mock.Anything, mock.Anything).Return(nil)
|
|
c.blobMgr.On("List", mock.Anything, mock.Anything).Return(nil, nil)
|
|
c.blobMgr.On("CleanupAssociationsForProject", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
|
c.artrashMgr.On("Create").Return(0, nil)
|
|
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, true)
|
|
c.Require().Nil(err)
|
|
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestCopy() {
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{
|
|
ID: 1,
|
|
Digest: "sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180",
|
|
}, nil)
|
|
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
Name: "library/hello-world",
|
|
}, nil)
|
|
c.artMgr.On("Count", mock.Anything, mock.Anything).Return(int64(0), nil)
|
|
c.artMgr.On("GetByDigest", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
|
c.tagCtl.On("List").Return([]*tag.Tag{
|
|
{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
Name: "latest",
|
|
},
|
|
},
|
|
}, nil)
|
|
acc := &basemodel.Default{
|
|
Data: accessorymodel.AccessoryData{
|
|
ID: 1,
|
|
ArtifactID: 2,
|
|
SubArtifactDigest: "sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180",
|
|
Type: accessorymodel.TypeCosignSignature,
|
|
},
|
|
}
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{
|
|
acc,
|
|
}, nil)
|
|
c.tagCtl.On("Update").Return(nil)
|
|
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{
|
|
RepositoryID: 1,
|
|
Name: "library/hello-world",
|
|
}, nil)
|
|
c.abstractor.On("AbstractMetadata").Return(nil)
|
|
c.artMgr.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
|
c.regCli.On("Copy", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
c.tagCtl.On("Ensure").Return(nil)
|
|
c.accMgr.On("Ensure", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
_, err := c.ctl.Copy(orm.NewContext(nil, &ormtesting.FakeOrmer{}), "library/hello-world", "latest", "library/hello-world2")
|
|
c.Require().Nil(err)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestUpdatePullTime() {
|
|
// artifact ID and tag ID matches
|
|
c.tagCtl.On("Get").Return(&tag.Tag{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
ArtifactID: 1,
|
|
},
|
|
}, nil)
|
|
c.tagCtl.On("Update").Return(nil)
|
|
c.artMgr.On("UpdatePullTime", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
err := c.ctl.UpdatePullTime(nil, 1, 1, time.Now())
|
|
c.Require().Nil(err)
|
|
c.artMgr.AssertExpectations(c.T())
|
|
c.tagCtl.AssertExpectations(c.T())
|
|
|
|
// reset the mock
|
|
c.SetupTest()
|
|
|
|
// artifact ID and tag ID doesn't match
|
|
c.tagCtl.On("Get").Return(&tag.Tag{
|
|
Tag: model_tag.Tag{
|
|
ID: 1,
|
|
ArtifactID: 2,
|
|
},
|
|
}, nil)
|
|
c.artMgr.On("UpdatePullTime", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
err = c.ctl.UpdatePullTime(nil, 1, 1, time.Now())
|
|
c.Require().NotNil(err)
|
|
c.tagCtl.AssertExpectations(c.T())
|
|
|
|
// if no tag, should not update tag
|
|
c.SetupTest()
|
|
c.tagCtl.On("Update").Return(nil)
|
|
c.artMgr.On("UpdatePullTime", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
err = c.ctl.UpdatePullTime(nil, 1, 0, time.Now())
|
|
c.Require().Nil(err)
|
|
c.artMgr.AssertExpectations(c.T())
|
|
// should not call tag Update
|
|
c.tagCtl.AssertNotCalled(c.T(), "Update")
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestGetAddition() {
|
|
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{}, nil)
|
|
_, err := c.ctl.GetAddition(nil, 1, "addition")
|
|
c.Require().NotNil(err)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestAddTo() {
|
|
c.labelMgr.On("AddTo", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
err := c.ctl.AddLabel(context.Background(), 1, 1)
|
|
c.Require().Nil(err)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestRemoveFrom() {
|
|
c.labelMgr.On("RemoveFrom", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
err := c.ctl.RemoveLabel(nil, 1, 1)
|
|
c.Require().Nil(err)
|
|
}
|
|
|
|
func (c *controllerTestSuite) TestWalk() {
|
|
c.artMgr.On("List", mock.Anything, mock.Anything).Return([]*artifact.Artifact{
|
|
{Digest: "d1", ManifestMediaType: v1.MediaTypeImageManifest},
|
|
{Digest: "d2", ManifestMediaType: v1.MediaTypeImageManifest},
|
|
}, nil)
|
|
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
|
|
|
{
|
|
root := &Artifact{}
|
|
|
|
var n int
|
|
c.ctl.Walk(context.TODO(), root, func(a *Artifact) error {
|
|
n++
|
|
return nil
|
|
}, nil)
|
|
|
|
c.Equal(1, n)
|
|
}
|
|
|
|
{
|
|
root := &Artifact{}
|
|
root.References = []*artifact.Reference{
|
|
{ParentID: 1, ChildID: 2},
|
|
{ParentID: 1, ChildID: 3},
|
|
}
|
|
|
|
var n int
|
|
c.ctl.Walk(context.TODO(), root, func(a *Artifact) error {
|
|
n++
|
|
return nil
|
|
}, nil)
|
|
|
|
c.Equal(3, n)
|
|
}
|
|
}
|
|
|
|
func TestControllerTestSuite(t *testing.T) {
|
|
suite.Run(t, &controllerTestSuite{})
|
|
}
|