package exporter import ( "strconv" "testing" "time" "github.com/stretchr/testify/suite" "github.com/goharbor/harbor/src/common" "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/utils/test" proctl "github.com/goharbor/harbor/src/controller/project" quotactl "github.com/goharbor/harbor/src/controller/quota" "github.com/goharbor/harbor/src/lib/orm" "github.com/goharbor/harbor/src/pkg" "github.com/goharbor/harbor/src/pkg/artifact" "github.com/goharbor/harbor/src/pkg/member" memberModels "github.com/goharbor/harbor/src/pkg/member/models" proModels "github.com/goharbor/harbor/src/pkg/project/models" qtypes "github.com/goharbor/harbor/src/pkg/quota/types" "github.com/goharbor/harbor/src/pkg/repository/model" "github.com/goharbor/harbor/src/pkg/user" ) var ( alice = models.User{Username: "alice", Password: "password", Email: "alice@test.com"} bob = models.User{Username: "bob", Password: "password", Email: "bob@test.com"} eve = models.User{Username: "eve", Password: "password", Email: "eve@test.com"} testPro1 = proModels.Project{OwnerID: 1, Name: "test1", Metadata: map[string]string{"public": "true"}} testPro2 = proModels.Project{OwnerID: 1, Name: "test2", Metadata: map[string]string{"public": "false"}} rs1 = qtypes.ResourceList{qtypes.ResourceStorage: 100} rs2 = qtypes.ResourceList{qtypes.ResourceStorage: 200} repo1 = model.RepoRecord{Name: "repo1"} repo2 = model.RepoRecord{Name: "repo2"} pmIDs = []int{} art1 = artifact.Artifact{RepositoryName: repo1.Name, Type: "IMAGE", Digest: "sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180"} art2 = artifact.Artifact{RepositoryName: repo1.Name, Type: "IMAGE", Digest: "sha256:3198b18471892718923712837192831287312893712893712897312db1a3bc73"} ) func setupTest(t *testing.T) { test.InitDatabaseFromEnv() ctx := orm.Context() // register projAdmin and assign project admin role aliceID, err := user.Mgr.Create(ctx, &alice) if err != nil { t.Errorf("register user error %v", err) } bobID, err := user.Mgr.Create(ctx, &bob) if err != nil { t.Errorf("register user error %v", err) } eveID, err := user.Mgr.Create(ctx, &eve) if err != nil { t.Errorf("register user error %v", err) } // Create Project proID1, err := proctl.Ctl.Create(ctx, &testPro1) if err != nil { t.Errorf("project creating %v", err) } proID2, err := proctl.Ctl.Create(ctx, &testPro2) if err != nil { t.Errorf("project creating %v", err) } testPro1.ProjectID = proID1 testPro2.ProjectID = proID2 // Create quota for project quotactl.Ctl.Create(ctx, "project", strconv.Itoa(int(testPro1.ProjectID)), rs1) quotactl.Ctl.Create(ctx, "project", strconv.Itoa(int(testPro2.ProjectID)), rs2) if err != nil { t.Errorf("add project error %v", err) } // Add repo to project repo1.ProjectID = testPro1.ProjectID repo1ID, err := pkg.RepositoryMgr.Create(ctx, &repo1) if err != nil { t.Errorf("add repo error %v", err) } repo1.RepositoryID = repo1ID repo2.ProjectID = testPro2.ProjectID repo2ID, err := pkg.RepositoryMgr.Create(ctx, &repo2) repo2.RepositoryID = repo2ID if err != nil { t.Errorf("add repo error %v", err) } // Add artifacts art1.ProjectID = testPro1.ProjectID art1.RepositoryID = repo1ID art1.PushTime = time.Now() _, err = pkg.ArtifactMgr.Create(ctx, &art1) if err != nil { t.Errorf("add repo error %v", err) } art2.ProjectID = testPro2.ProjectID art2.RepositoryID = repo2ID art2.PushTime = time.Now() _, err = pkg.ArtifactMgr.Create(ctx, &art2) if err != nil { t.Errorf("add repo error %v", err) } // Add member to project pmIDs = make([]int, 0) alice.UserID, bob.UserID, eve.UserID = int(aliceID), int(bobID), int(eveID) p1m1ID, err := member.Mgr.AddProjectMember(ctx, memberModels.Member{ProjectID: proID1, Role: common.RoleDeveloper, EntityID: int(aliceID), EntityType: common.UserMember}) if err != nil { t.Errorf("add project member error %v", err) } p2m1ID, err := member.Mgr.AddProjectMember(ctx, memberModels.Member{ProjectID: proID2, Role: common.RoleMaintainer, EntityID: int(bobID), EntityType: common.UserMember}) if err != nil { t.Errorf("add project member error %v", err) } p2m2ID, err := member.Mgr.AddProjectMember(ctx, memberModels.Member{ProjectID: proID2, Role: common.RoleMaintainer, EntityID: int(eveID), EntityType: common.UserMember}) if err != nil { t.Errorf("add project member error %v", err) } pmIDs = append(pmIDs, p1m1ID, p2m1ID, p2m2ID) } func tearDownTest(t *testing.T) { dao.GetOrmer().Raw("delete from project_member where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from project_metadata where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from quota where reference=\"project\" and reference_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from quota_usage where reference=\"project\" and reference_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from project where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from artifact where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from repository where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from cve_allowlist where project_id in (?, ?)", []int64{testPro1.ProjectID, testPro2.ProjectID}).Exec() dao.GetOrmer().Raw("delete from harbor_user where user_id in (?, ?, ?)", []int{alice.UserID, bob.UserID, eve.UserID}).Exec() } type PorjectCollectorTestSuite struct { suite.Suite } func (c *PorjectCollectorTestSuite) TestProjectCollector() { pMap := make(map[int64]*projectInfo) updateProjectBasicInfo(pMap) updateProjectMemberInfo(pMap) updateProjectRepoInfo(pMap) updateProjectArtifactInfo(pMap) c.Equalf(testPro1.ProjectID, pMap[testPro1.ProjectID].ProjectID, "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].ProjectID, testPro1.ProjectID, "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].Name, testPro1.Name, "pMap %v", pMap) c.Equalf(strconv.FormatBool(pMap[testPro1.ProjectID].Public), testPro1.Metadata["public"], "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].Quota, "{\"storage\": 100}", "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].Usage, "{\"storage\": 0}", "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].MemberTotal, float64(2), "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].PullTotal, float64(0), "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].Artifact["IMAGE"].ArtifactTotal, float64(1), "pMap %v", pMap) c.Equalf(pMap[testPro1.ProjectID].Artifact["IMAGE"].ArtifactType, "IMAGE", "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].ProjectID, testPro2.ProjectID, "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].Name, testPro2.Name, "pMap %v", pMap) c.Equalf(strconv.FormatBool(pMap[testPro2.ProjectID].Public), testPro2.Metadata["public"], "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].Quota, "{\"storage\": 200}", "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].Usage, "{\"storage\": 0}", "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].MemberTotal, float64(3), "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].PullTotal, float64(0), "pMap %v", pMap) c.Equalf(pMap[testPro2.ProjectID].Artifact["IMAGE"].ArtifactTotal, float64(1), "pMap %v", pMap) } func TestPorjectCollectorTestSuite(t *testing.T) { setupTest(t) defer tearDownTest(t) suite.Run(t, new(PorjectCollectorTestSuite)) }