refactor(接口测试): 接口测试执行相关代码整理优化
This commit is contained in:
parent
def44a3326
commit
59b6e5e556
|
@ -8,7 +8,6 @@ import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||||
import io.metersphere.api.dto.scenario.DatabaseConfig;
|
import io.metersphere.api.dto.scenario.DatabaseConfig;
|
||||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
|
||||||
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.api.service.ApiCaseResultService;
|
import io.metersphere.api.service.ApiCaseResultService;
|
||||||
|
@ -51,7 +50,7 @@ public class ApiCaseExecuteService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioSerialService apiScenarioSerialService;
|
private ApiCaseSerialService apiCaseSerialService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiExecutionQueueService apiExecutionQueueService;
|
private ApiExecutionQueueService apiExecutionQueueService;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -149,13 +148,13 @@ public class ApiCaseExecuteService {
|
||||||
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig());
|
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig());
|
||||||
|
|
||||||
// 开始选择执行模式
|
// 开始选择执行模式
|
||||||
if (deQueue != null && deQueue.getQueue() != null) {
|
if (deQueue != null && deQueue.getDetail() != null) {
|
||||||
Thread thread = new Thread(new Runnable() {
|
Thread thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Thread.currentThread().setName("PLAN-CASE:" + request.getPlanReportId());
|
Thread.currentThread().setName("PLAN-CASE:" + request.getPlanReportId());
|
||||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||||
apiScenarioSerialService.serial(deQueue, deQueue.getQueue());
|
apiCaseSerialService.serial(deQueue);
|
||||||
} else {
|
} else {
|
||||||
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), deQueue, runMode);
|
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), deQueue, runMode);
|
||||||
}
|
}
|
||||||
|
@ -277,7 +276,7 @@ public class ApiCaseExecuteService {
|
||||||
if (MapUtils.isEmpty(config.getEnvMap())) {
|
if (MapUtils.isEmpty(config.getEnvMap())) {
|
||||||
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
|
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
|
||||||
BeanUtils.copyBean(runModeConfig, request.getConfig());
|
BeanUtils.copyBean(runModeConfig, request.getConfig());
|
||||||
this.setExecutionEnvironmen(runModeConfig, testCaseEnvMap);
|
this.setExecutionEnvironment(runModeConfig, testCaseEnvMap);
|
||||||
config = runModeConfig;
|
config = runModeConfig;
|
||||||
}
|
}
|
||||||
ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.initBase(null, APITestStatus.Running.name(), serialReportId, config);
|
ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.initBase(null, APITestStatus.Running.name(), serialReportId, config);
|
||||||
|
@ -341,17 +340,17 @@ public class ApiCaseExecuteService {
|
||||||
|
|
||||||
String reportType = request.getConfig().getReportType();
|
String reportType = request.getConfig().getReportType();
|
||||||
String poolId = request.getConfig().getResourcePoolId();
|
String poolId = request.getConfig().getResourcePoolId();
|
||||||
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), serialReportId, reportType, ApiRunMode.DEFINITION.name(), request.getConfig());
|
DBTestQueue queue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), serialReportId, reportType, ApiRunMode.DEFINITION.name(), request.getConfig());
|
||||||
// 开始选择执行模式
|
// 开始选择执行模式
|
||||||
if (deQueue != null && deQueue.getQueue() != null) {
|
if (queue != null && queue.getDetail() != null) {
|
||||||
Thread thread = new Thread(new Runnable() {
|
Thread thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Thread.currentThread().setName("API-CASE-RUN");
|
Thread.currentThread().setName("API-CASE-RUN");
|
||||||
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||||
apiScenarioSerialService.serial(deQueue, deQueue.getQueue());
|
apiCaseSerialService.serial(queue);
|
||||||
} else {
|
} else {
|
||||||
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), deQueue, ApiRunMode.DEFINITION.name());
|
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), queue, ApiRunMode.DEFINITION.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -360,7 +359,7 @@ public class ApiCaseExecuteService {
|
||||||
return responseDTOS;
|
return responseDTOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExecutionEnvironmen(RunModeConfigWithEnvironmentDTO config, Map<String, List<String>> projectEnvMap) {
|
public void setExecutionEnvironment(RunModeConfigWithEnvironmentDTO config, Map<String, List<String>> projectEnvMap) {
|
||||||
if (MapUtils.isNotEmpty(projectEnvMap) && config != null) {
|
if (MapUtils.isNotEmpty(projectEnvMap) && config != null) {
|
||||||
config.setExecutionEnvironmentMap(projectEnvMap);
|
config.setExecutionEnvironmentMap(projectEnvMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package io.metersphere.api.exec.api;
|
package io.metersphere.api.exec.api;
|
||||||
|
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
||||||
|
@ -26,7 +25,7 @@ import java.util.Map;
|
||||||
@Service
|
@Service
|
||||||
public class ApiCaseParallelExecuteService {
|
public class ApiCaseParallelExecuteService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioSerialService apiScenarioSerialService;
|
private ApiCaseSerialService apiCaseSerialService;
|
||||||
@Resource
|
@Resource
|
||||||
private JMeterService jMeterService;
|
private JMeterService jMeterService;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -64,7 +63,7 @@ public class ApiCaseParallelExecuteService {
|
||||||
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, executionQueue.getDetailMap().get(result.getId())));
|
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, executionQueue.getDetailMap().get(result.getId())));
|
||||||
}
|
}
|
||||||
if (!pool.isPool()) {
|
if (!pool.isPool()) {
|
||||||
HashTree hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
|
HashTree hashTree = apiCaseSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
|
||||||
runRequest.setHashTree(hashTree);
|
runRequest.setHashTree(hashTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
package io.metersphere.api.exec.api;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.parser.Feature;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
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.exec.utils.GenerateHashTreeUtil;
|
||||||
|
import io.metersphere.api.exec.utils.RequestParamsUtil;
|
||||||
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
|
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
||||||
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
|
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||||
|
import io.metersphere.api.service.RemakeReportService;
|
||||||
|
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.ApiExecutionQueueDetail;
|
||||||
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.TestPlanApiCase;
|
||||||
|
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||||
|
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
|
||||||
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.HashTreeUtil;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
|
import io.metersphere.dto.ResultDTO;
|
||||||
|
import io.metersphere.plugin.core.MsTestElement;
|
||||||
|
import io.metersphere.utils.LoggerUtil;
|
||||||
|
import io.metersphere.xpack.api.dto.MsRetryLoopController;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ApiCaseSerialService {
|
||||||
|
@Resource
|
||||||
|
private JMeterService jMeterService;
|
||||||
|
@Resource
|
||||||
|
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private ObjectMapper mapper;
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
public void serial(DBTestQueue executionQueue) {
|
||||||
|
ApiExecutionQueueDetail queue = executionQueue.getDetail();
|
||||||
|
JmeterRunRequestDTO runRequest = RequestParamsUtil.init(executionQueue, queue, queue.getReportId());
|
||||||
|
// 判断触发资源对象是用例
|
||||||
|
if (!GenerateHashTreeUtil.isSetReport(executionQueue.getReportType())
|
||||||
|
|| StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||||
|
updateDefinitionExecResultToRunning(queue, runRequest);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (StringUtils.isEmpty(executionQueue.getPoolId())) {
|
||||||
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
|
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
|
||||||
|
map = JSON.parseObject(queue.getEvnMap(), Map.class);
|
||||||
|
}
|
||||||
|
runRequest.setHashTree(generateHashTree(queue.getTestId(), map, runRequest));
|
||||||
|
// 更新环境变量
|
||||||
|
if (runRequest.getHashTree() != null) {
|
||||||
|
this.initEnv(runRequest.getHashTree());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runRequest.getPool().isPool()) {
|
||||||
|
SmoothWeighted.setServerConfig(runRequest.getPoolId(), redisTemplate);
|
||||||
|
}
|
||||||
|
// 开始执行
|
||||||
|
jMeterService.run(runRequest);
|
||||||
|
} catch (Exception e) {
|
||||||
|
RequestParamsUtil.rollback(runRequest, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateDefinitionExecResultToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
|
||||||
|
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
|
||||||
|
if (execResult != null) {
|
||||||
|
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
|
||||||
|
this.put("userId", execResult.getUserId());
|
||||||
|
}});
|
||||||
|
execResult.setStartTime(System.currentTimeMillis());
|
||||||
|
execResult.setStatus(APITestStatus.Running.name());
|
||||||
|
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
|
||||||
|
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ]", execResult.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEnv(HashTree hashTree) {
|
||||||
|
ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||||
|
HashTreeUtil hashTreeUtil = new HashTreeUtil();
|
||||||
|
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService);
|
||||||
|
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashTree generateHashTree(String testId, Map<String, String> envMap, JmeterRunRequestDTO runRequest) {
|
||||||
|
try {
|
||||||
|
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
||||||
|
String envId = null;
|
||||||
|
if (caseWithBLOBs == null) {
|
||||||
|
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||||
|
if (apiCase != null) {
|
||||||
|
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
||||||
|
envId = apiCase.getEnvironmentId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (envMap != null && envMap.containsKey(caseWithBLOBs.getProjectId())) {
|
||||||
|
envId = envMap.get(caseWithBLOBs.getProjectId());
|
||||||
|
}
|
||||||
|
if (caseWithBLOBs != null) {
|
||||||
|
String data = caseWithBLOBs.getRequest();
|
||||||
|
// 失败重试
|
||||||
|
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
||||||
|
ApiRetryOnFailureService apiRetryOnFailureService = CommonBeanFactory.getBean(ApiRetryOnFailureService.class);
|
||||||
|
String retryData = apiRetryOnFailureService.retry(data, runRequest.getRetryNum(), true);
|
||||||
|
data = StringUtils.isNotEmpty(retryData) ? retryData : data;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTree jmeterHashTree = new HashTree();
|
||||||
|
MsTestPlan testPlan = new MsTestPlan();
|
||||||
|
testPlan.setHashTree(new LinkedList<>());
|
||||||
|
|
||||||
|
MsThreadGroup group = new MsThreadGroup();
|
||||||
|
group.setLabel(caseWithBLOBs.getName());
|
||||||
|
group.setName(runRequest.getReportId());
|
||||||
|
group.setProjectId(caseWithBLOBs.getProjectId());
|
||||||
|
MsTestElement testElement = null;
|
||||||
|
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
||||||
|
MsRetryLoopController controller = JSON.parseObject(data, MsRetryLoopController.class);
|
||||||
|
GenerateHashTreeUtil.parse(data, controller);
|
||||||
|
MsTestElement element = parse(JSON.toJSONString(controller.getHashTree().get(0)), testId, envId, caseWithBLOBs.getProjectId());
|
||||||
|
controller.setHashTree(new LinkedList<>() {{
|
||||||
|
this.add(element);
|
||||||
|
}});
|
||||||
|
testElement = controller;
|
||||||
|
} else {
|
||||||
|
testElement = parse(data, testId, envId, caseWithBLOBs.getProjectId());
|
||||||
|
}
|
||||||
|
group.setHashTree(new LinkedList<>());
|
||||||
|
group.getHashTree().add(testElement);
|
||||||
|
testPlan.getHashTree().add(group);
|
||||||
|
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||||
|
|
||||||
|
LoggerUtil.info("用例资源:" + caseWithBLOBs.getName() + ", 生成执行脚本JMX成功", runRequest.getReportId());
|
||||||
|
return jmeterHashTree;
|
||||||
|
}
|
||||||
|
} 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);
|
||||||
|
LoggerUtil.error("用例资源:" + testId + ", 生成执行脚本失败", runRequest.getReportId(), ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MsTestElement parse(String api, String planId, String envId, String projectId) {
|
||||||
|
try {
|
||||||
|
JSONObject element = JSON.parseObject(api, Feature.DisableSpecialKeyDetect);
|
||||||
|
ElementUtil.dataFormatting(element);
|
||||||
|
|
||||||
|
LinkedList<MsTestElement> list = new LinkedList<>();
|
||||||
|
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
|
||||||
|
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
|
||||||
|
new TypeReference<LinkedList<MsTestElement>>() {
|
||||||
|
});
|
||||||
|
list.addAll(elements);
|
||||||
|
}
|
||||||
|
if (element.getString("type").equals("HTTPSamplerProxy")) {
|
||||||
|
MsHTTPSamplerProxy httpSamplerProxy = JSON.parseObject(api, MsHTTPSamplerProxy.class, Feature.DisableSpecialKeyDetect);
|
||||||
|
httpSamplerProxy.setHashTree(list);
|
||||||
|
httpSamplerProxy.setName(planId);
|
||||||
|
if (StringUtils.isNotEmpty(envId)) {
|
||||||
|
httpSamplerProxy.setUseEnvironment(envId);
|
||||||
|
}
|
||||||
|
return httpSamplerProxy;
|
||||||
|
}
|
||||||
|
if (element.getString("type").equals("TCPSampler")) {
|
||||||
|
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class, Feature.DisableSpecialKeyDetect);
|
||||||
|
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.getString("type").equals("DubboSampler")) {
|
||||||
|
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class, Feature.DisableSpecialKeyDetect);
|
||||||
|
if (StringUtils.isNotEmpty(envId)) {
|
||||||
|
dubboSampler.setUseEnvironment(envId);
|
||||||
|
}
|
||||||
|
dubboSampler.setHashTree(list);
|
||||||
|
dubboSampler.setName(planId);
|
||||||
|
return dubboSampler;
|
||||||
|
}
|
||||||
|
if (element.getString("type").equals("JDBCSampler")) {
|
||||||
|
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
|
||||||
|
if (StringUtils.isNotEmpty(envId)) {
|
||||||
|
jDBCSampler.setUseEnvironment(envId);
|
||||||
|
}
|
||||||
|
jDBCSampler.setHashTree(list);
|
||||||
|
jDBCSampler.setName(planId);
|
||||||
|
return jDBCSampler;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,14 +77,14 @@ public class PerfQueueService {
|
||||||
}
|
}
|
||||||
// 获取串行下一个执行节点
|
// 获取串行下一个执行节点
|
||||||
DBTestQueue executionQueue = apiExecutionQueueService.handleQueue(detail.getQueueId(), detail.getTestId());
|
DBTestQueue executionQueue = apiExecutionQueueService.handleQueue(detail.getQueueId(), detail.getTestId());
|
||||||
if (executionQueue != null && executionQueue.getQueue() != null
|
if (executionQueue != null && executionQueue.getDetail() != null
|
||||||
&& StringUtils.isNotEmpty(executionQueue.getQueue().getTestId()) &&
|
&& StringUtils.isNotEmpty(executionQueue.getDetail().getTestId()) &&
|
||||||
StringUtils.equals(executionQueue.getRunMode(), RunModeConstants.SERIAL.toString())) {
|
StringUtils.equals(executionQueue.getRunMode(), RunModeConstants.SERIAL.toString())) {
|
||||||
|
|
||||||
LoggerUtil.info("获取下一个执行资源:" + executionQueue.getQueue().getTestId(), loadTestReport.getId());
|
LoggerUtil.info("获取下一个执行资源:" + executionQueue.getDetail().getTestId(), loadTestReport.getId());
|
||||||
RunTestPlanRequest request = new RunTestPlanRequest();
|
RunTestPlanRequest request = new RunTestPlanRequest();
|
||||||
request.setTestPlanLoadId(executionQueue.getQueue().getTestId());
|
request.setTestPlanLoadId(executionQueue.getDetail().getTestId());
|
||||||
request.setReportId(executionQueue.getQueue().getReportId());
|
request.setReportId(executionQueue.getDetail().getReportId());
|
||||||
try {
|
try {
|
||||||
perfModeExecService.serial(request);
|
perfModeExecService.serial(request);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -92,10 +92,10 @@ public class PerfQueueService {
|
||||||
LoggerUtil.info("失败停止处理:" + request.getId(), request.getReportId());
|
LoggerUtil.info("失败停止处理:" + request.getId(), request.getReportId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LoggerUtil.error("执行异常", executionQueue.getQueue().getTestId(), e);
|
LoggerUtil.error("执行异常", executionQueue.getDetail().getTestId(), e);
|
||||||
executionQueueDetailMapper.deleteByExample(detailExample);
|
executionQueueDetailMapper.deleteByExample(detailExample);
|
||||||
// 异常执行下一个
|
// 异常执行下一个
|
||||||
DBTestQueue next = apiExecutionQueueService.handleQueue(executionQueue.getId(), executionQueue.getQueue().getTestId());
|
DBTestQueue next = apiExecutionQueueService.handleQueue(executionQueue.getId(), executionQueue.getDetail().getTestId());
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
LoadTestReport report = new LoadTestReport();
|
LoadTestReport report = new LoadTestReport();
|
||||||
report.setId(next.getReportId());
|
report.setId(next.getReportId());
|
||||||
|
|
|
@ -10,6 +10,6 @@ import java.util.Map;
|
||||||
@Data
|
@Data
|
||||||
public class DBTestQueue extends ApiExecutionQueue {
|
public class DBTestQueue extends ApiExecutionQueue {
|
||||||
private String completedReportId;
|
private String completedReportId;
|
||||||
private ApiExecutionQueueDetail queue;
|
private ApiExecutionQueueDetail detail;
|
||||||
private Map<String, String> detailMap = new HashMap<>();
|
private Map<String, String> detailMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ public class ApiScenarioExecuteService {
|
||||||
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
|
RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO();
|
||||||
BeanUtils.copyBean(runModeConfig, request.getConfig());
|
BeanUtils.copyBean(runModeConfig, request.getConfig());
|
||||||
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios);
|
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios);
|
||||||
apiCaseExecuteService.setExecutionEnvironmen(runModeConfig, projectEnvMap);
|
apiCaseExecuteService.setExecutionEnvironment(runModeConfig, projectEnvMap);
|
||||||
request.setConfig(runModeConfig);
|
request.setConfig(runModeConfig);
|
||||||
}
|
}
|
||||||
APIScenarioReportResult report = getApiScenarioReportResult(request, serialReportId, scenarioNames, reportScenarioIds);
|
APIScenarioReportResult report = getApiScenarioReportResult(request, serialReportId, scenarioNames, reportScenarioIds);
|
||||||
|
@ -199,7 +199,7 @@ public class ApiScenarioExecuteService {
|
||||||
{
|
{
|
||||||
Thread.currentThread().setName("SCENARIO-THREAD");
|
Thread.currentThread().setName("SCENARIO-THREAD");
|
||||||
if (isSerial(request)) {
|
if (isSerial(request)) {
|
||||||
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
|
apiScenarioSerialService.serial(executionQueue);
|
||||||
} else {
|
} else {
|
||||||
apiScenarioParallelService.parallel(executeQueue, request, finalSerialReportId, executionQueue);
|
apiScenarioParallelService.parallel(executeQueue, request, finalSerialReportId, executionQueue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,21 @@
|
||||||
package io.metersphere.api.exec.scenario;
|
package io.metersphere.api.exec.scenario;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import com.alibaba.fastjson.parser.Feature;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
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.api.ApiRetryOnFailureService;
|
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
|
import io.metersphere.api.exec.utils.RequestParamsUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
|
||||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||||
import io.metersphere.api.service.RemakeReportService;
|
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||||
|
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
|
||||||
import io.metersphere.commons.utils.HashTreeUtil;
|
import io.metersphere.commons.utils.HashTreeUtil;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
|
||||||
import io.metersphere.constants.RunModeConstants;
|
|
||||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
|
||||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.dto.ResultDTO;
|
|
||||||
import io.metersphere.plugin.core.MsTestElement;
|
|
||||||
import io.metersphere.service.SystemParameterService;
|
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
import io.metersphere.xpack.api.dto.MsRetryLoopController;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
@ -45,7 +25,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -58,48 +37,24 @@ public class ApiScenarioSerialService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioMapper apiScenarioMapper;
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
|
||||||
@Resource
|
|
||||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
|
||||||
@Resource
|
|
||||||
private ApiTestCaseMapper apiTestCaseMapper;
|
|
||||||
@Resource
|
|
||||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioEnvService apiScenarioEnvService;
|
private ApiScenarioEnvService apiScenarioEnvService;
|
||||||
@Resource
|
@Resource
|
||||||
private ObjectMapper mapper;
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
@Resource
|
||||||
|
private ApiTestEnvironmentService apiTestEnvironmentService;
|
||||||
|
|
||||||
public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) {
|
public void serial(DBTestQueue executionQueue) {
|
||||||
|
ApiExecutionQueueDetail queue = executionQueue.getDetail();
|
||||||
String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
|
String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
|
||||||
if (!StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
if (!StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
||||||
reportId = queue.getReportId();
|
reportId = queue.getReportId();
|
||||||
}
|
}
|
||||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(queue.getTestId(), reportId, executionQueue.getRunMode(), null);
|
JmeterRunRequestDTO runRequest = RequestParamsUtil.init(executionQueue, queue, reportId);
|
||||||
// 获取可以执行的资源池
|
// 更新报告状态
|
||||||
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
|
|
||||||
runRequest.setRetryEnable(queue.getRetryEnable() == null ? false : queue.getRetryEnable());
|
|
||||||
runRequest.setRetryNum(queue.getRetryNumber());
|
|
||||||
// 判断触发资源对象是用例/场景更新对应报告状态
|
|
||||||
if (!GenerateHashTreeUtil.isSetReport(executionQueue.getReportType())
|
|
||||||
|| StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
|
||||||
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
|
||||||
updateReportToRunning(queue, runRequest);
|
updateReportToRunning(queue, runRequest);
|
||||||
} else {
|
|
||||||
updateDefinitionExecResultToRunning(queue, runRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runRequest.setReportType(executionQueue.getReportType());
|
|
||||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(executionQueue.getPoolId()));
|
|
||||||
runRequest.setTestPlanReportId(executionQueue.getReportId());
|
|
||||||
runRequest.setRunType(RunModeConstants.SERIAL.toString());
|
|
||||||
runRequest.setQueueId(executionQueue.getId());
|
|
||||||
runRequest.setPoolId(executionQueue.getPoolId());
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(executionQueue.getPoolId())) {
|
if (StringUtils.isEmpty(executionQueue.getPoolId())) {
|
||||||
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
ApiScenarioWithBLOBs scenario = null;
|
ApiScenarioWithBLOBs scenario = null;
|
||||||
|
@ -118,12 +73,6 @@ public class ApiScenarioSerialService {
|
||||||
planEnvMap = JSON.parseObject(queue.getEvnMap(), Map.class);
|
planEnvMap = JSON.parseObject(queue.getEvnMap(), Map.class);
|
||||||
}
|
}
|
||||||
runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(scenario, planEnvMap, runRequest));
|
runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(scenario, planEnvMap, runRequest));
|
||||||
} else {
|
|
||||||
Map<String, String> map = new LinkedHashMap<>();
|
|
||||||
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
|
|
||||||
map = JSON.parseObject(queue.getEvnMap(), Map.class);
|
|
||||||
}
|
|
||||||
runRequest.setHashTree(generateHashTree(queue.getTestId(), map, runRequest));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新环境变量
|
// 更新环境变量
|
||||||
|
@ -131,39 +80,30 @@ public class ApiScenarioSerialService {
|
||||||
this.initEnv(runRequest.getHashTree());
|
this.initEnv(runRequest.getHashTree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queue != null) {
|
|
||||||
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, queue.getId()));
|
|
||||||
}
|
|
||||||
if (runRequest.getPool().isPool()) {
|
if (runRequest.getPool().isPool()) {
|
||||||
SmoothWeighted.setServerConfig(runRequest.getPoolId(), redisTemplate);
|
SmoothWeighted.setServerConfig(runRequest.getPoolId(), redisTemplate);
|
||||||
}
|
}
|
||||||
// 开始执行
|
// 开始执行
|
||||||
jMeterService.run(runRequest);
|
jMeterService.run(runRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
RequestParamsUtil.rollback(runRequest, e);
|
||||||
remakeReportService.remake(runRequest);
|
|
||||||
ResultDTO dto = new ResultDTO();
|
|
||||||
BeanUtils.copyBean(dto, runRequest);
|
|
||||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
|
||||||
LoggerUtil.error("执行队列[" + queue.getId() + "]入队列失败:", queue.getReportId(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateDefinitionExecResultToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
|
|
||||||
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
|
|
||||||
if (execResult != null) {
|
|
||||||
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
|
|
||||||
this.put("userId", execResult.getUserId());
|
|
||||||
}});
|
|
||||||
execResult.setStartTime(System.currentTimeMillis());
|
|
||||||
execResult.setStatus(APITestStatus.Running.name());
|
|
||||||
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
|
|
||||||
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ]", execResult.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新报告状态
|
||||||
|
*
|
||||||
|
* @param queue
|
||||||
|
* @param runRequest
|
||||||
|
*/
|
||||||
public void updateReportToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
|
public void updateReportToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
|
||||||
|
if (!GenerateHashTreeUtil.isSetReport(runRequest.getReportType()) &&
|
||||||
|
StringUtils.equalsAny(runRequest.getRunMode(),
|
||||||
|
ApiRunMode.SCENARIO.name(),
|
||||||
|
ApiRunMode.SCENARIO_PLAN.name(),
|
||||||
|
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
|
||||||
|
ApiRunMode.SCHEDULE_SCENARIO.name(),
|
||||||
|
ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
|
||||||
if (report != null) {
|
if (report != null) {
|
||||||
report.setStatus(APITestStatus.Running.name());
|
report.setStatus(APITestStatus.Running.name());
|
||||||
|
@ -176,130 +116,11 @@ public class ApiScenarioSerialService {
|
||||||
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ]", report.getId());
|
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ]", report.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initEnv(HashTree hashTree) {
|
private void initEnv(HashTree hashTree) {
|
||||||
ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
|
||||||
HashTreeUtil hashTreeUtil = new HashTreeUtil();
|
HashTreeUtil hashTreeUtil = new HashTreeUtil();
|
||||||
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService);
|
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService);
|
||||||
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashTree generateHashTree(String testId, Map<String, String> envMap, JmeterRunRequestDTO runRequest) {
|
|
||||||
try {
|
|
||||||
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
|
||||||
String envId = null;
|
|
||||||
if (caseWithBLOBs == null) {
|
|
||||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
|
||||||
if (apiCase != null) {
|
|
||||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
|
||||||
envId = apiCase.getEnvironmentId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (envMap != null && envMap.containsKey(caseWithBLOBs.getProjectId())) {
|
|
||||||
envId = envMap.get(caseWithBLOBs.getProjectId());
|
|
||||||
}
|
|
||||||
if (caseWithBLOBs != null) {
|
|
||||||
String data = caseWithBLOBs.getRequest();
|
|
||||||
// 失败重试
|
|
||||||
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
|
||||||
ApiRetryOnFailureService apiRetryOnFailureService = CommonBeanFactory.getBean(ApiRetryOnFailureService.class);
|
|
||||||
String retryData = apiRetryOnFailureService.retry(data, runRequest.getRetryNum(), true);
|
|
||||||
data = StringUtils.isNotEmpty(retryData) ? retryData : data;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashTree jmeterHashTree = new HashTree();
|
|
||||||
MsTestPlan testPlan = new MsTestPlan();
|
|
||||||
testPlan.setHashTree(new LinkedList<>());
|
|
||||||
|
|
||||||
MsThreadGroup group = new MsThreadGroup();
|
|
||||||
group.setLabel(caseWithBLOBs.getName());
|
|
||||||
group.setName(runRequest.getReportId());
|
|
||||||
group.setProjectId(caseWithBLOBs.getProjectId());
|
|
||||||
MsTestElement testElement = null;
|
|
||||||
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
|
||||||
MsRetryLoopController controller = JSON.parseObject(data, MsRetryLoopController.class);
|
|
||||||
GenerateHashTreeUtil.parse(data, controller);
|
|
||||||
MsTestElement element = parse(JSON.toJSONString(controller.getHashTree().get(0)), testId, envId, caseWithBLOBs.getProjectId());
|
|
||||||
controller.setHashTree(new LinkedList<>() {{
|
|
||||||
this.add(element);
|
|
||||||
}});
|
|
||||||
testElement = controller;
|
|
||||||
} else {
|
|
||||||
testElement = parse(data, testId, envId, caseWithBLOBs.getProjectId());
|
|
||||||
}
|
|
||||||
group.setHashTree(new LinkedList<>());
|
|
||||||
group.getHashTree().add(testElement);
|
|
||||||
testPlan.getHashTree().add(group);
|
|
||||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
|
||||||
|
|
||||||
LoggerUtil.info("用例资源:" + caseWithBLOBs.getName() + ", 生成执行脚本JMX成功", runRequest.getReportId());
|
|
||||||
return jmeterHashTree;
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
LoggerUtil.error("用例资源:" + testId + ", 生成执行脚本失败", runRequest.getReportId(), ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MsTestElement parse(String api, String planId, String envId, String projectId) {
|
|
||||||
try {
|
|
||||||
JSONObject element = JSON.parseObject(api, Feature.DisableSpecialKeyDetect);
|
|
||||||
ElementUtil.dataFormatting(element);
|
|
||||||
|
|
||||||
LinkedList<MsTestElement> list = new LinkedList<>();
|
|
||||||
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
|
|
||||||
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
|
|
||||||
new TypeReference<LinkedList<MsTestElement>>() {
|
|
||||||
});
|
|
||||||
list.addAll(elements);
|
|
||||||
}
|
|
||||||
if (element.getString("type").equals("HTTPSamplerProxy")) {
|
|
||||||
MsHTTPSamplerProxy httpSamplerProxy = JSON.parseObject(api, MsHTTPSamplerProxy.class, Feature.DisableSpecialKeyDetect);
|
|
||||||
httpSamplerProxy.setHashTree(list);
|
|
||||||
httpSamplerProxy.setName(planId);
|
|
||||||
if (StringUtils.isNotEmpty(envId)) {
|
|
||||||
httpSamplerProxy.setUseEnvironment(envId);
|
|
||||||
}
|
|
||||||
return httpSamplerProxy;
|
|
||||||
}
|
|
||||||
if (element.getString("type").equals("TCPSampler")) {
|
|
||||||
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class, Feature.DisableSpecialKeyDetect);
|
|
||||||
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.getString("type").equals("DubboSampler")) {
|
|
||||||
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class, Feature.DisableSpecialKeyDetect);
|
|
||||||
if (StringUtils.isNotEmpty(envId)) {
|
|
||||||
dubboSampler.setUseEnvironment(envId);
|
|
||||||
}
|
|
||||||
dubboSampler.setHashTree(list);
|
|
||||||
dubboSampler.setName(planId);
|
|
||||||
return dubboSampler;
|
|
||||||
}
|
|
||||||
if (element.getString("type").equals("JDBCSampler")) {
|
|
||||||
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
|
|
||||||
if (StringUtils.isNotEmpty(envId)) {
|
|
||||||
jDBCSampler.setUseEnvironment(envId);
|
|
||||||
}
|
|
||||||
jDBCSampler.setHashTree(list);
|
|
||||||
jDBCSampler.setName(planId);
|
|
||||||
return jDBCSampler;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package io.metersphere.api.exec.utils;
|
||||||
|
|
||||||
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
|
import io.metersphere.api.service.RemakeReportService;
|
||||||
|
import io.metersphere.base.domain.ApiExecutionQueue;
|
||||||
|
import io.metersphere.base.domain.ApiExecutionQueueDetail;
|
||||||
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.constants.RunModeConstants;
|
||||||
|
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||||
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
|
import io.metersphere.dto.ResultDTO;
|
||||||
|
import io.metersphere.service.SystemParameterService;
|
||||||
|
import io.metersphere.utils.LoggerUtil;
|
||||||
|
|
||||||
|
public class RequestParamsUtil {
|
||||||
|
|
||||||
|
public static JmeterRunRequestDTO init(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue, String reportId) {
|
||||||
|
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(queue.getTestId(), reportId, executionQueue.getRunMode(), null);
|
||||||
|
runRequest.setRetryEnable(queue.getRetryEnable() == null ? false : queue.getRetryEnable());
|
||||||
|
runRequest.setRetryNum(queue.getRetryNumber());
|
||||||
|
runRequest.setReportType(executionQueue.getReportType());
|
||||||
|
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(executionQueue.getPoolId()));
|
||||||
|
runRequest.setTestPlanReportId(executionQueue.getReportId());
|
||||||
|
runRequest.setRunType(RunModeConstants.SERIAL.toString());
|
||||||
|
runRequest.setQueueId(executionQueue.getId());
|
||||||
|
runRequest.setPoolId(executionQueue.getPoolId());
|
||||||
|
// 获取可以执行的资源池
|
||||||
|
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
|
||||||
|
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, queue.getId()));
|
||||||
|
return runRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rollback(JmeterRunRequestDTO runRequest, Exception e) {
|
||||||
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
remakeReportService.remake(runRequest);
|
||||||
|
ResultDTO dto = new ResultDTO();
|
||||||
|
BeanUtils.copyBean(dto, runRequest);
|
||||||
|
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||||
|
LoggerUtil.error("执行队列[" + runRequest.getQueueId() + "]入队列失败:", runRequest.getReportId(), e);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.api.dto.RunModeDataDTO;
|
import io.metersphere.api.dto.RunModeDataDTO;
|
||||||
import io.metersphere.api.dto.UiExecutionQueueParam;
|
import io.metersphere.api.dto.UiExecutionQueueParam;
|
||||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||||
|
import io.metersphere.api.exec.api.ApiCaseSerialService;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
|
@ -66,6 +67,8 @@ public class ApiExecutionQueueService {
|
||||||
protected ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
|
protected ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioReportResultMapper apiScenarioReportResultMapper;
|
private ApiScenarioReportResultMapper apiScenarioReportResultMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiCaseSerialService apiCaseSerialService;
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
|
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
|
||||||
|
@ -116,7 +119,7 @@ public class ApiExecutionQueueService {
|
||||||
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], resQueue.getId(), envMap);
|
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], resQueue.getId(), envMap);
|
||||||
queue.setSort(sort[0]);
|
queue.setSort(sort[0]);
|
||||||
if (sort[0] == 0) {
|
if (sort[0] == 0) {
|
||||||
resQueue.setQueue(queue);
|
resQueue.setDetail(queue);
|
||||||
}
|
}
|
||||||
sort[0]++;
|
sort[0]++;
|
||||||
queue.setRetryEnable(config.isRetryEnable());
|
queue.setRetryEnable(config.isRetryEnable());
|
||||||
|
@ -132,8 +135,8 @@ public class ApiExecutionQueueService {
|
||||||
String envStr = JSON.toJSONString(config.getEnvMap());
|
String envStr = JSON.toJSONString(config.getEnvMap());
|
||||||
for (String k : runMap.keySet()) {
|
for (String k : runMap.keySet()) {
|
||||||
ApiExecutionQueueDetail queue = detail(runMap.get(k).getId(), k, config.getMode(), sort++, resQueue.getId(), envStr);
|
ApiExecutionQueueDetail queue = detail(runMap.get(k).getId(), k, config.getMode(), sort++, resQueue.getId(), envStr);
|
||||||
if (sort == 0) {
|
if (sort == 1) {
|
||||||
resQueue.setQueue(queue);
|
resQueue.setDetail(queue);
|
||||||
}
|
}
|
||||||
queue.setRetryEnable(config.isRetryEnable());
|
queue.setRetryEnable(config.isRetryEnable());
|
||||||
queue.setRetryNumber(config.getRetryNum());
|
queue.setRetryNumber(config.getRetryNum());
|
||||||
|
@ -149,8 +152,8 @@ public class ApiExecutionQueueService {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String testId : requests.keySet()) {
|
for (String testId : requests.keySet()) {
|
||||||
ApiExecutionQueueDetail queue = detail(requests.get(testId), testId, config.getMode(), i++, resQueue.getId(), envStr);
|
ApiExecutionQueueDetail queue = detail(requests.get(testId), testId, config.getMode(), i++, resQueue.getId(), envStr);
|
||||||
if (i == 0) {
|
if (i == 1) {
|
||||||
resQueue.setQueue(queue);
|
resQueue.setDetail(queue);
|
||||||
}
|
}
|
||||||
queue.setRetryEnable(config.isRetryEnable());
|
queue.setRetryEnable(config.isRetryEnable());
|
||||||
queue.setRetryNumber(config.getRetryNum());
|
queue.setRetryNumber(config.getRetryNum());
|
||||||
|
@ -258,7 +261,7 @@ public class ApiExecutionQueueService {
|
||||||
}
|
}
|
||||||
// 取出下一个要执行的节点
|
// 取出下一个要执行的节点
|
||||||
if (CollectionUtils.isNotEmpty(queues)) {
|
if (CollectionUtils.isNotEmpty(queues)) {
|
||||||
queue.setQueue(queues.get(0));
|
queue.setDetail(queues.get(0));
|
||||||
} else {
|
} else {
|
||||||
LoggerUtil.info("execution complete,clear queue:【" + id + "】");
|
LoggerUtil.info("execution complete,clear queue:【" + id + "】");
|
||||||
queueMapper.deleteByPrimaryKey(id);
|
queueMapper.deleteByPrimaryKey(id);
|
||||||
|
@ -331,22 +334,30 @@ public class ApiExecutionQueueService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoggerUtil.info("开始处理执行队列:" + executionQueue.getId() + " 当前资源是:" + dto.getTestId() + "报告ID:" + dto.getReportId());
|
LoggerUtil.info("开始处理执行队列:" + executionQueue.getId() + " 当前资源是:" + dto.getTestId() + "报告ID:" + dto.getReportId());
|
||||||
if (executionQueue.getQueue() != null && StringUtils.isNotEmpty(executionQueue.getQueue().getTestId())) {
|
if (executionQueue.getDetail() != null && StringUtils.isNotEmpty(executionQueue.getDetail().getTestId())) {
|
||||||
if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) {
|
if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) {
|
||||||
LoggerUtil.info("当前执行队列是:" + JSON.toJSONString(executionQueue.getQueue()));
|
LoggerUtil.info("当前执行队列是:" + JSON.toJSONString(executionQueue.getDetail()));
|
||||||
// 防止重复执行
|
// 防止重复执行
|
||||||
boolean isNext = redisTemplate.opsForValue().setIfAbsent(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), executionQueue.getQueue().getQueueId());
|
boolean isNext = redisTemplate.opsForValue().setIfAbsent(RunModeConstants.SERIAL.name() + "_" + executionQueue.getDetail().getReportId(), executionQueue.getDetail().getQueueId());
|
||||||
if (isNext) {
|
if (!isNext) {
|
||||||
redisTemplate.expire(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), 60, TimeUnit.MINUTES);
|
return;
|
||||||
|
}
|
||||||
|
redisTemplate.expire(RunModeConstants.SERIAL.name() + "_" + executionQueue.getDetail().getReportId(), 60, TimeUnit.MINUTES);
|
||||||
if (StringUtils.startsWith(executionQueue.getRunMode(), "UI")) {
|
if (StringUtils.startsWith(executionQueue.getRunMode(), "UI")) {
|
||||||
uiScenarioSerialServiceProxy.serial(executionQueue, executionQueue.getQueue());
|
uiScenarioSerialServiceProxy.serial(executionQueue, executionQueue.getDetail());
|
||||||
|
} else if (StringUtils.equalsAny(executionQueue.getRunMode(),
|
||||||
|
ApiRunMode.SCENARIO.name(),
|
||||||
|
ApiRunMode.SCENARIO_PLAN.name(),
|
||||||
|
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
|
||||||
|
ApiRunMode.SCHEDULE_SCENARIO.name(),
|
||||||
|
ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
|
apiScenarioSerialService.serial(executionQueue);
|
||||||
} else {
|
} else {
|
||||||
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
|
apiCaseSerialService.serial(executionQueue);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
if (StringUtils.equalsIgnoreCase(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||||
String reportId = dto.getReportId();
|
String reportId = dto.getReportId();
|
||||||
if (StringUtils.equalsIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
if (StringUtils.equalsIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||||
reportId = dto.getTestPlanReportId();
|
reportId = dto.getTestPlanReportId();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||||
import io.metersphere.api.dto.EnvironmentType;
|
import io.metersphere.api.dto.EnvironmentType;
|
||||||
import io.metersphere.api.dto.definition.request.MsTestPlan;
|
import io.metersphere.api.dto.definition.request.MsTestPlan;
|
||||||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
import io.metersphere.api.exec.api.ApiCaseSerialService;
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
||||||
|
@ -36,9 +36,8 @@ import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ApiJmeterFileService {
|
public class ApiJmeterFileService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioSerialService apiScenarioSerialService;
|
private ApiCaseSerialService apiCaseSerialService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -90,7 +89,7 @@ public class ApiJmeterFileService {
|
||||||
}
|
}
|
||||||
HashTree hashTree = null;
|
HashTree hashTree = null;
|
||||||
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
||||||
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, envMap, runRequest);
|
hashTree = apiCaseSerialService.generateHashTree(remoteTestId, envMap, runRequest);
|
||||||
} else {
|
} else {
|
||||||
if (scenario == null) {
|
if (scenario == null) {
|
||||||
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);
|
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);
|
||||||
|
|
Loading…
Reference in New Issue