diff --git a/test-track/backend/src/main/java/io/metersphere/plan/job/TestPlanTestJob.java b/test-track/backend/src/main/java/io/metersphere/plan/job/TestPlanTestJob.java index d9b2d63779..c3ce61d694 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/job/TestPlanTestJob.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/job/TestPlanTestJob.java @@ -60,7 +60,7 @@ public class TestPlanTestJob extends MsScheduleJob { // 定时任务指定调用微服务的user HttpHeaderUtils.runAsUser(baseUserService.getUserDTO(runUserId)); - testPlanService.runTestPlan(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(), null, ExecutionWay.RUN.name(), config); + testPlanService.runTestPlanBySchedule(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(), null, ExecutionWay.RUN.name(), config); HttpHeaderUtils.clearUser(); } diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java new file mode 100644 index 0000000000..f8ebb28101 --- /dev/null +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java @@ -0,0 +1,224 @@ +package io.metersphere.plan.service; + +import io.metersphere.base.domain.TestPlanWithBLOBs; +import io.metersphere.base.mapper.TestPlanMapper; +import io.metersphere.base.mapper.ext.ExtTestPlanMapper; +import io.metersphere.commons.constants.TestPlanReportStatus; +import io.metersphere.commons.utils.JSON; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.constants.RunModeConstants; +import io.metersphere.dto.*; +import io.metersphere.plan.dto.ExecutionWay; +import io.metersphere.plan.request.api.TestPlanRunRequest; +import io.metersphere.plan.service.remote.api.PlanApiAutomationService; +import io.metersphere.plan.service.remote.api.PlanTestPlanApiCaseService; +import io.metersphere.plan.service.remote.api.PlanTestPlanScenarioCaseService; +import io.metersphere.plan.service.remote.performance.PerfExecService; +import io.metersphere.plan.service.remote.ui.PlanTestPlanUiScenarioCaseService; +import io.metersphere.plan.service.remote.ui.PlanUiAutomationService; +import io.metersphere.plan.utils.TestPlanRequestUtil; +import io.metersphere.utils.LoggerUtil; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +@Service +@Transactional +public class TestPlanExecuteService { + @Resource + @Lazy + private TestPlanService testPlanService; + @Resource + private TestPlanReportService testPlanReportService; + @Resource + private PlanTestPlanApiCaseService planTestPlanApiCaseService; + @Resource + private PlanTestPlanScenarioCaseService planTestPlanScenarioCaseService; + @Resource + private PerfExecService perfExecService; + @Resource + private PlanTestPlanUiScenarioCaseService planTestPlanUiScenarioCaseService; + @Resource + private PlanApiAutomationService planApiAutomationService; + @Resource + private PlanUiAutomationService planUiAutomationService; + + @Resource + private TestPlanMapper testPlanMapper; + @Resource + private ExtTestPlanMapper extTestPlanMapper; + + /** + * 执行测试计划流程是会调用其它服务的执行方法,并通过kafka传递信息给test-track服务来判断测试计划是否执行结束 + * 执行方法采用单独的事务控制,执行完了就提交,让测试报告以及包括执行内容的数据及时入库 + */ + @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) + public String runTestPlan(String testPlanId, String projectId, String userId, String triggerMode, String planReportId, String executionWay, String apiRunConfig) { + RunModeConfigDTO runModeConfig = null; + try { + runModeConfig = JSON.parseObject(apiRunConfig, RunModeConfigDTO.class); + } catch (Exception e) { + LogUtil.error(e); + } + if (runModeConfig == null) { + runModeConfig = this.buildRunModeConfigDTO(); + } + + //环境参数为空时,依据测试计划保存的环境执行 + if (((StringUtils.equals("GROUP", runModeConfig.getEnvironmentType()) && StringUtils.isBlank(runModeConfig.getEnvironmentGroupId())) + || (!StringUtils.equals("GROUP", runModeConfig.getEnvironmentType()) && MapUtils.isEmpty(runModeConfig.getEnvMap()) && MapUtils.isEmpty(runModeConfig.getTestPlanDefaultEnvMap()))) + && !StringUtils.equals(executionWay, ExecutionWay.RUN.name())) { + TestPlanWithBLOBs testPlanWithBLOBs = testPlanMapper.selectByPrimaryKey(testPlanId); + if (StringUtils.isNotEmpty(testPlanWithBLOBs.getRunModeConfig())) { + try { + Map json = JSON.parseMap(testPlanWithBLOBs.getRunModeConfig()); + TestPlanRequestUtil.changeStringToBoolean(json); + TestPlanRunRequest testPlanRunRequest = JSON.parseObject(JSON.toJSONString(json), TestPlanRunRequest.class); + if (testPlanRunRequest != null) { + String envType = testPlanRunRequest.getEnvironmentType(); + Map envMap = testPlanRunRequest.getEnvMap(); + String environmentGroupId = testPlanRunRequest.getEnvironmentGroupId(); + runModeConfig = testPlanService.getRunModeConfigDTO(testPlanRunRequest, envType, envMap, environmentGroupId, testPlanId); + runModeConfig.setTestPlanDefaultEnvMap(testPlanRunRequest.getTestPlanDefaultEnvMap()); + if (!testPlanRunRequest.isRunWithinResourcePool()) { + runModeConfig.setResourcePoolId(null); + } + } + } catch (Exception e) { + LogUtil.error("获取测试计划保存的环境信息出错!", e); + } + } + } + if (planReportId == null) { + planReportId = UUID.randomUUID().toString(); + } + if (testPlanService.haveExecCase(testPlanId, true)) { + testPlanService.verifyPool(projectId, runModeConfig); + } + //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 + TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanService.genTestPlanReport(planReportId, testPlanId, userId, triggerMode, runModeConfig); + + LoggerUtil.info("预生成测试计划报告【" + reportInfoDTO.getTestPlanReport() != null ? reportInfoDTO.getTestPlanReport().getName() : StringUtils.EMPTY + "】计划报告ID[" + planReportId + "]"); + + List apiTestCases = null; + List scenarioCases = null; + List uiScenarios = null; + Map loadCaseReportMap = null; + if (MapUtils.isNotEmpty(reportInfoDTO.getApiTestCaseDataMap())) { + try { + apiTestCases = planTestPlanApiCaseService.getFailureListByIds(reportInfoDTO.getApiTestCaseDataMap().keySet()); + } catch (Exception e) { + LogUtil.error("测试计划执行查询接口用例失败!", e); + } + } + if (MapUtils.isNotEmpty(reportInfoDTO.getPlanScenarioIdMap())) { + try { + scenarioCases = planTestPlanScenarioCaseService.getFailureListByIds(reportInfoDTO.getPlanScenarioIdMap().keySet()); + } catch (Exception e) { + LogUtil.error("测试计划执行查询场景用例失败!", e); + } + } + if (MapUtils.isNotEmpty(reportInfoDTO.getUiScenarioIdMap())) { + try { + uiScenarios = planTestPlanUiScenarioCaseService.getFailureListByIds(reportInfoDTO.getUiScenarioIdMap().keySet()); + } catch (Exception e) { + LogUtil.error("测试计划执行查询UI用例失败!", e); + } + } + boolean haveApiCaseExec = false, haveScenarioCaseExec = false, haveLoadCaseExec = false, haveUICaseExec = false; + if (CollectionUtils.isNotEmpty(apiTestCases)) { + //执行接口案例任务 + LoggerUtil.info("开始执行测试计划接口用例 " + planReportId); + try { + Map apiCaseReportMap = testPlanService.executeApiTestCase(triggerMode, planReportId, userId, testPlanId, runModeConfig); + if (MapUtils.isNotEmpty(apiCaseReportMap)) { + haveApiCaseExec = true; + for (TestPlanApiDTO dto : apiTestCases) { + dto.setReportId(apiCaseReportMap.get(dto.getId())); + } + } + } catch (Exception e) { + apiTestCases = null; + LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划接口用例失败! ", e); + } + } + if (CollectionUtils.isNotEmpty(scenarioCases)) { + //执行场景执行任务 + LoggerUtil.info("开始执行测试计划场景用例 " + planReportId); + try { + Map scenarioReportMap = testPlanService.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap()); + if (MapUtils.isNotEmpty(scenarioReportMap)) { + haveScenarioCaseExec = true; + List removeDTO = new ArrayList<>(); + for (TestPlanScenarioDTO dto : scenarioCases) { + if (scenarioReportMap.containsKey(dto.getId())) { + dto.setReportId(scenarioReportMap.get(dto.getId())); + } else { + removeDTO.add(dto); + } + } + if (CollectionUtils.isNotEmpty(removeDTO)) { + scenarioCases.removeAll(removeDTO); + } + } + } catch (Exception e) { + scenarioCases = null; + LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划场景用例失败! ", e); + } + } + + if (MapUtils.isNotEmpty(reportInfoDTO.getPerformanceIdMap())) { + //执行性能测试任务 + LoggerUtil.info("开始执行测试计划性能用例 " + planReportId); + try { + loadCaseReportMap = perfExecService.executeLoadCase(planReportId, runModeConfig, testPlanService.transformationPerfTriggerMode(triggerMode), reportInfoDTO.getPerformanceIdMap()); + if (MapUtils.isNotEmpty(loadCaseReportMap)) { + haveLoadCaseExec = true; + } + } catch (Exception e) { + LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划性能用例失败! ", e); + } + } + + if (CollectionUtils.isNotEmpty(uiScenarios)) { + //执行UI场景执行任务 + LoggerUtil.info("开始执行测试计划 UI 场景用例 " + planReportId); + try { + Map uiScenarioReportMap = testPlanService.executeUiScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getUiScenarioIdMap()); + if (MapUtils.isNotEmpty(uiScenarioReportMap)) { + haveUICaseExec = true; + for (TestPlanUiScenarioDTO dto : uiScenarios) { + dto.setReportId(uiScenarioReportMap.get(dto.getId())); + } + } + } catch (Exception e) { + uiScenarios = null; + LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划 UI 用例失败! ", e); + } + } + + LoggerUtil.info("开始生成测试计划报告内容 " + planReportId); + testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiTestCases, scenarioCases, uiScenarios, loadCaseReportMap); + if (!haveApiCaseExec && !haveScenarioCaseExec && !haveLoadCaseExec && !haveUICaseExec) { + //如果没有执行的自动化用例,调用结束测试计划的方法。 因为方法中包含着测试计划执行队列的处理逻辑。 + testPlanReportService.testPlanExecuteOver(planReportId, TestPlanReportStatus.COMPLETED.name()); + } + return planReportId; + } + + private RunModeConfigDTO buildRunModeConfigDTO() { + RunModeConfigDTO runModeConfig = new RunModeConfigDTO(); + runModeConfig.setMode(RunModeConstants.SERIAL.name()); + runModeConfig.setReportType("iddReport"); + runModeConfig.setEnvMap(new HashMap<>()); + runModeConfig.setOnSampleError(false); + return runModeConfig; + } +} diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java index 96922c5d6c..8ad5882c5f 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java @@ -468,12 +468,6 @@ public class TestPlanReportService { testPlanReportMapper.insert(testPlanReport); - if (runInfoDTO != null) { - //runInfoDTO 不为Null时,是执行测试计划行为触发的,要更新TestPlan状态为进行中 - testPlan.setStatus(TestPlanStatus.Underway.name()); - testPlanMapper.updateByPrimaryKeySelective(testPlan); - } - TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO(); returnDTO.setTestPlanReport(testPlanReport); return returnDTO; diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java index 9d56afe635..848f3b577e 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -7,7 +7,6 @@ import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.ExtTestCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanMapper; -import io.metersphere.base.mapper.ext.ExtTestPlanReportMapper; import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper; import io.metersphere.commons.constants.*; import io.metersphere.commons.exception.MSException; @@ -43,7 +42,6 @@ import io.metersphere.plan.request.ui.UiPlanReportRequest; import io.metersphere.plan.service.remote.api.PlanApiAutomationService; import io.metersphere.plan.service.remote.api.PlanTestPlanApiCaseService; import io.metersphere.plan.service.remote.api.PlanTestPlanScenarioCaseService; -import io.metersphere.plan.service.remote.performance.PerfExecService; import io.metersphere.plan.service.remote.performance.PlanTestPlanLoadCaseService; import io.metersphere.plan.service.remote.ui.PlanTestPlanUiScenarioCaseService; import io.metersphere.plan.service.remote.ui.PlanUiAutomationService; @@ -132,14 +130,11 @@ public class TestPlanService { @Resource private TestCaseTestMapper testCaseTestMapper; @Resource - private ExtTestPlanReportMapper extTestPlanReportMapper; - @Resource private TestPlanReportService testPlanReportService; @Lazy @Resource private IssuesService issuesService; - @Resource - private PerfExecService perfExecService; + @Resource private TestPlanPrincipalService testPlanPrincipalService; @Resource @@ -158,6 +153,8 @@ public class TestPlanService { private ObjectMapper objectMapper; @Resource private ApiPoolDebugService apiPoolDebugService; + @Resource + private TestPlanExecuteService testPlanExecuteService; public TestPlan addTestPlan(AddTestPlanRequest testPlan) { if (getTestPlanByName(testPlan.getName()).size() > 0) { @@ -904,171 +901,6 @@ public class TestPlanService { return testPlanReportService.genTestPlanReportBySchedule(planReportId, planId, userId, triggerMode, runModeConfigDTO); } - public String runTestPlan(String testPlanId, String projectId, String userId, String triggerMode, String - planReportId, String executionWay, String apiRunConfig) { - RunModeConfigDTO runModeConfig = null; - try { - runModeConfig = JSON.parseObject(apiRunConfig, RunModeConfigDTO.class); - } catch (Exception e) { - LogUtil.error(e); - } - if (runModeConfig == null) { - runModeConfig = buildRunModeConfigDTO(); - } - - //环境参数为空时,依据测试计划保存的环境执行 - if (((StringUtils.equals("GROUP", runModeConfig.getEnvironmentType()) && StringUtils.isBlank(runModeConfig.getEnvironmentGroupId())) - || (!StringUtils.equals("GROUP", runModeConfig.getEnvironmentType()) && MapUtils.isEmpty(runModeConfig.getEnvMap()) && MapUtils.isEmpty(runModeConfig.getTestPlanDefaultEnvMap()))) - && !StringUtils.equals(executionWay, ExecutionWay.RUN.name())) { - TestPlanWithBLOBs testPlanWithBLOBs = testPlanMapper.selectByPrimaryKey(testPlanId); - if (StringUtils.isNotEmpty(testPlanWithBLOBs.getRunModeConfig())) { - try { - Map json = JSON.parseMap(testPlanWithBLOBs.getRunModeConfig()); - TestPlanRequestUtil.changeStringToBoolean(json); - TestPlanRunRequest testPlanRunRequest = JSON.parseObject(JSON.toJSONString(json), TestPlanRunRequest.class); - if (testPlanRunRequest != null) { - String envType = testPlanRunRequest.getEnvironmentType(); - Map envMap = testPlanRunRequest.getEnvMap(); - String environmentGroupId = testPlanRunRequest.getEnvironmentGroupId(); - runModeConfig = getRunModeConfigDTO(testPlanRunRequest, envType, envMap, environmentGroupId, testPlanId); - runModeConfig.setTestPlanDefaultEnvMap(testPlanRunRequest.getTestPlanDefaultEnvMap()); - if (!testPlanRunRequest.isRunWithinResourcePool()) { - runModeConfig.setResourcePoolId(null); - } - } - } catch (Exception e) { - LogUtil.error("获取测试计划保存的环境信息出错!", e); - } - } - } - if (planReportId == null) { - planReportId = UUID.randomUUID().toString(); - } - if (haveExecCase(testPlanId, true)) { - this.verifyPool(projectId, runModeConfig); - } - - //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 - TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(planReportId, testPlanId, userId, triggerMode, runModeConfig); - //定时任务执行重新设置实际开始时间 - if (StringUtils.equals(triggerMode, TriggerMode.SCHEDULE.name())) { - TestPlanWithBLOBs testPlanWithBLOBs = new TestPlanWithBLOBs(); - testPlanWithBLOBs.setId(testPlanId); - testPlanWithBLOBs.setActualStartTime(System.currentTimeMillis()); - testPlanMapper.updateByPrimaryKeySelective(testPlanWithBLOBs); - } - //测试计划准备执行,取消测试计划的实际结束时间 - extTestPlanMapper.updateActualEndTimeIsNullById(testPlanId); - - LoggerUtil.info("预生成测试计划报告【" + reportInfoDTO.getTestPlanReport() != null ? reportInfoDTO.getTestPlanReport().getName() : StringUtils.EMPTY + "】计划报告ID[" + planReportId + "]"); - - List apiTestCases = null; - List scenarioCases = null; - List uiScenarios = null; - Map loadCaseReportMap = null; - if (MapUtils.isNotEmpty(reportInfoDTO.getApiTestCaseDataMap())) { - try { - apiTestCases = planTestPlanApiCaseService.getFailureListByIds(reportInfoDTO.getApiTestCaseDataMap().keySet()); - } catch (Exception e) { - LogUtil.error("测试计划执行查询接口用例失败!", e); - } - } - if (MapUtils.isNotEmpty(reportInfoDTO.getPlanScenarioIdMap())) { - try { - scenarioCases = planTestPlanScenarioCaseService.getFailureListByIds(reportInfoDTO.getPlanScenarioIdMap().keySet()); - } catch (Exception e) { - LogUtil.error("测试计划执行查询场景用例失败!", e); - } - } - if (MapUtils.isNotEmpty(reportInfoDTO.getUiScenarioIdMap())) { - try { - uiScenarios = planTestPlanUiScenarioCaseService.getFailureListByIds(reportInfoDTO.getUiScenarioIdMap().keySet()); - } catch (Exception e) { - LogUtil.error("测试计划执行查询UI用例失败!", e); - } - } - boolean haveApiCaseExec = false, haveScenarioCaseExec = false, haveLoadCaseExec = false, haveUICaseExec = false; - if (CollectionUtils.isNotEmpty(apiTestCases)) { - //执行接口案例任务 - LoggerUtil.info("开始执行测试计划接口用例 " + planReportId); - try { - Map apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, testPlanId, runModeConfig); - if (MapUtils.isNotEmpty(apiCaseReportMap)) { - haveApiCaseExec = true; - for (TestPlanApiDTO dto : apiTestCases) { - dto.setReportId(apiCaseReportMap.get(dto.getId())); - } - } - } catch (Exception e) { - apiTestCases = null; - LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划接口用例失败! ", e); - } - } - if (CollectionUtils.isNotEmpty(scenarioCases)) { - //执行场景执行任务 - LoggerUtil.info("开始执行测试计划场景用例 " + planReportId); - try { - Map scenarioReportMap = this.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap()); - if (MapUtils.isNotEmpty(scenarioReportMap)) { - haveScenarioCaseExec = true; - List removeDTO = new ArrayList<>(); - for (TestPlanScenarioDTO dto : scenarioCases) { - if (scenarioReportMap.containsKey(dto.getId())) { - dto.setReportId(scenarioReportMap.get(dto.getId())); - } else { - removeDTO.add(dto); - } - } - if (CollectionUtils.isNotEmpty(removeDTO)) { - scenarioCases.removeAll(removeDTO); - } - } - } catch (Exception e) { - scenarioCases = null; - LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划场景用例失败! ", e); - } - } - - if (MapUtils.isNotEmpty(reportInfoDTO.getPerformanceIdMap())) { - //执行性能测试任务 - LoggerUtil.info("开始执行测试计划性能用例 " + planReportId); - try { - loadCaseReportMap = perfExecService.executeLoadCase(planReportId, runModeConfig, transformationPerfTriggerMode(triggerMode), reportInfoDTO.getPerformanceIdMap()); - if (MapUtils.isNotEmpty(loadCaseReportMap)) { - haveLoadCaseExec = true; - } - } catch (Exception e) { - LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划性能用例失败! ", e); - } - } - - if (CollectionUtils.isNotEmpty(uiScenarios)) { - //执行UI场景执行任务 - LoggerUtil.info("开始执行测试计划 UI 场景用例 " + planReportId); - try { - Map uiScenarioReportMap = this.executeUiScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getUiScenarioIdMap()); - if (MapUtils.isNotEmpty(uiScenarioReportMap)) { - haveUICaseExec = true; - for (TestPlanUiScenarioDTO dto : uiScenarios) { - dto.setReportId(uiScenarioReportMap.get(dto.getId())); - } - } - } catch (Exception e) { - uiScenarios = null; - LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划 UI 用例失败! ", e); - } - } - - LoggerUtil.info("开始生成测试计划报告内容 " + planReportId); - testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiTestCases, scenarioCases, uiScenarios, loadCaseReportMap); - if (!haveApiCaseExec && !haveScenarioCaseExec && !haveLoadCaseExec && !haveUICaseExec) { - //如果没有执行的自动化用例,调用结束测试计划的方法。 因为方法中包含着测试计划执行队列的处理逻辑。 - testPlanReportService.testPlanExecuteOver(planReportId, TestPlanReportStatus.COMPLETED.name()); - } - return planReportId; - } - - public void verifyPool(String projectId, RunModeConfigDTO runConfig) { // 检查是否禁用了本地执行 apiPoolDebugService.verifyPool(projectId, runConfig); @@ -1080,7 +912,7 @@ public class TestPlanService { * @param triggerMode * @return */ - private String transformationPerfTriggerMode(String triggerMode) { + public String transformationPerfTriggerMode(String triggerMode) { if (StringUtils.equalsIgnoreCase(triggerMode, ReportTriggerMode.SCHEDULE.name())) { return ReportTriggerMode.TEST_PLAN_SCHEDULE.name(); } else if (StringUtils.equalsIgnoreCase(triggerMode, ReportTriggerMode.API.name())) { @@ -1090,16 +922,7 @@ public class TestPlanService { } } - private RunModeConfigDTO buildRunModeConfigDTO() { - RunModeConfigDTO runModeConfig = new RunModeConfigDTO(); - runModeConfig.setMode(RunModeConstants.SERIAL.name()); - runModeConfig.setReportType("iddReport"); - runModeConfig.setEnvMap(new HashMap<>()); - runModeConfig.setOnSampleError(false); - return runModeConfig; - } - - private Map executeApiTestCase(String triggerMode, String planReportId, String userId, String + public Map executeApiTestCase(String triggerMode, String planReportId, String userId, String testPlanId, RunModeConfigDTO runModeConfig) { BatchRunDefinitionRequest request = new BatchRunDefinitionRequest(); request.setTriggerMode(triggerMode); @@ -1111,9 +934,9 @@ public class TestPlanService { return this.parseMsExecResponseDTOToTestIdReportMap(dtoList); } - private Map executeScenarioCase(String planReportId, String testPlanID, String + public Map executeScenarioCase(String planReportId, String testPlanID, String projectID, RunModeConfigDTO runModeConfig, String triggerMode, String - userId, Map planScenarioIdMap) { + userId, Map planScenarioIdMap) { if (!planScenarioIdMap.isEmpty()) { SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest(); String scenarioReportID = UUID.randomUUID().toString(); @@ -1146,9 +969,9 @@ public class TestPlanService { } } - private Map executeUiScenarioCase(String planReportId, String testPlanID, String + public Map executeUiScenarioCase(String planReportId, String testPlanID, String projectID, RunModeConfigDTO runModeConfig, String triggerMode, String - userId, Map planScenarioIdMap) { + userId, Map planScenarioIdMap) { if (!planScenarioIdMap.isEmpty()) { SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest(); String scenarioReportID = UUID.randomUUID().toString(); @@ -2007,13 +1830,24 @@ public class TestPlanService { runModeConfig.setResourcePoolId(null); } - String apiRunConfig = JSON.toJSONString(runModeConfig); - return this.runTestPlan(testPlanId, testplanRunRequest.getProjectId(), - testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getReportId(), testplanRunRequest.getExecutionWay(), apiRunConfig); + //执行测试计划行为,要更新TestPlan状态为进行中,并重置实际结束时间 + this.updateTestPlanExecuteInfo(testPlanId, TestPlanStatus.Underway.name()); + String apiRunConfig = JSON.toJSONString(runModeConfig); + return testPlanExecuteService.runTestPlan(testPlanId, testplanRunRequest.getProjectId(), + testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getReportId(), testplanRunRequest.getExecutionWay(), apiRunConfig); } - private RunModeConfigDTO getRunModeConfigDTO(TestPlanRunRequest testplanRunRequest, String + private void updateTestPlanExecuteInfo(String testPlanId, String status) { + TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId); + if (testPlan != null) { + testPlan.setStatus(status); + testPlan.setActualEndTime(null); + testPlanMapper.updateByPrimaryKey(testPlan); + } + } + + public RunModeConfigDTO getRunModeConfigDTO(TestPlanRunRequest testplanRunRequest, String envType, Map envMap, String environmentGroupId, String testPlanId) { RunModeConfigDTO runModeConfig = new RunModeConfigDTO(); if (!testplanRunRequest.isRunWithinResourcePool()) { @@ -2251,13 +2085,13 @@ public class TestPlanService { TestPlanWithBLOBs testPlan = testPlanMap.get(id); String planReportId = UUID.randomUUID().toString(); - //创建测试报告 + + //检查资源池运行情况 RunModeConfigDTO runModeConfigDTO = JSON.parseObject(testPlan.getRunModeConfig(), RunModeConfigDTO.class); runModeConfigDTO = ObjectUtils.isEmpty(runModeConfigDTO) ? new RunModeConfigDTO() : runModeConfigDTO; if (haveExecCase(testPlan.getId(), true)) { this.verifyPool(testPlan.getProjectId(), runModeConfigDTO); } - this.genTestPlanReport(planReportId, testPlan.getId(), request.getUserId(), request.getTriggerMode(), runModeConfigDTO); //测试计划准备执行,取消测试计划的实际结束时间 extTestPlanMapper.updateActualEndTimeIsNullById(testPlan.getId()); executeQueue.put(testPlan.getId(), planReportId); @@ -2265,14 +2099,14 @@ public class TestPlanService { LoggerUtil.info("开始生成测试计划队列"); + //生成测试计划队列 List planExecutionQueues = getTestPlanExecutionQueues(request, executeQueue); - - if (CollectionUtils.isNotEmpty(planExecutionQueues)) { + //串行存储队列,并行在目前的业务需求下不需要存储 + if (CollectionUtils.isNotEmpty(planExecutionQueues) && StringUtils.equalsIgnoreCase(request.getMode(), "serial")) { testPlanExecutionQueueService.batchSave(planExecutionQueues); } // 开始选择执行模式 runByMode(request, testPlanMap, planExecutionQueues); - } @@ -2299,33 +2133,24 @@ public class TestPlanService { private void runByMode(TestPlanRunRequest request, Map testPlanMap, List planExecutionQueues) { if (CollectionUtils.isNotEmpty(planExecutionQueues)) { - User user = SessionUtils.getUser(); - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - Thread.currentThread().setName("TEST_PLAN_BATCH:" + System.currentTimeMillis()); - HttpHeaderUtils.runAsUser(user); - if (StringUtils.equalsIgnoreCase(request.getMode(), RunModeConstants.SERIAL.name())) { - TestPlanExecutionQueue planExecutionQueue = planExecutionQueues.get(0); - TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); - Map jsonObject = JSON.parseMap(testPlan.getRunModeConfig()); - TestPlanRequestUtil.changeStringToBoolean(jsonObject); - TestPlanRunRequest runRequest = JSON.parseObject(JSON.toJSONString(jsonObject), TestPlanRunRequest.class); - runRequest.setReportId(planExecutionQueue.getReportId()); - runPlan(runRequest); - } else { - for (TestPlanExecutionQueue planExecutionQueue : planExecutionQueues) { - TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); - Map jsonObject = JSON.parseMap(testPlan.getRunModeConfig()); - TestPlanRequestUtil.changeStringToBoolean(jsonObject); - TestPlanRunRequest runRequest = JSON.parseObject(JSON.toJSONString(jsonObject), TestPlanRunRequest.class); - runRequest.setReportId(planExecutionQueue.getReportId()); - runPlan(runRequest); - } - } + if (StringUtils.equalsIgnoreCase(request.getMode(), RunModeConstants.SERIAL.name())) { + TestPlanExecutionQueue planExecutionQueue = planExecutionQueues.get(0); + TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); + Map jsonObject = JSON.parseMap(testPlan.getRunModeConfig()); + TestPlanRequestUtil.changeStringToBoolean(jsonObject); + TestPlanRunRequest runRequest = JSON.parseObject(JSON.toJSONString(jsonObject), TestPlanRunRequest.class); + runRequest.setReportId(planExecutionQueue.getReportId()); + runPlan(runRequest); + } else { + for (TestPlanExecutionQueue planExecutionQueue : planExecutionQueues) { + TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); + Map jsonObject = JSON.parseMap(testPlan.getRunModeConfig()); + TestPlanRequestUtil.changeStringToBoolean(jsonObject); + TestPlanRunRequest runRequest = JSON.parseObject(JSON.toJSONString(jsonObject), TestPlanRunRequest.class); + runRequest.setReportId(planExecutionQueue.getReportId()); + runPlan(runRequest); } - }); - thread.start(); + } } } @@ -2431,4 +2256,16 @@ public class TestPlanService { } return testPlanReportDataStruct; } + + //这个方法是为定时任务调用的。 + public String runTestPlanBySchedule(String testPlanId, String projectId, String userId, String triggerMode, String planReportId, String executionWay, String apiRunConfig) { + //定时任务执行重新设置实际开始时间 + if (StringUtils.equals(triggerMode, TriggerMode.SCHEDULE.name())) { + TestPlanWithBLOBs testPlanWithBLOBs = new TestPlanWithBLOBs(); + testPlanWithBLOBs.setId(testPlanId); + testPlanWithBLOBs.setActualStartTime(System.currentTimeMillis()); + testPlanMapper.updateByPrimaryKeySelective(testPlanWithBLOBs); + } + return testPlanExecuteService.runTestPlan(testPlanId, projectId, userId, triggerMode, planReportId, executionWay, apiRunConfig); + } }