fix(接口测试): 禁用接口执行调用自身引发死循环问题
--bug=1019430 --user=赵勇 【接口测试】接口测试中调用接口执行请求传入当前用例、场景ID导致递归调用 https://www.tapd.cn/55049933/s/1295542
This commit is contained in:
parent
3299ea2c44
commit
e9119a7472
|
@ -10,28 +10,24 @@ import io.metersphere.api.dto.scenario.DatabaseConfig;
|
|||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.service.definition.ApiCaseResultService;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.utils.ApiDefinitionExecResultUtil;
|
||||
import io.metersphere.commons.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.environment.service.BaseEnvGroupProjectService;
|
||||
import io.metersphere.environment.service.BaseEnvironmentService;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.ServiceUtils;
|
||||
import io.metersphere.service.definition.ApiCaseResultService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.beanutils.BeanComparator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -288,6 +284,8 @@ public class ApiCaseExecuteService {
|
|||
|
||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||
List<ApiTestCaseWithBLOBs> caseList = extApiTestCaseMapper.unTrashCaseListByIds(request.getIds());
|
||||
// 检查执行内容合规性
|
||||
PerformInspectionUtil.caseInspection(caseList);
|
||||
|
||||
LoggerUtil.debug("查询到执行数据:" + caseList.size());
|
||||
Map<String, List<String>> testCaseEnvMap = new HashMap<>();
|
||||
|
|
|
@ -119,6 +119,7 @@ public class ApiExecuteService {
|
|||
|
||||
public MsExecResponseDTO exec(RunCaseRequest request, Map<String, Object> extendedParameters) {
|
||||
ApiTestCaseWithBLOBs testCaseWithBLOBs = request.getBloBs();
|
||||
PerformInspectionUtil.countMatches(testCaseWithBLOBs.getRequest(), testCaseWithBLOBs.getId());
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
testCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getReportId());
|
||||
request.setCaseId(request.getReportId());
|
||||
|
@ -232,9 +233,10 @@ public class ApiExecuteService {
|
|||
// 加载自定义JAR
|
||||
NewDriverManager.loadJar(request);
|
||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("生成执行JMX内容【 " + request.getTestElement().getJmx(hashTree) + " 】");
|
||||
}
|
||||
String jmx = request.getTestElement().getJmx(hashTree);
|
||||
LoggerUtil.info("生成执行JMX内容【 " + jmx + " 】");
|
||||
// 检查执行内容合规性
|
||||
PerformInspectionUtil.inspection(jmx, testId, 4);
|
||||
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, request.getId(), runMode, hashTree);
|
||||
runRequest.setDebug(request.isDebug());
|
||||
|
@ -255,6 +257,7 @@ public class ApiExecuteService {
|
|||
}
|
||||
|
||||
public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception {
|
||||
PerformInspectionUtil.countMatches(testCaseWithBLOBs.getRequest(), testCaseWithBLOBs.getId());
|
||||
JSONObject elementObj = JSONUtil.parseObject(testCaseWithBLOBs.getRequest());
|
||||
ElementUtil.dataFormatting(elementObj);
|
||||
|
||||
|
|
|
@ -7,44 +7,36 @@ import io.metersphere.api.dto.automation.ApiScenarioReportResult;
|
|||
import io.metersphere.api.dto.automation.ExecuteType;
|
||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.MsTestPlan;
|
||||
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||
import io.metersphere.api.exec.api.ApiCaseExecuteService;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.NewDriverManager;
|
||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
import io.metersphere.service.definition.TcpApiParamService;
|
||||
import io.metersphere.base.domain.ApiScenario;
|
||||
import io.metersphere.base.domain.ApiScenarioExample;
|
||||
import io.metersphere.base.domain.ApiScenarioReportWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.plan.ext.ExtTestPlanScenarioCaseMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.environment.service.BaseEnvGroupProjectService;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.ServiceUtils;
|
||||
import io.metersphere.commons.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.service.definition.TcpApiParamService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.beanutils.BeanComparator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -58,14 +50,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -128,6 +113,8 @@ public class ApiScenarioExecuteService {
|
|||
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
|
||||
MSException.throwException((apiScenarios.get(0).getName() + "," + Translator.get("automation_exec_info")));
|
||||
}
|
||||
// 检查执行内容合规性
|
||||
PerformInspectionUtil.scenarioInspection(apiScenarios);
|
||||
// 环境检查
|
||||
LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查");
|
||||
apiScenarioEnvService.checkEnv(request, apiScenarios);
|
||||
|
@ -419,8 +406,11 @@ public class ApiScenarioExecuteService {
|
|||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||
String runMode = StringUtils.isEmpty(request.getRunMode()) ? ApiRunMode.SCENARIO.name() : request.getRunMode();
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree);
|
||||
LoggerUtil.info(new MsTestPlan().getJmx(hashTree));
|
||||
runRequest.setDebug(true);
|
||||
|
||||
String jmx = request.getTestElement().getJmx(hashTree);
|
||||
LoggerUtil.info(jmx);
|
||||
PerformInspectionUtil.inspection(jmx, request.getScenarioId(), 0);
|
||||
if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) {
|
||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
|
||||
runRequest.setPoolId(request.getConfig().getResourcePoolId());
|
||||
|
|
|
@ -123,6 +123,9 @@ public class GenerateHashTreeUtil {
|
|||
}
|
||||
|
||||
public static HashTree generateHashTree(ApiScenarioWithBLOBs item, Map<String, String> planEnvMap, JmeterRunRequestDTO runRequest) {
|
||||
// 检查执行内容合规性
|
||||
PerformInspectionUtil.countMatches(item.getScenarioDefinition(), item.getId());
|
||||
|
||||
HashTree jmeterHashTree = new HashTree();
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
if (!runRequest.getPool().isPool()) {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PerformInspectionUtil {
|
||||
private static final List<String> runPaths = List.of(
|
||||
"/api/testcase/batch/run", "/api/testcase/jenkins/run",
|
||||
"/api/definition/run", "/api/definition/run/debug",
|
||||
"/api/automation/run", "/api/automation/run/debug", "/api/automation/jenkins/run");
|
||||
|
||||
public static void countMatches(String content, String checkItem) {
|
||||
if (StringUtils.isNotBlank(content) && StringUtils.isNotBlank(checkItem) && isPathMatches(content)
|
||||
&& StringUtils.contains(content, checkItem) && StringUtils.countMatches(content, checkItem) > 1) {
|
||||
LoggerUtil.error("执行内容含自身信息", content, checkItem);
|
||||
MSException.throwException("执行内容不能包含自身接口信息");
|
||||
}
|
||||
}
|
||||
|
||||
public static void inspection(String content, String checkItem, int size) {
|
||||
if (StringUtils.isNotBlank(content) && StringUtils.isNotBlank(checkItem) && isPathMatches(content)
|
||||
&& StringUtils.contains(content, checkItem) && StringUtils.countMatches(content, checkItem) > size) {
|
||||
LoggerUtil.error("执行内容含自身信息", content, checkItem);
|
||||
MSException.throwException("执行内容不能包含自身接口信息");
|
||||
}
|
||||
}
|
||||
|
||||
public static void scenarioInspection(List<ApiScenarioWithBLOBs> scenarios) {
|
||||
if (CollectionUtils.isNotEmpty(scenarios)) {
|
||||
scenarios.forEach(scenario -> {
|
||||
countMatches(scenario.getScenarioDefinition(), scenario.getId());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void caseInspection(List<ApiTestCaseWithBLOBs> caseList) {
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
caseList.forEach(item -> {
|
||||
inspection(item.getRequest(), item.getId(), 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPathMatches(String content) {
|
||||
return runPaths.stream().filter(path -> StringUtils.contains(content, path)).count() > 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue