harbor/src/controller/scanner/base_controller_test.go
Loong Dai 09371b48e8
lint: sort imports (#17131)
* lint: add goimports

Signed-off-by: Loong Dai <loong.dai@intel.com>
2022-07-20 11:33:08 +08:00

313 lines
9.3 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 scanner
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
mocktesting "github.com/goharbor/harbor/src/testing/mock"
metadatatesting "github.com/goharbor/harbor/src/testing/pkg/project/metadata"
v1testing "github.com/goharbor/harbor/src/testing/pkg/scan/rest/v1"
scannertesting "github.com/goharbor/harbor/src/testing/pkg/scan/scanner"
)
// ControllerTestSuite is test suite to test the basic api controller.
type ControllerTestSuite struct {
suite.Suite
c *basicController
mMgr *scannertesting.Manager
mMeta *metadatatesting.Manager
sample *scanner.Registration
}
// TestController is the entry of controller test suite
func TestController(t *testing.T) {
suite.Run(t, new(ControllerTestSuite))
}
// SetupTest prepares env for the controller test suite
func (suite *ControllerTestSuite) SetupTest() {
suite.mMgr = &scannertesting.Manager{}
suite.mMeta = &metadatatesting.Manager{}
m := &v1.ScannerAdapterMetadata{
Scanner: &v1.Scanner{
Name: "Trivy",
Vendor: "Harbor",
Version: "0.1.0",
},
Capabilities: []*v1.ScannerCapability{{
ConsumesMimeTypes: []string{
v1.MimeTypeOCIArtifact,
v1.MimeTypeDockerArtifact,
},
ProducesMimeTypes: []string{
v1.MimeTypeNativeReport,
v1.MimeTypeRawReport,
v1.MimeTypeGenericVulnerabilityReport,
},
}},
Properties: v1.ScannerProperties{
"extra": "testing",
},
}
suite.sample = &scanner.Registration{
Name: "forUT",
Description: "sample registration",
URL: "https://sample.scanner.com",
}
mc := &v1testing.Client{}
mc.On("GetMetadata").Return(m, nil)
mcp := &v1testing.ClientPool{}
mocktesting.OnAnything(mcp, "Get").Return(mc, nil)
suite.c = &basicController{
manager: suite.mMgr,
proMetaMgr: suite.mMeta,
clientPool: mcp,
}
}
// Clear test case
func (suite *ControllerTestSuite) TearDownTest() {
suite.sample.UUID = ""
}
// TestListRegistrations tests ListRegistrations
func (suite *ControllerTestSuite) TestListRegistrations() {
query := &q.Query{
PageSize: 10,
PageNumber: 1,
}
suite.sample.UUID = "uuid"
l := []*scanner.Registration{suite.sample}
suite.mMgr.On("List", mock.Anything, query).Return(l, nil)
rl, err := suite.c.ListRegistrations(context.TODO(), query)
require.NoError(suite.T(), err)
assert.Equal(suite.T(), 1, len(rl))
}
// TestCreateRegistration tests CreateRegistration
func (suite *ControllerTestSuite) TestCreateRegistration() {
suite.mMgr.On("Create", mock.Anything, suite.sample).Return("uuid", nil)
uid, err := suite.mMgr.Create(context.TODO(), suite.sample)
require.NoError(suite.T(), err)
assert.Equal(suite.T(), uid, "uuid")
}
// TestGetRegistration tests GetRegistration
func (suite *ControllerTestSuite) TestGetRegistration() {
suite.sample.UUID = "uuid"
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
rr, err := suite.c.GetRegistration(context.TODO(), "uuid")
require.NoError(suite.T(), err)
assert.NotNil(suite.T(), rr)
assert.Equal(suite.T(), "forUT", rr.Name)
}
// TestRegistrationExists tests RegistrationExists
func (suite *ControllerTestSuite) TestRegistrationExists() {
suite.sample.UUID = "uuid"
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
exists := suite.c.RegistrationExists(context.TODO(), "uuid")
assert.Equal(suite.T(), true, exists)
suite.mMgr.On("Get", mock.Anything, "uuid2").Return(nil, nil)
exists = suite.c.RegistrationExists(context.TODO(), "uuid2")
assert.Equal(suite.T(), false, exists)
}
// TestUpdateRegistration tests UpdateRegistration
func (suite *ControllerTestSuite) TestUpdateRegistration() {
suite.sample.UUID = "uuid"
suite.mMgr.On("Update", mock.Anything, suite.sample).Return(nil)
err := suite.c.UpdateRegistration(context.TODO(), suite.sample)
require.NoError(suite.T(), err)
}
// TestDeleteRegistration tests DeleteRegistration
func (suite *ControllerTestSuite) TestDeleteRegistration() {
suite.sample.UUID = "uuid"
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
suite.mMgr.On("Delete", mock.Anything, "uuid").Return(nil)
r, err := suite.c.DeleteRegistration(context.TODO(), "uuid")
require.NoError(suite.T(), err)
require.NotNil(suite.T(), r)
assert.Equal(suite.T(), "forUT", r.Name)
}
// TestSetDefaultRegistration tests SetDefaultRegistration
func (suite *ControllerTestSuite) TestSetDefaultRegistration() {
suite.mMgr.On("SetAsDefault", mock.Anything, "uuid").Return(nil)
err := suite.c.SetDefaultRegistration(context.TODO(), "uuid")
require.NoError(suite.T(), err)
}
// TestSetRegistrationByProject tests SetRegistrationByProject
func (suite *ControllerTestSuite) TestSetRegistrationByProject() {
m := make(map[string]string, 1)
mm := make(map[string]string, 1)
mmm := make(map[string]string, 1)
mm[proScannerMetaKey] = "uuid"
mmm[proScannerMetaKey] = "uuid2"
var pid, pid2 int64 = 1, 2
// not set before
suite.mMeta.On("Get", mock.Anything, pid, proScannerMetaKey).Return(m, nil)
suite.mMeta.On("Add", mock.Anything, pid, mm).Return(nil)
err := suite.c.SetRegistrationByProject(context.TODO(), pid, "uuid")
require.NoError(suite.T(), err)
// Set before
suite.mMeta.On("Get", mock.Anything, pid2, proScannerMetaKey).Return(mm, nil)
suite.mMeta.On("Update", mock.Anything, pid2, mmm).Return(nil)
err = suite.c.SetRegistrationByProject(context.TODO(), pid2, "uuid2")
require.NoError(suite.T(), err)
}
// TestGetRegistrationByProject tests GetRegistrationByProject
func (suite *ControllerTestSuite) TestGetRegistrationByProject() {
m := make(map[string]string, 1)
m[proScannerMetaKey] = "uuid"
// Configured at project level
var pid int64 = 1
suite.sample.UUID = "uuid"
suite.mMeta.On("Get", mock.Anything, pid, proScannerMetaKey).Return(m, nil)
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
r, err := suite.c.GetRegistrationByProject(context.TODO(), pid)
require.NoError(suite.T(), err)
require.Equal(suite.T(), "forUT", r.Name)
// Not configured at project level, return system default
suite.mMeta.On("Get", mock.Anything, pid, proScannerMetaKey).Return(nil, nil)
suite.mMgr.On("GetDefault", mock.Anything).Return(suite.sample, nil)
r, err = suite.c.GetRegistrationByProject(context.TODO(), pid)
require.NoError(suite.T(), err)
require.NotNil(suite.T(), r)
assert.Equal(suite.T(), "forUT", r.Name)
}
// TestGetRegistrationByProjectWhenPingError tests GetRegistrationByProject
func (suite *ControllerTestSuite) TestGetRegistrationByProjectWhenPingError() {
m := make(map[string]string, 1)
m[proScannerMetaKey] = "uuid"
// Configured at project level
var pid int64 = 1
suite.sample.UUID = "uuid"
suite.mMeta.On("Get", mock.Anything, pid, proScannerMetaKey).Return(m, nil)
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
// Ping error
mc := &v1testing.Client{}
mc.On("GetMetadata").Return(nil, fmt.Errorf("getMetadata error"))
mcp := &v1testing.ClientPool{}
mocktesting.OnAnything(mcp, "Get").Return(mc, nil)
suite.c.clientPool = mcp
r, err := suite.c.GetRegistrationByProject(context.TODO(), pid)
require.NoError(suite.T(), err)
assert.Equal(suite.T(), "unhealthy", r.Health)
}
// TestPing ...
func (suite *ControllerTestSuite) TestPing() {
meta, err := suite.c.Ping(context.TODO(), suite.sample)
require.NoError(suite.T(), err)
suite.NotNil(meta)
}
// TestPingWithGenericMimeType tests ping for scanners supporting MIME type MimeTypeGenericVulnerabilityReport
func (suite *ControllerTestSuite) TestPingWithGenericMimeType() {
m := &v1.ScannerAdapterMetadata{
Scanner: &v1.Scanner{
Name: "Trivy",
Vendor: "Harbor",
Version: "0.1.0",
},
Capabilities: []*v1.ScannerCapability{{
ConsumesMimeTypes: []string{
v1.MimeTypeOCIArtifact,
v1.MimeTypeDockerArtifact,
},
ProducesMimeTypes: []string{
v1.MimeTypeGenericVulnerabilityReport,
v1.MimeTypeRawReport,
},
}},
Properties: v1.ScannerProperties{
"extra": "testing",
},
}
mc := &v1testing.Client{}
mc.On("GetMetadata").Return(m, nil)
mcp := &v1testing.ClientPool{}
mocktesting.OnAnything(mcp, "Get").Return(mc, nil)
suite.c = &basicController{
manager: suite.mMgr,
proMetaMgr: suite.mMeta,
clientPool: mcp,
}
meta, err := suite.c.Ping(context.TODO(), suite.sample)
require.NoError(suite.T(), err)
suite.NotNil(meta)
}
// TestGetMetadata ...
func (suite *ControllerTestSuite) TestGetMetadata() {
suite.sample.UUID = "uuid"
suite.mMgr.On("Get", mock.Anything, "uuid").Return(suite.sample, nil)
meta, err := suite.c.GetMetadata(context.TODO(), suite.sample.UUID)
require.NoError(suite.T(), err)
suite.NotNil(meta)
suite.Equal(1, len(meta.Capabilities))
}