This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 07107d380 feat(customize): clean up qa_apis and
qa_test_case_executions when non-incremental import qa_test_cases (#8445)
07107d380 is described below
commit 07107d380632c720792bfa5dadeaa883ba5a989e
Author: NaRro <[email protected]>
AuthorDate: Wed May 21 06:25:33 2025 +0000
feat(customize): clean up qa_apis and qa_test_case_executions when
non-incremental import qa_test_cases (#8445)
- 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
---
.../customize/e2e/import_qa_test_cases_test.go | 148 ++++++++++++++++++++-
.../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, 167 insertions(+), 3 deletions(-)
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..764421e5b 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"
@@ -34,8 +35,9 @@ func TestImportQaTestCasesDataFlow(t *testing.T) {
// Flush the relevant tables
dataflowTester.FlushTabler(&qa.QaTestCase{})
- dataflowTester.FlushTabler(&qa.QaProject{}) // qaTestCaseHandler
also creates/updates QaProject
- dataflowTester.FlushTabler(&qa.QaApi{}) // qaTestCaseHandler
also creates/updates QaApi for API test cases
+ dataflowTester.FlushTabler(&qa.QaProject{}) // qaTestCaseHandler also
creates/updates QaProject
+ dataflowTester.FlushTabler(&qa.QaApi{}) // qaTestCaseHandler also
creates/updates QaApi for API test cases
+ dataflowTester.FlushTabler(&qa.QaTestCaseExecution{})
dataflowTester.FlushTabler(&crossdomain.Account{}) // qaTestCaseHandler
also creates/updates Account for API test cases
// Create a new service instance
@@ -117,3 +119,145 @@ 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
+ initialApiCount, err = dataflowTester.Dal.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
+ initialTestCaseCount, err = dataflowTester.Dal.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
+ initialTestCaseExecutionCount, err = dataflowTester.Dal.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
+ finalApiCount, err = dataflowTester.Dal.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
+ finalTestCaseExecutionCount, err = dataflowTester.Dal.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
+ finalTestCaseCount, err = dataflowTester.Dal.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