harbor/src/controller/artifact/controller_test.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 = &registry.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{})
}