From 4a09c55735a8b51ac9d38e39dce90275431339db Mon Sep 17 00:00:00 2001 From: Chlins Zhang Date: Tue, 28 Mar 2023 17:55:06 +0800 Subject: [PATCH] [cherry-pick] fix: fix the invalid jobid for scan data export (#18420) fix: fix the invalid jobid for scan data export Change the JobId param type from int to string, use int will bring some problems for encode/decode type mismatch which generate the invalid repository name. Fixes: #18380 Signed-off-by: chlins --- src/controller/scandataexport/execution.go | 4 +- .../impl/scandataexport/scan_data_export.go | 47 ++++++----- .../scandataexport/scan_data_export_test.go | 77 ++++++++++--------- src/pkg/scan/export/manager.go | 2 + 4 files changed, 71 insertions(+), 59 deletions(-) diff --git a/src/controller/scandataexport/execution.go b/src/controller/scandataexport/execution.go index cf0242cb8..5aca3a5e0 100644 --- a/src/controller/scandataexport/execution.go +++ b/src/controller/scandataexport/execution.go @@ -128,8 +128,8 @@ func (c *controller) Start(ctx context.Context, request export.Request) (executi // create a job object and fill with metadata and parameters params := make(map[string]interface{}) - params["JobId"] = id - params["Request"] = request + params[export.JobID] = fmt.Sprintf("%d", id) + params[export.JobRequest] = request params[export.JobModeKey] = export.JobModeExport j := &task.Job{ diff --git a/src/jobservice/job/impl/scandataexport/scan_data_export.go b/src/jobservice/job/impl/scandataexport/scan_data_export.go index efa5c25fa..7ebdd4681 100644 --- a/src/jobservice/job/impl/scandataexport/scan_data_export.go +++ b/src/jobservice/job/impl/scandataexport/scan_data_export.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "github.com/gocarina/gocsv" @@ -47,7 +48,8 @@ func (sde *ScanDataExport) MaxCurrency() uint { // still less that the number declared by the method 'MaxFails'. // // Returns: -// true for retry and false for none-retry +// +// true for retry and false for none-retry func (sde *ScanDataExport) ShouldRetry() bool { return true } @@ -66,8 +68,8 @@ func (sde *ScanDataExport) Validate(params job.Parameters) error { // params map[string]interface{} : parameters with key-pair style for the job execution. // // Returns: -// error if failed to run. NOTES: If job is stopped or cancelled, a specified error should be returned // +// error if failed to run. NOTES: If job is stopped or cancelled, a specified error should be returned func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { if _, ok := params[export.JobModeKey]; !ok { return errors.Errorf("no mode specified for scan data export execution") @@ -77,7 +79,7 @@ func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { logger := ctx.GetLogger() logger.Infof("Scan data export job started in mode : %v", mode) sde.init() - fileName := fmt.Sprintf("%s/scandata_export_%v.csv", sde.scanDataExportDirPath, params["JobId"]) + fileName := fmt.Sprintf("%s/scandata_export_%s.csv", sde.scanDataExportDirPath, params[export.JobID]) // ensure that CSV files are cleared post the completion of the Run. defer sde.cleanupCsvFile(ctx, fileName, params) @@ -92,12 +94,12 @@ func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { logger.Errorf("Error when calculating checksum for generated file: %v", err) return err } - logger.Infof("Export Job Id = %v, FileName = %s, Hash = %v", params["JobId"], fileName, hash) + logger.Infof("Export Job Id = %s, FileName = %s, Hash = %v", params[export.JobID], fileName, hash) csvFile, err := os.OpenFile(fileName, os.O_RDONLY, os.ModePerm) if err != nil { logger.Errorf( - "Export Job Id = %v. Error when moving report file %s to persistent storage: %v", params["JobId"], fileName, err) + "Export Job Id = %s. Error when moving report file %s to persistent storage: %v", params[export.JobID], fileName, err) return err } baseFileName := filepath.Base(fileName) @@ -108,12 +110,12 @@ func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { logger.Errorf("Error when fetching file size: %v", err) return err } - logger.Infof("Export Job Id = %v. CSV file size: %d", params["JobId"], stat.Size()) + logger.Infof("Export Job Id = %s. CSV file size: %d", params[export.JobID], stat.Size()) csvExportArtifactRecord := model.SystemArtifact{Repository: repositoryName, Digest: hash.String(), Size: stat.Size(), Type: "ScanData_CSV", Vendor: strings.ToLower(export.Vendor)} artID, err := sde.sysArtifactMgr.Create(ctx.SystemContext(), &csvExportArtifactRecord, csvFile) if err != nil { logger.Errorf( - "Export Job Id = %v. Error when persisting report file %s to persistent storage: %v", params["JobId"], fileName, err) + "Export Job Id = %s. Error when persisting report file %s to persistent storage: %v", params[export.JobID], fileName, err) // NOTICE: this is a tentative solution to resolve error to push empty blob to S3 storage driver, // should unify the behaviour for different drivers. // Temporary set the status message to extra attributes, then the API handler will fetch it and combined to response for better experience. @@ -123,17 +125,17 @@ func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { } updateErr := sde.updateExecAttributes(ctx, params, extra) if updateErr != nil { - logger.Errorf("Export Job Id = %v. Error when updating the exec extra attributes 'status_message' to 'No vulnerabilities found or matched': %v", params["JobId"], updateErr) + logger.Errorf("Export Job Id = %s. Error when updating the exec extra attributes 'status_message' to 'No vulnerabilities found or matched': %v", params[export.JobID], updateErr) } } return err } - logger.Infof("Export Job Id = %v. Created system artifact: %v for report file %s to persistent storage: %v", params["JobId"], artID, fileName, err) + logger.Infof("Export Job Id = %s. Created system artifact: %v for report file %s to persistent storage: %v", params[export.JobID], artID, fileName, err) err = sde.updateExecAttributes(ctx, params, map[string]interface{}{export.DigestKey: hash.String()}) if err != nil { - logger.Errorf("Export Job Id = %v. Error when updating execution record : %v", params["JobId"], err) + logger.Errorf("Export Job Id = %s. Error when updating execution record : %v", params[export.JobID], err) return err } logger.Info("Scan data export job completed") @@ -142,11 +144,16 @@ func (sde *ScanDataExport) Run(ctx job.Context, params job.Parameters) error { } func (sde *ScanDataExport) updateExecAttributes(ctx job.Context, params job.Parameters, attrs map[string]interface{}) error { - execID := int64(params["JobId"].(float64)) - exec, err := sde.execMgr.Get(ctx.SystemContext(), execID) logger := ctx.GetLogger() + execID, err := strconv.ParseInt(params[export.JobID].(string), 10, 64) if err != nil { - logger.Errorf("Export Job Id = %v. Error when fetching execution record for update : %v", params["JobId"], err) + logger.Errorf("Export Job Id = %s. Error when parse execution id from params: %v", params[export.JobID], err) + return err + } + + exec, err := sde.execMgr.Get(ctx.SystemContext(), execID) + if err != nil { + logger.Errorf("Export Job Id = %s. Error when fetching execution record for update : %v", params[export.JobID], err) return err } // copy old extra @@ -175,8 +182,8 @@ func (sde *ScanDataExport) writeCsvFile(ctx job.Context, params job.Parameters, var exportParams export.Params var artIDGroups [][]int64 - if criteira, ok := params["Request"]; ok { - logger.Infof("Request for export : %v", criteira) + if criteria, ok := params[export.JobRequest]; ok { + logger.Infof("Request for export : %v", criteria) filterCriteria, err := sde.extractCriteria(params) if err != nil { return err @@ -253,7 +260,7 @@ func (sde *ScanDataExport) writeCsvFile(ctx job.Context, params job.Parameters, logger.Infof("No more data to fetch. Exiting...") break } - logger.Infof("Export Group Id = %d, Job Id = %v, Page Number = %d, Page Size = %d Num Records = %d", groupID, params["JobId"], exportParams.PageNumber, exportParams.PageSize, len(data)) + logger.Infof("Export Group Id = %d, Job Id = %s, Page Number = %d, Page Size = %d Num Records = %d", groupID, params[export.JobID], exportParams.PageNumber, exportParams.PageSize, len(data)) // for the first page write the CSV with the headers if exportParams.PageNumber == 1 && groupID == 0 { @@ -276,9 +283,9 @@ func (sde *ScanDataExport) writeCsvFile(ctx job.Context, params job.Parameters, } func (sde *ScanDataExport) extractCriteria(params job.Parameters) (*export.Request, error) { - filterMap, ok := params["Request"].(map[string]interface{}) + filterMap, ok := params[export.JobRequest].(map[string]interface{}) if !ok { - return nil, errors.Errorf("malformed criteria '%v'", params["Request"]) + return nil, errors.Errorf("malformed criteria '%v'", params[export.JobRequest]) } jsonData, err := json.Marshal(filterMap) if err != nil { @@ -347,12 +354,12 @@ func (sde *ScanDataExport) init() { func (sde *ScanDataExport) cleanupCsvFile(ctx job.Context, fileName string, params job.Parameters) { logger := ctx.GetLogger() if _, err := os.Stat(fileName); os.IsNotExist(err) { - logger.Infof("Export Job Id = %v, CSV Export File = %s does not exist. Nothing to do", params["JobId"], fileName) + logger.Infof("Export Job Id = %s, CSV Export File = %s does not exist. Nothing to do", params[export.JobID], fileName) return } err := os.Remove(fileName) if err != nil { - logger.Errorf("Export Job Id = %d, CSV Export File = %s could not deleted. Error = %v", params["JobId"], fileName, err) + logger.Errorf("Export Job Id = %s, CSV Export File = %s could not deleted. Error = %v", params[export.JobID], fileName, err) return } } diff --git a/src/jobservice/job/impl/scandataexport/scan_data_export_test.go b/src/jobservice/job/impl/scandataexport/scan_data_export_test.go index d2092b5e1..820156ea5 100644 --- a/src/jobservice/job/impl/scandataexport/scan_data_export_test.go +++ b/src/jobservice/job/impl/scandataexport/scan_data_export_test.go @@ -30,8 +30,11 @@ import ( tasktesting "github.com/goharbor/harbor/src/testing/pkg/task" ) -const JobId = float64(100) -const MockDigest = "mockDigest" +const ( + ExecID int64 = 1000000 + JobId = "1000000" + MockDigest = "mockDigest" +) type ScanDataExportJobTestSuite struct { htesting.Suite @@ -81,7 +84,7 @@ func (suite *ScanDataExportJobTestSuite) TestRun() { execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil) + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil) params := job.Parameters{} params[export.JobModeKey] = export.JobModeExport @@ -94,7 +97,7 @@ func (suite *ScanDataExportJobTestSuite) TestRun() { err := suite.job.Run(ctx, params) suite.NoError(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) @@ -106,8 +109,8 @@ func (suite *ScanDataExportJobTestSuite) TestRun() { _, ok := m[export.CreateTimestampKey] return attrsMap[export.DigestKey] == MockDigest && ok && attrsMap[export.JobNameAttribute] == "test-job" && attrsMap[export.UserNameAttribute] == "test-user" }) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), extraAttrsMatcher) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, extraAttrsMatcher) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.Truef(os.IsNotExist(err), "Expected CSV file to be deleted") } @@ -130,7 +133,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunCreateSysArtError() { execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil) + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil) params := job.Parameters{} params[export.JobModeKey] = export.JobModeExport @@ -143,7 +146,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunCreateSysArtError() { extraAttrsMatcher := testifymock.MatchedBy(func(attrsMap map[string]interface{}) bool { return attrsMap["status_message"] == "No vulnerabilities found or matched" && attrsMap[export.JobNameAttribute] == "test-job" && attrsMap[export.UserNameAttribute] == "test-user" }) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), extraAttrsMatcher) + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, extraAttrsMatcher) } func (suite *ScanDataExportJobTestSuite) TestRunAttributeUpdateError() { @@ -171,7 +174,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunAttributeUpdateError() { err := suite.job.Run(ctx, params) suite.Error(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) @@ -183,8 +186,8 @@ func (suite *ScanDataExportJobTestSuite) TestRunAttributeUpdateError() { _, ok := m[export.CreateTimestampKey] return attrsMap[export.DigestKey] == MockDigest && ok && attrsMap[export.JobNameAttribute] == "test-job" && attrsMap[export.UserNameAttribute] == "test-user" }) - suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), extraAttrsMatcher) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, extraAttrsMatcher) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.Truef(os.IsNotExist(err), "Expected CSV file to be deleted") } @@ -218,7 +221,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() repoCandidates := []int64{1} artCandidates := []*artifact.Artifact{{Artifact: artpkg.Artifact{ID: 1, Digest: "digest1"}}} @@ -247,7 +250,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { err := suite.job.Run(ctx, params) suite.NoError(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) @@ -259,8 +262,8 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { _, ok := m[export.CreateTimestampKey] return attrsMap[export.DigestKey] == MockDigest && ok }) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), extraAttrsMatcher) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, extraAttrsMatcher) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") exportParamsMatcher := testifymock.MatchedBy(func(params export.Params) bool { return reflect.DeepEqual(params.CVEIds, criteria.CVEIds) @@ -282,7 +285,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() repoCandidate1 := &selector.Candidate{NamespaceID: 1} repoCandidates := []*selector.Candidate{repoCandidate1} @@ -309,7 +312,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { err := suite.job.Run(ctx, params) suite.NoError(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) m := make(map[string]interface{}) @@ -320,8 +323,8 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteria() { _, ok := m[export.CreateTimestampKey] return attrsMap[export.DigestKey] == MockDigest && ok }) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), extraAttrsMatcher) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, extraAttrsMatcher) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") exportParamsMatcher := testifymock.MatchedBy(func(params export.Params) bool { return reflect.DeepEqual(params.CVEIds, criteria.CVEIds) @@ -345,7 +348,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdFilte execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessRepositoryFilter").Return([]int64{1}, errors.New("test error")).Once() mock.OnAnything(suite.filterProcessor, "ProcessTagFilter").Return([]*artifact.Artifact{{Artifact: artpkg.Artifact{ID: 1}}}, nil).Once() @@ -371,11 +374,11 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdFilte err := suite.job.Run(ctx, params) suite.Error(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertNotCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) - suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), mock.Anything) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, mock.Anything) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.exportMgr.AssertNotCalled(suite.T(), "Fetch", mock.Anything, mock.Anything) @@ -395,7 +398,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdFilte execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessRepositoryFilter").Return([]int64{}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessTagFilter").Return([]*artifact.Artifact{}, nil).Once() @@ -421,11 +424,11 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdFilte err := suite.job.Run(ctx, params) suite.NoError(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), mock.Anything) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, mock.Anything) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.exportMgr.AssertNotCalled(suite.T(), "Fetch", mock.Anything, mock.Anything) @@ -447,7 +450,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdWithT execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessRepositoryFilter").Return([]int64{1}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessTagFilter").Return(nil, errors.New("test error")).Once() @@ -473,11 +476,11 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdWithT err := suite.job.Run(ctx, params) suite.Error(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertNotCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) - suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), mock.Anything) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, mock.Anything) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.exportMgr.AssertNotCalled(suite.T(), "Fetch", mock.Anything, mock.Anything) @@ -497,7 +500,7 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdWithT execAttrs := make(map[string]interface{}) execAttrs[export.JobNameAttribute] = "test-job" execAttrs[export.UserNameAttribute] = "test-user" - mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: int64(JobId), ExtraAttrs: execAttrs}, nil).Once() + mock.OnAnything(suite.execMgr, "Get").Return(&task.Execution{ID: ExecID, ExtraAttrs: execAttrs}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessRepositoryFilter").Return([]int64{}, nil).Once() mock.OnAnything(suite.filterProcessor, "ProcessTagFilter").Return(nil, nil).Once() @@ -523,11 +526,11 @@ func (suite *ScanDataExportJobTestSuite) TestRunWithCriteriaForRepositoryIdWithT err := suite.job.Run(ctx, params) suite.NoError(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) - suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, int64(JobId), mock.Anything) - _, err = os.Stat("/tmp/scandata_export_100.csv") + suite.execMgr.AssertCalled(suite.T(), "UpdateExtraAttrs", mock.Anything, ExecID, mock.Anything) + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.exportMgr.AssertNotCalled(suite.T(), "Fetch", mock.Anything, mock.Anything) @@ -549,11 +552,11 @@ func (suite *ScanDataExportJobTestSuite) TestExportDigestCalculationErrorsOut() err := suite.job.Run(ctx, params) suite.Error(err) sysArtifactRecordMatcher := testifymock.MatchedBy(func(sa *model.SystemArtifact) bool { - return sa.Repository == "scandata_export_100" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest + return sa.Repository == "scandata_export_1000000" && sa.Vendor == strings.ToLower(export.Vendor) && sa.Digest == MockDigest }) suite.sysArtifactMgr.AssertNotCalled(suite.T(), "Create", mock.Anything, sysArtifactRecordMatcher, mock.Anything) suite.execMgr.AssertNotCalled(suite.T(), "UpdateExtraAttrs") - _, err = os.Stat("/tmp/scandata_export_100.csv") + _, err = os.Stat("/tmp/scandata_export_1000000.csv") suite.Truef(os.IsNotExist(err), "Expected CSV file to be deleted") } diff --git a/src/pkg/scan/export/manager.go b/src/pkg/scan/export/manager.go index 5b74abc13..6e0b110fa 100644 --- a/src/pkg/scan/export/manager.go +++ b/src/pkg/scan/export/manager.go @@ -56,6 +56,8 @@ group by ` JobModeExport = "export" JobModeKey = "mode" + JobID = "JobId" + JobRequest = "Request" ) var (