refactor(接口测试): 优化失败重跑功能
This commit is contained in:
parent
ea7539ba59
commit
77335c5044
|
@ -5,10 +5,6 @@ import io.metersphere.api.dto.definition.request.ElementUtil;
|
|||
import io.metersphere.api.dto.definition.request.MsTestPlan;
|
||||
import io.metersphere.api.dto.definition.request.MsThreadGroup;
|
||||
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.NewDriverManager;
|
||||
|
@ -22,17 +18,14 @@ import io.metersphere.base.mapper.ApiTestCaseMapper;
|
|||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.CommonConstants;
|
||||
import io.metersphere.commons.constants.ElementConstants;
|
||||
import io.metersphere.commons.constants.PropertyConstant;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.ProjectJarConfig;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
import io.metersphere.environment.service.BaseEnvironmentService;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.ApiRetryOnFailureService;
|
||||
import io.metersphere.service.RemakeReportService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
|
@ -50,6 +43,7 @@ import java.util.*;
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiCaseSerialService {
|
||||
private final static String PROJECT_ID = "projectId";
|
||||
public static final String NAME = "name";
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
@Resource
|
||||
|
@ -143,33 +137,30 @@ public class ApiCaseSerialService {
|
|||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(caseWithBLOBs.getName());
|
||||
group.setName(runRequest.getReportId());
|
||||
group.setHashTree(new LinkedList<>());
|
||||
// 接口用例集成报告
|
||||
if (StringUtils.isNotEmpty(runRequest.getTestPlanReportId())
|
||||
&& StringUtils.equals(runRequest.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||
group.setName(runRequest.getTestPlanReportId());
|
||||
}
|
||||
group.setProjectId(caseWithBLOBs.getProjectId());
|
||||
MsTestElement testElement;
|
||||
// 数据兼容处理
|
||||
JSONObject element = JSONUtil.parseObject(caseWithBLOBs.getRequest());
|
||||
ElementUtil.dataFormatting(element);
|
||||
String data = element.toString();
|
||||
parse(element, testId, envId, caseWithBLOBs.getProjectId());
|
||||
String runData = element.toString();
|
||||
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
||||
// 失败重试
|
||||
String retryData = apiRetryOnFailureService.retry(data, runRequest.getRetryNum(), true);
|
||||
data = StringUtils.isNotEmpty(retryData) ? retryData : data;
|
||||
// 格式化数据
|
||||
testElement = apiRetryOnFailureService.retryParse(data);
|
||||
MsTestElement msTestElement = parse(JSON.toJSONString(testElement.getHashTree().get(0)), testId, envId, caseWithBLOBs.getProjectId());
|
||||
testElement.setHashTree(new LinkedList<>() {{
|
||||
this.add(msTestElement);
|
||||
}});
|
||||
} else {
|
||||
testElement = parse(data, testId, envId, caseWithBLOBs.getProjectId());
|
||||
try {
|
||||
// 失败重试
|
||||
String retryData = apiRetryOnFailureService.retry(runData, runRequest.getRetryNum(), true);
|
||||
if (StringUtils.isNotBlank(retryData)) {
|
||||
runData = retryData;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("失败重试脚本生成失败 ", runRequest.getReportId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
group.setHashTree(new LinkedList<>());
|
||||
group.getHashTree().add(testElement);
|
||||
group.getHashTree().add(JSONUtil.parseObject(runData, MsTestElement.class));
|
||||
testPlan.getHashTree().add(group);
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||
LoggerUtil.info("用例资源:" + caseWithBLOBs.getName() + ", 生成执行脚本JMX成功", runRequest.getReportId());
|
||||
|
@ -177,64 +168,23 @@ public class ApiCaseSerialService {
|
|||
}
|
||||
} catch (Exception ex) {
|
||||
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||
remakeReportService.remake(runRequest);
|
||||
ResultDTO dto = new ResultDTO();
|
||||
BeanUtils.copyBean(dto, runRequest);
|
||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||
remakeReportService.testEnded(runRequest, ex.getMessage());
|
||||
LoggerUtil.error("用例资源:" + testId + ", 生成执行脚本失败", runRequest.getReportId(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MsTestElement parse(String api, String planId, String envId, String projectId) {
|
||||
private void parse(JSONObject element, String testId, String envId, String projectId) {
|
||||
try {
|
||||
JSONObject element = JSONUtil.parseObject(api);
|
||||
LinkedList<MsTestElement> list = new LinkedList<>();
|
||||
if (element != null && StringUtils.isNotEmpty(element.optString(ElementConstants.HASH_TREE))) {
|
||||
list.addAll(JSONUtil.readValue(element.optString(ElementConstants.HASH_TREE)));
|
||||
element.putOpt(NAME, testId);
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
element.putOpt(PropertyConstant.ENVIRONMENT, envId);
|
||||
}
|
||||
if (element.optString(PropertyConstant.TYPE).equals(ElementConstants.HTTP_SAMPLER)) {
|
||||
MsHTTPSamplerProxy httpSamplerProxy = JSONUtil.parseObject(element.toString(), MsHTTPSamplerProxy.class);
|
||||
httpSamplerProxy.setHashTree(list);
|
||||
httpSamplerProxy.setName(planId);
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
httpSamplerProxy.setUseEnvironment(envId);
|
||||
}
|
||||
return httpSamplerProxy;
|
||||
}
|
||||
if (element.optString(PropertyConstant.TYPE).equals(ElementConstants.TCP_SAMPLER)) {
|
||||
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class);
|
||||
if (StringUtils.isEmpty(msTCPSampler.getProjectId())) {
|
||||
msTCPSampler.setProjectId(projectId);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
msTCPSampler.setUseEnvironment(envId);
|
||||
}
|
||||
msTCPSampler.setHashTree(list);
|
||||
msTCPSampler.setName(planId);
|
||||
return msTCPSampler;
|
||||
}
|
||||
if (element.optString(PropertyConstant.TYPE).equals(ElementConstants.DUBBO_SAMPLER)) {
|
||||
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class);
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
dubboSampler.setUseEnvironment(envId);
|
||||
}
|
||||
dubboSampler.setHashTree(list);
|
||||
dubboSampler.setName(planId);
|
||||
return dubboSampler;
|
||||
}
|
||||
if (element.optString(PropertyConstant.TYPE).equals(ElementConstants.JDBC_SAMPLER)) {
|
||||
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
jDBCSampler.setUseEnvironment(envId);
|
||||
}
|
||||
jDBCSampler.setHashTree(list);
|
||||
jDBCSampler.setName(planId);
|
||||
return jDBCSampler;
|
||||
if (StringUtils.isBlank(element.optString(PROJECT_ID))) {
|
||||
element.putOpt(PROJECT_ID, projectId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,8 +174,6 @@ public class JMeterService {
|
|||
engine.start();
|
||||
} catch (Exception e) {
|
||||
remakeReportService.testEnded(request, e.getMessage());
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteScriptKey(request.getReportId(), request.getTestId()));
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteFileKeyInRedis(request.getReportId()));
|
||||
LoggerUtil.error("调用K8S执行请求[ " + request.getTestId() + " ]失败:", request.getReportId(), e);
|
||||
}
|
||||
} else if ((MapUtils.isNotEmpty(request.getExtendedParameters())
|
||||
|
@ -208,9 +206,7 @@ public class JMeterService {
|
|||
apiPoolDebugService.run(request, resources);
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error(e);
|
||||
remakeReportService.remake(request);
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteScriptKey(request.getReportId(), request.getTestId()));
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteFileKeyInRedis(request.getReportId()));
|
||||
remakeReportService.testEnded(request, e.getMessage());
|
||||
LoggerUtil.error("发送请求[ " + request.getTestId() + " ] 执行失败,进行数据回滚:", request.getReportId(), e);
|
||||
MSException.throwException("调用资源池执行失败,请检查资源池是否配置正常");
|
||||
}
|
||||
|
@ -228,7 +224,7 @@ public class JMeterService {
|
|||
}
|
||||
if (config == null) {
|
||||
LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】", request.getReportId());
|
||||
remakeReportService.remake(request);
|
||||
remakeReportService.testEnded(request, "未获取到资源池,请检查配置【系统设置-系统-测试资源池】");
|
||||
return;
|
||||
}
|
||||
request.setCorePoolSize(config.getCorePoolSize());
|
||||
|
@ -236,12 +232,12 @@ public class JMeterService {
|
|||
LoggerUtil.info("开始发送请求【 " + request.getTestId() + " 】到 " + config.getUrl() + " 节点执行", request.getReportId());
|
||||
ResponseEntity<String> result = restTemplate.postForEntity(config.getUrl(), request, String.class);
|
||||
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) {
|
||||
remakeReportService.remake(request);
|
||||
remakeReportService.testEnded(request, result.getBody());
|
||||
LoggerUtil.error("发送请求[ " + request.getTestId() + " ] 到" + config.getUrl() + " 节点执行失败", request.getReportId());
|
||||
LoggerUtil.info(result.getBody());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
remakeReportService.remake(request);
|
||||
remakeReportService.testEnded(request, e.getMessage());
|
||||
LoggerUtil.error("发送请求[ " + request.getTestId() + " ] 执行失败,进行数据回滚:", request.getReportId(), e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@
|
|||
<update id="updateAllStatus">
|
||||
update api_definition_exec_result
|
||||
set status="STOPPED"
|
||||
where status in ('Rerunning', 'Running', 'PENDING')
|
||||
where status in ('Rerunning', 'Running')
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -487,7 +487,7 @@
|
|||
<update id="updateAllStatus">
|
||||
update api_scenario_report
|
||||
set status="STOPPED"
|
||||
where status in ('Rerunning', 'Running', 'PENDING')
|
||||
where status in ('Rerunning', 'Running')
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -32,7 +32,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
public class GenerateHashTreeUtil {
|
||||
|
||||
public static MsScenario parseScenarioDefinition(String scenarioDefinition) {
|
||||
if (StringUtils.isNotEmpty(scenarioDefinition)) {
|
||||
MsScenario scenario = JSON.parseObject(scenarioDefinition, MsScenario.class);
|
||||
|
@ -148,9 +147,15 @@ public class GenerateHashTreeUtil {
|
|||
String data = definition;
|
||||
// 失败重试
|
||||
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
||||
ApiRetryOnFailureService apiRetryOnFailureService = CommonBeanFactory.getBean(ApiRetryOnFailureService.class);
|
||||
String retryData = apiRetryOnFailureService.retry(data, runRequest.getRetryNum(), false);
|
||||
data = StringUtils.isNotEmpty(retryData) ? retryData : data;
|
||||
try {
|
||||
ApiRetryOnFailureService apiRetryOnFailureService = CommonBeanFactory.getBean(ApiRetryOnFailureService.class);
|
||||
String retryData = apiRetryOnFailureService.retry(data, runRequest.getRetryNum(), false);
|
||||
if (StringUtils.isNotBlank(retryData)) {
|
||||
data = retryData;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("失败重试脚本生成失败 ", runRequest.getReportId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
GenerateHashTreeUtil.parse(data, scenario);
|
||||
|
@ -169,7 +174,7 @@ public class GenerateHashTreeUtil {
|
|||
|
||||
LoggerUtil.info("场景资源:" + item.getName() + ", 生成执行脚本JMX成功", runRequest.getReportId());
|
||||
} catch (Exception ex) {
|
||||
remakeException(runRequest);
|
||||
remakeException(runRequest, ex);
|
||||
LoggerUtil.error("场景资源:" + item.getName() + ", 生成执行脚本失败", runRequest.getReportId(), ex);
|
||||
return null;
|
||||
}
|
||||
|
@ -178,9 +183,9 @@ public class GenerateHashTreeUtil {
|
|||
return jmeterHashTree;
|
||||
}
|
||||
|
||||
public static void remakeException(JmeterRunRequestDTO runRequest) {
|
||||
public static void remakeException(JmeterRunRequestDTO runRequest, Exception e) {
|
||||
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||
remakeReportService.remake(runRequest);
|
||||
remakeReportService.testEnded(runRequest, e.getMessage());
|
||||
ResultDTO dto = new ResultDTO();
|
||||
BeanUtils.copyBean(dto, runRequest);
|
||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||
|
|
|
@ -31,7 +31,7 @@ public class RequestParamsUtil {
|
|||
|
||||
public static void rollback(JmeterRunRequestDTO runRequest, Exception e) {
|
||||
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||
remakeReportService.remake(runRequest);
|
||||
remakeReportService.testEnded(runRequest, e.getMessage());
|
||||
ResultDTO dto = new ResultDTO();
|
||||
BeanUtils.copyBean(dto, runRequest);
|
||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.api.dto.definition.request.controller.MsRetryLoopController;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
|
@ -45,8 +44,7 @@ public class ApiRetryOnFailureService {
|
|||
|
||||
public MsTestElement retryParse(String data) {
|
||||
try {
|
||||
MsRetryLoopController controller = JSON.parseObject(data, MsRetryLoopController.class);
|
||||
return controller;
|
||||
return JSONUtil.parseObject(data, MsRetryLoopController.class);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
@ -78,7 +76,7 @@ public class ApiRetryOnFailureService {
|
|||
loopController.setEnable(true);
|
||||
loopController.setResourceId(UUID.randomUUID().toString());
|
||||
|
||||
JSONObject whileObj = JSONUtil.parseObject(JSON.toJSONString(loopController));
|
||||
JSONObject whileObj = JSONUtil.parseObject(JSONUtil.toJSONString(loopController));
|
||||
JSONArray hashTree = new JSONArray();
|
||||
hashTree.put(element);
|
||||
|
||||
|
|
|
@ -1,149 +1,21 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiScenarioReport;
|
||||
import io.metersphere.base.domain.ApiScenarioReportWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanApiCase;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.api.jmeter.utils.JmxFileUtil;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.commons.utils.FixedCapacityUtil;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
import io.metersphere.commons.utils.FixedCapacityUtil;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class RemakeReportService {
|
||||
@Resource
|
||||
private ApiScenarioReportMapper apiScenarioReportMapper;
|
||||
@Resource
|
||||
private ApiScenarioMapper apiScenarioMapper;
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
@Resource
|
||||
private ApiDefinitionExecResultMapper execResultMapper;
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
@Resource
|
||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
|
||||
public void remake(JmeterRunRequestDTO request) {
|
||||
try {
|
||||
// 清理零时报告
|
||||
if (StringUtils.equalsAnyIgnoreCase(request.getRunMode(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
ApiDefinitionExecResultWithBLOBs result = execResultMapper.selectByPrimaryKey(request.getReportId());
|
||||
if (result != null) {
|
||||
result.setStatus(ApiReportStatus.ERROR.name());
|
||||
result.setEndTime(System.currentTimeMillis());
|
||||
execResultMapper.updateByPrimaryKeySelective(result);
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(request.getTestId());
|
||||
if (testPlanApiCase != null) {
|
||||
testPlanApiCase.setStatus(ApiReportStatus.ERROR.name());
|
||||
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanApiCaseMapper.updateByPrimaryKeySelective(testPlanApiCase);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||
ApiDefinitionExecResultWithBLOBs result = execResultMapper.selectByPrimaryKey(request.getReportId());
|
||||
if (result != null) {
|
||||
result.setStatus(ApiReportStatus.ERROR.name());
|
||||
result.setEndTime(System.currentTimeMillis());
|
||||
execResultMapper.updateByPrimaryKeySelective(result);
|
||||
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseMapper.selectByPrimaryKey(request.getTestId());
|
||||
if (apiTestCase != null) {
|
||||
apiTestCase.setStatus(ApiReportStatus.ERROR.name());
|
||||
apiTestCase.setUpdateTime(System.currentTimeMillis());
|
||||
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId());
|
||||
if (apiDefinitionWithBLOBs.getProtocol().equals("HTTP")) {
|
||||
apiDefinitionWithBLOBs.setToBeUpdated(true);
|
||||
apiDefinitionWithBLOBs.setToBeUpdateTime(System.currentTimeMillis());
|
||||
apiDefinitionMapper.updateByPrimaryKey(apiDefinitionWithBLOBs);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
||||
if (report != null) {
|
||||
report.setEndTime(System.currentTimeMillis());
|
||||
report.setStatus(ApiReportStatus.ERROR.name());
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
|
||||
if (testPlanApiScenario != null) {
|
||||
testPlanApiScenario.setLastResult(ApiReportStatus.ERROR.name());
|
||||
testPlanApiScenario.setPassRate("0%");
|
||||
testPlanApiScenario.setReportId(report.getId());
|
||||
testPlanApiScenario.setUpdateTime(report.getCreateTime());
|
||||
testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario);
|
||||
}
|
||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||
}
|
||||
} else if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||
ApiScenarioReportWithBLOBs report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
||||
if (report != null) {
|
||||
report.setEndTime(System.currentTimeMillis());
|
||||
report.setStatus(ApiReportStatus.ERROR.name());
|
||||
String planScenarioId = report.getScenarioId();
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(planScenarioId);
|
||||
if (testPlanApiScenario != null) {
|
||||
report.setScenarioId(testPlanApiScenario.getApiScenarioId());
|
||||
report.setEndTime(System.currentTimeMillis());
|
||||
|
||||
testPlanApiScenario.setLastResult(ApiReportStatus.ERROR.name());
|
||||
testPlanApiScenario.setPassRate("0%");
|
||||
testPlanApiScenario.setReportId(report.getId());
|
||||
testPlanApiScenario.setUpdateTime(report.getCreateTime());
|
||||
testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario);
|
||||
}
|
||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||
}
|
||||
} else {
|
||||
ApiScenarioReportWithBLOBs report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
||||
if (report != null && !StringUtils.equals(request.getRunType(), RunModeConstants.SERIAL.toString())) {
|
||||
report.setStatus(ApiReportStatus.ERROR.name());
|
||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(request.getTestId())) {
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(request.getTestId());
|
||||
if (scenarioWithBLOBs != null) {
|
||||
scenarioWithBLOBs.setLastResult(ApiReportStatus.ERROR.name());
|
||||
scenarioWithBLOBs.setPassRate("0%");
|
||||
scenarioWithBLOBs.setReportId(report.getId());
|
||||
scenarioWithBLOBs.setExecuteTimes(1);
|
||||
apiScenarioMapper.updateByPrimaryKeySelective(scenarioWithBLOBs);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理队列
|
||||
ResultDTO dto = new ResultDTO();
|
||||
BeanUtils.copyBean(dto, request);
|
||||
dto.setQueueId(request.getQueueId());
|
||||
dto.setTestId(request.getTestId());
|
||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
private RedisTemplateService redisTemplateService;
|
||||
|
||||
public void testEnded(JmeterRunRequestDTO request, String errorMsg) {
|
||||
try {
|
||||
|
@ -151,7 +23,7 @@ public class RemakeReportService {
|
|||
BeanUtils.copyBean(dto, request);
|
||||
dto.setQueueId(request.getQueueId());
|
||||
dto.setTestId(request.getTestId());
|
||||
|
||||
dto.setRemake(true);
|
||||
LoggerUtil.info("进入异常结果处理:" + dto.getRunMode() + " 整体处理完成", dto.getReportId());
|
||||
// 全局并发队列
|
||||
PoolExecBlockingQueueUtil.offer(dto.getReportId());
|
||||
|
@ -170,6 +42,9 @@ public class RemakeReportService {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("回退报告异常", request.getReportId(), e);
|
||||
}finally {
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteScriptKey(request.getReportId(), request.getTestId()));
|
||||
redisTemplateService.delete(JmxFileUtil.getExecuteFileKeyInRedis(request.getReportId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,19 @@ import io.metersphere.api.dto.automation.ApiTestReportVariable;
|
|||
import io.metersphere.api.exec.scenario.ApiEnvironmentRunningParamService;
|
||||
import io.metersphere.api.jmeter.utils.ReportStatusUtil;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.enums.ExecutionExecuteTypeEnum;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.vo.ResultVO;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||
import io.metersphere.dto.RequestResult;
|
||||
import io.metersphere.dto.ResponseResult;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
import io.metersphere.notice.sender.NoticeModel;
|
||||
import io.metersphere.notice.service.NoticeSendService;
|
||||
|
@ -23,12 +26,12 @@ import io.metersphere.service.scenario.ApiScenarioExecutionInfoService;
|
|||
import io.metersphere.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
import io.metersphere.service.scenario.ApiScenarioService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.beanutils.BeanMap;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
|
@ -54,7 +57,9 @@ public class TestResultService {
|
|||
@Resource
|
||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
@Resource
|
||||
BaseShareInfoService baseShareInfoService;
|
||||
private BaseShareInfoService baseShareInfoService;
|
||||
@Resource
|
||||
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
||||
|
||||
// 场景
|
||||
private static final List<String> scenarioRunModes = new ArrayList<>() {{
|
||||
|
@ -65,6 +70,12 @@ public class TestResultService {
|
|||
this.add(ApiRunMode.JENKINS_SCENARIO_PLAN.name());
|
||||
}};
|
||||
|
||||
private static final List<String> planRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.SCENARIO_PLAN.name());
|
||||
this.add(ApiRunMode.SCHEDULE_SCENARIO_PLAN.name());
|
||||
this.add(ApiRunMode.JENKINS_SCENARIO_PLAN.name());
|
||||
}};
|
||||
|
||||
// 接口测试 用例/接口
|
||||
private static final List<String> caseRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.DEFINITION.name());
|
||||
|
@ -79,6 +90,12 @@ public class TestResultService {
|
|||
this.add(ApiRunMode.MANUAL_PLAN.name());
|
||||
}};
|
||||
|
||||
private static final List<String> apiRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.DEFINITION.name());
|
||||
this.add(ApiRunMode.API_PLAN.name());
|
||||
this.add(ApiRunMode.SCHEDULE_API_PLAN.name());
|
||||
}};
|
||||
|
||||
/**
|
||||
* 执行结果存储
|
||||
*
|
||||
|
@ -194,69 +211,75 @@ public class TestResultService {
|
|||
}
|
||||
if (scenarioRunModes.contains(dto.getRunMode())) {
|
||||
ApiScenarioReport scenarioReport = edit(dto);
|
||||
if (scenarioReport != null) {
|
||||
String environment = StringUtils.EMPTY;
|
||||
//执行人
|
||||
String userName = StringUtils.EMPTY;
|
||||
//负责人
|
||||
String principal = StringUtils.EMPTY;
|
||||
if (scenarioReport == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||
if (apiScenario != null) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||
scenarioExecutionInfoService.insertExecutionInfo(dto.getTestId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiScenario.getVersionId());
|
||||
} else {
|
||||
scenarioExecutionInfoService.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiScenario.getVersionId());
|
||||
}
|
||||
environment = apiScenarioReportService.getEnvironment(apiScenario);
|
||||
userName = apiAutomationService.getUser(apiScenario.getUserId());
|
||||
principal = apiAutomationService.getUser(apiScenario.getPrincipal());
|
||||
} else {
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||
if (testPlanApiScenario != null) {
|
||||
apiScenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||
if (apiScenario != null) {
|
||||
scenarioExecutionInfoService.insertExecutionInfo(testPlanApiScenario.getId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiScenario.getVersionId());
|
||||
}
|
||||
String environment = StringUtils.EMPTY;
|
||||
//执行人
|
||||
String userName = StringUtils.EMPTY;
|
||||
//负责人
|
||||
String principal = StringUtils.EMPTY;
|
||||
|
||||
if (planRunModes.contains(dto.getRunMode())) {
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||
if (testPlanApiScenario != null) {
|
||||
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||
if (apiScenario != null) {
|
||||
scenarioExecutionInfoService.insertScenarioInfo(apiScenario, scenarioReport, dto);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||
scenarioExecutionInfoService.insertScenarioInfo(apiScenario, scenarioReport, dto);
|
||||
environment = apiScenarioReportService.getEnvironment(apiScenario);
|
||||
userName = apiAutomationService.getUser(apiScenario.getUserId());
|
||||
principal = apiAutomationService.getUser(apiScenario.getPrincipal());
|
||||
}
|
||||
|
||||
//报告内容
|
||||
ApiTestReportVariable reportTask = new ApiTestReportVariable();
|
||||
reportTask.setStatus(scenarioReport.getStatus());
|
||||
reportTask.setId(scenarioReport.getId());
|
||||
reportTask.setTriggerMode(scenarioReport.getTriggerMode());
|
||||
reportTask.setName(scenarioReport.getName());
|
||||
reportTask.setExecutor(userName);
|
||||
reportTask.setUserId(scenarioReport.getUserId());
|
||||
reportTask.setPrincipal(principal);
|
||||
reportTask.setExecutionTime(DateUtils.getTimeString(scenarioReport.getUpdateTime()));
|
||||
reportTask.setEnvironment(environment);
|
||||
reportTask.setProjectId(scenarioReport.getProjectId());
|
||||
//报告内容
|
||||
ApiTestReportVariable reportTask = new ApiTestReportVariable();
|
||||
reportTask.setStatus(scenarioReport.getStatus());
|
||||
reportTask.setId(scenarioReport.getId());
|
||||
reportTask.setTriggerMode(scenarioReport.getTriggerMode());
|
||||
reportTask.setName(scenarioReport.getName());
|
||||
reportTask.setExecutor(userName);
|
||||
reportTask.setUserId(scenarioReport.getUserId());
|
||||
reportTask.setPrincipal(principal);
|
||||
reportTask.setExecutionTime(DateUtils.getTimeString(scenarioReport.getUpdateTime()));
|
||||
reportTask.setEnvironment(environment);
|
||||
reportTask.setProjectId(scenarioReport.getProjectId());
|
||||
|
||||
if (reportTask != null) {
|
||||
if (StringUtils.equals(ReportTriggerMode.API.name(), reportTask.getTriggerMode()) || StringUtils.equals(ReportTriggerMode.SCHEDULE.name(), reportTask.getTriggerMode())) {
|
||||
sendTask(reportTask, dto.getTestId());
|
||||
}
|
||||
if (reportTask != null) {
|
||||
if (StringUtils.equals(ReportTriggerMode.API.name(), reportTask.getTriggerMode())
|
||||
|| StringUtils.equals(ReportTriggerMode.SCHEDULE.name(), reportTask.getTriggerMode())) {
|
||||
sendTask(reportTask, dto.getTestId());
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name())) {
|
||||
ApiDefinitionExecResultWithBLOBs record = new ApiDefinitionExecResultWithBLOBs();
|
||||
record.setId(dto.getReportId());
|
||||
record.setStatus(ApiReportStatus.STOPPED.name());
|
||||
} else if (apiRunModes.contains(dto.getRunMode()) && dto.isRemake()) {
|
||||
// 只处理RUNNING中的执行报告
|
||||
updateRunningResult(dto);
|
||||
}
|
||||
}
|
||||
|
||||
ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample();
|
||||
example.createCriteria().andIdEqualTo(dto.getReportId()).andStatusEqualTo(ApiReportStatus.RUNNING.name());
|
||||
apiDefinitionExecResultService.updateByExampleSelective(record, example);
|
||||
private void updateRunningResult(ResultDTO dto) {
|
||||
ApiDefinitionExecResultWithBLOBs result = apiDefinitionExecResultMapper.selectByPrimaryKey(dto.getReportId());
|
||||
if (result != null && StringUtils.equals(ApiReportStatus.RUNNING.name(), result.getStatus())) {
|
||||
result.setStatus(ApiReportStatus.PENDING.name());
|
||||
RequestResult item = new RequestResult();
|
||||
ResponseResult responseResult = new ResponseResult();
|
||||
responseResult.setConsole(dto.getConsole());
|
||||
item.setResponseResult(responseResult);
|
||||
result.setContent(JSON.toJSONString(item));
|
||||
|
||||
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(result);
|
||||
if (StringUtils.isNotEmpty(dto.getTestId())) {
|
||||
ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs();
|
||||
apiTestCase.setLastResultId(dto.getReportId());
|
||||
apiTestCase.setId(dto.getTestId());
|
||||
apiTestCase.setStatus(record.getStatus());
|
||||
apiTestCase.setStatus(result.getStatus());
|
||||
apiTestCaseService.updateByPrimaryKeySelective(apiTestCase);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.metersphere.service.scenario;
|
||||
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import io.metersphere.request.RelationshipEdgeRequest;
|
||||
import io.metersphere.service.RelationshipEdgeService;
|
||||
import io.metersphere.util.ObjectUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -57,7 +57,7 @@ public class ApiAutomationRelationshipEdgeService {
|
|||
List<String> referenceRelationships = new ArrayList<>();
|
||||
if (scenarioWithBLOBs.getScenarioDefinition().contains("\"referenced\":\"REF\"")) {
|
||||
// 深度解析对比,防止是复制的关系
|
||||
JSONObject element = ObjectUtil.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||
JSONObject element = JSONUtil.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||
// 历史数据处理
|
||||
this.relationships(element.getJSONArray("hashTree"), referenceRelationships);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package io.metersphere.service.scenario;
|
||||
|
||||
import io.metersphere.base.domain.ApiScenario;
|
||||
import io.metersphere.base.domain.ApiScenarioExample;
|
||||
import io.metersphere.base.domain.ScenarioExecutionInfo;
|
||||
import io.metersphere.base.domain.ScenarioExecutionInfoExample;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ScenarioExecutionInfoMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.enums.ExecutionExecuteTypeEnum;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
@ -16,6 +16,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -45,6 +46,15 @@ public class ApiScenarioExecutionInfoService {
|
|||
}
|
||||
}
|
||||
|
||||
@Lazy
|
||||
public void insertScenarioInfo(ApiScenarioWithBLOBs apiScenario, ApiScenarioReport scenarioReport, ResultDTO dto) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||
this.insertExecutionInfo(dto.getTestId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiScenario.getVersionId());
|
||||
} else {
|
||||
this.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiScenario.getVersionId());
|
||||
}
|
||||
}
|
||||
|
||||
public void insertExecutionInfoByScenarioList(List<ApiScenario> apiScenarios, String status, String triggerMode, String projectId, String executeType) {
|
||||
for (ApiScenario apiScenario : apiScenarios) {
|
||||
this.insertExecutionInfo(apiScenario.getId(), status, triggerMode, projectId, executeType, apiScenario.getVersionId());
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package io.metersphere.util;
|
||||
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ObjectUtil {
|
||||
public static JSONObject parseObject(String value) {
|
||||
try {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
MSException.throwException("value is null");
|
||||
}
|
||||
Map<String, Object> map = JSON.parseObject(value, Map.class);
|
||||
return new JSONObject(map);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ public class ResultDTO {
|
|||
private String runType;
|
||||
private String console;
|
||||
private String runningDebugSampler;
|
||||
private boolean isRemake;
|
||||
// 失败重试
|
||||
private boolean retryEnable;
|
||||
/**
|
||||
|
|
|
@ -241,7 +241,7 @@
|
|||
AND t.user_id = #{request.executor}
|
||||
</if>
|
||||
AND (t.integrated_report_id IS NULL OR t.integrated_report_id = 'null')
|
||||
AND t.status IN ("running","starting","pending")
|
||||
AND t.status ="running"
|
||||
) as apiTotal ,
|
||||
(SELECT
|
||||
count( t.id )
|
||||
|
|
Loading…
Reference in New Issue