fix(接口测试): 修复测试计划关联用例过多执行失败问题

https://github.com/metersphere/metersphere/issues/20545
This commit is contained in:
fit2-zhao 2023-01-04 15:23:46 +08:00 committed by fit2-zhao
parent 988615337e
commit 55822e7dc0
30 changed files with 385 additions and 326 deletions

View File

@ -1,5 +1,6 @@
package io.metersphere.api.dto.automation;
import io.metersphere.commons.vo.RunPlanScenarioVO;
import io.metersphere.dto.RunModeConfigDTO;
import lombok.Getter;
import lombok.Setter;
@ -14,8 +15,6 @@ public class RunScenarioRequest {
private String reportId;
private String environmentId;
private String projectId;
private String triggerMode;
@ -24,25 +23,14 @@ public class RunScenarioRequest {
private String runMode;
/**
* 测试情景和测试计划的关联ID
*/
private String planScenarioId;
private List<String> planCaseIds;
private List<String> ids;
private String reportUserID;
private Map<String, String> scenarioTestPlanIdMap;
private ApiScenarioRequest condition;
private RunModeConfigDTO config;
private boolean isTestPlanScheduleJob = false;
//生成测试报告当isTestPlanScheduleJob为true时使用
private String testPlanReportId;
@ -53,6 +41,10 @@ public class RunScenarioRequest {
private String serialReportId;
private Map<String, ApiScenarioReportResult> reportMap;
private String versionId;
private String testPlanId;
// 过程数据整个测试计划执行
private RunPlanScenarioVO processVO;
// 测试计划批量执行传入id
private List<String> planScenarioIds;
}

View File

@ -13,7 +13,7 @@ import java.util.Map;
public class BatchRunDefinitionRequest {
private String id;
private List<String> planIds;
private List<String> planCaseIds;
private String triggerMode;
@ -27,6 +27,9 @@ public class BatchRunDefinitionRequest {
private String planReportId;
// 失败重跑
private boolean rerun;
private String testPlanId;
private Map<String, ApiDefinitionExecResultWithBLOBs> executeQueue;
}

View File

@ -6,6 +6,7 @@ import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.RunModeConfigWithEnvironmentDTO;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
import io.metersphere.api.dto.plan.TestPlanApiCaseInfoDTO;
import io.metersphere.api.dto.scenario.DatabaseConfig;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.exec.queue.DBTestQueue;
@ -14,7 +15,7 @@ import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException;
@ -62,11 +63,11 @@ public class ApiCaseExecuteService {
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper;
@Resource
private JMeterService jMeterService;
@Resource
private BaseEnvironmentService baseEnvironmentService;
@Resource
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
/**
* 测试计划case执行
@ -76,33 +77,34 @@ public class ApiCaseExecuteService {
*/
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
if (CollectionUtils.isEmpty(request.getPlanIds())) {
return responseDTOS;
}
if (request.getConfig() == null) {
request.setConfig(new RunModeConfigDTO());
}
if (StringUtils.equals(EnvironmentType.GROUP.toString(), request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
if (StringUtils.equals(EnvironmentType.GROUP.name(), request.getConfig().getEnvironmentType())
&& StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
}
LoggerUtil.info("开始查询测试计划用例", request.getPlanIds().size());
List<TestPlanApiCase> planApiCases = this.selectByPlanApiCaseIds(request.getPlanIds());
List<TestPlanApiCaseInfoDTO> planApiCases;
if (CollectionUtils.isNotEmpty(request.getPlanCaseIds())) {
planApiCases = extTestPlanApiCaseMapper.selectByPlanCaseIds(request.getPlanCaseIds());
} else {
planApiCases = extTestPlanApiCaseMapper.selectLegalDataByTestPlanId(request.getTestPlanId());
}
if (CollectionUtils.isEmpty(planApiCases)) {
return responseDTOS;
}
LoggerUtil.info("查询到测试计划用例:" + planApiCases.size(), request.getPlanReportId());
if (StringUtils.isEmpty(request.getTriggerMode())) {
request.setTriggerMode(ApiRunMode.API_PLAN.name());
}
LoggerUtil.info("查询到测试计划用例 " + planApiCases.size());
Map<String, ApiDefinitionExecResultWithBLOBs> executeQueue = request.isRerun() ? request.getExecuteQueue() : new LinkedHashMap<>();
String status = StringUtils.equals(request.getConfig().getMode(), RunModeConstants.SERIAL.toString())
? ApiReportStatus.PENDING.name() : ApiReportStatus.RUNNING.name();
// 查出用例
List<String> apiCaseIds = planApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
List<String> apiCaseIds = planApiCases.stream().map(TestPlanApiCaseInfoDTO::getApiCaseId).collect(Collectors.toList());
ApiTestCaseExample caseExample = new ApiTestCaseExample();
caseExample.createCriteria().andIdIn(apiCaseIds);
List<ApiTestCase> apiTestCases = apiTestCaseMapper.selectByExample(caseExample);
@ -113,7 +115,7 @@ public class ApiCaseExecuteService {
resourcePoolId = request.getConfig().getResourcePoolId();
}
if (!request.isRerun()) {
for (TestPlanApiCase testPlanApiCase : planApiCases) {
for (TestPlanApiCaseInfoDTO testPlanApiCase : planApiCases) {
//处理环境配置为空时的情况
RunModeConfigDTO runModeConfigDTO = new RunModeConfigDTO();
BeanUtils.copyBean(runModeConfigDTO, request.getConfig());
@ -134,7 +136,7 @@ public class ApiCaseExecuteService {
apiCaseResultService.batchSave(executeQueue);
}
LoggerUtil.info("开始生成测试计划队列");
LoggerUtil.info("开始生成测试计划队列", request.getPlanReportId());
String reportType = request.getConfig().getReportType();
String poolId = request.getConfig().getResourcePoolId();
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
@ -155,16 +157,6 @@ public class ApiCaseExecuteService {
return responseDTOS;
}
public List<TestPlanApiCase> selectByPlanApiCaseIds(List<String> planApiCaseIds) {
if (CollectionUtils.isEmpty(planApiCaseIds)) {
return new ArrayList<>();
}
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
example.createCriteria().andIdIn(planApiCaseIds);
example.setOrderByClause("`order` DESC");
return testPlanApiCaseMapper.selectByExample(example);
}
public Map<String, List<String>> getRequestEnv(List<ApiTestCaseWithBLOBs> caseList) {
Map<String, List<String>> projectEnvMap = new HashMap<>();
if (CollectionUtils.isEmpty(caseList)) {
@ -247,7 +239,8 @@ public class ApiCaseExecuteService {
}
jMeterService.verifyPool(request.getProjectId(), request.getConfig());
if (StringUtils.equals(EnvironmentType.GROUP.toString(), request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
if (StringUtils.equals(EnvironmentType.GROUP.name(), request.getConfig().getEnvironmentType())
&& StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
}

View File

@ -9,6 +9,7 @@ import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.MsScenario;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.dto.scenario.environment.item.MsScenarioEnv;
import io.metersphere.base.domain.*;
@ -254,7 +255,7 @@ public class ApiScenarioEnvService {
return isEnv;
}
public boolean verifyPlanScenarioEnv(ApiScenarioWithBLOBs apiScenarioWithBLOBs, TestPlanApiScenario testPlanApiScenarios) {
public boolean verifyPlanScenarioEnv(ApiScenarioWithBLOBs apiScenarioWithBLOBs, TestPlanApiScenarioInfoDTO testPlanApiScenarios) {
if (apiScenarioWithBLOBs != null) {
String definition = apiScenarioWithBLOBs.getScenarioDefinition();
MsScenarioEnv scenario = JSON.parseObject(definition, MsScenarioEnv.class);
@ -285,7 +286,7 @@ public class ApiScenarioEnvService {
*/
public Map<String, List<String>> checkEnv(RunScenarioRequest request, List<ApiScenarioWithBLOBs> apiScenarios) {
Map<String, List<String>> projectEnvMap = new HashMap<>();
if (StringUtils.equals(request.getRequestOriginator(), "TEST_PLAN")) {
if (StringUtils.equals(request.getRequestOriginator(), CommonConstants.TEST_PLAN)) {
this.checkPlanScenarioEnv(request);
} else if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
StringBuilder builder = new StringBuilder();
@ -301,7 +302,7 @@ public class ApiScenarioEnvService {
}
}
if (builder.length() > 0) {
MSException.throwException("场景:" + builder.toString() + "运行环境未配置,请检查!");
MSException.throwException("场景:" + builder + "运行环境未配置,请检查!");
}
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCHEDULE_SCENARIO.name())) {
for (ApiScenarioWithBLOBs apiScenarioWithBLOBs : apiScenarios) {
@ -317,24 +318,23 @@ public class ApiScenarioEnvService {
public void checkPlanScenarioEnv(RunScenarioRequest request) {
StringBuilder builder = new StringBuilder();
List<String> planCaseIds = request.getPlanCaseIds();
if (CollectionUtils.isNotEmpty(planCaseIds)) {
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
example.createCriteria().andIdIn(planCaseIds);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(example);
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
if (request.getProcessVO() != null &&
MapUtils.isNotEmpty(request.getProcessVO().getTestPlanScenarioMap())
&& MapUtils.isNotEmpty(request.getProcessVO().getTestPlanScenarioMap())) {
for (String key : request.getProcessVO().getTestPlanScenarioMap().keySet()) {
try {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
boolean haveEnv = this.verifyPlanScenarioEnv(apiScenarioWithBLOBs, testPlanApiScenario);
TestPlanApiScenarioInfoDTO dto = request.getProcessVO().getTestPlanScenarioMap().get(key);
ApiScenarioWithBLOBs apiScenarioWithBLOBs = request.getProcessVO().getScenarioMap().get(dto.getApiScenarioId());
boolean haveEnv = this.verifyPlanScenarioEnv(apiScenarioWithBLOBs, dto);
if (!haveEnv) {
builder.append(apiScenarioWithBLOBs.getName()).append("; ");
}
} catch (Exception e) {
MSException.throwException("场景:" + builder.toString() + "运行环境未配置,请检查!");
MSException.throwException("场景:" + builder + "运行环境未配置,请检查!");
}
}
if (builder.length() > 0) {
MSException.throwException("场景:" + builder.toString() + "运行环境未配置,请检查!");
MSException.throwException("场景:" + builder + "运行环境未配置,请检查!");
}
}
}
@ -522,7 +522,8 @@ public class ApiScenarioEnvService {
JSONObject jsonObject = JSONUtil.parseObject(envConfig);
if (jsonObject.has("executionEnvironmentMap")) {
RunModeConfigWithEnvironmentDTO configWithEnvironment = JSON.parseObject(envConfig, RunModeConfigWithEnvironmentDTO.class);
if (StringUtils.equals("GROUP", configWithEnvironment.getEnvironmentType()) && StringUtils.isNotEmpty(configWithEnvironment.getEnvironmentGroupId())) {
if (StringUtils.equals(EnvironmentType.GROUP.name(), configWithEnvironment.getEnvironmentType())
&& StringUtils.isNotEmpty(configWithEnvironment.getEnvironmentGroupId())) {
groupId = configWithEnvironment.getEnvironmentGroupId();
}
if (MapUtils.isNotEmpty(configWithEnvironment.getExecutionEnvironmentMap())) {
@ -532,7 +533,8 @@ public class ApiScenarioEnvService {
}
} else {
RunModeConfigDTO config = JSON.parseObject(envConfig, RunModeConfigDTO.class);
if (StringUtils.equals("GROUP", config.getEnvironmentType()) && StringUtils.isNotEmpty(config.getEnvironmentGroupId())) {
if (StringUtils.equals(EnvironmentType.GROUP.name(), config.getEnvironmentType())
&& StringUtils.isNotEmpty(config.getEnvironmentGroupId())) {
groupId = config.getEnvironmentGroupId();
}
envMapByRunConfig = config.getEnvMap();
@ -576,4 +578,29 @@ public class ApiScenarioEnvService {
return project.getName();
}
}
public void setScenarioEnv(RunScenarioRequest request, Map<String, String> configEnvMap) {
if (StringUtils.equals(request.getConfig().getEnvironmentType(), EnvironmentType.JSON.toString())
&& MapUtils.isNotEmpty(request.getConfig().getEnvMap())) {
configEnvMap.putAll(request.getConfig().getEnvMap());
} else if (StringUtils.equals(request.getConfig().getEnvironmentType(), EnvironmentType.GROUP.toString())
&& StringUtils.isNotBlank(request.getConfig().getEnvironmentGroupId())) {
configEnvMap.putAll(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
}
}
public Map<String, String> getPlanScenarioEnv(TestPlanApiScenarioInfoDTO planApiScenario, Map<String, String> configEnvMap) {
Map<String, String> planEnvMap = new LinkedHashMap<>();
if (StringUtils.equals(planApiScenario.getEnvironmentType(), EnvironmentType.JSON.toString())
&& StringUtils.isNotBlank(planApiScenario.getEnvironment())) {
planEnvMap.putAll(JSON.parseObject(planApiScenario.getEnvironment(), Map.class));
} else if (StringUtils.equals(planApiScenario.getEnvironmentType(), EnvironmentType.GROUP.toString())
&& StringUtils.isNotBlank(planApiScenario.getEnvironmentGroupId())) {
planEnvMap.putAll(environmentGroupProjectService.getEnvMap(planApiScenario.getEnvironmentGroupId()));
}
if (MapUtils.isNotEmpty(configEnvMap)) {
planEnvMap.putAll(configEnvMap);
}
return planEnvMap;
}
}

View File

@ -8,15 +8,18 @@ import io.metersphere.api.dto.automation.ExecuteType;
import io.metersphere.api.dto.automation.RunScenarioRequest;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.api.exec.api.ApiCaseExecuteService;
import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.NewDriverManager;
import io.metersphere.base.domain.*;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioExample;
import io.metersphere.base.domain.ApiScenarioReportWithBLOBs;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ExtendedParameter;
@ -24,6 +27,7 @@ import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
import io.metersphere.commons.vo.RunPlanScenarioVO;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.JmeterRunRequestDTO;
@ -85,8 +89,6 @@ public class ApiScenarioExecuteService {
@Resource
protected JMeterService jMeterService;
@Resource
protected TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
private ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
@Resource
private SystemParameterService systemParameterService;
@ -102,7 +104,8 @@ public class ApiScenarioExecuteService {
request.setConfig(new RunModeConfigDTO());
}
if (StringUtils.equals("GROUP", request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
if (StringUtils.equals(EnvironmentType.GROUP.name(), request.getConfig().getEnvironmentType())
&& StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
}
@ -131,9 +134,10 @@ public class ApiScenarioExecuteService {
Map<String, RunModeDataDTO> executeQueue = new LinkedHashMap<>();
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列");
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
//测试计划执行
assemblyPlanScenario(apiScenarios, request, executeQueue);
assemblyPlanScenario(request, executeQueue);
} else {
// 按照场景执行
assemblyScenario(apiScenarios, request, executeQueue);
@ -141,47 +145,19 @@ public class ApiScenarioExecuteService {
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列完成:" + executeQueue.size());
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
if (executeQueue.isEmpty()) {
if (MapUtils.isEmpty(executeQueue)) {
return responseDTOS;
}
// 集合报告处理
if (GenerateHashTreeUtil.isSetReport(request.getConfig())) {
// 失败重跑更新报告状态
if (request.isRerun()) {
ApiScenarioReportWithBLOBs report = new ApiScenarioReportWithBLOBs();
report.setId(serialReportId);
report.setStatus(ApiReportStatus.RERUNNING.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} else {
LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId);
request.getConfig().setReportId(UUID.randomUUID().toString());
List<String> scenarioIds = new ArrayList<>();
String reportScenarioIds = generateScenarioIds(scenarioIds);
if (request.getConfig() == null) {
request.setConfig(new RunModeConfigWithEnvironmentDTO());
}
if (MapUtils.isEmpty(request.getConfig().getEnvMap())) {
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
BeanUtils.copyBean(runModeConfig, request.getConfig());
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios);
apiCaseExecuteService.setExecutionEnvironment(runModeConfig, projectEnvMap);
request.setConfig(runModeConfig);
}
// 生成集合报告
String names = apiScenarios.stream().map(ApiScenario::getName).collect(Collectors.joining(","));
ApiScenarioReportResult report = apiScenarioReportService.getApiScenarioReportResult(request, serialReportId, names, reportScenarioIds);
report.setVersionId(apiScenarios.get(0).getVersionId());
apiScenarioReportMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType());
}
this.setReport(request, serialReportId, apiScenarios, responseDTOS);
}
String reportType = request.getConfig().getReportType();
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
// 生成执行队列
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
DBTestQueue executionQueue = apiExecutionQueueService.add(
executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
// 预生成报告
if (!request.isRerun() && !GenerateHashTreeUtil.isSetReport(request.getConfig())) {
@ -215,7 +191,25 @@ public class ApiScenarioExecuteService {
}
public List<ApiScenarioWithBLOBs> get(RunScenarioRequest request) {
ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiScenarioMapper.selectIdsByQuery(query));
RunPlanScenarioVO vo = new RunPlanScenarioVO();
if (StringUtils.equalsAny(request.getRunMode(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
// 测试计划执行数据查询
List<TestPlanApiScenarioInfoDTO> testPlanApiScenarioList;
if (CollectionUtils.isNotEmpty(request.getPlanScenarioIds())) {
testPlanApiScenarioList = extTestPlanScenarioCaseMapper.selectByPlanIds(request.getPlanScenarioIds());
} else {
testPlanApiScenarioList = extTestPlanScenarioCaseMapper.selectLegalDataByTestPlanId(request.getTestPlanId());
}
if (CollectionUtils.isNotEmpty(testPlanApiScenarioList)) {
List<String> ids = testPlanApiScenarioList.stream().map(TestPlanApiScenarioInfoDTO::getApiScenarioId).collect(Collectors.toList());
request.setIds(ids);
vo.setTestPlanScenarioMap(testPlanApiScenarioList.stream()
.collect(Collectors.toMap(TestPlanApiScenarioInfoDTO::getId, Function.identity(), (t1, t2) -> t1)));
}
} else {
ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiScenarioMapper.selectIdsByQuery(query));
}
List<String> ids = request.getIds();
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(ids);
@ -226,9 +220,44 @@ public class ApiScenarioExecuteService {
sortById(ids, apiScenarios);
}
}
vo.setScenarioMap(apiScenarios.stream().collect(Collectors.toMap(ApiScenarioWithBLOBs::getId, Function.identity(), (t1, t2) -> t1)));
request.setProcessVO(vo);
return apiScenarios;
}
private void setReport(RunScenarioRequest request, String serialReportId, List<ApiScenarioWithBLOBs> apiScenarios, List<MsExecResponseDTO> responseDTOS) {
// 失败重跑更新报告状态
if (request.isRerun()) {
ApiScenarioReportWithBLOBs report = new ApiScenarioReportWithBLOBs();
report.setId(serialReportId);
report.setStatus(ApiReportStatus.RERUNNING.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} else {
LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId);
request.getConfig().setReportId(UUID.randomUUID().toString());
List<String> scenarioIds = new ArrayList<>();
String reportScenarioIds = generateScenarioIds(scenarioIds);
if (request.getConfig() == null) {
request.setConfig(new RunModeConfigWithEnvironmentDTO());
}
if (MapUtils.isEmpty(request.getConfig().getEnvMap())) {
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
BeanUtils.copyBean(runModeConfig, request.getConfig());
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios);
apiCaseExecuteService.setExecutionEnvironment(runModeConfig, projectEnvMap);
request.setConfig(runModeConfig);
}
// 生成集合报告
String names = apiScenarios.stream().map(ApiScenario::getName).collect(Collectors.joining(","));
ApiScenarioReportResult report = apiScenarioReportService.getApiScenarioReportResult(request, serialReportId, names, reportScenarioIds);
report.setVersionId(apiScenarios.get(0).getVersionId());
apiScenarioReportMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType());
}
}
protected void sortById(List<String> ids, List apiScenarios) {
FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(ids);
fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
@ -236,30 +265,20 @@ public class ApiScenarioExecuteService {
Collections.sort(apiScenarios, beanComparator);
}
/**
* 测试计划接口场景的预执行生成场景报告
*/
private void assemblyPlanScenario(List<ApiScenarioWithBLOBs> apiScenarios, RunScenarioRequest request, Map<String, RunModeDataDTO> executeQueue) {
private void assemblyPlanScenario(RunScenarioRequest request, Map<String, RunModeDataDTO> executeQueue) {
String reportId = request.getId();
Map<String, String> planScenarioIdMap = request.getScenarioTestPlanIdMap();
if (MapUtils.isEmpty(planScenarioIdMap)) {
return;
}
Map<String, ApiScenarioWithBLOBs> scenarioMap = apiScenarios.stream().collect(Collectors.toMap(ApiScenarioWithBLOBs::getId, Function.identity(), (t1, t2) -> t1));
Map<String, ApiScenarioWithBLOBs> scenarioMap = request.getProcessVO().getScenarioMap();
//检查环境组
Map<String, String> configEnvMap = new HashMap<>();
if (request.getConfig() != null) {
if (StringUtils.equals(request.getConfig().getEnvironmentType(), EnvironmentType.JSON.toString()) && MapUtils.isNotEmpty(request.getConfig().getEnvMap())) {
configEnvMap = request.getConfig().getEnvMap();
} else if (StringUtils.equals(request.getConfig().getEnvironmentType(), EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(request.getConfig().getEnvironmentGroupId())) {
configEnvMap = environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId());
}
apiScenarioEnvService.setScenarioEnv(request, configEnvMap);
}
for (String testPlanScenarioId : planScenarioIdMap.keySet()) {
String scenarioId = planScenarioIdMap.get(testPlanScenarioId);
ApiScenarioWithBLOBs scenario = scenarioMap.get(scenarioId);
for (String testPlanScenarioId : request.getProcessVO().getTestPlanScenarioMap().keySet()) {
TestPlanApiScenarioInfoDTO planApiScenario = request.getProcessVO().getTestPlanScenarioMap().get(testPlanScenarioId);
ApiScenarioWithBLOBs scenario = scenarioMap.get(planApiScenario.getApiScenarioId());
if (scenario.getStepTotal() == null || scenario.getStepTotal() == 0) {
continue;
}
@ -267,39 +286,30 @@ public class ApiScenarioExecuteService {
request.setProjectId(scenario.getProjectId());
}
// 获取场景用例单独的执行环境
Map<String, String> planEnvMap = new HashMap<>();
TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId);
if (planApiScenario == null) {
continue;
}
// 环境处理
if (StringUtils.equals(planApiScenario.getEnvironmentType(), EnvironmentType.JSON.toString()) && StringUtils.isNotBlank(planApiScenario.getEnvironment())) {
planEnvMap = JSON.parseObject(planApiScenario.getEnvironment(), Map.class);
} else if (StringUtils.equals(planApiScenario.getEnvironmentType(), EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(planApiScenario.getEnvironmentGroupId())) {
planEnvMap = environmentGroupProjectService.getEnvMap(planApiScenario.getEnvironmentGroupId());
}
planEnvMap.putAll(configEnvMap);
Map<String, String> planEnvMap = apiScenarioEnvService.getPlanScenarioEnv(planApiScenario, configEnvMap);
if (StringUtils.isEmpty(request.getProjectId())) {
request.setProjectId(extTestPlanScenarioCaseMapper.getProjectIdById(testPlanScenarioId));
}
ApiScenarioReportResult report = apiScenarioReportService.initResult(reportId, testPlanScenarioId, scenario.getName(), request);
if (request.isRerun()) {
if (request.getReportMap().containsKey(scenarioId)) {
report = request.getReportMap().get(scenarioId);
if (request.getReportMap().containsKey(planApiScenario.getApiScenarioId())) {
report = request.getReportMap().get(planApiScenario.getApiScenarioId());
} else if (request.getReportMap().containsKey(testPlanScenarioId)) {
report = request.getReportMap().get(testPlanScenarioId);
}
if (report == null) {
return;
}
}
if (report == null) {
return;
}
report.setVersionId(scenario.getVersionId());
RunModeDataDTO runModeDataDTO = getRunModeDataDTO(testPlanScenarioId, report);
runModeDataDTO.setPlanEnvMap(planEnvMap);
runModeDataDTO.setScenario(scenario);
executeQueue.put(report.getId(), runModeDataDTO);
if (ObjectUtils.isNotEmpty(request.getConfig())) {
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
BeanUtils.copyBean(runModeConfig, request.getConfig());
@ -311,7 +321,6 @@ public class ApiScenarioExecuteService {
Map<String, String> envMap = runModeConfig.getEnvMap();
planEnvMap.forEach((k, v) -> {
if (envMap != null && envMap.get(k) != null) {
diffEnvMap.put(k, envMap.get(k));
}
});

View File

@ -1,74 +0,0 @@
package io.metersphere.api.parse.api.har.command;///**
// *
// * har - HAR file reader, writer and viewer
// * Copyright (c) 2014, Sandeep Gupta
// *
// * http://sangupta.com/projects/har
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// *
// */
//
//package io.metersphere.api.dto.parse.api.har.command;
//
//import java.io.File;
//
//import com.sangupta.har.HarUtils;
//import com.sangupta.har.model.Har;
//import com.sangupta.har.model.HarEntry;
//import com.sangupta.har.model.HarPage;
//import com.sangupta.jerry.util.AssertUtils;
//
//import io.airlift.command.Arguments;
//import io.airlift.command.Command;
//
//@Command(name = "view", description = "View HAR file")
//public class ViewHar implements Runnable {
//
// @Arguments
// private String file;
//
// @Override
// public void run() {
// Har har = null;
//
// try {
// har = HarUtils.read(new File(this.file));
// } catch(Exception e) {
// System.out.println("Error reading HAR file: " + e.getMessage());
// return;
// }
//
// if(har.log == null || AssertUtils.isEmpty(har.log.pages)) {
// System.out.println("HAR file has no pages!");
// return;
// }
//
// // connect references
// HarUtils.connectReferences(har);
//
// // start displaying
// System.out.println("Number of pages viewed: " + har.log.pages.size());
// System.out.println();
//
// for(HarPage page : har.log.pages) {
// System.out.println(page);
//
// // output the calls for this page
// for(HarEntry entry : page.entries) {
// System.out.println("\t" + entry);
// }
// }
// }
//
//}

View File

@ -35,6 +35,8 @@ public interface ExtTestPlanApiCaseMapper {
List<TestPlanApiCaseInfoDTO> selectLegalDataByTestPlanId(String planId);
List<TestPlanApiCaseInfoDTO> selectByPlanCaseIds(List<String> planCaseIds);
List<Map> selectForPlanReport(String planId);
List<TestPlanFailureApiDTO> getFailureList(@Param("planId") String planId, @Param("status") String status);

View File

@ -544,4 +544,14 @@
#{v}
</foreach>
</select>
<select id="selectByPlanCaseIds" resultType="io.metersphere.api.dto.plan.TestPlanApiCaseInfoDTO">
SELECT a.project_id, t.*
FROM test_plan_api_case t
INNER JOIN api_test_case a ON t.api_case_id = a.id
WHERE t.id in
<foreach collection="planCaseIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -1,12 +1,10 @@
package io.metersphere.base.mapper.plan.ext;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.base.domain.TestPlanApiScenario;
import io.metersphere.dto.PlanReportCaseDTO;
import org.apache.ibatis.annotations.Param;
@ -30,6 +28,8 @@ public interface ExtTestPlanScenarioCaseMapper {
List<TestPlanApiScenarioInfoDTO> selectLegalDataByTestPlanId(String planId);
List<TestPlanApiScenarioInfoDTO> selectByPlanIds(List<String> planScenarioIds);
List<PlanReportCaseDTO> selectForPlanReport(String planId);
List<TestPlanFailureScenarioDTO> getFailureList(@Param("planId") String planId, @Param("status") String status);

View File

@ -401,4 +401,20 @@
SELECT test_plan_id FROM test_plan_api_scenario WHERE id = #{0}
)
</select>
<select id="selectByPlanIds" resultType="io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO">
SELECT tpas.id,
tpas.api_scenario_id,
tpas.environment,
tpas.environment_type,
tpas.environment_group_id,
apis.project_id
FROM test_plan_api_scenario tpas
INNER JOIN api_scenario apis ON tpas.api_scenario_id = apis.id
WHERE (apis.`status` IS NULL OR apis.`status` != 'Trash')
and tpas.id in
<foreach collection="planScenarioIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -2,7 +2,7 @@ package io.metersphere.commons.constants;
public class CommonConstants {
public static final String TrashStatus = "Trash";
public static final String PROJECT_TEMPLATE = "PROJECT_TEMPLATE";
public static final String TEST_PLAN = "TEST_PLAN";
public static final String LOCAL_STATUS_KEY = "LOCAL_STATUS_KEY";
public static final String REPORT_STATUS = "REPORT_STATUS";
public static final String TRIGGER_MODE = "trigger_mode";

View File

@ -2,9 +2,9 @@ package io.metersphere.commons.utils;
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
import io.metersphere.api.dto.plan.TestPlanApiCaseInfoDTO;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.base.domain.ApiTestCase;
import io.metersphere.base.domain.TestPlanApiCase;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTypeConstants;
import io.metersphere.commons.constants.TriggerMode;
@ -45,7 +45,7 @@ public class ApiDefinitionExecResultUtil {
public static ApiDefinitionExecResultWithBLOBs addResult(
BatchRunDefinitionRequest request,
RunModeConfigDTO runModeConfigDTO,
TestPlanApiCase key,
TestPlanApiCaseInfoDTO key,
String status,
ApiTestCase testCase,
String poolId) {

View File

@ -0,0 +1,22 @@
package io.metersphere.commons.vo;
import io.metersphere.api.dto.plan.TestPlanApiScenarioInfoDTO;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import lombok.Getter;
import lombok.Setter;
import java.util.LinkedHashMap;
import java.util.Map;
@Setter
@Getter
public class RunPlanScenarioVO {
private Map<String, TestPlanApiScenarioInfoDTO> testPlanScenarioMap;
private Map<String, ApiScenarioWithBLOBs> scenarioMap;
public RunPlanScenarioVO() {
this.testPlanScenarioMap = new LinkedHashMap<>();
this.scenarioMap = new LinkedHashMap<>();
}
}

View File

@ -190,11 +190,6 @@ public class TestPlanScenarioCaseController {
return testPlanScenarioCaseService.buildExecuteApiReport(request);
}
@PostMapping("/plan/report/schedule/info/{planId}")
public TestPlanApiReportInfoDTO genApiReportInfoForSchedule(@PathVariable("planId") String planId, @RequestBody RunModeConfigDTO runModeConfigDTO) {
return testPlanScenarioCaseService.genApiReportInfoForSchedule(planId, runModeConfigDTO);
}
@GetMapping("/is/executing/{planId}")
public Boolean isExecuting(@PathVariable("planId") String planId) {
return testPlanScenarioCaseService.isExecuting(planId);

View File

@ -69,7 +69,7 @@ public class ApiExecutionQueueService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
LoggerUtil.info("报告【" + reportId + "】开始生成执行链");
LoggerUtil.info("报告【" + type + "】开始生成执行链", reportId);
if (config.getEnvMap() == null) {
config.setEnvMap(new LinkedHashMap<>());
}
@ -99,7 +99,7 @@ public class ApiExecutionQueueService {
extApiExecutionQueueMapper.sqlInsert(queueDetails);
}
resQueue.setDetailMap(detailMap);
LoggerUtil.info("报告【" + reportId + "】生成执行链结束");
LoggerUtil.info("报告【" + type + "】生成执行链结束", reportId);
return resQueue;
}

View File

@ -16,7 +16,6 @@ import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiTestEnvironmentMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioModuleMapper;
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiScenarioMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.ApiRunMode;
@ -29,7 +28,6 @@ import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.dto.ProjectConfig;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.environment.service.BaseEnvGroupProjectService;
import io.metersphere.environment.service.BaseEnvironmentService;
import io.metersphere.i18n.Translator;
import io.metersphere.log.vo.OperatingLogDetails;
@ -70,8 +68,6 @@ public class TestPlanScenarioCaseService {
@Resource
ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
@Resource
ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
@Resource
ApiScenarioReportService apiScenarioReportService;
@ -94,8 +90,6 @@ public class TestPlanScenarioCaseService {
@Resource
private ApiDefinitionExecResultService apiDefinitionExecResultService;
@Resource
private BaseEnvGroupProjectService environmentGroupProjectService;
@Resource
private BaseEnvironmentService apiTestEnvironmentService;
@Resource
private ExtApiScenarioModuleMapper extApiScenarioModuleMapper;
@ -293,14 +287,13 @@ public class TestPlanScenarioCaseService {
RunScenarioRequest request = new RunScenarioRequest();
request.setIds(scenarioIds);
request.setReportId(testPlanScenarioRequest.getId());
request.setScenarioTestPlanIdMap(scenarioPlanIdMap);
request.setRunMode(ApiRunMode.SCENARIO_PLAN.name());
request.setId(testPlanScenarioRequest.getId());
request.setExecuteType(ExecuteType.Saved.name());
request.setTriggerMode(testPlanScenarioRequest.getTriggerMode());
request.setConfig(testPlanScenarioRequest.getConfig());
request.setPlanCaseIds(planCaseIdList);
request.setRequestOriginator("TEST_PLAN");
request.setPlanScenarioIds(planCaseIdList);
request.setRequestOriginator(CommonConstants.TEST_PLAN);
return apiAutomationService.run(request);
}
@ -1009,70 +1002,6 @@ public class TestPlanScenarioCaseService {
return testPlanApiCaseService.buildCases(apiTestCases);
}
public TestPlanApiReportInfoDTO genApiReportInfoForSchedule(String planId, RunModeConfigDTO runModeConfigDTO) {
TestPlanApiReportInfoDTO testPlanApiReportInfo = new TestPlanApiReportInfoDTO();
Map<String, String> planApiCaseIdMap = new LinkedHashMap<>();
Map<String, String> planScenarioIdMap = new LinkedHashMap<>();
List<TestPlanApiScenarioInfoDTO> testPlanApiScenarioList = extTestPlanScenarioCaseMapper.selectLegalDataByTestPlanId(planId);
for (TestPlanApiScenarioInfoDTO model : testPlanApiScenarioList) {
planScenarioIdMap.put(model.getId(), model.getApiScenarioId());
}
List<TestPlanApiCaseInfoDTO> testPlanApiCaseList = extTestPlanApiCaseMapper.selectLegalDataByTestPlanId(planId);
for (TestPlanApiCaseInfoDTO model : testPlanApiCaseList) {
planApiCaseIdMap.put(model.getId(), model.getApiCaseId());
}
testPlanApiReportInfo.setPlanApiCaseIdMap(planApiCaseIdMap);
testPlanApiReportInfo.setPlanScenarioIdMap(planScenarioIdMap);
//解析运行环境信息
TestPlanReportRunInfoDTO runInfoDTO = this.parseTestPlanRunInfo(runModeConfigDTO, testPlanApiCaseList, testPlanApiScenarioList);
testPlanApiReportInfo.setRunInfoDTO(runInfoDTO);
return testPlanApiReportInfo;
}
public TestPlanReportRunInfoDTO parseTestPlanRunInfo(RunModeConfigDTO runModeConfigDTO, List<TestPlanApiCaseInfoDTO> testPlanApiCaseList, List<TestPlanApiScenarioInfoDTO> testPlanApiScenarioList) {
TestPlanReportRunInfoDTO runInfoDTO = new TestPlanReportRunInfoDTO();
Map<String, String> selectEnvMap = runModeConfigDTO.getEnvMap();
runInfoDTO.setRunMode(runModeConfigDTO.getMode());
if (StringUtils.equals("GROUP", runModeConfigDTO.getEnvironmentType()) && StringUtils.isNotEmpty(runModeConfigDTO.getEnvironmentGroupId())) {
selectEnvMap = environmentGroupProjectService.getEnvMap(runModeConfigDTO.getEnvironmentGroupId());
runInfoDTO.setEnvGroupId(runModeConfigDTO.getEnvironmentGroupId());
}
for (TestPlanApiScenarioInfoDTO model : testPlanApiScenarioList) {
Map<String, String> envMap = null;
if (StringUtils.equalsIgnoreCase("group", model.getEnvironmentType()) && StringUtils.isNotEmpty(model.getEnvironmentGroupId())) {
envMap = environmentGroupProjectService.getEnvMap(model.getEnvironmentGroupId());
} else {
if (MapUtils.isNotEmpty(selectEnvMap) && selectEnvMap.containsKey(model.getProjectId())) {
runInfoDTO.putScenarioRunInfo(model.getId(), model.getProjectId(), selectEnvMap.get(model.getProjectId()));
} else if (StringUtils.isNotEmpty(model.getEnvironment())) {
try {
envMap = JSON.parseObject(model.getEnvironment(), Map.class);
} catch (Exception e) {
LogUtil.error("解析场景环境失败!", e);
}
}
}
if (MapUtils.isNotEmpty(envMap)) {
for (Map.Entry<String, String> entry : envMap.entrySet()) {
String projectId = entry.getKey();
String envIdStr = entry.getValue();
runInfoDTO.putScenarioRunInfo(model.getId(), projectId, envIdStr);
}
}
}
for (TestPlanApiCaseInfoDTO model : testPlanApiCaseList) {
if (MapUtils.isNotEmpty(selectEnvMap) && selectEnvMap.containsKey(model.getProjectId())) {
runInfoDTO.putApiCaseRunInfo(model.getId(), model.getProjectId(), selectEnvMap.get(model.getProjectId()));
} else {
runInfoDTO.putApiCaseRunInfo(model.getId(), model.getProjectId(), model.getEnvironmentId());
}
}
return runInfoDTO;
}
public Boolean isExecuting(String planId) {
List<TestPlanApiScenarioInfoDTO> testPlanApiScenarioList = extTestPlanScenarioCaseMapper.selectLegalDataByTestPlanId(planId);
return !testPlanApiScenarioList.stream()

View File

@ -16,6 +16,7 @@ import io.metersphere.base.mapper.ext.ExtApiScenarioReportResultMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiScenarioMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.constants.ElementConstants;
import io.metersphere.commons.constants.ReportTypeConstants;
import io.metersphere.commons.enums.ApiReportStatus;
@ -228,7 +229,7 @@ public class ApiScenarioRerunService {
BatchRunDefinitionRequest request = new BatchRunDefinitionRequest();
request.setTriggerMode(testPlanReport.getTriggerMode());
request.setRerun(true);
request.setPlanIds(ids);
request.setPlanCaseIds(ids);
request.setPlanReportId(parametersDTO.getReportId());
request.setUserId(parametersDTO.getCases().get(0).getUserId());
@ -271,9 +272,7 @@ public class ApiScenarioRerunService {
}
List<String> scenarioIds = apiScenarios.stream().map(TestPlanApiScenario::getApiScenarioId).collect(Collectors.toList());
LoggerUtil.info("重跑测试计划报告:【" + parametersDTO.getReportId() + "】,对应重跑场景资源:" + scenarioIds.size());
Map<String, String> scenarioTestPlanIdMap = apiScenarios.stream().collect(Collectors.toMap(TestPlanApiScenario::getId, a -> a.getApiScenarioId(), (k1, k2) -> k1));
List<String> planScenarioIds = apiScenarios.stream().map(TestPlanApiScenario::getId).collect(Collectors.toList());
// 查出原始报告
List<String> reportIds = apiScenarios.stream().map(TestPlanApiScenario::getReportId).collect(Collectors.toList());
if (com.alibaba.nacos.common.utils.CollectionUtils.isEmpty(reportIds)) {
@ -282,7 +281,7 @@ public class ApiScenarioRerunService {
ApiScenarioReportExample reportExample = new ApiScenarioReportExample();
reportExample.createCriteria().andIdIn(reportIds);
List<ApiScenarioReport> reports = apiScenarioReportMapper.selectByExample(reportExample);
if (com.alibaba.nacos.common.utils.CollectionUtils.isEmpty(reports)) {
if (CollectionUtils.isEmpty(reports)) {
return isStart;
}
// config
@ -312,7 +311,8 @@ public class ApiScenarioRerunService {
request.setExecuteType(ExecuteType.Completed.name());
request.setRunMode(ApiRunMode.SCENARIO_PLAN.name());
request.setIds(scenarioIds); // 场景IDS
request.setScenarioTestPlanIdMap(scenarioTestPlanIdMap);//场景id和计划场景id映射关系
request.setPlanScenarioIds(planScenarioIds);
// 一批执行的报告配置都是相同的
ApiScenarioReportWithBLOBs scenario = apiScenarioReportMapper.selectByPrimaryKey(reportIds.get(0));
if (scenario != null && StringUtils.isNotEmpty(scenario.getEnvConfig())) {
@ -322,7 +322,7 @@ public class ApiScenarioRerunService {
}
request.setTestPlanReportId(parametersDTO.getReportId());
request.setId(UUID.randomUUID().toString());
request.setRequestOriginator("TEST_PLAN");
request.setRequestOriginator(CommonConstants.TEST_PLAN);
LoggerUtil.info("清理原始报告对应结果:【" + request.getTestPlanReportId() + "】," + reportIds.size());
ApiScenarioReportResultExample reportResultExample = new ApiScenarioReportResultExample();

View File

@ -18,22 +18,22 @@ public class MsWebSocketClient extends WebSocketClient {
LogUtil.info("握手...");
for (Iterator<String> it = shake.iterateHttpFields(); it.hasNext(); ) {
String key = it.next();
System.out.println(key + ":" + shake.getFieldValue(key));
LogUtil.info(key + ":" + shake.getFieldValue(key));
}
}
@Override
public void onMessage(String paramString) {
System.out.println("接收到消息:" + paramString);
LogUtil.info("接收到消息:" + paramString);
}
@Override
public void onClose(int paramInt, String paramString, boolean paramBoolean) {
System.out.println("关闭...");
LogUtil.info("关闭...");
}
@Override
public void onError(Exception e) {
System.out.println("异常" + e);
LogUtil.info("异常" + e);
}
}

View File

@ -35,7 +35,7 @@ public class RestTemplateConfig implements WebMvcConfigurer {
private final static int MAX_PER_ROUTE = 500;
private final static int CONN_REQUEST_TIMEOUT = 5000;
private final static int CONNECT_TIMEOUT = 8000;
private final static int SOCKET_TIMEOUT = 20 * 1000;
private final static int SOCKET_TIMEOUT = 200 * 1000;
@Bean
public RestTemplate restTemplate() {

View File

@ -0,0 +1,10 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.plan.dto.TestPlanApiCaseInfoDTO;
import java.util.List;
public interface ExtTestPlanApiCaseMapper {
List<TestPlanApiCaseInfoDTO> selectLegalDataByTestPlanId(String planId);
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper">
<select id="selectLegalDataByTestPlanId" resultType="io.metersphere.plan.dto.TestPlanApiCaseInfoDTO">
SELECT a.project_id, t.*
FROM test_plan_api_case t
INNER JOIN api_test_case a ON t.api_case_id = a.id
WHERE t.test_plan_id = #{0}
AND (a.status IS NULL OR a.status != 'Trash')
ORDER BY t.`order` DESC
</select>
</mapper>

View File

@ -0,0 +1,9 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.plan.dto.TestPlanApiScenarioInfoDTO;
import java.util.List;
public interface ExtTestPlanScenarioCaseMapper {
List<TestPlanApiScenarioInfoDTO> selectLegalDataByTestPlanId(String planId);
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper">
<select id="selectLegalDataByTestPlanId" resultType="io.metersphere.plan.dto.TestPlanApiScenarioInfoDTO">
SELECT tpas.id,
tpas.api_scenario_id,
tpas.environment,
tpas.environment_type,
tpas.environment_group_id,
apis.project_id
FROM test_plan_api_scenario tpas
INNER JOIN api_scenario apis ON tpas.api_scenario_id = apis.id
WHERE (apis.`status` IS NULL OR apis.`status` != 'Trash')
AND tpas.test_plan_id = #{0}
ORDER BY tpas.`order` DESC;
</select>
</mapper>

View File

@ -25,6 +25,8 @@ public class BatchRunDefinitionRequest {
private String planReportId;
// 失败重跑
private boolean rerun;
private Map<String, ApiDefinitionExecResultWithBLOBs> executeQueue;
private String testPlanId;
}

View File

@ -53,4 +53,6 @@ public class RunScenarioRequest {
private String serialReportId;
// private Map<String, ApiScenarioReportResult> reportMap;
private String testPlanId;
}

View File

@ -4,14 +4,12 @@ package io.metersphere.plan.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanReportContentMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanReportMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.utils.*;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.*;
import io.metersphere.environment.service.BaseEnvGroupProjectService;
import io.metersphere.excel.constants.TestPlanTestCaseStatus;
import io.metersphere.log.vo.OperatingLogDetails;
import io.metersphere.plan.constant.ApiReportStatus;
@ -80,8 +78,12 @@ public class TestPlanReportService {
private TestPlanPrincipalMapper testPlanPrincipalMapper;
@Resource
ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
// @Resource
// private PerformanceTestService performanceTestService;
@Resource
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
private ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
@Resource
private BaseEnvGroupProjectService baseEnvGroupProjectService;
@Resource
private PlanApiDefinitionExecResultService planApiDefinitionExecResultService;
@Resource
@ -103,6 +105,8 @@ public class TestPlanReportService {
@Resource
private BaseUserService baseUserService;
private final String GROUP = "GROUP";
public List<TestPlanReportDTO> list(QueryTestPlanReportRequest request) {
List<TestPlanReportDTO> list = new ArrayList<>();
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
@ -231,6 +235,78 @@ public class TestPlanReportService {
}
}
public TestPlanApiReportInfoDTO genApiReportInfoForSchedule(String planId, RunModeConfigDTO runModeConfigDTO) {
TestPlanApiReportInfoDTO testPlanApiReportInfo = new TestPlanApiReportInfoDTO();
Map<String, String> planApiCaseIdMap = new LinkedHashMap<>();
Map<String, String> planScenarioIdMap = new LinkedHashMap<>();
List<TestPlanApiScenarioInfoDTO> testPlanApiScenarioList = extTestPlanScenarioCaseMapper.selectLegalDataByTestPlanId(planId);
for (TestPlanApiScenarioInfoDTO model : testPlanApiScenarioList) {
planScenarioIdMap.put(model.getId(), model.getApiScenarioId());
}
List<TestPlanApiCaseInfoDTO> testPlanApiCaseList = extTestPlanApiCaseMapper.selectLegalDataByTestPlanId(planId);
for (TestPlanApiCaseInfoDTO model : testPlanApiCaseList) {
planApiCaseIdMap.put(model.getId(), model.getApiCaseId());
}
testPlanApiReportInfo.setPlanApiCaseIdMap(planApiCaseIdMap);
testPlanApiReportInfo.setPlanScenarioIdMap(planScenarioIdMap);
//解析运行环境信息
TestPlanReportRunInfoDTO runInfoDTO = this.parseTestPlanRunInfo(runModeConfigDTO, testPlanApiCaseList, testPlanApiScenarioList);
testPlanApiReportInfo.setRunInfoDTO(runInfoDTO);
return testPlanApiReportInfo;
}
public TestPlanReportRunInfoDTO parseTestPlanRunInfo(
RunModeConfigDTO config,
List<TestPlanApiCaseInfoDTO> cases,
List<TestPlanApiScenarioInfoDTO> scenarios) {
TestPlanReportRunInfoDTO runInfoDTO = new TestPlanReportRunInfoDTO();
final Map<String, String> runEnvMap = config.getEnvMap();
runInfoDTO.setRunMode(config.getMode());
if (StringUtils.equals(GROUP, config.getEnvironmentType()) && StringUtils.isNotEmpty(config.getEnvironmentGroupId())) {
runEnvMap.putAll(baseEnvGroupProjectService.getEnvMap(config.getEnvironmentGroupId()));
runInfoDTO.setEnvGroupId(config.getEnvironmentGroupId());
}
// 场景环境处理
scenarios.forEach(item -> {
Map<String, String> envMap = null;
if (StringUtils.equalsIgnoreCase(GROUP, item.getEnvironmentType())
&& StringUtils.isNotEmpty(item.getEnvironmentGroupId())) {
envMap = baseEnvGroupProjectService.getEnvMap(item.getEnvironmentGroupId());
} else {
if (MapUtils.isNotEmpty(runEnvMap) && runEnvMap.containsKey(item.getProjectId())) {
runInfoDTO.putScenarioRunInfo(item.getId(), item.getProjectId(), runEnvMap.get(item.getProjectId()));
} else if (StringUtils.isNotEmpty(item.getEnvironment())) {
try {
envMap = JSON.parseObject(item.getEnvironment(), Map.class);
} catch (Exception e) {
LogUtil.error("解析场景环境失败!", e);
}
}
}
if (MapUtils.isNotEmpty(envMap)) {
for (Map.Entry<String, String> entry : envMap.entrySet()) {
String projectId = entry.getKey();
String envIdStr = entry.getValue();
runInfoDTO.putScenarioRunInfo(item.getId(), projectId, envIdStr);
}
}
});
// 用例环境处理
cases.forEach(item -> {
if (MapUtils.isNotEmpty(runEnvMap) && runEnvMap.containsKey(item.getProjectId())) {
runInfoDTO.putApiCaseRunInfo(item.getId(), item.getProjectId(), runEnvMap.get(item.getProjectId()));
} else {
runInfoDTO.putApiCaseRunInfo(item.getId(), item.getProjectId(), item.getEnvironmentId());
}
});
return runInfoDTO;
}
public TestPlanScheduleReportInfoDTO genTestPlanReportBySchedule(String planReportId, String planId, String userId, String triggerMode, RunModeConfigDTO runModeConfigDTO) {
TestPlanReport testPlanReport = this.getTestPlanReport(planReportId);
TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO();
@ -250,7 +326,8 @@ public class TestPlanReportService {
Set<String> serviceIdSet = DiscoveryUtil.getServiceIdSet();
if (serviceIdSet.contains(MicroServiceName.API_TEST)) {
TestPlanApiReportInfoDTO testPlanApiReportInfoDTO = planTestPlanScenarioCaseService.genApiReportInfoForSchedule(planId, runModeConfigDTO);
// 这里不再调用API服务生成相关数据否则当关联用例/场景量大时会超时
TestPlanApiReportInfoDTO testPlanApiReportInfoDTO = this.genApiReportInfoForSchedule(planId, runModeConfigDTO);
Map<String, String> planScenarioIdMap = testPlanApiReportInfoDTO.getPlanScenarioIdMap();
Map<String, String> planApiCaseIdMap = testPlanApiReportInfoDTO.getPlanApiCaseIdMap();
runInfoDTO = testPlanApiReportInfoDTO.getRunInfoDTO();

View File

@ -155,12 +155,7 @@ public class TestPlanService {
@Resource
private TestResourcePoolMapper testResourcePoolMapper;
@Resource
private SystemParameterService systemParameterService;
@Resource
private BaseProjectApplicationService projectApplicationService;
@Resource
private TestPlanReportMapper testPlanReportMapper;
public static final String POOL = "POOL";
public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) {
if (getTestPlanByName(testPlan.getName()).size() > 0) {
@ -792,23 +787,26 @@ public class TestPlanService {
RunScenarioRequest request = new RunScenarioRequest();
request.setReportId(planScenarioExecuteRequest.getReportId());
request.setTestPlanId(entry.getKey());
request.setEnvironmentId(planScenarioExecuteRequest.getEnvironmentId());
request.setTriggerMode(planScenarioExecuteRequest.getTriggerMode());
request.setExecuteType(planScenarioExecuteRequest.getExecuteType());
request.setRunMode(planScenarioExecuteRequest.getRunMode());
request.setIds(new ArrayList<>(scenarioMap.values()));//场景IDS
request.setReportUserID(planScenarioExecuteRequest.getReportUserID());
request.setScenarioTestPlanIdMap(scenarioMap);//未知
request.setConfig(planScenarioExecuteRequest.getConfig());
request.setTestPlanScheduleJob(true);
request.setTestPlanReportId(planScenarioExecuteRequest.getTestPlanReportId());
request.setId(UUID.randomUUID().toString());
request.setProjectId(planScenarioExecuteRequest.getProjectId());
request.setRequestOriginator("TEST_PLAN");
request.setPlanCaseIds(new ArrayList<>(testPlanScenarioIdMap.keySet()));
if ("api".equalsIgnoreCase(planScenarioExecuteRequest.getType())) {
list.addAll(planApiAutomationService.run(request));
} else {
// 以下三个参数接口测试未使用到暂时迁移到这里
request.setIds(new ArrayList<>(scenarioMap.values()));//场景IDS
request.setScenarioTestPlanIdMap(scenarioMap);//未知
request.setPlanCaseIds(new ArrayList<>(testPlanScenarioIdMap.keySet()));
RunUiScenarioRequest runUiScenarioRequest = new RunUiScenarioRequest();
BeanUtils.copyBean(runUiScenarioRequest, request);
RunModeConfigDTO configDTO = new RunModeConfigDTO();
@ -887,7 +885,7 @@ public class TestPlanService {
if (MapUtils.isNotEmpty(reportInfoDTO.getApiTestCaseDataMap())) {
//执行接口案例任务
LoggerUtil.info("开始执行测试计划接口用例 " + planReportId);
apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, new ArrayList<>(reportInfoDTO.getApiTestCaseDataMap().keySet()), runModeConfig);
apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, testPlanId, runModeConfig);
}
if (MapUtils.isNotEmpty(reportInfoDTO.getPlanScenarioIdMap())) {
//执行场景执行任务
@ -946,13 +944,13 @@ public class TestPlanService {
return runModeConfig;
}
private Map<String, String> executeApiTestCase(String triggerMode, String planReportId, String userId, List<String> planCaseIds, RunModeConfigDTO runModeConfig) {
private Map<String, String> executeApiTestCase(String triggerMode, String planReportId, String userId, String testPlanId, RunModeConfigDTO runModeConfig) {
BatchRunDefinitionRequest request = new BatchRunDefinitionRequest();
request.setTriggerMode(triggerMode);
request.setPlanIds(planCaseIds);
request.setPlanReportId(planReportId);
request.setConfig(runModeConfig);
request.setUserId(userId);
request.setTestPlanId(testPlanId);
List<MsExecResponseDTO> dtoList = planTestPlanApiCaseService.run(request);
return this.parseMsExecResponseDTOToTestIdReportMap(dtoList);
}

View File

@ -1,11 +1,13 @@
package io.metersphere.plan.service.remote.api;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.plan.request.api.RunScenarioRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.ArrayList;
import java.util.List;
@Service
@ -15,7 +17,12 @@ public class PlanApiAutomationService extends ApiTestService {
public List<MsExecResponseDTO> run(RunScenarioRequest request) {
return microService.postForDataArray(serviceName, BASE_UEL + "/plan/run", request, MsExecResponseDTO.class);
try {
return microService.postForDataArray(serviceName, BASE_UEL + "/plan/run", request, MsExecResponseDTO.class);
} catch (Exception e) {
LogUtil.error("调用API服务执行场景用例失败", e);
return new ArrayList<>();
}
}
public ApiScenarioWithBLOBs get(@PathVariable String id) {

View File

@ -93,7 +93,12 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
}
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
return microService.postForDataArray(serviceName, BASE_UEL + "/run", request, MsExecResponseDTO.class);
try {
return microService.postForDataArray(serviceName, BASE_UEL + "/run", request, MsExecResponseDTO.class);
} catch (Exception e) {
LogUtil.info("调用API服务执行用例失败", e);
return new ArrayList<>();
}
}
public RunModeConfigDTO setApiCaseEnv(String planId, RunModeConfigDTO runModeConfig) {

View File

@ -155,10 +155,6 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService {
return microService.postForData(serviceName, BASE_UEL + "/plan/execute/report", request, ApiPlanReportDTO.class);
}
public TestPlanApiReportInfoDTO genApiReportInfoForSchedule(String planId, RunModeConfigDTO runModeConfigDTO) {
return microService.postForData(serviceName, BASE_UEL + "/plan/report/schedule/info/" + planId, runModeConfigDTO, TestPlanApiReportInfoDTO.class);
}
public Boolean isCaseExecuting(String planId) {
return microService.getForData(serviceName, BASE_UEL + "/is/executing/" + planId, Boolean.class);
}