From d2dd6e5829e8e7aba6ae3827af58bd53de9d5a6c Mon Sep 17 00:00:00 2001 From: AgAngle <1323481023@qq.com> Date: Wed, 6 Mar 2024 10:56:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E7=8E=AF=E5=A2=83=E5=92=8C=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/ApiTestController.java | 1 - .../jmeter/JmeterTestElementParserHelper.java | 61 ++++++++++ .../parser/jmeter/MsHTTPElementConverter.java | 33 +++++- .../parser/jmeter/MsScenarioConverter.java | 108 ++++++++++++++++-- .../processor/ScriptProcessorConverter.java | 9 +- .../processor/SqlProcessorConverter.java | 9 +- .../ApiScenarioControllerTests.java | 34 ++++++ 7 files changed, 223 insertions(+), 32 deletions(-) create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/JmeterTestElementParserHelper.java diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/ApiTestController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/ApiTestController.java index cbea996b14..76739e55f3 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/ApiTestController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/ApiTestController.java @@ -82,7 +82,6 @@ public class ApiTestController { @RequiresPermissions(value = { PermissionConstants.PROJECT_API_DEFINITION_READ, PermissionConstants.PROJECT_API_DEFINITION_CASE_READ, - PermissionConstants.PROJECT_API_DEBUG_READ, PermissionConstants.PROJECT_API_SCENARIO_READ }, logical = Logical.OR) public List getEnvList(@PathVariable String projectId) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/JmeterTestElementParserHelper.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/JmeterTestElementParserHelper.java new file mode 100644 index 0000000000..0da2c1b58c --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/JmeterTestElementParserHelper.java @@ -0,0 +1,61 @@ +package io.metersphere.api.parser.jmeter; + +import io.metersphere.jmeter.mock.Mock; +import io.metersphere.project.dto.environment.variables.CommonVariables; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Argument; +import org.apache.jmeter.config.Arguments; +import org.apache.jmeter.save.SaveService; +import org.apache.jmeter.testelement.TestElement; + +import java.util.ArrayList; +import java.util.List; + +import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL; + +/** + * @Author: jianxing + * @CreateTime: 2024-03-05 21:06 + */ +public class JmeterTestElementParserHelper { + + public static Arguments getArguments(String name) { + Arguments arguments = new Arguments(); + arguments.setEnabled(true); + arguments.setName(name + "_Arguments"); + arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); + arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL)); + return arguments; + } + + public static Arguments getArguments(String name, List argumentList) { + Arguments arguments = getArguments(name); + parse2ArgumentList(argumentList).forEach(arguments::addArgument); + return arguments; + } + + public static List parse2ArgumentList(List variables) { + List arguments = new ArrayList<>(variables.size()); + variables.forEach(variable -> { + if (BooleanUtils.isFalse(variable.getEnable())) { + return; + } + if (variable.isConstantValid()) { + // 处理常量 + String value = StringUtils.isBlank(variable.getValue()) ? variable.getValue() + : Mock.buildFunctionCallString(variable.getValue()).replaceAll("[\r\n]", ""); + arguments.add(new Argument(variable.getKey(), value, "=")); + } else if (variable.isListValid()) { + // 处理 List 变量 + String[] arrays = variable.getValue().replaceAll("[\r\n]", "").split(","); + for (int i = 0; i < arrays.length; i++) { + arguments.add(new Argument(variable.getKey() + "_" + (i + 1), arrays[i], "=")); + } + } + }); + return arguments; + } + + +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java index 4f72d8ea72..1068927c15 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java @@ -25,11 +25,13 @@ import io.metersphere.project.dto.environment.GlobalParams; import io.metersphere.project.dto.environment.http.HttpConfig; import io.metersphere.project.dto.environment.http.HttpConfigPathMatchRule; import io.metersphere.project.dto.environment.http.SelectModule; +import io.metersphere.project.dto.environment.variables.CommonVariables; import io.metersphere.sdk.util.EnumValidator; import io.metersphere.sdk.util.LogUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.http.control.AuthManager; import org.apache.jmeter.protocol.http.control.Authorization; import org.apache.jmeter.protocol.http.control.Header; @@ -68,6 +70,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter envVariables = envInfo.getConfig().getCommonVariables(); + if (CollectionUtils.isEmpty(envVariables)) { + return null; + } + + return JmeterTestElementParserHelper.getArguments(msHTTPElement.getName(), envVariables); + } + /** * 设置步骤标识 * 当前步骤唯一标识,结果和步骤匹配的关键 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsScenarioConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsScenarioConverter.java index 19d8e9a06e..c9da8132de 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsScenarioConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsScenarioConverter.java @@ -7,6 +7,7 @@ import io.metersphere.api.dto.request.MsScenario; import io.metersphere.api.dto.request.processors.MsProcessorConfig; import io.metersphere.api.dto.scenario.ScenarioConfig; import io.metersphere.api.dto.scenario.ScenarioStepConfig; +import io.metersphere.api.dto.scenario.ScenarioVariable; import io.metersphere.api.parser.jmeter.processor.MsProcessorConverter; import io.metersphere.api.parser.jmeter.processor.MsProcessorConverterFactory; import io.metersphere.api.parser.jmeter.processor.assertion.AssertionConverterFactory; @@ -17,10 +18,12 @@ import io.metersphere.project.api.processor.MsProcessor; import io.metersphere.project.dto.environment.EnvironmentConfig; import io.metersphere.project.dto.environment.EnvironmentInfoDTO; import io.metersphere.project.dto.environment.processors.EnvProcessorConfig; +import io.metersphere.project.dto.environment.variables.CommonVariables; import io.metersphere.sdk.util.BeanUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.http.control.CookieManager; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -29,6 +32,8 @@ import org.apache.jorphan.collections.HashTree; import java.util.List; import java.util.Map; import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.COOKIE_PANEL; @@ -50,6 +55,9 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter commonVariables = scenarioVariable.getCommonVariables(); + + List envCommonVariables = List.of(); + if (needParseEnv(msScenario) && envInfo.getConfig() != null) { + // 获取环境变量 + envCommonVariables = envInfo.getConfig().getCommonVariables(); + // 获取后,将环境变量置空,避免请求重复设置 + envInfo.getConfig().setCommonVariables(List.of()); + } + + List constantVariables = mergeEnvVariables(commonVariables, envCommonVariables, CommonVariables::isConstantValid); + List listVariables = mergeEnvVariables(commonVariables, envCommonVariables, CommonVariables::isListValid); + + if (CollectionUtils.isEmpty(commonVariables) && CollectionUtils.isEmpty(envCommonVariables)) { + return; + } + + Arguments arguments = JmeterTestElementParserHelper.getArguments(msScenario.getName()); + JmeterTestElementParserHelper.parse2ArgumentList(constantVariables).forEach(arguments::addArgument); + JmeterTestElementParserHelper.parse2ArgumentList(listVariables).forEach(arguments::addArgument); + tree.add(arguments); + } + + /** + * 合并环境变量和场景变量 + * @param scenarioVariables + * @param envCommonVariables + * @param filter + * @return + */ + private List mergeEnvVariables(List scenarioVariables, List envCommonVariables, Predicate filter) { + List variables = scenarioVariables + .stream() + .filter(CommonVariables::getEnable) + .filter(filter::test) + .collect(Collectors.toList()); + + List envConstantVariables = envCommonVariables + .stream() + .filter(CommonVariables::getEnable) + .filter(filter::test) + .collect(Collectors.toList()); + + Map scenarioVariableMap = variables + .stream() + .collect(Collectors.toMap(CommonVariables::getKey, CommonVariables::getValue)); + + for (CommonVariables globalConstantVariable : envConstantVariables) { + String key = globalConstantVariable.getKey(); + if (!scenarioVariableMap.containsKey(key)) { + variables.add(globalConstantVariable); + } + } + return variables; + } + /** * 添加场景断言 * @@ -105,18 +179,8 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter arguments.addArgument(keyValue.getKey(), String.format("vars.get(\"%s\")", keyValue.getValue()), "=") diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java index d39eabb9bf..b655ba94c7 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java @@ -45,6 +45,7 @@ import io.metersphere.project.dto.environment.http.SelectModule; import io.metersphere.project.dto.environment.processors.EnvProcessorConfig; import io.metersphere.project.dto.environment.processors.EnvRequestScriptProcessor; import io.metersphere.project.dto.environment.processors.EnvScenarioScriptProcessor; +import io.metersphere.project.dto.environment.variables.CommonVariables; import io.metersphere.project.dto.filemanagement.request.FileUploadRequest; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; import io.metersphere.project.mapper.ProjectVersionMapper; @@ -760,6 +761,7 @@ public class ApiScenarioControllerTests extends BaseTest { request.getStepDetails().put(pluginStep.getId(), pluginStepDetail); request.getScenarioConfig().getOtherConfig().setEnableCookieShare(true); request.getScenarioConfig().getOtherConfig().setEnableGlobalCookie(false); + request.getScenarioConfig().setVariable(getScenarioVariable()); Plugin plugin = addEnvTestPlugin(); this.requestPostWithOk(DEBUG, request); @@ -769,6 +771,24 @@ public class ApiScenarioControllerTests extends BaseTest { requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, DEBUG, request); } + private ScenarioVariable getScenarioVariable() { + ScenarioVariable scenarioVariable = new ScenarioVariable(); + CommonVariables commonVariables1 = new CommonVariables(); + commonVariables1.setType(VariableTypeConstants.CONSTANT.name()); + commonVariables1.setKey("a"); + commonVariables1.setValue("b"); + CommonVariables commonVariables2 = new CommonVariables(); + commonVariables2.setType(VariableTypeConstants.CONSTANT.name()); + commonVariables2.setKey("b"); + commonVariables2.setValue("c"); + CommonVariables commonVariables3 = new CommonVariables(); + commonVariables3.setType(VariableTypeConstants.LIST.name()); + commonVariables3.setKey("list1"); + commonVariables3.setValue("1,2,3"); + scenarioVariable.setCommonVariables(List.of(commonVariables1, commonVariables2, commonVariables3)); + return scenarioVariable; + } + @Test @Order(7) public void testTransfer() throws Exception { @@ -1051,6 +1071,20 @@ public class ApiScenarioControllerTests extends BaseTest { DataSource dataSource = getDataSource(); environmentConfig.setDataSources(List.of(dataSource)); + CommonVariables commonVariables1 = new CommonVariables(); + commonVariables1.setType(VariableTypeConstants.CONSTANT.name()); + commonVariables1.setKey("a"); + commonVariables1.setValue("c"); + CommonVariables commonVariables2 = new CommonVariables(); + commonVariables2.setType(VariableTypeConstants.CONSTANT.name()); + commonVariables2.setKey("q"); + commonVariables2.setValue("qq"); + CommonVariables commonVariables3 = new CommonVariables(); + commonVariables3.setType(VariableTypeConstants.LIST.name()); + commonVariables3.setKey("list1"); + commonVariables3.setValue("1,2,3,5"); + environmentConfig.setCommonVariables(List.of(commonVariables1, commonVariables2, commonVariables3)); + EnvProcessorConfig preProcessorConfig = environmentConfig.getPreProcessorConfig(); EnvProcessorConfig postProcessorConfig = environmentConfig.getPostProcessorConfig(); List preProcessors = preProcessorConfig.getApiProcessorConfig().getScenarioProcessorConfig().getProcessors();