From e9119a7472121fa2c59114ce91c5b42ee82bfc65 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Mon, 14 Nov 2022 15:58:29 +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 | 18 +++---- .../api/exec/api/ApiExecuteService.java | 9 ++-- .../scenario/ApiScenarioExecuteService.java | 42 ++++++--------- .../commons/utils/GenerateHashTreeUtil.java | 3 ++ .../commons/utils/PerformInspectionUtil.java | 53 +++++++++++++++++++ 5 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 api-test/backend/src/main/java/io/metersphere/commons/utils/PerformInspectionUtil.java diff --git a/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java b/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java index 9cc0f2153b..2abd0f12fa 100644 --- a/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java +++ b/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java @@ -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 responseDTOS = new LinkedList<>(); List caseList = extApiTestCaseMapper.unTrashCaseListByIds(request.getIds()); + // 检查执行内容合规性 + PerformInspectionUtil.caseInspection(caseList); LoggerUtil.debug("查询到执行数据:" + caseList.size()); Map> testCaseEnvMap = new HashMap<>(); diff --git a/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java b/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java index 25aeae20a1..aba4b5141b 100644 --- a/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java +++ b/api-test/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java @@ -119,6 +119,7 @@ public class ApiExecuteService { public MsExecResponseDTO exec(RunCaseRequest request, Map 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); diff --git a/api-test/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java b/api-test/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java index 79b27f8a80..2081c34a3a 100644 --- a/api-test/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java +++ b/api-test/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java @@ -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()); diff --git a/api-test/backend/src/main/java/io/metersphere/commons/utils/GenerateHashTreeUtil.java b/api-test/backend/src/main/java/io/metersphere/commons/utils/GenerateHashTreeUtil.java index 2ac5c48759..b523af0be8 100644 --- a/api-test/backend/src/main/java/io/metersphere/commons/utils/GenerateHashTreeUtil.java +++ b/api-test/backend/src/main/java/io/metersphere/commons/utils/GenerateHashTreeUtil.java @@ -123,6 +123,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(); if (!runRequest.getPool().isPool()) { diff --git a/api-test/backend/src/main/java/io/metersphere/commons/utils/PerformInspectionUtil.java b/api-test/backend/src/main/java/io/metersphere/commons/utils/PerformInspectionUtil.java new file mode 100644 index 0000000000..b1c4dbb044 --- /dev/null +++ b/api-test/backend/src/main/java/io/metersphere/commons/utils/PerformInspectionUtil.java @@ -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 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; + } +}