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

This commit is contained in:
fit2-zhao 2022-04-06 14:23:55 +08:00 committed by 刘瑞斌
parent 840f7c5b99
commit a70ba9aa58
17 changed files with 145 additions and 102 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.scenario.ApiScenarioSerialService;
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.ApiExecutionQueueService;
import io.metersphere.api.service.ApiScenarioReportStructureService;
@ -40,6 +41,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ApiCaseExecuteService {
@ -60,7 +62,7 @@ public class ApiCaseExecuteService {
@Resource
private ApiCaseResultService apiCaseResultService;
@Resource
ApiScenarioReportStructureService apiScenarioReportStructureService;
private ApiScenarioReportStructureService apiScenarioReportStructureService;
/**
* 测试计划case执行
@ -92,9 +94,22 @@ public class ApiCaseExecuteService {
Map<String, ApiDefinitionExecResult> executeQueue = new LinkedHashMap<>();
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
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<>();
planApiCases.forEach(testPlanApiCase -> {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status);
for (TestPlanApiCase testPlanApiCase : planApiCases) {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, caseMap, resourcePoolId);
if (planProjects.containsKey(testPlanApiCase.getTestPlanId())) {
report.setProjectId(planProjects.get(testPlanApiCase.getTestPlanId()));
} else {
@ -106,7 +121,7 @@ public class ApiCaseExecuteService {
}
executeQueue.put(testPlanApiCase.getId(), report);
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
});
}
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.jmeter.JMeterService;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.TestResource;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.vo.BooleanPool;
import org.apache.commons.collections4.MapUtils;
import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@ -23,11 +27,16 @@ public class ApiCaseParallelExecuteService {
private JMeterService jMeterService;
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()) {
ApiDefinitionExecResult result = executeQueue.get(testId);
String reportId = result.getId();
HashTree hashTree = null;
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, null);
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
runRequest.setTestPlanReportId(executionQueue.getReportId());
runRequest.setPoolId(config.getResourcePoolId());
@ -37,11 +46,11 @@ public class ApiCaseParallelExecuteService {
if (MapUtils.isNotEmpty(executionQueue.getDetailMap())) {
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(result.getId()));
}
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
if (!pool.isPool()) {
HashTree hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
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.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.RunCaseRequest;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
@ -60,6 +59,8 @@ public class ApiExecuteService {
private TcpApiParamService tcpApiParamService;
@Resource
private ExtApiTestCaseMapper extApiTestCaseMapper;
@Resource
private ObjectMapper mapper;
public MsExecResponseDTO jenkinsRun(RunCaseRequest request) {
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);
jMeterService.run(runRequest);
jMeterService.run(runRequest, new ArrayList<>());
} catch (Exception ex) {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId());
if (result != null) {
@ -186,13 +187,11 @@ public class ApiExecuteService {
this.put("SYN_RES", request.isSyncResult());
}});
// 开始执行
jMeterService.run(runRequest);
jMeterService.run(runRequest, new ArrayList<>());
return new MsExecResponseDTO(runRequest.getTestId(), runRequest.getReportId(), runMode);
}
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());
ElementUtil.dataFormatting(elementObj);

View File

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

View File

@ -369,7 +369,7 @@ public class ApiScenarioExecuteService {
// 调用执行方法
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree);
runRequest.setDebug(true);
jMeterService.run(runRequest);
jMeterService.run(runRequest, new ArrayList<>());
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.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.base.domain.TestResource;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.utils.LoggerUtil;
import io.metersphere.vo.BooleanPool;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@ -21,15 +25,20 @@ public class ApiScenarioParallelService {
private JMeterService jMeterService;
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()) {
RunModeDataDTO dataDTO = executeQueue.get(reportId);
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.setQueueId(executionQueue.getId());
if (request.getConfig() != null) {
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
runRequest.setPoolId(request.getConfig().getResourcePoolId());
}
runRequest.setPool(pool);
runRequest.setPoolId(request.getConfig().getResourcePoolId());
runRequest.setTestPlanReportId(request.getTestPlanReportId());
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId));
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
@ -40,7 +49,7 @@ public class ApiScenarioParallelService {
if (request.getConfig() != null && !runRequest.getPool().isPool()) {
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.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.MsTestPlan;
@ -36,9 +35,7 @@ import org.apache.jorphan.collections.HashTree;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.*;
@Service
public class ApiScenarioSerialService {
@ -58,6 +55,8 @@ public class ApiScenarioSerialService {
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
private ApiScenarioEnvService apiScenarioEnvService;
@Resource
private ObjectMapper mapper;
public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) {
LoggerUtil.debug("Scenario run-执行脚本装载-进入串行准备");
@ -126,8 +125,13 @@ public class ApiScenarioSerialService {
if (queue != null) {
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) {
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
remakeReportService.remake(runRequest);
@ -188,8 +192,6 @@ public class ApiScenarioSerialService {
}
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId, String envId) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
String api = caseWithBLOBs.getRequest();
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.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.mapper.ApiTestCaseMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTypeConstants;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.RunModeConfigDTO;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
@ -41,23 +40,24 @@ public class ApiDefinitionExecResultUtil {
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();
apiResult.setId(UUID.randomUUID().toString());
apiResult.setCreateTime(System.currentTimeMillis());
apiResult.setStartTime(System.currentTimeMillis());
apiResult.setEndTime(System.currentTimeMillis());
apiResult.setReportType(ReportTypeConstants.API_INDEPENDENT.name());
ApiTestCaseWithBLOBs caseWithBLOBs = CommonBeanFactory.getBean(ApiTestCaseMapper.class).selectByPrimaryKey(key.getApiCaseId());
if (caseWithBLOBs != null) {
apiResult.setName(caseWithBLOBs.getName());
apiResult.setProjectId(caseWithBLOBs.getProjectId());
apiResult.setVersionId(caseWithBLOBs.getVersionId());
ApiTestCase testCase = caseMap.get(key.getApiCaseId());
if (testCase != null) {
apiResult.setName(testCase.getName());
apiResult.setProjectId(testCase.getProjectId());
apiResult.setVersionId(testCase.getVersionId());
}
apiResult.setTriggerMode(request.getTriggerMode());
apiResult.setActuator("LOCAL");
if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) {
apiResult.setActuator(request.getConfig().getResourcePoolId());
if (StringUtils.isNotEmpty(poolId)) {
apiResult.setActuator(poolId);
}
if (StringUtils.isEmpty(request.getUserId())) {
if (SessionUtils.getUser() != null) {

View File

@ -14,6 +14,6 @@ public class FixedTask {
if (queueService == null) {
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.KafkaConfig;
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.LocalRunner;
import io.metersphere.performance.engine.Engine;
@ -112,7 +114,7 @@ public class JMeterService {
runner.run(request.getReportId());
}
private void runNode(JmeterRunRequestDTO request) {
private void runNode(JmeterRunRequestDTO request, List<TestResource> resources) {
// 获取可以执行的资源池
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
// 占位符
@ -145,13 +147,15 @@ public class JMeterService {
MSException.throwException(e.getMessage());
}
} else {
this.send(request);
this.send(request, resources);
}
}
private void send(JmeterRunRequestDTO request) {
private void send(JmeterRunRequestDTO request, List<TestResource> resources) {
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)) {
LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】");
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()) {
this.runNode(request);
this.runNode(request, resources);
} else {
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
}

View File

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

View File

@ -296,7 +296,7 @@ public class ApiExecutionQueueService {
LoggerUtil.info("处理队列结束:" + dto.getReportId() + "QID" + dto.getQueueId());
}
public void timeOut() {
public void defendQueue() {
final int SECOND_MILLIS = 1000;
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.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.ApiCaseEditRequest;
import io.metersphere.api.dto.DeleteCheckResult;
@ -102,6 +101,8 @@ public class ApiTestCaseService {
private ExtProjectVersionMapper extProjectVersionMapper;
@Resource
private TcpApiParamService tcpApiParamService;
@Resource
private ObjectMapper mapper;
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
@ -725,8 +726,6 @@ public class ApiTestCaseService {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
bloBs.forEach(apiTestCase -> {
MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class);
try {

View File

@ -1,5 +1,7 @@
package io.metersphere.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.commons.utils.LogUtil;
import org.apache.http.NoHttpResponseException;
import org.apache.http.conn.ConnectTimeoutException;
@ -28,6 +30,13 @@ public class WebConfig implements WebMvcConfigurer {
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) {
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory httpRequestFactory =

View File

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

View File

@ -191,7 +191,7 @@ public class TestPlanScenarioCaseService {
if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty())
|| (StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) {
// 更新场景用例环境信息运行时从数据库读取最新环境
this.setScenarioEnv(planCaseIdList, testPlanScenarioRequest.getConfig());
this.setScenarioEnv(new ArrayList<>(), planCaseIdList, testPlanScenarioRequest.getConfig());
}
}
planCaseIdList.forEach(item -> {
@ -221,12 +221,19 @@ public class TestPlanScenarioCaseService {
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(testPlanApiScenarios)) {
TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample();
testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds);
testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample);
}
if (CollectionUtils.isEmpty(planScenarioIds)) {
return;
}
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample();
testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample);
TestPlanApiScenarioMapper mapper = sqlSession.getMapper(TestPlanApiScenarioMapper.class);
String environmentType = runModeConfig.getEnvironmentType();
@ -234,9 +241,6 @@ public class TestPlanScenarioCaseService {
if (StringUtils.equals(environmentType, EnvironmentType.JSON.toString())) {
Map<String, String> envMap = runModeConfig.getEnvMap();
if (CollectionUtils.isEmpty(planScenarioIds)) {
return;
}
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
String env = testPlanApiScenario.getEnvironment();
if (StringUtils.isBlank(env)) {
@ -254,15 +258,17 @@ public class TestPlanScenarioCaseService {
map.put(s, envMap.get(s));
}
}
testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString());
testPlanApiScenario.setEnvironment(JSON.toJSONString(map));
mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario);
String envJsonStr = JSON.toJSONString(map);
if (!StringUtils.equals(envJsonStr, testPlanApiScenario.getEnvironment())) {
testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString());
testPlanApiScenario.setEnvironment(JSON.toJSONString(map));
mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario);
}
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
return;
}
if (StringUtils.equals(environmentType, EnvironmentType.GROUP.toString())) {
@ -472,7 +478,7 @@ public class TestPlanScenarioCaseService {
private int getUnderwayStepsCounts(List<String> underwayIds) {
if (CollectionUtils.isNotEmpty(underwayIds)) {
List<Integer> underwayStepsCounts = extTestPlanScenarioCaseMapper.getUnderwaySteps(underwayIds);
return underwayStepsCounts.stream().filter(Objects::nonNull).reduce(0,Integer::sum);
return underwayStepsCounts.stream().filter(Objects::nonNull).reduce(0, Integer::sum);
}
return 0;
}

View File

@ -429,7 +429,7 @@ public class TestPlanService {
request.setProjectId(request.getProjectId());
}
List<TestPlanDTOWithMetric> testPlans = extTestPlanMapper.list(request);
if(testPlans.size()==0){
if (testPlans.size() == 0) {
return new ArrayList<>();
}
Set<String> ids = testPlans.stream().map(TestPlan::getId).collect(Collectors.toSet());
@ -443,7 +443,7 @@ public class TestPlanService {
Map<String, ParamsDTO> stringParamsDTOMap = testPlanReportMapper.reportCount(ids);
testPlans.forEach(item -> {
item.setExecutionTimes(stringParamsDTOMap.get(item.getId()) == null ? 0 : Integer.parseInt(stringParamsDTOMap.get(item.getId()).getValue() == null ? "0" : stringParamsDTOMap.get(item.getId()).getValue()));
item.setExecutionTimes(stringParamsDTOMap.get(item.getId()) == null ? 0 : Integer.parseInt(stringParamsDTOMap.get(item.getId()).getValue() == null ? "0" : stringParamsDTOMap.get(item.getId()).getValue()));
if (StringUtils.isNotBlank(item.getScheduleId())) {
if (item.isScheduleOpen()) {
item.setScheduleStatus(ScheduleStatus.OPEN.name());
@ -456,10 +456,10 @@ public class TestPlanService {
} else {
item.setScheduleStatus(ScheduleStatus.NOTSET.name());
}
item.setTestPlanTestCaseCount(planTestCaseCountMap.get(item.getId()) == null ? 0 : Integer.parseInt(planTestCaseCountMap.get(item.getId()).getValue() == null ? "0" : planTestCaseCountMap.get(item.getId()).getValue()));
item.setTestPlanApiCaseCount(planApiCaseMap.get(item.getId()) == null ? 0 : Integer.parseInt(planApiCaseMap.get(item.getId()).getValue() == null ? "0" : planApiCaseMap.get(item.getId()).getValue()));
item.setTestPlanApiScenarioCount(planApiScenarioMap.get(item.getId()) == null? 0 : Integer.parseInt(planApiScenarioMap.get(item.getId()).getValue() == null ? "0" : planApiScenarioMap.get(item.getId()).getValue()));
item.setTestPlanLoadCaseCount(planLoadCaseMap.get(item.getId()) == null ? 0 : Integer.parseInt(planLoadCaseMap.get(item.getId()).getValue() == null ? "0" : planLoadCaseMap.get(item.getId()).getValue()));
item.setTestPlanTestCaseCount(planTestCaseCountMap.get(item.getId()) == null ? 0 : Integer.parseInt(planTestCaseCountMap.get(item.getId()).getValue() == null ? "0" : planTestCaseCountMap.get(item.getId()).getValue()));
item.setTestPlanApiCaseCount(planApiCaseMap.get(item.getId()) == null ? 0 : Integer.parseInt(planApiCaseMap.get(item.getId()).getValue() == null ? "0" : planApiCaseMap.get(item.getId()).getValue()));
item.setTestPlanApiScenarioCount(planApiScenarioMap.get(item.getId()) == null ? 0 : Integer.parseInt(planApiScenarioMap.get(item.getId()).getValue() == null ? "0" : planApiScenarioMap.get(item.getId()).getValue()));
item.setTestPlanLoadCaseCount(planLoadCaseMap.get(item.getId()) == null ? 0 : Integer.parseInt(planLoadCaseMap.get(item.getId()).getValue() == null ? "0" : planLoadCaseMap.get(item.getId()).getValue()));
});
calcTestPlanRate(testPlans);
return testPlans;
@ -1617,7 +1617,7 @@ public class TestPlanService {
failureScenarios.add(scenario);
} else if (StringUtils.equalsIgnoreCase(scenario.getLastResult(), ExecuteResult.errorReportResult.name())) {
errorReportScenarios.add(scenario);
} else if (StringUtils.equalsAnyIgnoreCase(scenario.getLastResult(), "stop","unexecute")) {
} else if (StringUtils.equalsAnyIgnoreCase(scenario.getLastResult(), "stop", "unexecute")) {
unExecuteScenarios.add(scenario);
}
}
@ -1643,7 +1643,7 @@ public class TestPlanService {
apiFailureCases.add(apiDTO);
} else if (StringUtils.equalsIgnoreCase(apiDTO.getExecResult(), ExecuteResult.errorReportResult.name())) {
apiErrorReportCases.add(apiDTO);
} else if (StringUtils.equalsAnyIgnoreCase(apiDTO.getExecResult(), "stop","unexecute")) {
} else if (StringUtils.equalsAnyIgnoreCase(apiDTO.getExecResult(), "stop", "unexecute")) {
apiUnExecuteCases.add(apiDTO);
}
}
@ -1932,13 +1932,14 @@ public class TestPlanService {
envMap = environmentGroupProjectService.getEnvMap(environmentGroupId);
}
testPlanApiCaseService.setApiCaseEnv(planApiCaseIds, envMap);
testPlanApiCaseService.setApiCaseEnv(testPlanApiCases, planApiCaseIds, envMap);
TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample();
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());
testPlanScenarioCaseService.setScenarioEnv(planScenarioIds, runModeConfig);
testPlanScenarioCaseService.setScenarioEnv(testPlanApiScenarios, planScenarioIds, runModeConfig);
}
public void editReportConfig(TestPlanDTO testPlanDTO) {