diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java index 084b46607d..d52f58bd3f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanFunctionalCaseController.java @@ -6,6 +6,7 @@ import io.metersphere.dto.BugProviderDTO; import io.metersphere.plan.constants.TestPlanResourceConfig; import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.response.*; +import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.service.TestPlanCaseLogService; import io.metersphere.plan.service.TestPlanFunctionalCaseService; import io.metersphere.plan.service.TestPlanManagementService; @@ -48,6 +49,8 @@ public class TestPlanFunctionalCaseController { private TestPlanManagementService testPlanManagementService; @Resource private TestPlanFunctionalCaseService testPlanFunctionalCaseService; + @Resource + private ExtTestPlanMapper extTestPlanMapper; @PostMapping(value = "/sort") @Operation(summary = "测试计划功能用例-功能用例拖拽排序") @@ -140,6 +143,7 @@ public class TestPlanFunctionalCaseController { @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") public void run(@Validated @RequestBody TestPlanCaseRunRequest request) { testPlanFunctionalCaseService.run(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/run", HttpMethodConstants.POST.name())); + extTestPlanMapper.setActualStartTime(request.getTestPlanId(), System.currentTimeMillis()); testPlanService.refreshTestPlanStatus(request.getTestPlanId()); } @@ -149,6 +153,7 @@ public class TestPlanFunctionalCaseController { @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") public void batchRun(@Validated @RequestBody TestPlanCaseBatchRunRequest request) { testPlanFunctionalCaseService.batchRun(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/batch/run", HttpMethodConstants.POST.name())); + extTestPlanMapper.setActualStartTime(request.getTestPlanId(), System.currentTimeMillis()); testPlanService.refreshTestPlanStatus(request.getTestPlanId()); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanDetailResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanDetailResponse.java index 32499ba1b1..6af70af277 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanDetailResponse.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanDetailResponse.java @@ -1,5 +1,6 @@ package io.metersphere.plan.dto.response; +import io.metersphere.sdk.constants.TestPlanConstants; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -17,7 +18,7 @@ public class TestPlanDetailResponse extends TestPlanStatisticsResponse implement private static final long serialVersionUID = 1L; @Schema(description = "测试计划组Id") - private String groupId; + private String groupId = TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID; @Schema(description = "测试计划组名称") private String groupName; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanResponse.java index 7aab4a53ee..5d91c5094c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanResponse.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanResponse.java @@ -39,6 +39,18 @@ public class TestPlanResponse extends TestPlanStatisticsResponse { @Schema(description = "组内计划数量") private Integer childrenCount; + @Schema(description = "计划开始时间") + private Long plannedStartTime; + + @Schema(description = "计划结束时间") + private Long plannedEndTime; + + @Schema(description = "实际开始时间") + private Long actualStartTime; + + @Schema(description = "实际结束时间") + private Long actualEndTime; + @Schema(description = "测试计划组Id") private String groupId; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java index b00e1c0a83..02ea07a0ab 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java @@ -41,6 +41,12 @@ public interface ExtTestPlanMapper { void batchUpdate(@Param("testPlan") TestPlan testPlan, @Param("ids") List ids); + void setActualStartTime(@Param("id") String id, @Param("time") Long actualStartTime); + + void setActualEndTime(@Param("id") String id, @Param("time") Long actualEndTime); + + void clearActualEndTime(String id); + List selectIdByProjectId(String projectId); List selectNotArchivedIds(@Param("ids") List selectIds); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml index b26f44ebab..42b84a3440 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml @@ -53,6 +53,10 @@ t.type, t.description, t.pos, + t.planned_start_time AS plannedStartTime, + t.planned_end_time AS plannedEndTime, + t.actual_start_time AS actualStartTime, + t.actual_end_time AS actualEndTime, t.tags FROM test_plan t INNER JOIN user createUser ON t.create_user = createUser.id @@ -486,6 +490,23 @@ and project_id = #{testPlan.projectId} + + update test_plan + set actual_start_time = #{time} + where id = #{id} + and actual_start_time is null + + + update test_plan + set actual_end_time = #{time} + where id = #{id} + + + update test_plan + set actual_end_time = null + where id = #{0} + and actual_end_time is not null + diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseBatchRunService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseBatchRunService.java index e57be882f3..9c2bbd3713 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseBatchRunService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseBatchRunService.java @@ -19,10 +19,7 @@ import io.metersphere.plan.domain.TestPlanCollection; import io.metersphere.plan.domain.TestPlanCollectionExample; import io.metersphere.plan.dto.request.ApiExecutionMapService; import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRunRequest; -import io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper; -import io.metersphere.plan.mapper.TestPlanApiCaseMapper; -import io.metersphere.plan.mapper.TestPlanCollectionMapper; -import io.metersphere.plan.mapper.TestPlanMapper; +import io.metersphere.plan.mapper.*; import io.metersphere.sdk.constants.ApiExecuteResourceType; import io.metersphere.sdk.constants.CaseType; import io.metersphere.sdk.constants.CommonConstants; @@ -76,6 +73,8 @@ public class TestPlanApiCaseBatchRunService { private TestPlanApiBatchRunBaseService testPlanApiBatchRunBaseService; @Resource private TestPlanMapper testPlanMapper; + @Resource + private ExtTestPlanMapper extTestPlanMapper; /** * 异步批量执行 @@ -84,6 +83,7 @@ public class TestPlanApiCaseBatchRunService { * @param userId */ public void asyncBatchRun(TestPlanApiCaseBatchRunRequest request, String userId) { + extTestPlanMapper.setActualStartTime(request.getTestPlanId(), System.currentTimeMillis()); Thread.startVirtualThread(() -> batchRun(request, userId)); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java index ce69ca220e..bb5fad6e67 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java @@ -71,6 +71,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService { @Resource private TestPlanMapper testPlanMapper; @Resource + private ExtTestPlanMapper extTestPlanMapper; + @Resource private TestPlanApiCaseMapper testPlanApiCaseMapper; @Resource private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper; @@ -625,6 +627,7 @@ public class TestPlanApiCaseService extends TestPlanResourceService { public TaskRequestDTO run(String id, String reportId, String userId) { TestPlanApiCase testPlanApiCase = checkResourceExist(id); + extTestPlanMapper.setActualStartTime(testPlanApiCase.getTestPlanId(), System.currentTimeMillis()); ApiTestCase apiTestCase = apiTestCaseService.checkResourceExist(testPlanApiCase.getApiCaseId()); ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(testPlanApiCase.getTestPlanCollectionId()); runModeConfig.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiCase.getEnvironmentId())); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioBatchRunService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioBatchRunService.java index feae00a69a..3e7d8ef528 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioBatchRunService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioBatchRunService.java @@ -17,10 +17,7 @@ import io.metersphere.plan.domain.TestPlanCollection; import io.metersphere.plan.domain.TestPlanCollectionExample; import io.metersphere.plan.dto.request.ApiExecutionMapService; import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest; -import io.metersphere.plan.mapper.ExtTestPlanApiScenarioMapper; -import io.metersphere.plan.mapper.TestPlanApiScenarioMapper; -import io.metersphere.plan.mapper.TestPlanCollectionMapper; -import io.metersphere.plan.mapper.TestPlanMapper; +import io.metersphere.plan.mapper.*; import io.metersphere.sdk.constants.ApiExecuteResourceType; import io.metersphere.sdk.constants.CaseType; import io.metersphere.sdk.constants.CommonConstants; @@ -75,6 +72,8 @@ public class TestPlanApiScenarioBatchRunService { private ApiExecutionMapService apiExecutionMapService; @Resource private TestPlanCollectionMapper testPlanCollectionMapper; + @Resource + private ExtTestPlanMapper extTestPlanMapper; /** * 异步批量执行 @@ -83,6 +82,7 @@ public class TestPlanApiScenarioBatchRunService { * @param userId */ public void asyncBatchRun(TestPlanApiScenarioBatchRunRequest request, String userId) { + extTestPlanMapper.setActualStartTime(request.getTestPlanId(), System.currentTimeMillis()); Thread.startVirtualThread(() -> batchRun(request, userId)); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java index 6af5b0398d..492fea4f7c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java @@ -82,6 +82,8 @@ public class TestPlanApiScenarioService extends TestPlanResourceService { @Resource private TestPlanMapper testPlanMapper; @Resource + private ExtTestPlanMapper extTestPlanMapper; + @Resource private TestPlanResourceLogService testPlanResourceLogService; @Resource private ApiScenarioRunService apiScenarioRunService; @@ -287,6 +289,7 @@ public class TestPlanApiScenarioService extends TestPlanResourceService { public TaskRequestDTO run(String id, String reportId, String userId) { TestPlanApiScenario testPlanApiScenario = checkResourceExist(id); + extTestPlanMapper.setActualStartTime(testPlanApiScenario.getTestPlanId(), System.currentTimeMillis()); ApiScenario apiScenario = apiScenarioService.checkResourceExist(testPlanApiScenario.getApiScenarioId()); ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(testPlanApiScenario.getTestPlanCollectionId()); runModeConfig.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiScenario.getEnvironmentId())); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java index 311f51e8c2..b21bcf7ee8 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java @@ -7,6 +7,7 @@ import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest; import io.metersphere.plan.dto.request.TestPlanExecuteRequest; import io.metersphere.plan.dto.request.TestPlanReportGenRequest; import io.metersphere.plan.mapper.ExtTestPlanReportMapper; +import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.mapper.TestPlanCollectionMapper; import io.metersphere.plan.mapper.TestPlanConfigMapper; import io.metersphere.plan.mapper.TestPlanMapper; @@ -41,6 +42,8 @@ public class TestPlanExecuteService { @Resource private ExtTestPlanReportMapper extTestPlanReportMapper; @Resource + private ExtTestPlanMapper extTestPlanMapper; + @Resource private TestPlanConfigMapper testPlanConfigMapper; @Resource private TestPlanService testPlanService; @@ -194,6 +197,7 @@ public class TestPlanExecuteService { //执行测试计划里不同类型的用例 回调:caseTypeExecuteQueueFinish public String executeTestPlan(TestPlanExecutionQueue executionQueue) { + extTestPlanMapper.setActualStartTime(executionQueue.getSourceID(), System.currentTimeMillis()); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(executionQueue.getSourceID()); TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample(); testPlanCollectionExample.createCriteria().andTestPlanIdEqualTo(testPlan.getId()).andParentIdEqualTo("NONE"); @@ -439,12 +443,18 @@ public class TestPlanExecuteService { postParam.setEndTime(System.currentTimeMillis()); postParam.setExecStatus(ExecStatus.COMPLETED.name()); testPlanReportService.postHandleReport(postParam); + + if(!isGroupReport){ + TestPlanReport testPlanReport = testPlanReportService.selectById(reportId); + if(testPlanReport!=null){ + testPlanService.refreshTestPlanStatus(testPlanReport.getTestPlanId()); + } + } }catch (Exception e){ LogUtils.error("Cannot find test plan report for " + reportId, e); } } - private void queueExecuteFinish(TestPlanExecutionQueue queue) { if (StringUtils.equalsIgnoreCase(queue.getParentQueueType(), QUEUE_PREFIX_TEST_PLAN_BATCH_EXECUTE)) { if(StringUtils.equalsIgnoreCase(queue.getQueueType(),QUEUE_PREFIX_TEST_PLAN_GROUP_EXECUTE)){ diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java index 070423aac6..02e9e4dd4c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java @@ -462,6 +462,9 @@ public class TestPlanReportService { testPlanReportMapper.updateByPrimaryKeySelective(planReport); } + public TestPlanReport selectById(String reportId) { + return testPlanReportMapper.selectByPrimaryKey(reportId); + } /** * 获取报告分析详情 diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java index 2eca2ed4db..2cf734763e 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -769,12 +769,15 @@ public class TestPlanService extends TestPlanBaseUtilsService { if (MapUtils.isEmpty(caseExecResultCount)) { // 没有任何执行结果: 状态是未开始 testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED; + extTestPlanMapper.clearActualEndTime(testPlanId); } else if (caseExecResultCount.size() == 1 && caseExecResultCount.containsKey(ExecStatus.PENDING.name()) && caseExecResultCount.get(ExecStatus.PENDING.name()) > 0) { // 执行结果只有未开始: 状态是未开始 testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED; + extTestPlanMapper.clearActualEndTime(testPlanId); } else if (!caseExecResultCount.containsKey(ExecStatus.PENDING.name())) { // 执行结果没有未开始: 已完成 testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_COMPLETED; + extTestPlanMapper.setActualEndTime(testPlanId, System.currentTimeMillis()); } TestPlan testPlan = new TestPlan(); testPlan.setId(testPlanId);