This is an automated email from the ASF dual-hosted git repository. narro pushed a commit to branch #8444 in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
commit 0683a6b4ce9a89690933b566639fc83578b4a361 Author: narro wizard <[email protected]> AuthorDate: Wed May 21 03:38:39 2025 +0000 feat(customize): clean up qa_apis and qa_test_case_executions when non-incremental import qa_test_cases - Implement new e2e test case for QA data cleanup functionality - Add test data files for QA test cases, APIs, and test case executions - Update ImportQaTestCases method to delete old data for non-incremental imports - Verify that API data, test cases, and test case executions are properly cleaned up #8444 --- .../customize/e2e/import_qa_test_cases_test.go | 155 +++++++++++++++++++++ .../e2e/raw_tables/qa_full_test_cases_input.csv | 7 + .../e2e/raw_tables/qa_non_api_test_cases.csv | 3 + backend/plugins/customize/service/service.go | 12 +- 4 files changed, 176 insertions(+), 1 deletion(-) diff --git a/backend/plugins/customize/e2e/import_qa_test_cases_test.go b/backend/plugins/customize/e2e/import_qa_test_cases_test.go index 58d448298..80e436a7e 100644 --- a/backend/plugins/customize/e2e/import_qa_test_cases_test.go +++ b/backend/plugins/customize/e2e/import_qa_test_cases_test.go @@ -21,6 +21,7 @@ import ( "os" "testing" + "github.com/apache/incubator-devlake/core/dal" "github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain" "github.com/apache/incubator-devlake/core/models/domainlayer/qa" "github.com/apache/incubator-devlake/helpers/e2ehelper" @@ -117,3 +118,157 @@ func TestImportQaTestCasesDataFlow(t *testing.T) { }, ) } + +func TestImportQaTestCasesDataCleanup(t *testing.T) { + var plugin impl.Customize + dataflowTester := e2ehelper.NewDataFlowTester(t, "customize", plugin) + + // Flush all relevant tables + dataflowTester.FlushTabler(&qa.QaTestCase{}) + dataflowTester.FlushTabler(&qa.QaProject{}) + dataflowTester.FlushTabler(&qa.QaApi{}) + dataflowTester.FlushTabler(&qa.QaTestCaseExecution{}) + dataflowTester.FlushTabler(&crossdomain.Account{}) + + svc := service.NewService(dataflowTester.Dal) + + qaProjectId := "test-cleanup-project" + qaProjectName := "Test Cleanup Project" + + // 1. First import import test cases with API references + testCasesFile, err := os.Open("raw_tables/qa_full_test_cases_input.csv") + if err != nil { + t.Fatal(err) + } + defer testCasesFile.Close() + + err = svc.ImportQaTestCases(qaProjectId, qaProjectName, testCasesFile, false) + if err != nil { + t.Fatal(err) + } + + // import test case executions + testCaseExecutionsFile, err := os.Open("raw_tables/qa_test_case_executions_input.csv") + if err != nil { + t.Fatal(err) + } + defer testCaseExecutionsFile.Close() + + err = svc.ImportQaTestCaseExecutions(qaProjectId, testCaseExecutionsFile, false) + if err != nil { + t.Fatal(err) + } + + // Then import APIs + apisFile, err := os.Open("raw_tables/qa_apis_input.csv") + if err != nil { + t.Fatal(err) + } + defer apisFile.Close() + + err = svc.ImportQaApis(qaProjectId, apisFile, false) + if err != nil { + t.Fatal(err) + } + + // Verify APIs, test cases and test case executions were imported + var initialApiCount int64 + err = dataflowTester.Dal.First( + &initialApiCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaApi{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + if initialApiCount == 0 { + t.Error("Expected API data to be imported initially") + } + + var initialTestCaseCount int64 + err = dataflowTester.Dal.First( + &initialTestCaseCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaTestCase{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + if initialTestCaseCount == 0 { + t.Error("Expected test cases to be imported initially") + } + + var initialTestCaseExecutionCount int64 + err = dataflowTester.Dal.First( + &initialTestCaseExecutionCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaTestCaseExecution{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + + if initialTestCaseExecutionCount == 0 { + t.Error("Expected test case executions to be imported initially") + } + + // 2. Second import non-incremental - test cases + nonApiDataFile, err := os.Open("raw_tables/qa_non_api_test_cases.csv") + if err != nil { + t.Fatal(err) + } + defer nonApiDataFile.Close() + + err = svc.ImportQaTestCases(qaProjectId, qaProjectName, nonApiDataFile, false) + if err != nil { + t.Fatal(err) + } + + // Verify API data was cleaned up + var finalApiCount int64 + err = dataflowTester.Dal.First( + &finalApiCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaApi{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + if finalApiCount != 0 { + t.Errorf("Expected API data to be cleaned up, but found %d records", finalApiCount) + } + + // Verify test case execution data was cleaned up + var finalTestCaseExecutionCount int64 + err = dataflowTester.Dal.First( + &finalTestCaseExecutionCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaTestCaseExecution{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + if finalTestCaseExecutionCount != 0 { + t.Errorf("Expected test case executions to be cleaned up, but found %d records", finalTestCaseExecutionCount) + } + + // Verify test case count is correct (should be 2) + var finalTestCaseCount int64 + err = dataflowTester.Dal.First( + &finalTestCaseCount, + dal.Select("COUNT(*)"), + dal.From(&qa.QaTestCase{}), + dal.Where("qa_project_id = ?", qaProjectId), + ) + if err != nil { + t.Fatal(err) + } + if finalTestCaseCount != 2 { + t.Errorf("Expected 2 test cases after non-incremental import, got %d", finalTestCaseCount) + } +} diff --git a/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv b/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv new file mode 100644 index 000000000..95b607ffc --- /dev/null +++ b/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv @@ -0,0 +1,7 @@ +id,name,create_time,creator_name,type,qa_api_id +tc-1,Full Test Case 1,2023-02-01T10:00:00.000+00:00,user-a,functional, +tc-2,Full Test Case 2 API,2023-02-02T11:00:00.000+00:00,user-b,api,api-1 +api-1,Test API 1,2023-02-01T10:00:00.000+00:00,user-a,GET,/api/v1/test +api-2,Test API 2,2023-02-02T11:00:00.000+00:00,user-b,POST,/api/v1/test +exec-1,tc-1,2023-02-01T10:30:00.000+00:00,2023-02-01T10:35:00.000+00:00,passed,user-a +exec-2,tc-2,2023-02-02T11:30:00.000+00:00,2023-02-02T11:40:00.000+00:00,failed,user-b \ No newline at end of file diff --git a/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv b/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv new file mode 100644 index 000000000..0e95a5013 --- /dev/null +++ b/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv @@ -0,0 +1,3 @@ +id,name,create_time,creator_name,type,qa_api_id +tc-1,Functional Test Case 1,2023-02-01T10:00:00.000+00:00,user-a,functional, +tc-2,Functional Test Case 2,2023-02-02T11:00:00.000+00:00,user-b,functional, \ No newline at end of file diff --git a/backend/plugins/customize/service/service.go b/backend/plugins/customize/service/service.go index 6f6b0d097..22267453f 100644 --- a/backend/plugins/customize/service/service.go +++ b/backend/plugins/customize/service/service.go @@ -453,11 +453,21 @@ func (s *Service) qaApiHandler(qaProjectId string) func(record map[string]interf func (s *Service) ImportQaTestCases(qaProjectId, qaProjectName string, file io.ReadCloser, incremental bool) errors.Error { if !incremental { // delete old data associated with this qaProjectId + // delete qa_test_cases err := s.dal.Delete(&qa.QaTestCase{}, dal.Where("qa_project_id = ?", qaProjectId)) if err != nil { return errors.Default.Wrap(err, fmt.Sprintf("failed to delete old qa_test_cases for qaProjectId %s", qaProjectId)) } - // using ImportQaApis to delete data in qa_apis + // delete qa_apis + err = s.dal.Delete(&qa.QaApi{}, dal.Where("qa_project_id = ?", qaProjectId)) + if err != nil { + return errors.Default.Wrap(err, fmt.Sprintf("failed to delete old qa_apis for qaProjectId %s", qaProjectId)) + } + // delete qa_test_case_executions + err = s.dal.Delete(&qa.QaTestCaseExecution{}, dal.Where("qa_project_id = ?", qaProjectId)) + if err != nil { + return errors.Default.Wrap(err, fmt.Sprintf("failed to delete old qa_test_case_executions for qaProjectId %s", qaProjectId)) + } // never delete data in qa_projects } // create or update qa_projects
