fix(测试计划): 修复测试计划批量执行时出现的问题
测试计划批量执行(尤其是串行)时,由于每个测试计划执行是需要记录执行产生的报告并入库,在测试计划数量较多时会出现由于事务导致的数据一致性问题:测试计划批量执行方法还在进行,测试计划报告数据还未入库,但是先执行的测试计划已经执行结束并通过kafka发送回消息。此时由于数据并未入库,也就无法更改测试计划报告状态,导致测试计划报告状态停留在了入库时的running
This commit is contained in:
parent
f1dd651e70
commit
1091268602
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String, String> 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<TestPlanApiDTO> apiTestCases = null;
|
||||
List<TestPlanScenarioDTO> scenarioCases = null;
|
||||
List<TestPlanUiScenarioDTO> uiScenarios = null;
|
||||
Map<String, String> 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<String, String> 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<String, String> scenarioReportMap = testPlanService.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap());
|
||||
if (MapUtils.isNotEmpty(scenarioReportMap)) {
|
||||
haveScenarioCaseExec = true;
|
||||
List<TestPlanScenarioDTO> 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<String, String> 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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<String, String> 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<TestPlanApiDTO> apiTestCases = null;
|
||||
List<TestPlanScenarioDTO> scenarioCases = null;
|
||||
List<TestPlanUiScenarioDTO> uiScenarios = null;
|
||||
Map<String, String> 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<String, String> 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<String, String> scenarioReportMap = this.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap());
|
||||
if (MapUtils.isNotEmpty(scenarioReportMap)) {
|
||||
haveScenarioCaseExec = true;
|
||||
List<TestPlanScenarioDTO> 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<String, String> 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<String, String> executeApiTestCase(String triggerMode, String planReportId, String userId, String
|
||||
public Map<String, String> 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<String, String> executeScenarioCase(String planReportId, String testPlanID, String
|
||||
public Map<String, String> executeScenarioCase(String planReportId, String testPlanID, String
|
||||
projectID, RunModeConfigDTO runModeConfig, String triggerMode, String
|
||||
userId, Map<String, String> planScenarioIdMap) {
|
||||
userId, Map<String, String> planScenarioIdMap) {
|
||||
if (!planScenarioIdMap.isEmpty()) {
|
||||
SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest();
|
||||
String scenarioReportID = UUID.randomUUID().toString();
|
||||
|
@ -1146,9 +969,9 @@ public class TestPlanService {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, String> executeUiScenarioCase(String planReportId, String testPlanID, String
|
||||
public Map<String, String> executeUiScenarioCase(String planReportId, String testPlanID, String
|
||||
projectID, RunModeConfigDTO runModeConfig, String triggerMode, String
|
||||
userId, Map<String, String> planScenarioIdMap) {
|
||||
userId, Map<String, String> 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<String, String> 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<TestPlanExecutionQueue> 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<String, TestPlanWithBLOBs> testPlanMap, List<TestPlanExecutionQueue> 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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue