perf(测试计划): 测试计划执行时准备数据查询优化

This commit is contained in:
fit2-zhao 2022-04-06 14:23:55 +08:00 committed by 刘瑞斌
parent 63b5bd3bc3
commit db46056049
17 changed files with 136 additions and 93 deletions

View File

@ -9,6 +9,7 @@ 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.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.service.ApiCaseResultService; import io.metersphere.api.service.ApiCaseResultService;
import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.ApiScenarioReportStructureService; import io.metersphere.api.service.ApiScenarioReportStructureService;
@ -40,6 +41,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
public class ApiCaseExecuteService { public class ApiCaseExecuteService {
@ -60,7 +62,7 @@ public class ApiCaseExecuteService {
@Resource @Resource
private ApiCaseResultService apiCaseResultService; private ApiCaseResultService apiCaseResultService;
@Resource @Resource
ApiScenarioReportStructureService apiScenarioReportStructureService; private ApiScenarioReportStructureService apiScenarioReportStructureService;
/** /**
* 测试计划case执行 * 测试计划case执行
@ -92,9 +94,22 @@ public class ApiCaseExecuteService {
Map<String, ApiDefinitionExecResult> executeQueue = new LinkedHashMap<>(); Map<String, ApiDefinitionExecResult> executeQueue = new LinkedHashMap<>();
List<MsExecResponseDTO> responseDTOS = new LinkedList<>(); List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name(); String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
// 查出用例
List<String> apiCaseIds = planApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
ApiTestCaseExample caseExample = new ApiTestCaseExample();
caseExample.createCriteria().andIdIn(apiCaseIds);
List<ApiTestCase> apiTestCases = apiTestCaseMapper.selectByExample(caseExample);
Map<String, ApiTestCase> caseMap = apiTestCases.stream().collect(Collectors.toMap(ApiTestCase::getId, a -> a, (k1, k2) -> k1));
// 资源池
String resourcePoolId = null;
if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) {
resourcePoolId = request.getConfig().getResourcePoolId();
}
Map<String, String> planProjects = new HashMap<>(); Map<String, String> planProjects = new HashMap<>();
planApiCases.forEach(testPlanApiCase -> { for (TestPlanApiCase testPlanApiCase : planApiCases) {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status); ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, caseMap, resourcePoolId);
if (planProjects.containsKey(testPlanApiCase.getTestPlanId())) { if (planProjects.containsKey(testPlanApiCase.getTestPlanId())) {
report.setProjectId(planProjects.get(testPlanApiCase.getTestPlanId())); report.setProjectId(planProjects.get(testPlanApiCase.getTestPlanId()));
} else { } else {
@ -106,7 +121,7 @@ public class ApiCaseExecuteService {
} }
executeQueue.put(testPlanApiCase.getId(), report); executeQueue.put(testPlanApiCase.getId(), report);
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode())); responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
}); }
apiCaseResultService.batchSave(executeQueue); apiCaseResultService.batchSave(executeQueue);

View File

@ -5,14 +5,18 @@ 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.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.TestResource;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.RunModeConfigDTO; import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.vo.BooleanPool;
import org.apache.commons.collections4.MapUtils; import org.apache.commons.collections4.MapUtils;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
@ -23,11 +27,16 @@ public class ApiCaseParallelExecuteService {
private JMeterService jMeterService; private JMeterService jMeterService;
public void parallel(Map<String, ApiDefinitionExecResult> executeQueue, RunModeConfigDTO config, DBTestQueue executionQueue, String runMode) { public void parallel(Map<String, ApiDefinitionExecResult> executeQueue, RunModeConfigDTO config, DBTestQueue executionQueue, String runMode) {
List<TestResource> resources = new ArrayList<>();
BooleanPool pool = GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId());
if (pool.isPool()) {
resources = GenerateHashTreeUtil.setPoolResource(config.getResourcePoolId());
}
for (String testId : executeQueue.keySet()) { for (String testId : executeQueue.keySet()) {
ApiDefinitionExecResult result = executeQueue.get(testId); ApiDefinitionExecResult result = executeQueue.get(testId);
String reportId = result.getId(); String reportId = result.getId();
HashTree hashTree = null; JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, null);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId())); runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
runRequest.setTestPlanReportId(executionQueue.getReportId()); runRequest.setTestPlanReportId(executionQueue.getReportId());
runRequest.setPoolId(config.getResourcePoolId()); runRequest.setPoolId(config.getResourcePoolId());
@ -37,11 +46,11 @@ public class ApiCaseParallelExecuteService {
if (MapUtils.isNotEmpty(executionQueue.getDetailMap())) { if (MapUtils.isNotEmpty(executionQueue.getDetailMap())) {
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(result.getId())); runRequest.setPlatformUrl(executionQueue.getDetailMap().get(result.getId()));
} }
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) { if (!pool.isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest); HashTree hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
runRequest.setHashTree(hashTree); runRequest.setHashTree(hashTree);
} }
jMeterService.run(runRequest); jMeterService.run(runRequest, resources);
} }
} }
} }

View File

@ -3,7 +3,6 @@ package io.metersphere.api.exec.api;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.RunCaseRequest; import io.metersphere.api.dto.definition.RunCaseRequest;
import io.metersphere.api.dto.definition.RunDefinitionRequest; import io.metersphere.api.dto.definition.RunDefinitionRequest;
@ -60,6 +59,8 @@ public class ApiExecuteService {
private TcpApiParamService tcpApiParamService; private TcpApiParamService tcpApiParamService;
@Resource @Resource
private ExtApiTestCaseMapper extApiTestCaseMapper; private ExtApiTestCaseMapper extApiTestCaseMapper;
@Resource
private ObjectMapper mapper;
public MsExecResponseDTO jenkinsRun(RunCaseRequest request) { public MsExecResponseDTO jenkinsRun(RunCaseRequest request) {
ApiTestCaseWithBLOBs caseWithBLOBs = null; ApiTestCaseWithBLOBs caseWithBLOBs = null;
@ -117,7 +118,7 @@ public class ApiExecuteService {
} }
// 调用执行方法 // 调用执行方法
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testCaseWithBLOBs.getId(), StringUtils.isEmpty(request.getReportId()) ? request.getId() : request.getReportId(), request.getRunMode(), jmeterHashTree); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testCaseWithBLOBs.getId(), StringUtils.isEmpty(request.getReportId()) ? request.getId() : request.getReportId(), request.getRunMode(), jmeterHashTree);
jMeterService.run(runRequest); jMeterService.run(runRequest, new ArrayList<>());
} catch (Exception ex) { } catch (Exception ex) {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId()); ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId());
if (result != null) { if (result != null) {
@ -186,13 +187,11 @@ public class ApiExecuteService {
this.put("SYN_RES", request.isSyncResult()); this.put("SYN_RES", request.isSyncResult());
}}); }});
// 开始执行 // 开始执行
jMeterService.run(runRequest); jMeterService.run(runRequest, new ArrayList<>());
return new MsExecResponseDTO(runRequest.getTestId(), runRequest.getReportId(), runMode); return new MsExecResponseDTO(runRequest.getTestId(), runRequest.getReportId(), runMode);
} }
public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception { public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JSONObject elementObj = JSON.parseObject(testCaseWithBLOBs.getRequest()); JSONObject elementObj = JSON.parseObject(testCaseWithBLOBs.getRequest());
ElementUtil.dataFormatting(elementObj); ElementUtil.dataFormatting(elementObj);

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.EnvironmentType; import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.ScenarioEnv; import io.metersphere.api.dto.ScenarioEnv;
@ -55,6 +54,8 @@ public class ApiScenarioEnvService {
private ApiTestEnvironmentMapper apiTestEnvironmentMapper; private ApiTestEnvironmentMapper apiTestEnvironmentMapper;
@Resource @Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper; private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
private ObjectMapper mapper;
public ScenarioEnv getApiScenarioEnv(String definition) { public ScenarioEnv getApiScenarioEnv(String definition) {
ScenarioEnv env = new ScenarioEnv(); ScenarioEnv env = new ScenarioEnv();
@ -138,8 +139,6 @@ public class ApiScenarioEnvService {
private void getHashTree(List<MsTestElement> tree, ScenarioEnv env) { private void getHashTree(List<MsTestElement> tree, ScenarioEnv env) {
try { try {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
for (int i = 0; i < tree.size(); i++) { for (int i = 0; i < tree.size(); i++) {
MsTestElement tr = tree.get(i); MsTestElement tr = tree.get(i);
if (!tr.isEnable()) { if (!tr.isEnable()) {

View File

@ -369,7 +369,7 @@ public class ApiScenarioExecuteService {
// 调用执行方法 // 调用执行方法
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree);
runRequest.setDebug(true); runRequest.setDebug(true);
jMeterService.run(runRequest); jMeterService.run(runRequest, new ArrayList<>());
return request.getId(); return request.getId();
} }

View File

@ -6,13 +6,17 @@ import io.metersphere.api.dto.automation.RunScenarioRequest;
import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.queue.DBTestQueue;
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.base.domain.TestResource;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import io.metersphere.vo.BooleanPool;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
@ -21,15 +25,20 @@ public class ApiScenarioParallelService {
private JMeterService jMeterService; private JMeterService jMeterService;
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) { public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) {
List<TestResource> resources = new ArrayList<>();
BooleanPool pool = GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId());
if (pool.isPool()) {
resources = GenerateHashTreeUtil.setPoolResource(request.getConfig().getResourcePoolId());
}
for (String reportId : executeQueue.keySet()) { for (String reportId : executeQueue.keySet()) {
RunModeDataDTO dataDTO = executeQueue.get(reportId); RunModeDataDTO dataDTO = executeQueue.get(reportId);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null);
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString()); runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
runRequest.setQueueId(executionQueue.getId()); runRequest.setQueueId(executionQueue.getId());
if (request.getConfig() != null) {
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId())); runRequest.setPool(pool);
runRequest.setPoolId(request.getConfig().getResourcePoolId()); runRequest.setPoolId(request.getConfig().getResourcePoolId());
}
runRequest.setTestPlanReportId(request.getTestPlanReportId()); runRequest.setTestPlanReportId(request.getTestPlanReportId());
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId)); runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId));
runRequest.setRunType(RunModeConstants.PARALLEL.toString()); runRequest.setRunType(RunModeConstants.PARALLEL.toString());
@ -40,7 +49,7 @@ public class ApiScenarioParallelService {
if (request.getConfig() != null && !runRequest.getPool().isPool()) { if (request.getConfig() != null && !runRequest.getPool().isPool()) {
runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest)); runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest));
} }
jMeterService.run(runRequest); jMeterService.run(runRequest, resources);
} }
} }
} }

View File

@ -3,7 +3,6 @@ package io.metersphere.api.exec.scenario;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.MsTestPlan;
@ -36,9 +35,7 @@ import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.LinkedHashMap; import java.util.*;
import java.util.LinkedList;
import java.util.Map;
@Service @Service
public class ApiScenarioSerialService { public class ApiScenarioSerialService {
@ -58,6 +55,8 @@ public class ApiScenarioSerialService {
private TestPlanApiScenarioMapper testPlanApiScenarioMapper; private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource @Resource
private ApiScenarioEnvService apiScenarioEnvService; private ApiScenarioEnvService apiScenarioEnvService;
@Resource
private ObjectMapper mapper;
public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) { public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) {
LoggerUtil.debug("Scenario run-执行脚本装载-进入串行准备"); LoggerUtil.debug("Scenario run-执行脚本装载-进入串行准备");
@ -126,8 +125,13 @@ public class ApiScenarioSerialService {
if (queue != null) { if (queue != null) {
runRequest.setPlatformUrl(queue.getId()); runRequest.setPlatformUrl(queue.getId());
} }
List<TestResource> resources = new ArrayList<>();
if (runRequest.getPool().isPool()) {
resources = GenerateHashTreeUtil.setPoolResource(runRequest.getPoolId());
}
// 开始执行 // 开始执行
jMeterService.run(runRequest); jMeterService.run(runRequest, resources);
} catch (Exception e) { } catch (Exception e) {
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
remakeReportService.remake(runRequest); remakeReportService.remake(runRequest);
@ -188,8 +192,6 @@ public class ApiScenarioSerialService {
} }
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId, String envId) { private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId, String envId) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try { try {
String api = caseWithBLOBs.getRequest(); String api = caseWithBLOBs.getRequest();
JSONObject element = JSON.parseObject(api); JSONObject element = JSON.parseObject(api);

View File

@ -2,17 +2,16 @@ package io.metersphere.api.exec.utils;
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest; import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
import io.metersphere.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs; import io.metersphere.base.domain.ApiTestCase;
import io.metersphere.base.domain.TestPlanApiCase; import io.metersphere.base.domain.TestPlanApiCase;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTypeConstants; import io.metersphere.commons.constants.ReportTypeConstants;
import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.RunModeConfigDTO; import io.metersphere.dto.RunModeConfigDTO;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -41,23 +40,24 @@ public class ApiDefinitionExecResultUtil {
return apiResult; return apiResult;
} }
public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status) { public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status,
Map<String, ApiTestCase> caseMap, String poolId) {
ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult(); ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult();
apiResult.setId(UUID.randomUUID().toString()); apiResult.setId(UUID.randomUUID().toString());
apiResult.setCreateTime(System.currentTimeMillis()); apiResult.setCreateTime(System.currentTimeMillis());
apiResult.setStartTime(System.currentTimeMillis()); apiResult.setStartTime(System.currentTimeMillis());
apiResult.setEndTime(System.currentTimeMillis()); apiResult.setEndTime(System.currentTimeMillis());
apiResult.setReportType(ReportTypeConstants.API_INDEPENDENT.name()); apiResult.setReportType(ReportTypeConstants.API_INDEPENDENT.name());
ApiTestCaseWithBLOBs caseWithBLOBs = CommonBeanFactory.getBean(ApiTestCaseMapper.class).selectByPrimaryKey(key.getApiCaseId()); ApiTestCase testCase = caseMap.get(key.getApiCaseId());
if (caseWithBLOBs != null) { if (testCase != null) {
apiResult.setName(caseWithBLOBs.getName()); apiResult.setName(testCase.getName());
apiResult.setProjectId(caseWithBLOBs.getProjectId()); apiResult.setProjectId(testCase.getProjectId());
apiResult.setVersionId(caseWithBLOBs.getVersionId()); apiResult.setVersionId(testCase.getVersionId());
} }
apiResult.setTriggerMode(request.getTriggerMode()); apiResult.setTriggerMode(request.getTriggerMode());
apiResult.setActuator("LOCAL"); apiResult.setActuator("LOCAL");
if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) { if (StringUtils.isNotEmpty(poolId)) {
apiResult.setActuator(request.getConfig().getResourcePoolId()); apiResult.setActuator(poolId);
} }
if (StringUtils.isEmpty(request.getUserId())) { if (StringUtils.isEmpty(request.getUserId())) {
if (SessionUtils.getUser() != null) { if (SessionUtils.getUser() != null) {

View File

@ -14,6 +14,6 @@ public class FixedTask {
if (queueService == null) { if (queueService == null) {
queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class); queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class);
} }
queueService.timeOut(); queueService.defendQueue();
} }
} }

View File

@ -12,7 +12,9 @@ import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.config.JmeterProperties; import io.metersphere.config.JmeterProperties;
import io.metersphere.config.KafkaConfig; import io.metersphere.config.KafkaConfig;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.*; import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.NodeDTO;
import io.metersphere.jmeter.JMeterBase; import io.metersphere.jmeter.JMeterBase;
import io.metersphere.jmeter.LocalRunner; import io.metersphere.jmeter.LocalRunner;
import io.metersphere.performance.engine.Engine; import io.metersphere.performance.engine.Engine;
@ -112,7 +114,7 @@ public class JMeterService {
runner.run(request.getReportId()); runner.run(request.getReportId());
} }
private void runNode(JmeterRunRequestDTO request) { private void runNode(JmeterRunRequestDTO request, List<TestResource> resources) {
// 获取可以执行的资源池 // 获取可以执行的资源池
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo(); BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
// 占位符 // 占位符
@ -145,13 +147,15 @@ public class JMeterService {
MSException.throwException(e.getMessage()); MSException.throwException(e.getMessage());
} }
} else { } else {
this.send(request); this.send(request, resources);
} }
} }
private void send(JmeterRunRequestDTO request) { private void send(JmeterRunRequestDTO request, List<TestResource> resources) {
try { try {
List<TestResource> resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId()); if (StringUtils.isNotEmpty(request.getPoolId()) && CollectionUtils.isEmpty(resources)) {
resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId());
}
if (CollectionUtils.isEmpty(resources)) { if (CollectionUtils.isEmpty(resources)) {
LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】"); LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】");
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
@ -186,9 +190,9 @@ public class JMeterService {
} }
public void run(JmeterRunRequestDTO request) { public void run(JmeterRunRequestDTO request, List<TestResource> resources) {
if (request.getPool().isPool()) { if (request.getPool().isPool()) {
this.runNode(request); this.runNode(request, resources);
} else { } else {
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request); CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
} }

View File

@ -1,10 +1,8 @@
package io.metersphere.api.jmeter; package io.metersphere.api.jmeter;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil; import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.service.ApiEnvironmentRunningParamService;
import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.TestResultService; import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
@ -12,6 +10,7 @@ import io.metersphere.config.KafkaConfig;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -26,6 +25,10 @@ public class MsKafkaListener {
public static final String CONSUME_ID = "ms-api-exec-consume"; public static final String CONSUME_ID = "ms-api-exec-consume";
@Resource @Resource
private ApiExecutionQueueService apiExecutionQueueService; private ApiExecutionQueueService apiExecutionQueueService;
@Resource
private TestResultService testResultService;
@Resource
private ObjectMapper mapper;
private static final Map<String, String> RUN_MODE_MAP = new HashMap<String, String>() {{ private static final Map<String, String> RUN_MODE_MAP = new HashMap<String, String>() {{
this.put(ApiRunMode.SCHEDULE_API_PLAN.name(), "schedule-task"); this.put(ApiRunMode.SCHEDULE_API_PLAN.name(), "schedule-task");
@ -72,7 +75,7 @@ public class MsKafkaListener {
} }
} }
}); });
if (!assortMap.isEmpty()) { if (MapUtils.isNotEmpty(assortMap)) {
testResultService.batchSaveResults(assortMap); testResultService.batchSaveResults(assortMap);
LoggerUtil.info("KAFKA消费执行内容存储结束"); LoggerUtil.info("KAFKA消费执行内容存储结束");
} }
@ -99,26 +102,12 @@ public class MsKafkaListener {
} }
} }
@Resource
private TestResultService testResultService;
@Resource
private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService;
private ResultDTO formatResult(String result) { private ResultDTO formatResult(String result) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try { try {
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取 // 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (StringUtils.isNotEmpty(result)) { if (StringUtils.isNotEmpty(result)) {
ResultDTO element = mapper.readValue(result, new TypeReference<ResultDTO>() { return mapper.readValue(result, new TypeReference<ResultDTO>() {
}); });
if (StringUtils.isNotEmpty(element.getRunningDebugSampler())) {
String evnStr = element.getRunningDebugSampler();
apiEnvironmentRunningParamService.parseEvn(evnStr);
}
LoggerUtil.info("formatResult 完成:" + element.getReportId());
return element;
} }
} catch (Exception e) { } catch (Exception e) {
LoggerUtil.error("formatResult 格式化数据失败:", e); LoggerUtil.error("formatResult 格式化数据失败:", e);

View File

@ -296,7 +296,7 @@ public class ApiExecutionQueueService {
LoggerUtil.info("处理队列结束:" + dto.getReportId() + "QID" + dto.getQueueId()); LoggerUtil.info("处理队列结束:" + dto.getReportId() + "QID" + dto.getQueueId());
} }
public void timeOut() { public void defendQueue() {
final int SECOND_MILLIS = 1000; final int SECOND_MILLIS = 1000;
final int MINUTE_MILLIS = 60 * SECOND_MILLIS; final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
// 计算一小时前的超时报告 // 计算一小时前的超时报告

View File

@ -3,7 +3,6 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.ApiCaseEditRequest; import io.metersphere.api.dto.ApiCaseEditRequest;
import io.metersphere.api.dto.DeleteCheckResult; import io.metersphere.api.dto.DeleteCheckResult;
@ -102,6 +101,8 @@ public class ApiTestCaseService {
private ExtProjectVersionMapper extProjectVersionMapper; private ExtProjectVersionMapper extProjectVersionMapper;
@Resource @Resource
private TcpApiParamService tcpApiParamService; private TcpApiParamService tcpApiParamService;
@Resource
private ObjectMapper mapper;
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR; private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
@ -734,8 +735,6 @@ public class ApiTestCaseService {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class); ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
bloBs.forEach(apiTestCase -> { bloBs.forEach(apiTestCase -> {
MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class); MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class);
try { try {

View File

@ -1,5 +1,7 @@
package io.metersphere.config; package io.metersphere.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import org.apache.http.NoHttpResponseException; import org.apache.http.NoHttpResponseException;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectTimeoutException;
@ -28,6 +30,13 @@ public class WebConfig implements WebMvcConfigurer {
return getTimeOutTemplate(4000, 4000, 10 * 1000); return getTimeOutTemplate(4000, 4000, 10 * 1000);
} }
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
private RestTemplate getTimeOutTemplate(int requestTimeout, int connectTimeout, int readTimeout) { private RestTemplate getTimeOutTemplate(int requestTimeout, int connectTimeout, int readTimeout) {
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory httpRequestFactory = HttpComponentsClientHttpRequestFactory httpRequestFactory =

View File

@ -289,10 +289,10 @@ public class TestPlanApiCaseService {
String envGroupId = config.getEnvironmentGroupId(); String envGroupId = config.getEnvironmentGroupId();
Map<String, String> envMap = config.getEnvMap(); Map<String, String> envMap = config.getEnvMap();
if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty())) { if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty())) {
setApiCaseEnv(request.getPlanIds(), envMap); setApiCaseEnv(null, request.getPlanIds(), envMap);
} else if ((StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) { } else if ((StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) {
Map<String, String> map = environmentGroupProjectService.getEnvMap(envGroupId); Map<String, String> map = environmentGroupProjectService.getEnvMap(envGroupId);
setApiCaseEnv(request.getPlanIds(), map); setApiCaseEnv(null, request.getPlanIds(), map);
} }
} }
return testPlanApiCaseExecuteService.run(request); return testPlanApiCaseExecuteService.run(request);
@ -300,14 +300,16 @@ public class TestPlanApiCaseService {
return null; return null;
} }
public void setApiCaseEnv(List<String> planIds, Map<String, String> map) { public void setApiCaseEnv(List<TestPlanApiCase> testPlanApiCases, List<String> planIds, Map<String, String> map) {
if (CollectionUtils.isEmpty(planIds) || (map != null && map.isEmpty())) { if (CollectionUtils.isEmpty(planIds) || (map != null && map.isEmpty())) {
return; return;
} }
if (CollectionUtils.isEmpty(testPlanApiCases)) {
TestPlanApiCaseExample caseExample = new TestPlanApiCaseExample(); TestPlanApiCaseExample caseExample = new TestPlanApiCaseExample();
caseExample.createCriteria().andIdIn(planIds); caseExample.createCriteria().andIdIn(planIds);
List<TestPlanApiCase> testPlanApiCases = testPlanApiCaseMapper.selectByExample(caseExample); testPlanApiCases = testPlanApiCaseMapper.selectByExample(caseExample);
}
List<String> apiCaseIds = testPlanApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList()); List<String> apiCaseIds = testPlanApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(apiCaseIds)) { if (CollectionUtils.isEmpty(apiCaseIds)) {
return; return;
@ -326,7 +328,7 @@ public class TestPlanApiCaseService {
String caseId = testPlanApiCase.getApiCaseId(); String caseId = testPlanApiCase.getApiCaseId();
String projectId = projectCaseIdMap.get(caseId); String projectId = projectCaseIdMap.get(caseId);
String envId = map.get(projectId); String envId = map.get(projectId);
if (StringUtils.isNotBlank(envId)) { if (StringUtils.isNotBlank(envId) && !StringUtils.equals(testPlanApiCase.getEnvironmentId(), envId)) {
testPlanApiCase.setEnvironmentId(envId); testPlanApiCase.setEnvironmentId(envId);
mapper.updateByPrimaryKey(testPlanApiCase); mapper.updateByPrimaryKey(testPlanApiCase);
} }

View File

@ -188,7 +188,7 @@ public class TestPlanScenarioCaseService {
if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty()) if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty())
|| (StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) { || (StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) {
// 更新场景用例环境信息运行时从数据库读取最新环境 // 更新场景用例环境信息运行时从数据库读取最新环境
this.setScenarioEnv(planCaseIdList, testPlanScenarioRequest.getConfig()); this.setScenarioEnv(new ArrayList<>(), planCaseIdList, testPlanScenarioRequest.getConfig());
} }
} }
planCaseIdList.forEach(item -> { planCaseIdList.forEach(item -> {
@ -218,12 +218,19 @@ public class TestPlanScenarioCaseService {
return apiAutomationService.run(request); return apiAutomationService.run(request);
} }
public void setScenarioEnv(List<String> planScenarioIds, RunModeConfigDTO runModeConfig) { public void setScenarioEnv(List<TestPlanApiScenario> testPlanApiScenarios, List<String> planScenarioIds, RunModeConfigDTO runModeConfig) {
if (CollectionUtils.isEmpty(planScenarioIds)) return; if (CollectionUtils.isEmpty(planScenarioIds)) return;
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
if (CollectionUtils.isEmpty(testPlanApiScenarios)) {
TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample(); TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample();
testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds); testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample); testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample);
}
if (CollectionUtils.isEmpty(planScenarioIds)) {
return;
}
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TestPlanApiScenarioMapper mapper = sqlSession.getMapper(TestPlanApiScenarioMapper.class); TestPlanApiScenarioMapper mapper = sqlSession.getMapper(TestPlanApiScenarioMapper.class);
String environmentType = runModeConfig.getEnvironmentType(); String environmentType = runModeConfig.getEnvironmentType();
@ -231,9 +238,6 @@ public class TestPlanScenarioCaseService {
if (StringUtils.equals(environmentType, EnvironmentType.JSON.toString())) { if (StringUtils.equals(environmentType, EnvironmentType.JSON.toString())) {
Map<String, String> envMap = runModeConfig.getEnvMap(); Map<String, String> envMap = runModeConfig.getEnvMap();
if (CollectionUtils.isEmpty(planScenarioIds)) {
return;
}
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) { for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
String env = testPlanApiScenario.getEnvironment(); String env = testPlanApiScenario.getEnvironment();
if (StringUtils.isBlank(env)) { if (StringUtils.isBlank(env)) {
@ -251,15 +255,17 @@ public class TestPlanScenarioCaseService {
map.put(s, envMap.get(s)); map.put(s, envMap.get(s));
} }
} }
String envJsonStr = JSON.toJSONString(map);
if (!StringUtils.equals(envJsonStr, testPlanApiScenario.getEnvironment())) {
testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString()); testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString());
testPlanApiScenario.setEnvironment(JSON.toJSONString(map)); testPlanApiScenario.setEnvironment(JSON.toJSONString(map));
mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario); mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario);
} }
}
sqlSession.flushStatements(); sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) { if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
} }
return;
} }
if (StringUtils.equals(environmentType, EnvironmentType.GROUP.toString())) { if (StringUtils.equals(environmentType, EnvironmentType.GROUP.toString())) {

View File

@ -1946,13 +1946,14 @@ public class TestPlanService {
envMap = environmentGroupProjectService.getEnvMap(environmentGroupId); envMap = environmentGroupProjectService.getEnvMap(environmentGroupId);
} }
testPlanApiCaseService.setApiCaseEnv(planApiCaseIds, envMap); testPlanApiCaseService.setApiCaseEnv(testPlanApiCases, planApiCaseIds, envMap);
TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample(); TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample();
scenarioExample.createCriteria().andTestPlanIdEqualTo(planId); scenarioExample.createCriteria().andTestPlanIdEqualTo(planId);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(scenarioExample);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(scenarioExample);
List<String> planScenarioIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getId).collect(Collectors.toList()); List<String> planScenarioIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getId).collect(Collectors.toList());
testPlanScenarioCaseService.setScenarioEnv(planScenarioIds, runModeConfig); testPlanScenarioCaseService.setScenarioEnv(testPlanApiScenarios, planScenarioIds, runModeConfig);
} }
public void editReportConfig(TestPlanDTO testPlanDTO) { public void editReportConfig(TestPlanDTO testPlanDTO) {