Merge branch 'main' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
5dc33c1121
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class BatchDataCopyRequest {
|
||||
private List<String> ids;
|
||||
private boolean copyCase;
|
||||
private boolean copyMock;
|
||||
private String versionId;
|
||||
|
||||
private ApiDefinitionRequest condition;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
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 TRASH_STATUS = "Trash";
|
||||
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";
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<>();
|
||||
}
|
||||
}
|
|
@ -139,6 +139,13 @@ public class ApiDefinitionController {
|
|||
apiDefinitionService.deleteByParams(request);
|
||||
}
|
||||
|
||||
@PostMapping("/copy/by/version")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_API)
|
||||
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.ids)", title = "#request.name", content = "#msClass.getLogDetails(#request.ids)", msClass = ApiDefinitionService.class)
|
||||
public void copyByVersion(@RequestBody BatchDataCopyRequest request) {
|
||||
apiDefinitionService.copyCaseOrMockByVersion(request);
|
||||
}
|
||||
|
||||
@PostMapping("/move-gc")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_API)
|
||||
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiDefinitionService.class)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,12 @@ public class MockConfigService {
|
|||
return extMockExpectConfigMapper.selectByApiId(apiId);
|
||||
}
|
||||
|
||||
public List<MockExpectConfig> selectSimpleMockExpectConfigByMockConfigId(String mockConfigId) {
|
||||
MockExpectConfigExample example = new MockExpectConfigExample();
|
||||
example.createCriteria().andMockConfigIdEqualTo(mockConfigId);
|
||||
return mockExpectConfigMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public List<MockConfigImportDTO> selectMockExpectConfigByApiIdIn(List<String> apiIds) {
|
||||
if (CollectionUtils.isNotEmpty(apiIds)) {
|
||||
List<MockConfigImportDTO> returnDTO = new ArrayList<>();
|
||||
|
@ -263,15 +269,22 @@ public class MockConfigService {
|
|||
return mockExpectConfigMapper.selectByPrimaryKey(model.getId());
|
||||
}
|
||||
|
||||
private String getMockExpectId(String mockConfigId) {
|
||||
List<String> savedExpectNumber = extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId);
|
||||
public String getMockExpectId(String mockConfigId) {
|
||||
List<String> savedExpectNumber = this.selectExpectNumberByConfigId(mockConfigId);
|
||||
String apiNum = extMockExpectConfigMapper.selectApiNumberByMockConfigId(mockConfigId);
|
||||
return this.getMockExpectId(apiNum, savedExpectNumber);
|
||||
}
|
||||
|
||||
public List<String> selectExpectNumberByConfigId(String mockConfigId) {
|
||||
return extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId);
|
||||
}
|
||||
|
||||
public String getMockExpectId(String apiNum, List<String> savedExpectNumber) {
|
||||
if (StringUtils.isEmpty(apiNum)) {
|
||||
apiNum = StringUtils.EMPTY;
|
||||
} else {
|
||||
apiNum = apiNum + "_";
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
for (String expectNum : savedExpectNumber) {
|
||||
if (StringUtils.startsWith(expectNum, apiNum)) {
|
||||
|
@ -1153,7 +1166,7 @@ public class MockConfigService {
|
|||
}
|
||||
|
||||
|
||||
private MockConfig selectMockConfigByApiId(String apiId) {
|
||||
public MockConfig selectMockConfigByApiId(String apiId) {
|
||||
MockConfigExample example = new MockConfigExample();
|
||||
example.createCriteria().andApiIdEqualTo(apiId);
|
||||
List<MockConfig> mockConfigList = this.mockConfigMapper.selectByExample(example);
|
||||
|
|
|
@ -50,6 +50,7 @@ import io.metersphere.service.ext.ExtApiScheduleService;
|
|||
import io.metersphere.service.ext.ExtFileAssociationService;
|
||||
import io.metersphere.service.plan.TestPlanApiCaseService;
|
||||
import io.metersphere.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.utils.BatchProcessingUtil;
|
||||
import io.metersphere.xpack.api.service.ApiCaseBatchSyncService;
|
||||
import io.metersphere.xpack.api.service.ApiDefinitionSyncService;
|
||||
import io.metersphere.xpack.quota.service.QuotaService;
|
||||
|
@ -133,6 +134,9 @@ public class ApiDefinitionService {
|
|||
@Lazy
|
||||
@Resource
|
||||
private ApiModuleService apiModuleService;
|
||||
@Lazy
|
||||
@Resource
|
||||
private MockConfigService mockConfigService;
|
||||
@Resource
|
||||
private BaseEnvironmentService apiTestEnvironmentService;
|
||||
@Lazy
|
||||
|
@ -2143,4 +2147,217 @@ public class ApiDefinitionService {
|
|||
allSourceIdCount = apiExecutionInfoService.countSourceIdByProjectIdIsNull();
|
||||
}
|
||||
}
|
||||
|
||||
public void copyCaseOrMockByVersion(BatchDataCopyRequest request) {
|
||||
if (!request.isCopyCase() && !request.isCopyMock()) {
|
||||
return;
|
||||
}
|
||||
if (request.getCondition() == null) {
|
||||
return;
|
||||
}
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiDefinitionMapper.selectIds(query));
|
||||
// ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiDefinitionMapper.selectIds(query));
|
||||
|
||||
if (StringUtils.isBlank(request.getVersionId()) || CollectionUtils.isEmpty(request.getCondition().getIds())) {
|
||||
MSException.throwException(Translator.get("invalid_parameter"));
|
||||
}
|
||||
request.setIds(request.getCondition().getIds());
|
||||
|
||||
//函数是批量操作,可能会出现数据太多导致的sql过长错误,采用批量处理
|
||||
BatchProcessingUtil.batchProcessingByDataCopy(request, this::batchCopyCaseOrMockByVersion);
|
||||
|
||||
}
|
||||
|
||||
public void batchCopyCaseOrMockByVersion(BatchDataCopyRequest request) {
|
||||
|
||||
if (sqlSessionFactory != null && CollectionUtils.isNotEmpty(request.getIds())) {
|
||||
Map<String, ApiDefinition> refIdMap = new HashMap<>();
|
||||
List<ApiDefinition> apiDefinitionList = this.selectByIds(request.getIds());
|
||||
apiDefinitionList.forEach(item -> {
|
||||
//过滤到自身的引用
|
||||
if (!StringUtils.equals(item.getVersionId(), request.getVersionId())) {
|
||||
refIdMap.put(item.getRefId(), item);
|
||||
}
|
||||
});
|
||||
if (MapUtils.isNotEmpty(refIdMap)) {
|
||||
ApiDefinitionExample apiExample = new ApiDefinitionExample();
|
||||
apiExample.createCriteria().andStatusNotEqualTo(ApiTestDataStatus.TRASH.getValue()).andRefIdIn(new ArrayList<>(refIdMap.keySet())).andVersionIdEqualTo(request.getVersionId());
|
||||
List<ApiDefinition> versionApiList = apiDefinitionMapper.selectByExample(apiExample);
|
||||
Map<String, String> sourceApiIdRefIdMap = new HashMap<>();
|
||||
versionApiList.forEach(item -> sourceApiIdRefIdMap.put(item.getId(), item.getRefId()));
|
||||
if (MapUtils.isEmpty(sourceApiIdRefIdMap)) {
|
||||
return;
|
||||
}
|
||||
SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (request.isCopyCase()) {
|
||||
this.copyCaseByVersion(request.getIds(), sourceApiIdRefIdMap, refIdMap, batchSqlSession);
|
||||
}
|
||||
if (request.isCopyMock()) {
|
||||
this.copyMockByVersion(sourceApiIdRefIdMap, refIdMap, batchSqlSession);
|
||||
}
|
||||
batchSqlSession.flushStatements();
|
||||
if (sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(batchSqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyMockByVersion(Map<String, String> sourceApiIdRefIdMap, Map<String, ApiDefinition> refIdMap, SqlSession batchSqlSession) {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
MockConfigExample mockConfigExample = new MockConfigExample();
|
||||
mockConfigExample.createCriteria().andApiIdIn(new ArrayList<>(sourceApiIdRefIdMap.keySet()));
|
||||
List<MockConfig> mockConfigList = mockConfigMapper.selectByExample(mockConfigExample);
|
||||
if (CollectionUtils.isNotEmpty(mockConfigList)) {
|
||||
List<String> mockIdList = mockConfigList.stream().map(MockConfig::getId).collect(Collectors.toList());
|
||||
MockExpectConfigExample mockExpectConfigExample = new MockExpectConfigExample();
|
||||
mockExpectConfigExample.createCriteria().andMockConfigIdIn(mockIdList);
|
||||
List<MockExpectConfigWithBLOBs> mockExpectConfigWithBLOBsList = mockExpectConfigMapper.selectByExampleWithBLOBs(mockExpectConfigExample);
|
||||
Map<String, List<MockExpectConfigWithBLOBs>> mockConfigIdExpectMap = mockExpectConfigWithBLOBsList.stream().collect(Collectors.groupingBy(MockExpectConfigWithBLOBs::getMockConfigId));
|
||||
|
||||
List<MockConfig> saveMockList = new ArrayList<>();
|
||||
|
||||
List<MockExpectConfigWithBLOBs> saveMockExpectList = new ArrayList<>();
|
||||
List<MockExpectConfigWithBLOBs> updateMockExpectList = new ArrayList<>();
|
||||
|
||||
mockConfigList.forEach(item -> {
|
||||
String oldApiId = item.getApiId();
|
||||
String refId = sourceApiIdRefIdMap.get(oldApiId);
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
ApiDefinition api = refIdMap.get(refId);
|
||||
if (api != null) {
|
||||
MockConfig baseMockConfig = mockConfigService.selectMockConfigByApiId(api.getId());
|
||||
String mockConfigId = UUID.randomUUID().toString();
|
||||
|
||||
Map<String, MockExpectConfig> oldMockExpectConfig = new HashMap<>();
|
||||
//已经存储的mock期望编号
|
||||
List<String> saveExpectNumList = new ArrayList<>();
|
||||
|
||||
if (baseMockConfig == null) {
|
||||
MockConfig mockConfig = new MockConfig();
|
||||
BeanUtils.copyBean(mockConfig, item);
|
||||
mockConfig.setApiId(api.getId());
|
||||
mockConfig.setId(mockConfigId);
|
||||
mockConfig.setCreateTime(timeStamp);
|
||||
mockConfig.setUpdateTime(timeStamp);
|
||||
saveMockList.add(mockConfig);
|
||||
} else {
|
||||
mockConfigId = baseMockConfig.getId();
|
||||
saveExpectNumList = mockConfigService.selectExpectNumberByConfigId(mockConfigId);
|
||||
List<MockExpectConfig> oldMockExpectList = mockConfigService.selectSimpleMockExpectConfigByMockConfigId(mockConfigId);
|
||||
oldMockExpectList.forEach(mockExpectConfig -> {
|
||||
oldMockExpectConfig.put(StringUtils.trim(mockExpectConfig.getName()), mockExpectConfig);
|
||||
});
|
||||
}
|
||||
List<MockExpectConfigWithBLOBs> mockExpectConfigList = mockConfigIdExpectMap.get(item.getId());
|
||||
if (CollectionUtils.isNotEmpty(mockExpectConfigList)) {
|
||||
String finalMockConfigId = mockConfigId;
|
||||
List<String> finalSaveExpectNumList = saveExpectNumList;
|
||||
mockExpectConfigList.forEach(mockExpectConfigWithBLOBs -> {
|
||||
MockExpectConfig oldExpect = oldMockExpectConfig.get(StringUtils.trim(mockExpectConfigWithBLOBs.getName()));
|
||||
MockExpectConfigWithBLOBs expectConfigWithBLOBs = new MockExpectConfigWithBLOBs();
|
||||
BeanUtils.copyBean(expectConfigWithBLOBs, mockExpectConfigWithBLOBs);
|
||||
if (oldExpect == null) {
|
||||
String newMockExpectNum = mockConfigService.getMockExpectId(String.valueOf(api.getNum()), finalSaveExpectNumList);
|
||||
finalSaveExpectNumList.add(newMockExpectNum);
|
||||
|
||||
expectConfigWithBLOBs.setId(UUID.randomUUID().toString());
|
||||
expectConfigWithBLOBs.setExpectNum(newMockExpectNum);
|
||||
expectConfigWithBLOBs.setCreateTime(timeStamp);
|
||||
expectConfigWithBLOBs.setUpdateTime(timeStamp);
|
||||
expectConfigWithBLOBs.setMockConfigId(finalMockConfigId);
|
||||
saveMockExpectList.add(expectConfigWithBLOBs);
|
||||
} else {
|
||||
expectConfigWithBLOBs.setId(oldExpect.getId());
|
||||
expectConfigWithBLOBs.setCreateTime(oldExpect.getCreateTime());
|
||||
expectConfigWithBLOBs.setUpdateTime(timeStamp);
|
||||
updateMockExpectList.add(expectConfigWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(saveMockList)) {
|
||||
MockConfigMapper mockConfigBatchMapper = batchSqlSession.getMapper(MockConfigMapper.class);
|
||||
saveMockList.forEach(mockConfigBatchMapper::insert);
|
||||
}
|
||||
MockExpectConfigMapper mockExpectConfigBatchMapper = batchSqlSession.getMapper(MockExpectConfigMapper.class);
|
||||
if (CollectionUtils.isNotEmpty(saveMockExpectList)) {
|
||||
saveMockExpectList.forEach(mockExpectConfigBatchMapper::insert);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateMockExpectList)) {
|
||||
updateMockExpectList.forEach(mockExpectConfigBatchMapper::updateByPrimaryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyCaseByVersion(List<String> chooseApiIdList, Map<String, String> sourceApiIdRefIdMap, Map<String, ApiDefinition> refIdMap, SqlSession batchSqlSession) {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
List<ApiTestCaseWithBLOBs> sourceApiCaseList = apiTestCaseService.selectCasesBydApiIds(new ArrayList<>(sourceApiIdRefIdMap.keySet()));
|
||||
List<ApiTestCase> caseInChooseApi = apiTestCaseService.selectSimpleCasesBydApiIds(chooseApiIdList);
|
||||
Map<String, Map<String, ApiTestCase>> apiIdOldCaseMap = new HashMap<>();
|
||||
caseInChooseApi.forEach(item -> {
|
||||
String caseName = StringUtils.trim(item.getName());
|
||||
if (StringUtils.isNotBlank(caseName)) {
|
||||
if (apiIdOldCaseMap.containsKey(item.getApiDefinitionId())) {
|
||||
apiIdOldCaseMap.get(item.getApiDefinitionId()).put(caseName, item);
|
||||
} else {
|
||||
apiIdOldCaseMap.put(item.getApiDefinitionId(), new HashMap<>() {{
|
||||
this.put(caseName, item);
|
||||
}});
|
||||
}
|
||||
}
|
||||
});
|
||||
List<ApiTestCaseWithBLOBs> saveCaseList = new ArrayList<>();
|
||||
List<ApiTestCaseWithBLOBs> updateCaseList = new ArrayList<>();
|
||||
Map<String, Integer> lastCaseNumMap = new LinkedHashMap<>();
|
||||
sourceApiCaseList.forEach(item -> {
|
||||
String oldApiId = item.getApiDefinitionId();
|
||||
String refId = sourceApiIdRefIdMap.get(oldApiId);
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
ApiDefinition api = refIdMap.get(refId);
|
||||
if (api != null) {
|
||||
//通过用例名称检查是否需要覆盖
|
||||
ApiTestCase oldCase = null;
|
||||
if (apiIdOldCaseMap.containsKey(api.getId())) {
|
||||
oldCase = apiIdOldCaseMap.get(api.getId()).get(StringUtils.trim(item.getName()));
|
||||
}
|
||||
ApiTestCaseWithBLOBs newCase = new ApiTestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(newCase, item);
|
||||
newCase.setApiDefinitionId(api.getId());
|
||||
newCase.setVersionId(api.getVersionId());
|
||||
if (oldCase == null) {
|
||||
int lastCaseNum = 0;
|
||||
if (lastCaseNumMap.containsKey(api.getId())) {
|
||||
lastCaseNum = lastCaseNumMap.get(api.getId());
|
||||
} else {
|
||||
lastCaseNum = apiTestCaseService.getNextNum(api.getId());
|
||||
}
|
||||
int caseNum = apiTestCaseService.getNextNum(lastCaseNum);
|
||||
newCase.setNum(caseNum);
|
||||
newCase.setId(UUID.randomUUID().toString());
|
||||
newCase.setCreateTime(timeStamp);
|
||||
newCase.setUpdateTime(timeStamp);
|
||||
|
||||
lastCaseNumMap.put(api.getId(), caseNum);
|
||||
saveCaseList.add(newCase);
|
||||
} else {
|
||||
newCase.setId(oldCase.getId());
|
||||
newCase.setNum(oldCase.getNum());
|
||||
newCase.setCreateTime(oldCase.getCreateTime());
|
||||
newCase.setUpdateTime(timeStamp);
|
||||
updateCaseList.add(newCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ApiTestCaseMapper apiTestCaseBatchMapper = batchSqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
if (CollectionUtils.isNotEmpty(saveCaseList)) {
|
||||
saveCaseList.forEach(apiTestCaseBatchMapper::insert);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateCaseList)) {
|
||||
updateCaseList.forEach(apiTestCaseBatchMapper::updateByPrimaryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -480,15 +480,19 @@ public class ApiTestCaseService {
|
|||
|
||||
public int getNextNum(String definitionId) {
|
||||
ApiTestCase apiTestCase = extApiTestCaseMapper.getNextNum(definitionId);
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
if (apiTestCase == null) {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
int n = apiDefinitionWithBLOBs.getNum();
|
||||
return n * 1000 + 1;
|
||||
} else {
|
||||
return Optional.of(apiTestCase.getNum() + 1).orElse(apiDefinitionWithBLOBs.getNum() * 1000 + 1);
|
||||
return this.getNextNum(apiTestCase.getNum());
|
||||
}
|
||||
}
|
||||
|
||||
public int getNextNum(Integer lastApiCaseNum) {
|
||||
return Optional.of(lastApiCaseNum + 1).orElse(lastApiCaseNum * 1000 + 1);
|
||||
}
|
||||
|
||||
public int getNextNum(String definitionId, Integer definitionNum, String projectId) {
|
||||
ApiTestCase apiTestCase = extApiTestCaseMapper.getNextNum(definitionId);
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(definitionId);
|
||||
|
@ -607,6 +611,12 @@ public class ApiTestCaseService {
|
|||
return apiTestCaseMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<ApiTestCase> selectSimpleCasesBydApiIds(List<String> apiIds) {
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andApiDefinitionIdIn(apiIds).andStatusNotEqualTo("Trash");
|
||||
return apiTestCaseMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public Map<String, String> getRequest(ApiTestCaseRequest request) {
|
||||
List<ApiTestCaseInfo> list = extApiTestCaseMapper.getRequest(request);
|
||||
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
||||
|
@ -986,7 +996,7 @@ public class ApiTestCaseService {
|
|||
if (CollectionUtils.isNotEmpty(apiCaseIds)) {
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andIdIn(apiCaseIds);
|
||||
example.or().andStatusNotEqualTo(CommonConstants.TrashStatus).andStatusIsNull();
|
||||
example.or().andStatusNotEqualTo(CommonConstants.TRASH_STATUS).andStatusIsNull();
|
||||
return apiTestCaseMapper.selectByExample(example);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
|
|
|
@ -734,9 +734,9 @@ public class TestPlanApiCaseService {
|
|||
|
||||
List<String> caseIds = apiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
|
||||
|
||||
List<String> definitionIds = apiTestCaseService.selectCasesBydIds(caseIds).stream().filter(apiTestCase -> apiTestCase.getStatus() == null || !CommonConstants.TrashStatus.equals(apiTestCase.getStatus())).map(ApiTestCase::getApiDefinitionId).collect(Collectors.toList());
|
||||
List<String> definitionIds = apiTestCaseService.selectCasesBydIds(caseIds).stream().filter(apiTestCase -> apiTestCase.getStatus() == null || !CommonConstants.TRASH_STATUS.equals(apiTestCase.getStatus())).map(ApiTestCase::getApiDefinitionId).collect(Collectors.toList());
|
||||
|
||||
List<String> dataNodeIds = apiDefinitionService.selectApiDefinitionBydIds(definitionIds).stream().filter(apiDefinition -> apiDefinition.getStatus() == null || !CommonConstants.TrashStatus.equals(apiDefinition.getStatus())).map(ApiDefinition::getModuleId).collect(Collectors.toList());
|
||||
List<String> dataNodeIds = apiDefinitionService.selectApiDefinitionBydIds(definitionIds).stream().filter(apiDefinition -> apiDefinition.getStatus() == null || !CommonConstants.TRASH_STATUS.equals(apiDefinition.getStatus())).map(ApiDefinition::getModuleId).collect(Collectors.toList());
|
||||
|
||||
List<ApiModuleDTO> nodeTrees = apiModuleService.getNodeTrees(testCaseNodes);
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
@ -1220,7 +1149,7 @@ public class TestPlanScenarioCaseService {
|
|||
.collect(Collectors.toList());
|
||||
|
||||
List<String> dataNodeIds = apiAutomationService.selectByIds(caseIds).stream()
|
||||
.filter(apiScenario -> apiScenario.getStatus() == null || !CommonConstants.TrashStatus.equals(apiScenario.getStatus()))
|
||||
.filter(apiScenario -> apiScenario.getStatus() == null || !CommonConstants.TRASH_STATUS.equals(apiScenario.getStatus()))
|
||||
.map(ApiScenario::getApiScenarioModuleId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -2222,7 +2222,7 @@ public class ApiScenarioService {
|
|||
public List<ApiScenario> getScenarioCaseByIds(List<String> ids) {
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdIn(ids).andStatusNotEqualTo(CommonConstants.TrashStatus);
|
||||
example.createCriteria().andIdIn(ids).andStatusNotEqualTo(CommonConstants.TRASH_STATUS);
|
||||
return apiScenarioMapper.selectByExample(example);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package io.metersphere.utils;
|
||||
|
||||
import io.metersphere.api.dto.definition.BatchDataCopyRequest;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 批量处理工具
|
||||
*/
|
||||
public class BatchProcessingUtil {
|
||||
|
||||
private static final int BATCH_PROCESS_QUANTITY = 1000;
|
||||
|
||||
public static void batchProcessingByDataCopy(BatchDataCopyRequest paramRequest, Consumer<BatchDataCopyRequest> func) {
|
||||
List<String> paramList = paramRequest.getIds();
|
||||
if (CollectionUtils.isNotEmpty(paramList)) {
|
||||
BatchDataCopyRequest queryRequest = new BatchDataCopyRequest();
|
||||
BeanUtils.copyBean(queryRequest, paramRequest);
|
||||
int unProcessingCount = paramList.size();
|
||||
while (paramList.size() > BATCH_PROCESS_QUANTITY) {
|
||||
List<String> processingList = new ArrayList<>();
|
||||
for (int i = 0; i < BATCH_PROCESS_QUANTITY; i++) {
|
||||
processingList.add(paramList.get(i));
|
||||
}
|
||||
//函数处理
|
||||
queryRequest.setIds(processingList);
|
||||
func.accept(queryRequest);
|
||||
|
||||
paramList.removeAll(processingList);
|
||||
if (paramList.size() == unProcessingCount) {
|
||||
//如果剩余数量没有发生变化,则跳出循环。防止出现死循环的情况
|
||||
break;
|
||||
} else {
|
||||
unProcessingCount = paramList.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(paramList)) {
|
||||
//剩余待处理数据进行处理
|
||||
queryRequest.setIds(paramList);
|
||||
func.accept(queryRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { fileDownload, fileUpload } from '@/api/base-network';
|
||||
import { fileUpload } from '@/api/base-network';
|
||||
import { get, post } from 'metersphere-frontend/src/plugins/request';
|
||||
|
||||
export function getRelationshipCountApi(id) {
|
||||
|
@ -137,6 +137,10 @@ export function removeToGcByParams(params) {
|
|||
return post('/api/definition/move-gc-batch', params);
|
||||
}
|
||||
|
||||
export function copyDataByVersion(params) {
|
||||
return post('/api/definition/copy/by/version', params);
|
||||
}
|
||||
|
||||
export function removeToGcByIds(params) {
|
||||
return post('/api/definition/move-gc', params);
|
||||
}
|
||||
|
|
|
@ -369,6 +369,7 @@ export default {
|
|||
file: false,
|
||||
encode: true,
|
||||
enable: true,
|
||||
isEdit: false,
|
||||
contentType: 'text/plain',
|
||||
})
|
||||
);
|
||||
|
|
|
@ -225,6 +225,8 @@
|
|||
:data-count="$refs.table ? $refs.table.selectDataCounts : 0"
|
||||
:typeArr="typeArr"
|
||||
:value-arr="valueArr" />
|
||||
<!--从指定版本复制数据-->
|
||||
<version-selector @handleSave="handleCopyDataFromVersion" ref="versionSelector" />
|
||||
<!--高级搜索-->
|
||||
<ms-table-adv-search-bar :condition.sync="condition" :showLink="false" ref="searchBar" @search="search" />
|
||||
<case-batch-move @refresh="initTable" @moveSave="moveSave" ref="testCaseBatchMove" />
|
||||
|
@ -239,6 +241,7 @@
|
|||
import {
|
||||
batchCopyByParams,
|
||||
batchEditByParams,
|
||||
copyDataByVersion,
|
||||
definitionReduction,
|
||||
delDefinition,
|
||||
delDefinitionByRefId,
|
||||
|
@ -292,6 +295,7 @@ import { getGraphByCondition } from '@/api/graph';
|
|||
import ListItemDeleteConfirm from 'metersphere-frontend/src/components/ListItemDeleteConfirm';
|
||||
import MsSearch from 'metersphere-frontend/src/components/search/MsSearch';
|
||||
import { buildNodePath } from 'metersphere-frontend/src/model/NodeTree';
|
||||
import VersionSelector from '@/business/definition/components/version/VersionSelector';
|
||||
|
||||
export default {
|
||||
name: 'ApiList',
|
||||
|
@ -316,6 +320,7 @@ export default {
|
|||
MsTable,
|
||||
MsTableColumn,
|
||||
MsSearch,
|
||||
VersionSelector,
|
||||
MsApiReportStatus: () => import('../../../automation/report/ApiReportStatus'),
|
||||
MxRelationshipGraphDrawer: () => import('metersphere-frontend/src/components/graph/MxRelationshipGraphDrawer'),
|
||||
},
|
||||
|
@ -357,6 +362,12 @@ export default {
|
|||
handleClick: this.handleBatchCopy,
|
||||
permissions: ['PROJECT_API_DEFINITION:READ+CREATE_API'],
|
||||
},
|
||||
{
|
||||
name: this.$t('api_definition.copy_data_from_other_version'),
|
||||
isXPack: true,
|
||||
handleClick: this.batchCopyDataFromVersion,
|
||||
permissions: ['PROJECT_API_DEFINITION:READ+EDIT_API'],
|
||||
},
|
||||
{
|
||||
name: this.$t('test_track.case.generate_dependencies'),
|
||||
isXPack: true,
|
||||
|
@ -646,6 +657,11 @@ export default {
|
|||
this.isMoveBatch = false;
|
||||
this.$refs.testCaseBatchMove.open(this.moduleTree, this.$refs.table.selectIds, this.moduleOptionsNew);
|
||||
},
|
||||
batchCopyDataFromVersion() {
|
||||
if (this.$refs.versionSelector) {
|
||||
this.$refs.versionSelector.open(this.projectId);
|
||||
}
|
||||
},
|
||||
closeCaseModel() {
|
||||
//关闭案例弹窗
|
||||
if (this.$refs.caseList) {
|
||||
|
@ -849,7 +865,7 @@ export default {
|
|||
this.search();
|
||||
},
|
||||
search() {
|
||||
this.$EventBus.$emit("apiConditionBus", this.condition)
|
||||
this.$EventBus.$emit('apiConditionBus', this.condition);
|
||||
this.changeSelectDataRangeAll();
|
||||
this.initTable();
|
||||
},
|
||||
|
@ -1181,6 +1197,35 @@ export default {
|
|||
return '';
|
||||
}
|
||||
},
|
||||
//从指定版本拷贝数据
|
||||
handleCopyDataFromVersion(selectVersionId, copyCase, copyMock) {
|
||||
let copyParam = {};
|
||||
// let param = {};
|
||||
// if (vueObj.selectRows) {
|
||||
// param.ids = selectIds ? selectIds : Array.from(vueObj.selectRows).map(row => row.id);
|
||||
// } else {
|
||||
// param.ids = selectIds;
|
||||
// }
|
||||
// param.projectId = projectId ? projectId : getCurrentProjectID();
|
||||
// param.condition = vueObj.condition;
|
||||
// return param;
|
||||
|
||||
// copyParam.versionId = selectVersionId;
|
||||
copyParam.copyCase = copyCase;
|
||||
copyParam.copyMock = copyMock;
|
||||
copyParam.versionId = selectVersionId;
|
||||
copyParam.condition = this.condition;
|
||||
copyParam.condition.ids = this.$refs.table.selectIds;
|
||||
copyParam.condition.protocol = this.currentProtocol;
|
||||
|
||||
copyDataByVersion(copyParam).then(() => {
|
||||
this.$success(this.$t('commons.copy_success'));
|
||||
if (this.$refs.versionSelector) {
|
||||
this.$refs.versionSelector.handleClose();
|
||||
}
|
||||
this.initTable();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -525,6 +525,7 @@ export default {
|
|||
file: false,
|
||||
encode: true,
|
||||
enable: true,
|
||||
isEdit: false,
|
||||
contentType: 'text/plain',
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<template>
|
||||
<ms-edit-dialog
|
||||
:visible.sync="visible"
|
||||
width="300px"
|
||||
:title="$t('commons.delete_all_version')"
|
||||
:with-footer="false"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose">
|
||||
<el-row>
|
||||
<div v-loading="loading">
|
||||
<el-row>
|
||||
<el-select v-model="versionId" size="small" :placeholder="$t('project.version.please_input_version')">
|
||||
<el-option v-for="v in versionData" :key="v.id" :label="v.name" :value="v.id" />
|
||||
</el-select>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-checkbox v-model="selectCase" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_CASE']">{{ $t('commons.api_case') }}</el-checkbox>
|
||||
<el-checkbox v-model="selectMock">{{ $t('commons.mock') }}</el-checkbox>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
<template v-slot:footer>
|
||||
<el-button type="primary" :loading="saving" size="small" @click="save" @keydown.enter.native.prevent>{{
|
||||
$t('commons.save')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</ms-edit-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsEditDialog from '@/business/commons/MsEditDialog';
|
||||
import { getProjectVersions } from '@/api/xpack';
|
||||
export default {
|
||||
name: 'VersionSelector',
|
||||
components: { MsEditDialog },
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
visible: false,
|
||||
saving:false,
|
||||
versionId: '',
|
||||
versionData: [],
|
||||
selectCase: true,
|
||||
selectMock: true,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
tips: String,
|
||||
projectId: String,
|
||||
},
|
||||
methods: {
|
||||
open(projectId) {
|
||||
this.saving = false;
|
||||
this.selectMock = true;
|
||||
this.selectCase = true;
|
||||
this.versionId = '';
|
||||
this.versionData = [];
|
||||
this.visible = true;
|
||||
this.loading = true;
|
||||
|
||||
getProjectVersions(projectId)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
this.versionData = response.data;
|
||||
} else {
|
||||
this.versionData = [];
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleClose() {
|
||||
this.saving = false;
|
||||
this.$emit('handleClose');
|
||||
this.visible = false;
|
||||
},
|
||||
save() {
|
||||
if (!this.versionId || this.versionId === '') {
|
||||
this.$error(this.$t('project.version.please_input_version'));
|
||||
} else {
|
||||
this.saving = true;
|
||||
this.$emit('handleSave', this.versionId,this.selectCase,this.selectMock);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -18,6 +18,7 @@ const message = {
|
|||
type: 'Type',
|
||||
default_value: 'Default value',
|
||||
},
|
||||
copy_data_from_other_version: 'Copy data from other version',
|
||||
body: {
|
||||
json_format_error: 'JSON format error',
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ const message = {
|
|||
type: '类型',
|
||||
default_value: '默认值',
|
||||
},
|
||||
copy_data_from_other_version: '复制版本数据',
|
||||
body: {
|
||||
json_format_error: 'JSON格式错误',
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ const message = {
|
|||
type: '類型',
|
||||
default_value: '默認值',
|
||||
},
|
||||
copy_data_from_other_version: '複製版本數據',
|
||||
body: {
|
||||
json_format_error: 'JSON格式錯誤',
|
||||
},
|
||||
|
|
|
@ -1,95 +1,159 @@
|
|||
<template>
|
||||
|
||||
<div>
|
||||
<div style="float: right;">
|
||||
<el-button size="mini" @click="open" :disabled="isReadOnly">{{ $t('test_track.case.import.click_upload') }}
|
||||
<div style="float: right">
|
||||
<el-button size="mini" @click="open" :disabled="isReadOnly"
|
||||
>{{ $t("test_track.case.import.click_upload") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="tip">{{ this.$t('commons.ssl.files') }}
|
||||
</div>
|
||||
<div class="tip">{{ this.$t("commons.ssl.files") }}</div>
|
||||
|
||||
<div class="ms-border">
|
||||
<el-table :data="sslConfig.files" highlight-current-row>
|
||||
<el-table-column prop="name" :label="$t('load_test.file_name')" show-overflow-tooltip width="180"/>
|
||||
<el-table-column prop="type" :label="$t('api_test.definition.request.esb_table.type')" show-overflow-tooltip
|
||||
min-width="100px"/>
|
||||
<el-table-column prop="password" show-overflow-tooltip min-width="120px" :label="$t('commons.password')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-input size="small" v-model="row.password" clearable show-password/>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.file_name')"
|
||||
show-overflow-tooltip
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:label="$t('api_test.definition.request.esb_table.type')"
|
||||
show-overflow-tooltip
|
||||
min-width="100px"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="password"
|
||||
show-overflow-tooltip
|
||||
min-width="120px"
|
||||
:label="$t('commons.password')"
|
||||
>
|
||||
<template v-slot:default="{ row }">
|
||||
<el-input
|
||||
size="small"
|
||||
v-model="row.password"
|
||||
clearable
|
||||
show-password
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" show-overflow-tooltip min-width="120px"
|
||||
:label="$t('load_test.last_modify_time')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
show-overflow-tooltip
|
||||
min-width="120px"
|
||||
:label="$t('load_test.last_modify_time')"
|
||||
>
|
||||
<template v-slot:default="{ row }">
|
||||
<span>{{ row.updateTime | datetimeFormat }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')" width="100px">
|
||||
<template v-slot:default="{row}">
|
||||
<template v-slot:default="{ row }">
|
||||
<div>
|
||||
<ms-table-operator-button :tip="$t('commons.update')" icon="el-icon-edit"
|
||||
type="primary" @exec="edit(row)"/>
|
||||
<ms-table-operator-button :tip="$t('api_test.automation.remove')"
|
||||
icon="el-icon-delete" @exec="remove(row)" type="danger"/>
|
||||
<ms-table-operator-button
|
||||
:tip="$t('commons.update')"
|
||||
icon="el-icon-edit"
|
||||
type="primary"
|
||||
@exec="edit(row)"
|
||||
/>
|
||||
<ms-table-operator-button
|
||||
:tip="$t('api_test.automation.remove')"
|
||||
icon="el-icon-delete"
|
||||
@exec="remove(row)"
|
||||
type="danger"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<p class="tip">{{ this.$t('commons.ssl.entry') }} </p>
|
||||
<p class="tip">{{ this.$t("commons.ssl.entry") }}</p>
|
||||
<div class="ms-border">
|
||||
<el-table :data="sslConfig.entry" highlight-current-row v-if="!loading">
|
||||
<el-table-column prop="originalAsName" :label="$t('commons.ssl.original_as_name')" show-overflow-tooltip
|
||||
width="180"/>
|
||||
<el-table-column prop="newAsName" :label="$t('commons.ssl.new_as_name')" show-overflow-tooltip
|
||||
min-width="100px">
|
||||
<template v-slot:default="{row}">
|
||||
<el-table-column
|
||||
prop="originalAsName"
|
||||
:label="$t('commons.ssl.original_as_name')"
|
||||
show-overflow-tooltip
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="newAsName"
|
||||
:label="$t('commons.ssl.new_as_name')"
|
||||
show-overflow-tooltip
|
||||
min-width="100px"
|
||||
>
|
||||
<template v-slot:default="{ row }">
|
||||
<el-input size="mini" v-model="row.newAsName"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" show-overflow-tooltip min-width="120px"
|
||||
:label="$t('api_test.definition.request.esb_table.type')"/>
|
||||
<el-table-column prop="password" show-overflow-tooltip min-width="120px" :label="$t('commons.password')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-input size="mini" v-model="row.password" show-password></el-input>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
show-overflow-tooltip
|
||||
min-width="120px"
|
||||
:label="$t('api_test.definition.request.esb_table.type')"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="password"
|
||||
show-overflow-tooltip
|
||||
min-width="120px"
|
||||
:label="$t('commons.password')"
|
||||
>
|
||||
<template v-slot:default="{ row }">
|
||||
<el-input
|
||||
size="mini"
|
||||
v-model="row.password"
|
||||
show-password
|
||||
></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="sourceName" show-overflow-tooltip min-width="120px" :label="$t('commons.ssl.source')"/>
|
||||
<el-table-column
|
||||
prop="sourceName"
|
||||
show-overflow-tooltip
|
||||
min-width="120px"
|
||||
:label="$t('commons.ssl.source')"
|
||||
/>
|
||||
<el-table-column :label="$t('commons.ssl.default')" width="100px">
|
||||
<template v-slot:default="{row}">
|
||||
<el-checkbox v-model="row.default" @change="changeCheck(row)"/>
|
||||
<template v-slot:default="{ row }">
|
||||
<el-checkbox v-model="row.default" @change="changeCheck(row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<ms-s-s-l-file-upload :config="fileConfig" :sslConfig="sslConfig" :callback="addConfig" ref="sslConfigUpload"/>
|
||||
<ms-s-s-l-file-upload
|
||||
:config="fileConfig"
|
||||
:sslConfig="sslConfig"
|
||||
:callback="addConfig"
|
||||
ref="sslConfigUpload"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {environmentEntry} from "../../api/environment";
|
||||
import {SSLConfig} from "../../model/EnvironmentModel";
|
||||
import { environmentEntry } from "../../api/environment";
|
||||
import { SSLConfig } from "../../model/EnvironmentModel";
|
||||
import MsApiKeyValue from "./commons/ApiKeyValue";
|
||||
import {REQUEST_HEADERS} from "../../utils/constants";
|
||||
import MsSelectTree from "../select-tree/SelectTree";
|
||||
import MsTableOperatorButton from "../MsTableOperatorButton";
|
||||
import {getUUID} from "../../utils";
|
||||
import { getUUID } from "../../utils";
|
||||
import MsSSLFileUpload from "./SSLFileUpload";
|
||||
|
||||
export default {
|
||||
name: "MsEnvironmentSSLConfig",
|
||||
components: {MsApiKeyValue, MsSelectTree, MsTableOperatorButton, MsSSLFileUpload},
|
||||
components: {
|
||||
MsApiKeyValue,
|
||||
MsSelectTree,
|
||||
MsTableOperatorButton,
|
||||
MsSSLFileUpload,
|
||||
},
|
||||
props: {
|
||||
sslConfig: new SSLConfig(),
|
||||
projectId: String,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -97,8 +161,7 @@ export default {
|
|||
};
|
||||
},
|
||||
watch: {
|
||||
projectId() {
|
||||
},
|
||||
projectId() {},
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
|
@ -111,7 +174,7 @@ export default {
|
|||
type: file.type,
|
||||
updateTime: new Date().getTime(),
|
||||
password: config.password,
|
||||
file: file
|
||||
file: file,
|
||||
};
|
||||
if (!sslFile.type && sslFile.name) {
|
||||
let type = sslFile.name.substr(sslFile.name.lastIndexOf(".") + 1);
|
||||
|
@ -125,18 +188,19 @@ export default {
|
|||
this.$refs.sslConfigUpload.open(row);
|
||||
},
|
||||
reload() {
|
||||
this.loading = true
|
||||
this.loading = true;
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getEntry(sslFile) {
|
||||
environmentEntry(sslFile.file, null, sslFile.password).then(response => {
|
||||
let data = response.data;
|
||||
environmentEntry(sslFile.file, null, sslFile.password).then(
|
||||
(response) => {
|
||||
let data = response.data.data;
|
||||
if (data) {
|
||||
if (!sslFile.id) {
|
||||
sslFile.id = getUUID();
|
||||
data.forEach(item => {
|
||||
data.forEach((item) => {
|
||||
if (item) {
|
||||
item.id = getUUID();
|
||||
item.sourceId = sslFile.id;
|
||||
|
@ -146,12 +210,12 @@ export default {
|
|||
item.default = false;
|
||||
|
||||
this.sslConfig.entry.unshift(item);
|
||||
})
|
||||
});
|
||||
this.sslConfig.files.unshift(sslFile);
|
||||
} else {
|
||||
// 更新条目
|
||||
this.remove(sslFile);
|
||||
data.forEach(item => {
|
||||
data.forEach((item) => {
|
||||
if (item) {
|
||||
item.id = getUUID();
|
||||
item.sourceId = sslFile.id;
|
||||
|
@ -160,11 +224,12 @@ export default {
|
|||
item.password = "";
|
||||
item.default = false;
|
||||
this.sslConfig.entry.unshift(item);
|
||||
})
|
||||
});
|
||||
this.sslConfig.files.unshift(sslFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
remove(row) {
|
||||
const index = this.sslConfig.files.findIndex((d) => d.id === row.id);
|
||||
|
@ -172,22 +237,24 @@ export default {
|
|||
// 同时删除条目
|
||||
if (this.sslConfig.entry) {
|
||||
let removeKeys = [];
|
||||
this.sslConfig.entry.forEach(item => {
|
||||
this.sslConfig.entry.forEach((item) => {
|
||||
if (item && item.sourceId === row.id) {
|
||||
const index = this.sslConfig.entry.findIndex((d) => d.sourceId === row.id);
|
||||
const index = this.sslConfig.entry.findIndex(
|
||||
(d) => d.sourceId === row.id
|
||||
);
|
||||
removeKeys.push(index);
|
||||
}
|
||||
});
|
||||
removeKeys.forEach(index => {
|
||||
removeKeys.forEach((index) => {
|
||||
if (index !== -1) {
|
||||
this.sslConfig.entry.splice(index, 1);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
changeCheck(row) {
|
||||
if (row.default) {
|
||||
this.sslConfig.entry.forEach(item => {
|
||||
this.sslConfig.entry.forEach((item) => {
|
||||
if (item && item.sourceId !== row.id) {
|
||||
item.default = false;
|
||||
}
|
||||
|
@ -195,8 +262,8 @@ export default {
|
|||
row.default = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -374,10 +374,20 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
AND project_id = #{projectId,jdbcType=VARCHAR}
|
||||
<if test="request.name!=null">
|
||||
<if test="request.name != null">
|
||||
AND file_metadata.name LIKE CONCAT('%', #{request.name}, '%')
|
||||
</if>
|
||||
order by update_time DESC
|
||||
<if test="request.ids != null and request.ids.size() > 0">
|
||||
AND file_metadata.id NOT IN (
|
||||
SELECT file_id
|
||||
FROM load_test_file t
|
||||
WHERE t.test_id IN
|
||||
<foreach collection="request.ids" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
ORDER BY update_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectProjectIds" resultType="java.lang.String">
|
||||
|
|
|
@ -102,11 +102,19 @@
|
|||
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
||||
import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {findThreadGroup} from "../../../business/test/model/ThreadGroup";
|
||||
import {findThreadGroup} from "@/business/test/model/ThreadGroup";
|
||||
import MsTableButton from "metersphere-frontend/src/components/MsTableButton";
|
||||
import MsTableHeader from "metersphere-frontend/src/components/MsTableHeader";
|
||||
import MsTableOperatorButton from "metersphere-frontend/src/components/MsTableOperatorButton";
|
||||
import {checkFileIsRelated, deleteFile, getJmxContents, getProjectFileByName, getProjectFiles, updateFile, uploadFiles} from "../../../api/performance";
|
||||
import {
|
||||
checkFileIsRelated,
|
||||
deleteFile,
|
||||
getJmxContents,
|
||||
getProjectFileByName,
|
||||
getProjectFiles,
|
||||
updateFile,
|
||||
uploadFiles
|
||||
} from "@/api/performance";
|
||||
|
||||
export default {
|
||||
name: "ExistFiles",
|
||||
|
@ -117,6 +125,7 @@ export default {
|
|||
uploadList: Array,
|
||||
scenarios: Array,
|
||||
isReadOnly: Boolean,
|
||||
testId: String
|
||||
},
|
||||
inject: [
|
||||
'reload'
|
||||
|
@ -131,6 +140,7 @@ export default {
|
|||
loadType: 'jmx',
|
||||
existFiles: [],
|
||||
selectIds: new Set,
|
||||
selectFiles: [],
|
||||
condition: {},
|
||||
projectId: getCurrentProjectID()
|
||||
};
|
||||
|
@ -144,16 +154,23 @@ export default {
|
|||
close() {
|
||||
this.loadFileVisible = false;
|
||||
this.selectIds.clear();
|
||||
this.selectFiles = [];
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
if (selection.length > 0) {
|
||||
this.existFiles.forEach(item => {
|
||||
this.selectIds.add(item.id);
|
||||
this.selectFiles.push(item);
|
||||
});
|
||||
} else {
|
||||
this.existFiles.forEach(item => {
|
||||
if (this.selectIds.has(item.id)) {
|
||||
this.selectIds.delete(item.id);
|
||||
for (let i = 0; i < this.selectFiles.length - 1; i++) {
|
||||
if (this.selectFiles[i].id === item.id) {
|
||||
this.selectFiles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -161,11 +178,21 @@ export default {
|
|||
handleSelectionChange(selection, row) {
|
||||
if (this.selectIds.has(row.id)) {
|
||||
this.selectIds.delete(row.id);
|
||||
for (let i = 0; i < this.selectFiles.length - 1; i++) {
|
||||
if (this.selectFiles[i].id === row.id) {
|
||||
this.selectFiles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.selectIds.add(row.id);
|
||||
this.selectFiles.push(row);
|
||||
}
|
||||
},
|
||||
getProjectFiles() {
|
||||
if (this.testId) {
|
||||
this.condition.ids = [];
|
||||
this.condition.ids.push(this.testId);
|
||||
}
|
||||
this.loading = getProjectFiles(this.loadType, this.projectId, this.currentPage, this.pageSize, this.condition)
|
||||
.then(res => {
|
||||
let data = res.data;
|
||||
|
@ -176,6 +203,7 @@ export default {
|
|||
handleImport(file) {
|
||||
if (file) { // 接口测试创建的性能测试
|
||||
this.selectIds.add(file.id);
|
||||
this.selectFiles.push(file)
|
||||
this.getJmxContents();
|
||||
return;
|
||||
}
|
||||
|
@ -183,11 +211,9 @@ export default {
|
|||
this.loadFileVisible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let rows = this.existFiles.filter(f => this.selectIds.has(f.id));
|
||||
let jmxIds = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
for (let i = 0; i < this.selectFiles.length; i++) {
|
||||
let row = this.selectFiles[i];
|
||||
if (this.tableData.filter(f => f.name === row.name).length > 0) {
|
||||
setTimeout(() => {
|
||||
this.$warning(this.$t('load_test.delete_file') + 'name: ' + row.name);
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
|
||||
<exist-files ref="existFiles"
|
||||
@fileChange="fileChange"
|
||||
:test-id="test.id"
|
||||
:file-list="fileList"
|
||||
:table-data="tableData"
|
||||
:upload-list="uploadList"
|
||||
|
|
3
pom.xml
3
pom.xml
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.5</version>
|
||||
<version>2.7.7</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
|||
<revision>main</revision>
|
||||
<java.version>11</java.version>
|
||||
<spring-cloud.version>2021.0.5</spring-cloud.version>
|
||||
<spring-security.version>5.7.5</spring-security.version>
|
||||
<dubbo.version>2.7.18</dubbo.version>
|
||||
<platform-plugin-sdk.version>1.2.0</platform-plugin-sdk.version>
|
||||
<flyway.version>7.15.0</flyway.version>
|
||||
|
|
|
@ -11,10 +11,12 @@ import io.metersphere.commons.utils.FileUtils;
|
|||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.dto.PluginResourceDTO;
|
||||
import io.metersphere.plugin.core.api.UiScriptApi;
|
||||
import io.metersphere.plugin.core.ui.PluginResource;
|
||||
import io.metersphere.utils.CommonUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jorphan.reflect.ClassFinder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -84,7 +86,29 @@ public class ApiPluginService {
|
|||
|
||||
private List<PluginResourceDTO> getMethod(String path, String fileName) {
|
||||
List<PluginResourceDTO> resources = new LinkedList<>();
|
||||
try {
|
||||
this.loadJar(path);
|
||||
String jarPath[] = new String[]{path};
|
||||
List<String> classes = ClassFinder.findClassesThatExtend(jarPath, new Class[]{UiScriptApi.class}, true);
|
||||
for (String clazzName : classes) {
|
||||
UiScriptApi uiScriptApi = Class.forName(clazzName)
|
||||
.asSubclass(UiScriptApi.class)
|
||||
.getDeclaredConstructor().newInstance();
|
||||
PluginResource pluginObj = uiScriptApi.init();
|
||||
if (pluginObj != null) {
|
||||
PluginResourceDTO pluginResourceDTO = new PluginResourceDTO();
|
||||
BeanUtils.copyBean(pluginResourceDTO, pluginObj);
|
||||
pluginResourceDTO.setEntry(clazzName);
|
||||
resources.add(pluginResourceDTO);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.init(fileName, resources);
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
private void init(String fileName, List<PluginResourceDTO> resources) {
|
||||
List<Class<?>> classes = CommonUtil.getSubClass(fileName);
|
||||
try {
|
||||
for (Class<?> aClass : classes) {
|
||||
|
@ -101,7 +125,6 @@ public class ApiPluginService {
|
|||
LogUtil.error("初始化脚本异常:" + e.getMessage());
|
||||
MSException.throwException("调用插件初始化脚本失败");
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
private void create(PluginResourceDTO resource, String path, String name, List<PluginWithBLOBs> addPlugins) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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>
|
|
@ -3,20 +3,21 @@ package io.metersphere.controller;
|
|||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.TestPlanReport;
|
||||
import io.metersphere.base.domain.TestPlanReportContentWithBLOBs;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.constants.OperLogModule;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.dto.TestPlanReportDTO;
|
||||
import io.metersphere.dto.TestPlanScheduleReportInfoDTO;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.plan.dto.TestPlanSimpleReportDTO;
|
||||
import io.metersphere.plan.request.TestPlanReportSaveRequest;
|
||||
import io.metersphere.request.report.QueryTestPlanReportRequest;
|
||||
import io.metersphere.plan.service.TestPlanReportService;
|
||||
import io.metersphere.request.report.QueryTestPlanReportRequest;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -86,4 +87,9 @@ public class TestPlanReportController {
|
|||
public void reName(@RequestBody TestPlanReport request) {
|
||||
testPlanReportService.reName(request.getId(), request.getName());
|
||||
}
|
||||
|
||||
@PostMapping("/edit/report")
|
||||
public void editReport(@RequestBody TestPlanReportContentWithBLOBs reportContentWithBLOBs) {
|
||||
testPlanReportService.editReport(reportContentWithBLOBs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ public class BatchRunDefinitionRequest {
|
|||
private String planReportId;
|
||||
// 失败重跑
|
||||
private boolean rerun;
|
||||
|
||||
private Map<String, ApiDefinitionExecResultWithBLOBs> executeQueue;
|
||||
|
||||
private String testPlanId;
|
||||
}
|
||||
|
|
|
@ -53,4 +53,6 @@ public class RunScenarioRequest {
|
|||
private String serialReportId;
|
||||
// private Map<String, ApiScenarioReportResult> reportMap;
|
||||
|
||||
private String testPlanId;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
@ -1496,4 +1573,12 @@ public class TestPlanReportService {
|
|||
testPlanReportDTO.setName(testPlanReport.getName());
|
||||
return testPlanReportDTO;
|
||||
}
|
||||
|
||||
public void editReport(TestPlanReportContentWithBLOBs reportContentWithBLOBs) {
|
||||
if (StringUtils.isNotBlank(reportContentWithBLOBs.getTestPlanReportId())) {
|
||||
TestPlanReportContentExample example = new TestPlanReportContentExample();
|
||||
example.createCriteria().andTestPlanReportIdEqualTo(reportContentWithBLOBs.getTestPlanReportId());
|
||||
testPlanReportContentMapper.updateByExampleSelective(reportContentWithBLOBs, example);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
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) {
|
||||
|
|
|
@ -93,7 +93,12 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
|
|||
}
|
||||
|
||||
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -22,3 +22,7 @@ export function testPlanReportReName(param) {
|
|||
export function testPlanReportGetDb(id) {
|
||||
return get(BASE_URL + `db/${id}`);
|
||||
}
|
||||
|
||||
export function testPlanDbReportEdit(param) {
|
||||
return post(BASE_URL + 'edit/report', param);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<ms-table :data="tableData" :select-node-ids="selectNodeIds" :condition="condition" :page-size="pageSize"
|
||||
:total="total" enableSelection
|
||||
:screenHeight="screenHeight"
|
||||
row-key="id"
|
||||
:reserve-option="true"
|
||||
:page-refresh="pageRefresh"
|
||||
@refresh="initTable"
|
||||
@selectCountChange="selectCountChange"
|
||||
operator-width="170px"
|
||||
|
@ -89,7 +92,7 @@
|
|||
</template>
|
||||
</ms-table-column>
|
||||
</ms-table>
|
||||
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
<ms-table-pagination :change="pageChange" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</api-list-container>
|
||||
|
||||
|
@ -157,6 +160,7 @@ export default {
|
|||
total: 0,
|
||||
environmentId: "",
|
||||
versionEnable: false,
|
||||
pageRefresh: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -220,7 +224,11 @@ export default {
|
|||
selectCountChange(data) {
|
||||
this.$emit('selectCountChange', data);
|
||||
},
|
||||
initTable(projectId) {
|
||||
pageChange() {
|
||||
this.initTable(null, "page");
|
||||
},
|
||||
initTable(projectId, data) {
|
||||
this.pageRefresh = data === "page";
|
||||
this.condition.status = "";
|
||||
this.condition.moduleIds = this.selectNodeIds;
|
||||
if (projectId != null && typeof projectId === 'string') {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<test-plan-report-container id='summary' :title="$t('test_track.report.report_summary')">
|
||||
<template v-slot:title>
|
||||
<el-link class="edit-link" v-if="!isTemplate && !isShare && !isDb && !isEdit" @click="isEdit = true">
|
||||
<el-link class="edit-link" v-if="showEdit" @click="isEdit = true">
|
||||
<i class="el-icon-edit">{{ $t('commons.edit') }}</i>
|
||||
</el-link>
|
||||
<el-link class="edit-link" v-if="!isTemplate && !isShare && !isDb && isEdit" @click="saveSummary">
|
||||
<el-link class="edit-link" v-if="showEdit" @click="saveSummary">
|
||||
<i class="el-icon-circle-check">{{ $t('commons.save') }}</i>
|
||||
</el-link>
|
||||
</template>
|
||||
|
@ -25,6 +25,7 @@ import MsFormDivider from "metersphere-frontend/src/components/MsFormDivider";
|
|||
import {editPlanReport} from "@/api/remote/plan/test-plan";
|
||||
import TestPlanReportContainer from "@/business/plan/view/comonents/report/detail/TestPlanReportContainer";
|
||||
import MsRichText from "@/business/case/components/MsRichText";
|
||||
import {testPlanDbReportEdit} from "@/api/remote/plan/test-plan-report";
|
||||
export default {
|
||||
name: "TestPlanSummaryReport",
|
||||
components: {MsRichText, TestPlanReportContainer, MsFormDivider},
|
||||
|
@ -41,12 +42,24 @@ export default {
|
|||
isEdit: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showEdit() {
|
||||
return !this.isTemplate && !this.isShare && !this.isEdit;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
saveSummary() {
|
||||
if (this.isDb) {
|
||||
testPlanDbReportEdit({
|
||||
testPlanReportId: this.report.id,
|
||||
summary: this.report.summary || ''
|
||||
});
|
||||
} else {
|
||||
editPlanReport({
|
||||
id: this.planId,
|
||||
reportSummary: this.report.summary ? this.report.summary : ''
|
||||
reportSummary: this.report.summary || ''
|
||||
});
|
||||
}
|
||||
this.isEdit = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue