From a92a15dfb3d79a6703b8ffe330077ba909c640aa Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Mon, 14 Nov 2022 15:32:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E6=8E=A5=E5=8F=A3=E6=89=A7=E8=A1=8C=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=87=AA=E8=BA=AB=E5=BC=95=E5=8F=91=E6=AD=BB=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1019430 --user=赵勇 【接口测试】接口测试中调用接口执行请求传入当前用例、场景ID导致递归调用 https://www.tapd.cn/55049933/s/1295542 --- .../api/exec/api/ApiCaseExecuteService.java | 3 ++ .../api/exec/api/ApiExecuteService.java | 14 +++-- .../scenario/ApiScenarioExecuteService.java | 12 +++-- .../scenario/ApiScenarioSerialService.java | 4 ++ .../api/exec/utils/GenerateHashTreeUtil.java | 3 ++ .../api/exec/utils/PerformInspectionUtil.java | 53 +++++++++++++++++++ 6 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/exec/utils/PerformInspectionUtil.java diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java index 2782831335..4a7576f0ee 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java @@ -10,6 +10,7 @@ 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.exec.utils.PerformInspectionUtil; import io.metersphere.api.service.ApiCaseResultService; import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiScenarioReportStructureService; @@ -222,6 +223,8 @@ public class ApiCaseExecuteService { example.createCriteria().andIdIn(request.getIds()); List caseList = apiTestCaseMapper.selectByExampleWithBLOBs(example); LoggerUtil.debug("查询到执行数据:" + caseList.size()); + // 检查执行内容合规性 + PerformInspectionUtil.caseInspection(caseList); // 环境检查 if (MapUtils.isEmpty(request.getConfig().getEnvMap())) { this.checkEnv(caseList); diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java index 50221c4ed5..09eeef0ca1 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java @@ -15,6 +15,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil; +import io.metersphere.api.exec.utils.PerformInspectionUtil; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.api.service.TcpApiParamService; @@ -103,6 +104,8 @@ public class ApiExecuteService { public MsExecResponseDTO exec(RunCaseRequest request) { 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()); @@ -179,10 +182,10 @@ public class ApiExecuteService { } 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()); @@ -197,9 +200,10 @@ public class ApiExecuteService { } public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception { + PerformInspectionUtil.countMatches(testCaseWithBLOBs.getRequest(), testCaseWithBLOBs.getId()); + JSONObject elementObj = JSON.parseObject(testCaseWithBLOBs.getRequest(), Feature.DisableSpecialKeyDetect); ElementUtil.dataFormatting(elementObj); - MsTestElement element = mapper.readValue(elementObj.toJSONString(), new TypeReference() { }); element.setProjectId(testCaseWithBLOBs.getProjectId()); diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java index 9881c517ac..ee2f920340 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java @@ -11,12 +11,15 @@ import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.utils.GenerateHashTreeUtil; +import io.metersphere.api.exec.utils.PerformInspectionUtil; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiScenarioReportService; import io.metersphere.api.service.ApiScenarioReportStructureService; import io.metersphere.api.service.TcpApiParamService; -import io.metersphere.base.domain.*; +import io.metersphere.base.domain.ApiScenarioExample; +import io.metersphere.base.domain.ApiScenarioWithBLOBs; +import io.metersphere.base.domain.TestPlanApiScenario; import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioReportMapper; import io.metersphere.base.mapper.TestPlanApiScenarioMapper; @@ -27,7 +30,6 @@ import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.constants.ReportTypeConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.FileUtils; -import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.constants.RunModeConstants; @@ -111,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); @@ -361,7 +365,9 @@ public class ApiScenarioExecuteService { FileUtils.createBodyFiles(request.getScenarioFileIds(), scenarioFiles); this.testElement(request); hashTree = request.getTestElement().generateHashTree(config); - LogUtil.info(request.getTestElement().getJmx(hashTree)); + String jmx = request.getTestElement().getJmx(hashTree); + LoggerUtil.info(jmx); + PerformInspectionUtil.inspection(jmx, request.getScenarioId(), 0); } catch (Exception e) { LoggerUtil.error("调试失败", request.getReportId(), e); MSException.throwException(e.getMessage()); diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java index a43004ec8e..f3a1cb8286 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java @@ -14,6 +14,7 @@ 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.utils.GenerateHashTreeUtil; +import io.metersphere.api.exec.utils.PerformInspectionUtil; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.utils.SmoothWeighted; import io.metersphere.api.service.ApiExecutionQueueService; @@ -196,6 +197,9 @@ public class ApiScenarioSerialService { } if (caseWithBLOBs != null) { String data = caseWithBLOBs.getRequest(); + // 检查执行内容合规性 + PerformInspectionUtil.countMatches(data, caseWithBLOBs.getId()); + HashTree jmeterHashTree = new HashTree(); MsTestPlan testPlan = new MsTestPlan(); testPlan.setHashTree(new LinkedList<>()); diff --git a/backend/src/main/java/io/metersphere/api/exec/utils/GenerateHashTreeUtil.java b/backend/src/main/java/io/metersphere/api/exec/utils/GenerateHashTreeUtil.java index 7f691ce134..e8b39c8c54 100644 --- a/backend/src/main/java/io/metersphere/api/exec/utils/GenerateHashTreeUtil.java +++ b/backend/src/main/java/io/metersphere/api/exec/utils/GenerateHashTreeUtil.java @@ -120,6 +120,9 @@ public class GenerateHashTreeUtil { } public static HashTree generateHashTree(ApiScenarioWithBLOBs item, Map planEnvMap, JmeterRunRequestDTO runRequest) { + // 检查执行内容合规性 + PerformInspectionUtil.countMatches(item.getScenarioDefinition(), item.getId()); + HashTree jmeterHashTree = new HashTree(); MsTestPlan testPlan = new MsTestPlan(); testPlan.setHashTree(new LinkedList<>()); diff --git a/backend/src/main/java/io/metersphere/api/exec/utils/PerformInspectionUtil.java b/backend/src/main/java/io/metersphere/api/exec/utils/PerformInspectionUtil.java new file mode 100644 index 0000000000..500e399973 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/exec/utils/PerformInspectionUtil.java @@ -0,0 +1,53 @@ +package io.metersphere.api.exec.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 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 scenarios) { + if (CollectionUtils.isNotEmpty(scenarios)) { + scenarios.forEach(scenario -> { + countMatches(scenario.getScenarioDefinition(), scenario.getId()); + }); + } + } + + public static void caseInspection(List 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; + } +}