From 9b4431e5a25d218d4941fe8a6d3a2078d06d7ac7 Mon Sep 17 00:00:00 2001 From: AgAngle <1323481023@qq.com> Date: Sun, 4 Feb 2024 17:24:53 +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=89=8D=E5=90=8E=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spi/AbstractJmeterElementConverter.java | 6 +- .../plugin/api/spi/AbstractMsTestElement.java | 4 + .../api/constants/ApiConstants.java | 11 ++ .../metersphere/api/dto/ApiParamConfig.java | 8 +- .../api/dto/ApiScenarioParamConfig.java | 13 ++ .../api/dto/assertion/MsAssertionConfig.java | 3 +- .../api/dto/debug/ApiDebugRunRequest.java | 2 + .../api/dto/request/MsCommonElement.java | 1 + .../request/processors/MsProcessorConfig.java | 7 +- .../dto/scenario/ApiScenarioAddRequest.java | 2 +- .../scenario/ApiScenarioStepCommonDTO.java | 4 + .../api/dto/scenario/ApiScenarioStepDTO.java | 3 - .../dto/scenario/ApiScenarioStepRequest.java | 4 - .../scenario/ApiScenarioUpdateRequest.java | 2 +- .../api/dto/scenario/ScenarioConfig.java | 10 +- .../api/dto/scenario/ScenarioStepConfig.java | 2 +- .../api/dto/scenario/ScenarioVariable.java | 5 +- .../api/parser/api/Swagger3Parser.java | 3 +- .../jmeter/MsCommonElementConverter.java | 124 +++++++++++++++--- .../parser/jmeter/MsScenarioConverter.java | 117 ++++++++++++++++- .../MsProcessorConverterFactory.java | 6 + .../ScenarioScriptProcessorConverter.java | 38 ++++++ .../ScriptPostProcessorConverter.java | 2 +- .../ScriptPreProcessorConverter.java | 2 +- .../api/service/ApiExecuteService.java | 45 ++++--- .../api/service/ApiTestService.java | 4 +- .../api/service/debug/ApiDebugService.java | 3 +- .../service/scenario/ApiScenarioService.java | 3 + .../controller/ApiDebugControllerTests.java | 11 +- .../ApiDebugModuleControllerTests.java | 5 +- .../ApiDefinitionControllerTests.java | 7 +- .../ApiDefinitionModuleControllerTests.java | 13 +- .../ApiScenarioControllerTests.java | 61 +++++++-- .../ApiTestCaseControllerTests.java | 3 +- .../api/controller/ApiTestServiceTest.java | 3 +- .../api/controller/CleanupApiTests.java | 3 +- .../api/controller/MsHTTPElementTest.java | 28 ++-- .../project/api/processor/MsProcessor.java | 12 +- .../api/processor/ScriptProcessor.java | 10 ++ .../dto/environment/EnvironmentConfig.java | 43 ++---- .../dto/environment/EnvironmentInfoDTO.java | 2 +- .../dto/environment/MsEnvAssertionConfig.java | 10 +- .../dto/environment/auth/AuthConfig.java | 2 +- .../dto/environment/host/HostConfig.java | 3 +- .../processors/ApiEnvPlanProcessorConfig.java | 9 +- .../processors/ApiEnvProcessorConfig.java | 14 +- .../ApiEnvRequestProcessorConfig.java | 9 +- .../ApiEnvScenarioProcessorConfig.java | 9 +- .../processors/EnvProcessorConfig.java | 10 +- ...or.java => EnvRequestScriptProcessor.java} | 7 +- ...r.java => EnvScenarioScriptProcessor.java} | 4 +- .../project/service/EnvironmentService.java | 8 +- .../EnvironmentControllerTests.java | 6 +- .../system/service/ApiPluginService.java | 20 +++ 54 files changed, 573 insertions(+), 173 deletions(-) create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/constants/ApiConstants.java create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScenarioScriptProcessorConverter.java rename backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/{RequestScriptProcessor.java => EnvRequestScriptProcessor.java} (73%) rename backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/{ScenarioScriptProcessor.java => EnvScenarioScriptProcessor.java} (80%) diff --git a/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractJmeterElementConverter.java b/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractJmeterElementConverter.java index 134d1e33c1..c5a194b5b1 100644 --- a/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractJmeterElementConverter.java +++ b/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractJmeterElementConverter.java @@ -43,8 +43,10 @@ public abstract class AbstractJmeterElementConverter im */ public void parseChild(HashTree tree, AbstractMsTestElement element, ParameterConfig config) { if (element != null && element.getChildren() != null) { - element.getChildren().forEach(child -> - getConverterFunc.apply(child.getClass()).toHashTree(tree, child, config)); + element.getChildren().forEach(child -> { + child.setParent(element); + getConverterFunc.apply(child.getClass()).toHashTree(tree, child, config); + }); } } } diff --git a/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractMsTestElement.java b/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractMsTestElement.java index af578ac3f5..ab28bfb079 100644 --- a/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractMsTestElement.java +++ b/backend/framework/plugin/plugin-api-sdk/src/main/java/io/metersphere/plugin/api/spi/AbstractMsTestElement.java @@ -38,4 +38,8 @@ public abstract class AbstractMsTestElement implements MsTestElement { * 子组件 */ private LinkedList children; + /** + * 父组件 + */ + private AbstractMsTestElement parent; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/constants/ApiConstants.java b/backend/services/api-test/src/main/java/io/metersphere/api/constants/ApiConstants.java new file mode 100644 index 0000000000..e11398eb85 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/constants/ApiConstants.java @@ -0,0 +1,11 @@ +package io.metersphere.api.constants; + +/** + * @Author: jianxing + * @CreateTime: 2024-02-02 19:15 + */ +public class ApiConstants { + public static final String HTTP_PROTOCOL = "HTTP"; + + private ApiConstants() {} +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiParamConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiParamConfig.java index 7eb8482890..1e1e99086e 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiParamConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiParamConfig.java @@ -27,6 +27,13 @@ public class ApiParamConfig extends ParameterConfig { * value 为对应的插件 ID */ private Map, String> testElementClassPluginIdMap; + /** + * AbstractMsTestElement 实现类与接口协议的映射 + * key 为 AbstractMsTestElement 实现类对象 + * value 为对应的接口协议 + * 环境前后置忽略协议需要使用 + */ + private Map, String> testElementClassProtocalMap; @Override @@ -53,5 +60,4 @@ public class ApiParamConfig extends ParameterConfig { String pluginId = testElementClassPluginIdMap.get(msTestElement.getClass()); return pluginConfigMap.get(pluginId); } - } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiScenarioParamConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiScenarioParamConfig.java index cac372a29f..53a24996ae 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiScenarioParamConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiScenarioParamConfig.java @@ -34,4 +34,17 @@ public class ApiScenarioParamConfig extends ApiParamConfig { return super.getProtocolEnvConfig(msTestElement); } } + + /** + * 获取当前环境或者环境组的配置 + * @param projectId + * @return + */ + public EnvironmentInfoDTO getEnvConfig(String projectId) { + if (BooleanUtils.isTrue(grouped)) { + return projectEnvMap.get(projectId); + } else { + return getEnvConfig(); + } + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/assertion/MsAssertionConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/assertion/MsAssertionConfig.java index 123d656e90..64d67a5c3a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/assertion/MsAssertionConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/assertion/MsAssertionConfig.java @@ -3,6 +3,7 @@ package io.metersphere.api.dto.assertion; import io.metersphere.project.api.assertion.MsAssertion; import lombok.Data; +import java.util.ArrayList; import java.util.List; /** @@ -20,5 +21,5 @@ public class MsAssertionConfig { /** * 断言列表 */ - private List assertions; + private List assertions = new ArrayList<>(0); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/debug/ApiDebugRunRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/debug/ApiDebugRunRequest.java index 9227c09016..effbccf8d9 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/debug/ApiDebugRunRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/debug/ApiDebugRunRequest.java @@ -22,4 +22,6 @@ public class ApiDebugRunRequest { @NotNull @Schema(description = "请求内容") private Object request; + @Schema(description = "项目ID") + private String projectId; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java index 994a99738f..8bd0f75e52 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java @@ -33,4 +33,5 @@ public class MsCommonElement extends AbstractMsTestElement { */ @Valid private MsAssertionConfig assertionConfig; + } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java index 107b3ea7f7..2c9e64dd3a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java @@ -4,6 +4,7 @@ import io.metersphere.project.api.processor.MsProcessor; import jakarta.validation.Valid; import lombok.Data; +import java.util.ArrayList; import java.util.List; /** @@ -15,12 +16,12 @@ import java.util.List; public class MsProcessorConfig { /** * 是否启用全局前置 - * 默认为 false + * 默认为 true */ - private Boolean enableGlobal = false; + private Boolean enableGlobal = true; /** * 处理器列表 */ @Valid - private List processors; + private List processors = new ArrayList<>(0); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioAddRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioAddRequest.java index be9f1c1f1c..e214251305 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioAddRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioAddRequest.java @@ -58,7 +58,7 @@ public class ApiScenarioAddRequest { private String environmentId; @Schema(description = "场景的通用配置") - private ScenarioConfig scenarioConfig; + private ScenarioConfig scenarioConfig = new ScenarioConfig(); @Schema(description = "步骤集合") @Valid diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepCommonDTO.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepCommonDTO.java index 76c2923826..80da11dd06 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepCommonDTO.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepCommonDTO.java @@ -56,6 +56,10 @@ public class ApiScenarioStepCommonDTO { @Schema(description = "csv文件id集合") private List csvFileIds; + @Schema(description = "项目fk") + @NotBlank + private String projectId; + @Valid @Schema(description = "子步骤") private List children; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepDTO.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepDTO.java index 5ee1cb92b7..73292f5f6c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepDTO.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepDTO.java @@ -16,9 +16,6 @@ public class ApiScenarioStepDTO extends ApiScenarioStepCommonDTO { @Schema(description = "资源编号") private String resourceNum; - @Schema(description = "项目fk") - private String projectId; - @Schema(description = "版本号") private String versionId; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepRequest.java index 4bc18b1036..bd95af653b 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioStepRequest.java @@ -20,10 +20,6 @@ public class ApiScenarioStepRequest extends ApiScenarioStepCommonDTO { @Size(min = 1, max = 50, message = "{api_scenario_step.resource_num.length_range}") private String resourceNum; - @Schema(description = "项目fk") - @Size(min = 1, max = 50, message = "{api_scenario_step.project_id.length_range}") - private String projectId; - @Schema(description = "版本号") @Size(min = 1, max = 50, message = "{api_scenario_step.version_id.length_range}") private String versionId; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioUpdateRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioUpdateRequest.java index a6b110ce93..e75b70bcbd 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioUpdateRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ApiScenarioUpdateRequest.java @@ -56,7 +56,7 @@ public class ApiScenarioUpdateRequest { private String environmentId; @Schema(description = "场景的通用配置") - private ScenarioConfig scenarioConfig; + private ScenarioConfig scenarioConfig = new ScenarioConfig(); @Valid @Schema(description = "步骤集合") diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioConfig.java index a3d085a3fc..365bc915e4 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioConfig.java @@ -13,21 +13,21 @@ public class ScenarioConfig { /** * 场景变量 */ - private ScenarioVariable variable; + private ScenarioVariable variable = new ScenarioVariable(); /** * 前置处理器配置 */ - private MsProcessorConfig preProcessorConfig; + private MsProcessorConfig preProcessorConfig = new MsProcessorConfig(); /** * 后置处理器配置 */ - private MsProcessorConfig postProcessorConfig; + private MsProcessorConfig postProcessorConfig = new MsProcessorConfig(); /** * 断言配置 */ - private MsAssertionConfig assertionConfig; + private MsAssertionConfig assertionConfig = new MsAssertionConfig(); /** * 其他配置 */ - private ScenarioOtherConfig otherConfig; + private ScenarioOtherConfig otherConfig = new ScenarioOtherConfig(); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioStepConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioStepConfig.java index 83d0bfa625..1024008aa7 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioStepConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioStepConfig.java @@ -7,7 +7,7 @@ import lombok.Data; @Data public class ScenarioStepConfig extends ApiScenario { @Schema(description = "是否使用源场景环境") - private Boolean enableScenarioEnv; + private Boolean enableScenarioEnv = false; @Schema(description = "是否使用当前场景参数,如果为false,则使用源场景参数") private Boolean useCurrentScenarioParam = false; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioVariable.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioVariable.java index 861c37659f..e8dea5e2ba 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioVariable.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/scenario/ScenarioVariable.java @@ -3,6 +3,7 @@ package io.metersphere.api.dto.scenario; import io.metersphere.project.dto.environment.variables.CommonVariables; import lombok.Data; +import java.util.ArrayList; import java.util.List; /** @@ -14,9 +15,9 @@ public class ScenarioVariable { /** * 普通变量 */ - private List commonVariables; + private List commonVariables = new ArrayList<>(0); /** * csv变量 */ - private List csvVariables; + private List csvVariables = new ArrayList<>(0); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/api/Swagger3Parser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/api/Swagger3Parser.java index 07bb5f1671..02c6fe4555 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/api/Swagger3Parser.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/api/Swagger3Parser.java @@ -1,5 +1,6 @@ package io.metersphere.api.parser.api; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.dto.definition.HttpResponse; import io.metersphere.api.dto.converter.ApiDefinitionImport; import io.metersphere.api.dto.converter.ApiDefinitionImportDetail; @@ -279,7 +280,7 @@ public class Swagger3Parser implements ImportParser { ApiDefinitionImportDetail apiDefinition = new ApiDefinitionImportDetail(); apiDefinition.setName(name); apiDefinition.setPath(formatPath(path)); - apiDefinition.setProtocol("HTTP"); + apiDefinition.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDefinition.setMethod(method); apiDefinition.setProjectId(this.projectId); apiDefinition.setCreateUser(importRequest.getUserId()); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java index 6bb9f26974..699dd38d11 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java @@ -1,19 +1,37 @@ package io.metersphere.api.parser.jmeter; -import io.metersphere.api.dto.request.MsCommonElement; -import io.metersphere.project.api.assertion.MsAssertion; +import io.metersphere.api.constants.ApiConstants; +import io.metersphere.api.dto.ApiParamConfig; +import io.metersphere.api.dto.ApiScenarioParamConfig; import io.metersphere.api.dto.assertion.MsAssertionConfig; -import io.metersphere.project.api.assertion.MsResponseCodeAssertion; +import io.metersphere.api.dto.request.MsCommonElement; +import io.metersphere.api.dto.request.http.MsHTTPElement; import io.metersphere.api.dto.request.processors.MsProcessorConfig; +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; import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter; +import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.metersphere.project.api.assertion.MsAssertion; +import io.metersphere.project.api.assertion.MsResponseCodeAssertion; +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.ApiEnvProcessorConfig; +import io.metersphere.project.dto.environment.processors.ApiEnvRequestProcessorConfig; +import io.metersphere.project.dto.environment.processors.EnvProcessorConfig; +import io.metersphere.project.dto.environment.processors.EnvRequestScriptProcessor; import io.metersphere.sdk.constants.MsAssertionCondition; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.jorphan.collections.HashTree; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + /** * @Author: jianxing * @CreateTime: 2023-10-27 10:07 @@ -25,17 +43,24 @@ public class MsCommonElementConverter extends AbstractJmeterElementConverter AssertionConverterFactory.getConverter(assertion.getClass()).parse(tree, assertion, config, finalIsIgnoreStatus)); } - private void handlePreProcessor(HashTree tree, MsProcessorConfig preProcessorConfig, ParameterConfig config) { - if (preProcessorConfig == null || preProcessorConfig.getProcessors() == null) { + private void addProcessors(HashTree tree, MsCommonElement msCommonElement, ParameterConfig config, + EnvironmentInfoDTO envInfo, boolean isPre) { + MsProcessorConfig processorConfig = isPre ? msCommonElement.getPreProcessorConfig() : msCommonElement.getPostProcessorConfig(); + if (processorConfig == null || processorConfig.getProcessors() == null) { return; } - preProcessorConfig.getProcessors() - .forEach(processor -> MsProcessorConverterFactory.getPreConverter(processor.getClass()).parse(tree, processor, config)); + AbstractMsTestElement parent = msCommonElement.getParent(); + String protocol = null; + if (parent instanceof MsHTTPElement) { + protocol = ApiConstants.HTTP_PROTOCOL; + } else { + if (config instanceof ApiParamConfig apiParamConfig) { + protocol = apiParamConfig.getTestElementClassProtocalMap().get(parent.getClass()); + } + } + + List beforeStepProcessors = new ArrayList<>(0); + List afterStepProcessors = new ArrayList<>(0); + + // 开启全局前置才处理环境前置处理器 + if (BooleanUtils.isTrue(processorConfig.getEnableGlobal()) && envInfo != null) { + EnvironmentConfig envConfig = envInfo.getConfig(); + EnvProcessorConfig envProcessorConfig = isPre ? envConfig.getPreProcessorConfig() : envConfig.getPostProcessorConfig(); + addEnvProcessors(envProcessorConfig, beforeStepProcessors, afterStepProcessors, protocol, true); + } + + Function, MsProcessorConverter> getConverterFunc = + isPre ? MsProcessorConverterFactory::getPreConverter : MsProcessorConverterFactory::getPostConverter; + + // 处理环境中,步骤前处理器 + beforeStepProcessors.forEach(processor -> + getConverterFunc.apply(processor.getClass()).parse(tree, processor, config)); + + processorConfig.getProcessors() + .forEach(processor -> getConverterFunc.apply(processor.getClass()).parse(tree, processor, config)); + + // 处理环境中,步骤后处理器 + afterStepProcessors.forEach(processor -> + getConverterFunc.apply(processor.getClass()).parse(tree, processor, config)); } - private void handlePostProcessor(HashTree tree, MsProcessorConfig postProcessorConfig , ParameterConfig config) { - if (postProcessorConfig == null || postProcessorConfig.getProcessors() == null) { - return; + private void addEnvProcessors(EnvProcessorConfig envProcessorConfig, + List beforeStepProcessors, + List afterStepProcessors, + String protocol, + boolean isPre) { + // 获取环境中的前后置处理器 + ApiEnvProcessorConfig apiProcessorConfig = envProcessorConfig.getApiProcessorConfig(); + ApiEnvRequestProcessorConfig requestProcessorConfig = apiProcessorConfig.getRequestProcessorConfig(); + List processors = requestProcessorConfig.getProcessors(); + + for (MsProcessor processor : processors) { + if (processor instanceof EnvRequestScriptProcessor requestScriptProcessor) { + // 如果是脚本处理器,处理步骤内前置脚本前后配置,以及忽略的协议 + Boolean beforeStepScript = requestScriptProcessor.getBeforeStepScript(); + List ignoreProtocols = requestScriptProcessor.getIgnoreProtocols(); + if (ignoreProtocols.contains(protocol)) { + return; + } + if (BooleanUtils.isTrue(beforeStepScript)) { + beforeStepProcessors.add(processor); + } else { + afterStepProcessors.add(processor); + } + } else { + // 其他处理器 + if (isPre) { + // 如果是前置,则在前置处理器之前执行 + beforeStepProcessors.add(processor); + } else { + // 如果是后置,则在后置处理器之后执行 + afterStepProcessors.add(processor); + } + } } - postProcessorConfig.getProcessors() - .forEach(processor -> MsProcessorConverterFactory.getPostConverter(processor.getClass()).parse(tree, processor, config)); } } 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 d613ba68cd..a30f1b16b9 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 @@ -1,22 +1,34 @@ package io.metersphere.api.parser.jmeter; +import io.metersphere.api.constants.ApiScenarioStepRefType; import io.metersphere.api.dto.ApiScenarioParamConfig; 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.parser.jmeter.processor.MsProcessorConverter; +import io.metersphere.api.parser.jmeter.processor.MsProcessorConverterFactory; import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter; +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.sdk.util.BeanUtils; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.jorphan.collections.HashTree; +import java.util.List; import java.util.Map; +import java.util.function.Function; /** * @Author: jianxing * @CreateTime: 2023-10-27 10:07 - * + *

* 脚本解析器 */ public class MsScenarioConverter extends AbstractJmeterElementConverter { @@ -24,26 +36,127 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter envScenarioProcessors = processorConfig.getApiProcessorConfig() + .getScenarioProcessorConfig() + .getProcessors(); + + if (CollectionUtils.isEmpty(envScenarioProcessors)) { + return; + } + + Function, MsProcessorConverter> getConverterFunc = + isPre ? MsProcessorConverterFactory::getPreConverter : MsProcessorConverterFactory::getPostConverter; + + // 添加前后置 + envScenarioProcessors.forEach(processor -> + getConverterFunc.apply(processor.getClass()).parse(tree, processor, config)); + } + + private void addScenarioProcessor(HashTree tree, MsScenario msScenario, ParameterConfig config, boolean isPre) { + if (isCopy(msScenario.getRefType())) { + // 复制的场景,没有前后置 + return; + } + // 获取场景前后置 + ScenarioConfig scenarioConfig = msScenario.getScenarioConfig(); + MsProcessorConfig processorConfig = isPre ? scenarioConfig.getPreProcessorConfig() : scenarioConfig.getPostProcessorConfig(); + List scenarioPreProcessors = processorConfig.getProcessors(); + + if (CollectionUtils.isEmpty(scenarioPreProcessors)) { + return; + } + + Function, MsProcessorConverter> getConverterFunc = + isPre ? MsProcessorConverterFactory::getPreConverter : MsProcessorConverterFactory::getPostConverter; + + // 添加场景前置处理器 + scenarioPreProcessors.forEach(processor -> + getConverterFunc.apply(processor.getClass()).parse(tree, processor, config)); + } + + private boolean isRef(String refType) { + return StringUtils.equalsAny(refType, ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name()); + } + + private boolean isCopy(String refType) { + return StringUtils.equals(refType, ApiScenarioStepRefType.COPY.name()); } /** * 获取子步骤的配置信息 * 如果使用源场景环境,则使用当前场景的环境信息 + * * @param msScenario * @param config * @return */ private ApiScenarioParamConfig getChileConfig(MsScenario msScenario, ApiScenarioParamConfig config) { + if (!isRef(msScenario.getRefType())) { + // 非引用的场景,使用当前环境参数 + return config; + } ScenarioStepConfig scenarioStepConfig = msScenario.getScenarioStepConfig(); if (scenarioStepConfig != null && BooleanUtils.isTrue(scenarioStepConfig.getEnableScenarioEnv())) { // 使用源场景环境 ApiScenarioParamConfig chileConfig = BeanUtils.copyBean(new ApiScenarioParamConfig(), config); chileConfig.setGrouped(msScenario.getGrouped()); + // 清空环境信息 chileConfig.setEnvConfig(null); chileConfig.setProjectEnvMap(null); if (BooleanUtils.isTrue(msScenario.getGrouped())) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/MsProcessorConverterFactory.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/MsProcessorConverterFactory.java index e9ed78811e..00beace4e4 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/MsProcessorConverterFactory.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/MsProcessorConverterFactory.java @@ -4,6 +4,8 @@ import io.metersphere.project.api.processor.ExtractPostProcessor; import io.metersphere.project.api.processor.SQLProcessor; import io.metersphere.project.api.processor.ScriptProcessor; import io.metersphere.project.api.processor.TimeWaitingProcessor; +import io.metersphere.project.dto.environment.processors.EnvRequestScriptProcessor; +import io.metersphere.project.dto.environment.processors.EnvScenarioScriptProcessor; import java.util.HashMap; import java.util.Map; @@ -21,11 +23,15 @@ public class MsProcessorConverterFactory { preConverterMap.put(ScriptProcessor.class, new ScriptPreProcessorConverter()); preConverterMap.put(SQLProcessor.class, new SqlPreProcessorConverter()); preConverterMap.put(TimeWaitingProcessor.class, new TimeWaitingProcessorConverter()); + preConverterMap.put(EnvRequestScriptProcessor.class, new ScriptPreProcessorConverter()); + preConverterMap.put(EnvScenarioScriptProcessor.class, new ScenarioScriptProcessorConverter()); postConverterMap.put(ScriptProcessor.class, new ScriptPostProcessorConverter()); postConverterMap.put(SQLProcessor.class, new SqlPostProcessorConverter()); postConverterMap.put(TimeWaitingProcessor.class, new TimeWaitingProcessorConverter()); postConverterMap.put(ExtractPostProcessor.class, new ExtractPostProcessorConverter()); + postConverterMap.put(EnvRequestScriptProcessor.class, new ScriptPostProcessorConverter()); + postConverterMap.put(EnvScenarioScriptProcessor.class, new ScenarioScriptProcessorConverter()); } public static MsProcessorConverter getPreConverter(Class processorClass) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScenarioScriptProcessorConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScenarioScriptProcessorConverter.java new file mode 100644 index 0000000000..45e6c46710 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScenarioScriptProcessorConverter.java @@ -0,0 +1,38 @@ +package io.metersphere.api.parser.jmeter.processor; + +import io.metersphere.plugin.api.dto.ParameterConfig; +import io.metersphere.project.api.processor.ScriptProcessor; +import io.metersphere.project.dto.environment.processors.EnvScenarioScriptProcessor; +import org.apache.jmeter.protocol.java.sampler.BeanShellSampler; +import org.apache.jmeter.protocol.java.sampler.JSR223Sampler; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; + +/** + * 环境场景级前置处理器处理 + * + * @Author: jianxing + * @CreateTime: 2023-12-26 14:49 + */ +public class ScenarioScriptProcessorConverter extends ScriptProcessorConverter { + @Override + public void parse(HashTree hashTree, ScriptProcessor scriptProcessor, ParameterConfig config) { + if (!needParse(scriptProcessor, config) || !scriptProcessor.isValid()) { + return; + } + EnvScenarioScriptProcessor scenarioScriptProcessor = (EnvScenarioScriptProcessor) scriptProcessor; + Boolean associateScenarioResult = scenarioScriptProcessor.getAssociateScenarioResult(); + + TestElement processor; + if (isJSR233(scriptProcessor)) { + processor = new JSR223Sampler(); + } else { + processor = new BeanShellSampler(); + } + + parse(processor, scriptProcessor); + // 标记当前处理器是否关联场景结果 + processor.setName("ASSOCIATE_RESULT_PROCESSOR_" + associateScenarioResult); + hashTree.add(processor); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPostProcessorConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPostProcessorConverter.java index 1e49510238..6c5ccdbb68 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPostProcessorConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPostProcessorConverter.java @@ -14,7 +14,7 @@ import org.apache.jorphan.collections.HashTree; public class ScriptPostProcessorConverter extends ScriptProcessorConverter { @Override public void parse(HashTree hashTree, ScriptProcessor scriptProcessor, ParameterConfig config) { - if (!needParse(scriptProcessor, config)) { + if (!needParse(scriptProcessor, config) || !scriptProcessor.isValid()) { return; } // todo 处理公共脚本 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPreProcessorConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPreProcessorConverter.java index c29ebd9fbc..83445f8db3 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPreProcessorConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptPreProcessorConverter.java @@ -14,7 +14,7 @@ import org.apache.jorphan.collections.HashTree; public class ScriptPreProcessorConverter extends ScriptProcessorConverter { @Override public void parse(HashTree hashTree, ScriptProcessor scriptProcessor, ParameterConfig config) { - if (!needParse(scriptProcessor, config)) { + if (!needParse(scriptProcessor, config) || !scriptProcessor.isValid()) { return; } // todo 处理公共脚本 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiExecuteService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiExecuteService.java index 40c5947735..a91f0caa62 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiExecuteService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiExecuteService.java @@ -24,15 +24,11 @@ import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo; import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO; import io.metersphere.sdk.dto.api.task.TaskRequestDTO; import io.metersphere.sdk.exception.MSException; -import io.metersphere.sdk.util.BeanUtils; -import io.metersphere.sdk.util.CommonBeanFactory; -import io.metersphere.sdk.util.EncryptUtils; -import io.metersphere.sdk.util.JSON; -import io.metersphere.sdk.util.LogUtils; +import io.metersphere.sdk.util.*; import io.metersphere.system.config.MinioProperties; import io.metersphere.system.domain.TestResourcePool; -import io.metersphere.system.dto.pool.TestResourceDTO; import io.metersphere.system.dto.pool.TestResourceNodeDTO; +import io.metersphere.system.dto.pool.TestResourcePoolReturnDTO; import io.metersphere.system.service.CommonProjectService; import io.metersphere.system.service.SystemParameterService; import io.metersphere.system.service.TestResourcePoolService; @@ -134,9 +130,7 @@ public class ApiExecuteService { // todo 接口用例 method 获取定义中的数据库字段 String executeScript = parseExecuteScript(request.getTestElement(), parameterConfig); - TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(request.getProjectId()); - - doDebug(reportId, testId, taskRequest, executeScript, testResourceNodeDTO); + doDebug(reportId, testId, taskRequest, executeScript, request.getProjectId()); } /** @@ -146,13 +140,21 @@ public class ApiExecuteService { * @param testId 资源ID * @param taskRequest 执行参数 * @param executeScript 执行脚本 - * @param testResourceNodeDTO 资源池 + * @param projectId 项目ID */ private void doDebug(String reportId, String testId, TaskRequestDTO taskRequest, String executeScript, - TestResourceNodeDTO testResourceNodeDTO) { + String projectId) { + + TestResourcePoolReturnDTO testResourcePoolDTO = getGetResourcePoolNodeDTO(projectId); + TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(testResourcePoolDTO); + if (StringUtils.isNotBlank(testResourcePoolDTO.getServerUrl())) { + // 如果资源池配置了当前站点,则使用资源池的 + taskRequest.setMsUrl(testResourcePoolDTO.getServerUrl()); + } + // 将测试脚本缓存到 redis String scriptRedisKey = getScriptRedisKey(reportId, testId); stringRedisTemplate.opsForValue().set(scriptRedisKey, executeScript); @@ -169,18 +171,21 @@ public class ApiExecuteService { } } - private TestResourceNodeDTO getProjectExecuteNode(String projectId) { - String resourcePoolId = getProjectApiResourcePoolId(projectId); - TestResourceDTO resourcePoolDTO = getAvailableResourcePoolDTO(projectId, resourcePoolId); - roundRobinService.initializeNodes(resourcePoolId, resourcePoolDTO.getNodesList()); + private TestResourceNodeDTO getProjectExecuteNode(TestResourcePoolReturnDTO resourcePoolDTO) { + roundRobinService.initializeNodes(resourcePoolDTO.getId(), resourcePoolDTO.getTestResourceReturnDTO().getNodesList()); try { - return roundRobinService.getNextNode(resourcePoolId); + return roundRobinService.getNextNode(resourcePoolDTO.getId()); } catch (Exception e) { LogUtils.error(e); throw new MSException("get execute node error", e); } } + private TestResourcePoolReturnDTO getGetResourcePoolNodeDTO(String projectId) { + String resourcePoolId = getProjectApiResourcePoolId(projectId); + return getAvailableResourcePoolDTO(projectId, resourcePoolId); + } + /** * 设置minio kafka ms 等信息 * @@ -216,9 +221,7 @@ public class ApiExecuteService { apiRunModeConfig.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name()); taskRequest.setRunModeConfig(apiRunModeConfig); - TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(runRequest.getProjectId()); - - doDebug(reportId, testId, taskRequest, executeScript, testResourceNodeDTO); + doDebug(reportId, testId, taskRequest, executeScript, runRequest.getProjectId()); return reportId; } @@ -336,7 +339,7 @@ public class ApiExecuteService { * @param projectId 项目ID * @param resourcePoolId 资源池ID */ - public TestResourceDTO getAvailableResourcePoolDTO(String projectId, String resourcePoolId) { + public TestResourcePoolReturnDTO getAvailableResourcePoolDTO(String projectId, String resourcePoolId) { TestResourcePool testResourcePool = testResourcePoolService.getTestResourcePool(resourcePoolId); if (testResourcePool == null || // 资源池禁用 @@ -345,7 +348,7 @@ public class ApiExecuteService { !commonProjectService.validateProjectResourcePool(testResourcePool, projectId)) { throw new MSException(ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG); } - return testResourcePoolService.getTestResourceDTO(resourcePoolId); + return testResourcePoolService.getTestResourcePoolDetail(resourcePoolId); } private String getProjectApiResourcePoolId(String projectId) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiTestService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiTestService.java index 59890cdb18..7f1f135624 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiTestService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiTestService.java @@ -1,5 +1,6 @@ package io.metersphere.api.service; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.dto.ApiTestPluginOptionRequest; import io.metersphere.api.dto.request.http.MsHTTPElement; import io.metersphere.plugin.api.dto.ApiPluginOptionsRequest; @@ -25,7 +26,6 @@ import java.util.List; @Transactional(rollbackFor = Exception.class) public class ApiTestService { - private static final String HTTP_PROTOCOL = "HTTP"; @Resource private ApiPluginService apiPluginService; @@ -33,7 +33,7 @@ public class ApiTestService { List protocols = apiPluginService.getProtocols(orgId); // 将 http 协议放最前面 ProtocolDTO protocolDTO = new ProtocolDTO(); - protocolDTO.setProtocol(HTTP_PROTOCOL); + protocolDTO.setProtocol(ApiConstants.HTTP_PROTOCOL); protocolDTO.setPolymorphicName(MsHTTPElement.class.getSimpleName()); protocols.addFirst(protocolDTO); return protocols; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java index d342e5c6f8..da1abf5dd7 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java @@ -197,10 +197,9 @@ public class ApiDebugService { public String debug(ApiDebugRunRequest request) { String id = request.getId(); - ApiDebug apiDebug = checkResourceExist(id); ApiResourceRunRequest runRequest = BeanUtils.copyBean(new ApiResourceRunRequest(), request); - runRequest.setProjectId(apiDebug.getProjectId()); + runRequest.setProjectId(request.getProjectId()); runRequest.setTestId(id); runRequest.setReportId(id); runRequest.setResourceType(ApiResourceType.API_DEBUG.name()); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java index c4e664f99f..176df85e57 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java @@ -1041,6 +1041,7 @@ public class ApiScenarioService { MsScenario msScenario = new MsScenario(); msScenario.setRefType(ApiScenarioStepRefType.DIRECT.name()); msScenario.setScenarioConfig(getScenarioConfig(request, hasSave)); + msScenario.setProjectId(request.getProjectId()); // 获取场景环境相关配置 ApiScenarioParseEnvInfo scenarioParseEnvInfo = getScenarioParseEnvInfo(refResourceMap, request.getEnvironmentId(), request.getGrouped()); @@ -1059,6 +1060,7 @@ public class ApiScenarioService { ApiScenarioParamConfig parseConfig = new ApiScenarioParamConfig(); parseConfig.setTestElementClassPluginIdMap(apiPluginService.getTestElementPluginMap()); + parseConfig.setTestElementClassProtocalMap(apiPluginService.getTestElementProtocolMap()); parseConfig.setGrouped(request.getGrouped()); parseConfig.setReportId(request.getReportId()); scenarioParseEnvInfo.getPluginClassEnvConfigMap(); @@ -1156,6 +1158,7 @@ public class ApiScenarioService { // 将步骤详情解析生成对应的MsTestElement AbstractMsTestElement msTestElement = stepParser.parseTestElement(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId())); if (msTestElement != null) { + msTestElement.setProjectId(step.getProjectId()); setMsScenarioParam(scenarioParseEnvInfo, step, msTestElement); parentElement.getChildren().add(msTestElement); } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java index 62663889c3..e8389583fd 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.controller.result.ApiResultCode; import io.metersphere.api.domain.ApiDebug; import io.metersphere.api.domain.ApiDebugBlob; @@ -60,7 +61,6 @@ public class ApiDebugControllerTests extends BaseTest { protected static final String DEFAULT_LIST = "list/{0}"; protected static final String UPLOAD_TEMP_FILE = "upload/temp/file"; protected static final String DEBUG = "debug"; - protected static final String HTTP_PROTOCOL = "HTTP"; @Resource private ApiDebugMapper apiDebugMapper; @@ -86,7 +86,7 @@ public class ApiDebugControllerTests extends BaseTest { @Order(0) public void listEmpty() throws Exception { // @@校验没有数据的情况 - this.requestGetWithOk(DEFAULT_LIST, HTTP_PROTOCOL); + this.requestGetWithOk(DEFAULT_LIST, ApiConstants.HTTP_PROTOCOL); // 准备数据,上传文件管理文件 uploadFileMetadata(); } @@ -133,7 +133,7 @@ public class ApiDebugControllerTests extends BaseTest { request.setPath("http://test.com"); request.setMethod("GET"); request.setName("test"); - request.setProtocol(HTTP_PROTOCOL); + request.setProtocol(ApiConstants.HTTP_PROTOCOL); request.setModuleId("default"); request.setProjectId(DEFAULT_PROJECT_ID); MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement(); @@ -320,7 +320,7 @@ public class ApiDebugControllerTests extends BaseTest { @Order(4) public void list() throws Exception { // @@请求成功 - MvcResult mvcResult = this.requestGetWithOk(DEFAULT_LIST, HTTP_PROTOCOL) + MvcResult mvcResult = this.requestGetWithOk(DEFAULT_LIST, ApiConstants.HTTP_PROTOCOL) .andReturn(); // 校验数据是否正确 List apiDebugList = getResultDataArray(mvcResult, ApiDebugSimpleDTO.class); @@ -331,7 +331,7 @@ public class ApiDebugControllerTests extends BaseTest { BeanUtils.copyBean(new ApiDebugSimpleDTO(), apiDebugMapper.selectByPrimaryKey(anotherAddApiDebug.getId()))); // @@校验权限 - requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ, DEFAULT_LIST, HTTP_PROTOCOL); + requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_READ, DEFAULT_LIST, ApiConstants.HTTP_PROTOCOL); } @@ -362,6 +362,7 @@ public class ApiDebugControllerTests extends BaseTest { msHTTPElement.setMethod("GET"); request.setRequest(JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement))); request.setReportId(IDGenerator.nextStr()); + request.setProjectId(DEFAULT_PROJECT_ID); // @校验组织没有资源池权限异常 assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugModuleControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugModuleControllerTests.java index aa17ef557e..8a3576c888 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugModuleControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugModuleControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.domain.*; import io.metersphere.api.dto.debug.ApiDebugRequest; import io.metersphere.api.dto.debug.ModuleCreateRequest; @@ -114,7 +115,7 @@ public class ApiDebugModuleControllerTests extends BaseTest { apiDebug.setProjectId(project.getId()); apiDebug.setName(StringUtils.join("接口调试", apiDebug.getId())); apiDebug.setModuleId(moduleId); - apiDebug.setProtocol("HTTP"); + apiDebug.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDebug.setMethod("GET"); apiDebug.setPath(StringUtils.join("api/debug/", apiDebug.getId())); apiDebug.setCreateTime(System.currentTimeMillis()); @@ -748,7 +749,7 @@ public class ApiDebugModuleControllerTests extends BaseTest { public void TestModuleCountSuccess() throws Exception { this.preliminaryData(); ApiDebugRequest request = new ApiDebugRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); }}; MvcResult moduleCountMvcResult = this.requestPostWithOkAndReturn(URL_FILE_MODULE_COUNT, request); Map moduleCountResult = JSON.parseObject(JSON.toJSONString( diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java index 944efc22d7..169951be21 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.constants.ApiDefinitionDocType; import io.metersphere.api.constants.ApiDefinitionStatus; import io.metersphere.api.controller.result.ApiResultCode; @@ -238,7 +239,7 @@ public class ApiDefinitionControllerTests extends BaseTest { String defaultVersion = extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID); ApiDefinitionAddRequest request = new ApiDefinitionAddRequest(); request.setName("接口定义test"); - request.setProtocol("HTTP"); + request.setProtocol(ApiConstants.HTTP_PROTOCOL); request.setProjectId(DEFAULT_PROJECT_ID); request.setMethod("POST"); request.setPath("/api/admin/posts"); @@ -404,7 +405,7 @@ public class ApiDefinitionControllerTests extends BaseTest { //校验修改path和method时,是否会影响用例 ApiDefinitionAddRequest addRequest = new ApiDefinitionAddRequest(); addRequest.setName("测试修改path和method"); - addRequest.setProtocol("HTTP"); + addRequest.setProtocol(ApiConstants.HTTP_PROTOCOL); addRequest.setProjectId(DEFAULT_PROJECT_ID); addRequest.setMethod("POST"); addRequest.setPath("/api/admin/posts"); @@ -1400,7 +1401,7 @@ public class ApiDefinitionControllerTests extends BaseTest { request.setCoverData(true); request.setCoverModule(true); request.setModuleId(apiDefinitionModule.getId()); - request.setProtocol("HTTP"); + request.setProtocol(ApiConstants.HTTP_PROTOCOL); request.setUserId("admin"); MultiValueMap paramMap = new LinkedMultiValueMap<>(); paramMap.add("request", JSON.toJSONString(request)); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java index 677ff47379..2c357cef06 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.domain.*; import io.metersphere.api.dto.debug.ApiDebugRequest; import io.metersphere.api.dto.debug.ModuleCreateRequest; @@ -134,7 +135,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { apiDefinition.setProjectId(project.getId()); apiDefinition.setName(StringUtils.join("接口定义", apiDefinition.getId())); apiDefinition.setModuleId(moduleId); - apiDefinition.setProtocol("HTTP"); + apiDefinition.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDefinition.setMethod("GET"); apiDefinition.setStatus("未规划"); apiDefinition.setNum(NumGenerator.nextNum(project.getId(), ApplicationNumScope.API_DEFINITION)); @@ -811,7 +812,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { public void TestModuleCountSuccess() throws Exception { this.preliminaryData(); ApiModuleRequest request = new ApiModuleRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); this.setProjectId(project.getId()); }}; MvcResult moduleCountMvcResult = this.requestPostWithOkAndReturn(URL_FILE_MODULE_COUNT, request); @@ -876,7 +877,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { apiDefinition.setDeleted(true); apiDefinitionMapper.updateByExampleSelective(apiDefinition, example); MvcResult result = this.requestPostWithOkAndReturn(URL_MODULE_TRASH_TREE, new ApiModuleRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); this.setProjectId(project.getId()); }}); @@ -889,7 +890,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { @Order(12) public void getModuleTrashTreeCount() throws Exception { ApiModuleRequest request = new ApiModuleRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); this.setProjectId(project.getId()); }}; MvcResult moduleCountMvcResult = this.requestPostWithOkAndReturn(URL_MODULE_TRASH_COUNT, request); @@ -951,11 +952,11 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { private List getModuleTreeNode() throws Exception { MvcResult result = this.requestPostWithOkAndReturn(URL_MODULE_TREE, new ApiModuleRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); this.setProjectId(project.getId()); }}); this.requestPostWithOkAndReturn(URL_MODULE_ONLY_TREE, new ApiModuleRequest() {{ - this.setProtocol("HTTP"); + this.setProtocol(ApiConstants.HTTP_PROTOCOL); this.setProjectId(project.getId()); }}); String returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8); 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 171379a284..f5bbb81c42 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 @@ -1,13 +1,11 @@ package io.metersphere.api.controller; -import io.metersphere.api.constants.ApiDefinitionStatus; -import io.metersphere.api.constants.ApiScenarioStatus; -import io.metersphere.api.constants.ApiScenarioStepRefType; -import io.metersphere.api.constants.ApiScenarioStepType; +import io.metersphere.api.constants.*; import io.metersphere.api.domain.*; -import io.metersphere.api.dto.assertion.MsAssertionConfig; import io.metersphere.api.dto.definition.ApiDefinitionAddRequest; import io.metersphere.api.dto.definition.ApiTestCaseAddRequest; +import io.metersphere.api.dto.assertion.MsAssertionConfig; +import io.metersphere.project.api.assertion.MsScriptAssertion; import io.metersphere.api.dto.request.http.MsHTTPElement; import io.metersphere.api.dto.response.ApiScenarioBatchOperationResponse; import io.metersphere.api.dto.response.OperationDataInfo; @@ -24,11 +22,15 @@ import io.metersphere.api.utils.JmeterElementConverterRegister; import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter; import io.metersphere.plugin.api.spi.JmeterElementConverter; import io.metersphere.plugin.api.spi.MsTestElement; -import io.metersphere.project.api.assertion.MsScriptAssertion; +import io.metersphere.project.api.processor.MsProcessor; +import io.metersphere.project.api.processor.SQLProcessor; import io.metersphere.project.dto.environment.EnvironmentConfig; import io.metersphere.project.dto.environment.EnvironmentGroupProjectDTO; import io.metersphere.project.dto.environment.EnvironmentGroupRequest; import io.metersphere.project.dto.environment.EnvironmentRequest; +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.filemanagement.request.FileUploadRequest; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; import io.metersphere.project.service.EnvironmentGroupService; @@ -284,8 +286,8 @@ public class ApiScenarioControllerTests extends BaseTest { @Test @Order(1) public void add() throws Exception { - initTestData(); initEnv(); + initTestData(); // @@请求成功 ApiScenarioAddRequest request = new ApiScenarioAddRequest(); @@ -322,6 +324,7 @@ public class ApiScenarioControllerTests extends BaseTest { stepRequest.setResourceId(addApiScenario.getId()); stepRequest.setRefType(ApiScenarioStepRefType.REF.name()); stepRequest.setStepType(ApiScenarioStepType.API_SCENARIO.name()); + stepRequest.setProjectId(DEFAULT_PROJECT_ID); ApiScenarioStepRequest stepRequest2 = new ApiScenarioStepRequest(); stepRequest2.setId(IDGenerator.nextStr()); @@ -330,6 +333,7 @@ public class ApiScenarioControllerTests extends BaseTest { stepRequest2.setRefType(ApiScenarioStepRefType.PARTIAL_REF.name()); stepRequest2.setChildren(List.of(stepRequest)); stepRequest2.setStepType(ApiScenarioStepType.API_SCENARIO.name()); + stepRequest2.setProjectId(DEFAULT_PROJECT_ID); steps = List.of(stepRequest, stepRequest2); request.setSteps(steps); mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request); @@ -478,7 +482,7 @@ public class ApiScenarioControllerTests extends BaseTest { private void initTestData() { ApiDefinitionAddRequest apiDefinitionAddRequest = new ApiDefinitionAddRequest(); apiDefinitionAddRequest.setName("test scenario"); - apiDefinitionAddRequest.setProtocol("HTTP"); + apiDefinitionAddRequest.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDefinitionAddRequest.setProjectId(DEFAULT_PROJECT_ID); apiDefinitionAddRequest.setMethod("POST"); apiDefinitionAddRequest.setPath("/api/admin/posts"); @@ -487,7 +491,7 @@ public class ApiScenarioControllerTests extends BaseTest { apiDefinitionAddRequest.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID)); apiDefinitionAddRequest.setDescription("描述内容"); apiDefinitionAddRequest.setName("test scenario"); - MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement(); + MsHTTPElement msHttpElement = MsHTTPElementTest.getAddProcessorHttpElement(); apiDefinitionAddRequest.setRequest(getMsElementParam(msHttpElement)); apiDefinitionAddRequest.setResponse("{}"); apiDefinition = apiDefinitionService.create(apiDefinitionAddRequest, "admin"); @@ -611,6 +615,7 @@ public class ApiScenarioControllerTests extends BaseTest { stepRequest.setStepType(ApiScenarioStepType.API_SCENARIO.name()); stepRequest.setChildren(getApiScenarioStepRequests()); stepRequest.setConfig(scenarioStepConfig); + stepRequest.setProjectId(DEFAULT_PROJECT_ID); steps.add(stepRequest); ApiScenarioStepRequest copyScenarioStep = BeanUtils.copyBean(new ApiScenarioStepRequest(), stepRequest); copyScenarioStep.setRefType(ApiScenarioStepRefType.COPY.name()); @@ -640,6 +645,7 @@ public class ApiScenarioControllerTests extends BaseTest { pluginStep.setName("plugin step"); pluginStep.setStepType(ApiScenarioStepType.API.name()); pluginStep.setChildren(getApiScenarioStepRequests()); + pluginStep.setProjectId(DEFAULT_PROJECT_ID); request.getSteps().add(pluginStep); HashMap pluginStepDetail = new HashMap<>(); pluginStepDetail.put("polymorphicName", "MsTCPSampler"); @@ -686,7 +692,44 @@ public class ApiScenarioControllerTests extends BaseTest { // 添加插件的环境配置,供后续测试使用 Map> pluginConfigMap = new HashMap<>(); pluginConfigMap.put("tcpp-sampler", new HashMap<>()); + + EnvScenarioScriptProcessor envScenarioScriptProcessor = new EnvScenarioScriptProcessor(); + envScenarioScriptProcessor.setScript("test"); + envScenarioScriptProcessor.setEnableCommonScript(false); + envScenarioScriptProcessor.setAssociateScenarioResult(true); + EnvScenarioScriptProcessor envScenarioScriptProcessor1 = BeanUtils.copyBean(new EnvScenarioScriptProcessor(), envScenarioScriptProcessor); + envScenarioScriptProcessor1.setAssociateScenarioResult(false); + SQLProcessor sqlProcessor = new SQLProcessor(); + sqlProcessor.setScript("select * from test"); + sqlProcessor.setName("select * from test"); + EnvironmentConfig environmentConfig = new EnvironmentConfig(); + EnvProcessorConfig preProcessorConfig = environmentConfig.getPreProcessorConfig(); + EnvProcessorConfig postProcessorConfig = environmentConfig.getPostProcessorConfig(); + List preProcessors = preProcessorConfig.getApiProcessorConfig().getScenarioProcessorConfig().getProcessors(); + preProcessors.add(envScenarioScriptProcessor); + preProcessors.add(envScenarioScriptProcessor1); + preProcessors.add(sqlProcessor); + + List postProcessors = postProcessorConfig.getApiProcessorConfig().getScenarioProcessorConfig().getProcessors(); + postProcessors.add(envScenarioScriptProcessor); + postProcessors.add(envScenarioScriptProcessor1); + postProcessors.add(sqlProcessor); + + EnvRequestScriptProcessor envRequestScriptProcessor = new EnvRequestScriptProcessor(); + envRequestScriptProcessor.setScript("test"); + envRequestScriptProcessor.setBeforeStepScript(true); + envRequestScriptProcessor.setIgnoreProtocols(List.of("TCP")); + EnvRequestScriptProcessor envRequestScriptProcessor1 = new EnvRequestScriptProcessor(); + envRequestScriptProcessor1.setScript("test1"); + envRequestScriptProcessor1.setBeforeStepScript(false); + envRequestScriptProcessor1.setIgnoreProtocols(List.of()); + List preRequestProcessors = preProcessorConfig.getApiProcessorConfig().getRequestProcessorConfig().getProcessors(); + preRequestProcessors.add(envRequestScriptProcessor); + preRequestProcessors.add(sqlProcessor); + List postRequestProcessors = postProcessorConfig.getApiProcessorConfig().getRequestProcessorConfig().getProcessors(); + postRequestProcessors.add(envRequestScriptProcessor); + postRequestProcessors.add(sqlProcessor); environmentConfig.setPluginConfigMap(pluginConfigMap); envRequest.setConfig(environmentConfig); Environment environment = environmentService.add(envRequest, "admin", null); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java index cbb1174cf8..2202ccd03d 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.controller.param.ApiTestCaseAddRequestDefinition; import io.metersphere.api.domain.*; import io.metersphere.api.dto.definition.*; @@ -147,7 +148,7 @@ public class ApiTestCaseControllerTests extends BaseTest { apiDefinition.setProjectId(DEFAULT_PROJECT_ID); apiDefinition.setName(StringUtils.join("接口定义", apiDefinition.getId())); apiDefinition.setModuleId("case-moduleId"); - apiDefinition.setProtocol("HTTP"); + apiDefinition.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDefinition.setMethod("GET"); apiDefinition.setStatus("未规划"); apiDefinition.setNum(NumGenerator.nextNum(DEFAULT_PROJECT_ID, ApplicationNumScope.API_DEFINITION)); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestServiceTest.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestServiceTest.java index 0b27beffb1..13b4c8aaac 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestServiceTest.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestServiceTest.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.dto.request.http.MsHTTPElement; import io.metersphere.api.service.ApiTestService; import io.metersphere.system.base.BaseApiPluginTestService; @@ -36,7 +37,7 @@ public class ApiTestServiceTest extends BaseTest { List protocols = apiTestService.getProtocols(this.DEFAULT_ORGANIZATION_ID); List expected = new ArrayList(); ProtocolDTO httpProtocol = new ProtocolDTO(); - httpProtocol.setProtocol("HTTP"); + httpProtocol.setProtocol(ApiConstants.HTTP_PROTOCOL); httpProtocol.setPolymorphicName(MsHTTPElement.class.getSimpleName()); ProtocolDTO jdbcProtocol = new ProtocolDTO(); jdbcProtocol.setProtocol("JDBC"); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/CleanupApiTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/CleanupApiTests.java index cf241bed5e..5fb14329e2 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/CleanupApiTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/CleanupApiTests.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.constants.ApiConstants; import io.metersphere.api.domain.*; import io.metersphere.api.dto.scenario.CsvVariable; import io.metersphere.api.job.ApiScenarioScheduleJob; @@ -98,7 +99,7 @@ public class CleanupApiTests { apiDefinition.setModuleId("test-module"); apiDefinition.setName("test"); apiDefinition.setPath("test"); - apiDefinition.setProtocol("http"); + apiDefinition.setProtocol(ApiConstants.HTTP_PROTOCOL); apiDefinition.setMethod("test"); apiDefinition.setCreateUser("admin"); apiDefinition.setUpdateUser("admin"); diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java index 6991609083..ebdabae87b 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java @@ -134,6 +134,22 @@ public class MsHTTPElementTest { @Test public void processorParseTest() { + + MsHTTPElement msHTTPElement = getAddProcessorHttpElement(); + // 测试序列化 + String json = ApiDataUtils.toJSONString(msHTTPElement); + Assertions.assertNotNull(json); + Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement); + + // 测试脚本解析 + ParameterConfig parameterConfig = new ApiParamConfig(); + parameterConfig.setReportId("reportId"); + TestElementParser defaultParser = TestElementParserFactory.getDefaultParser(); + AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(json, AbstractMsTestElement.class); + defaultParser.parse(msTestElement, parameterConfig); + } + + public static MsHTTPElement getAddProcessorHttpElement() { MsHTTPElement msHTTPElement = getMsHttpElement(); List processors = new ArrayList<>(); @@ -219,17 +235,7 @@ public class MsHTTPElementTest { linkedList.add(msCommonElement); msHTTPElement.setChildren(linkedList); - // 测试序列化 - String json = ApiDataUtils.toJSONString(msHTTPElement); - Assertions.assertNotNull(json); - Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement); - - // 测试脚本解析 - ParameterConfig parameterConfig = new ApiParamConfig(); - parameterConfig.setReportId("reportId"); - TestElementParser defaultParser = TestElementParserFactory.getDefaultParser(); - AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(json, AbstractMsTestElement.class); - defaultParser.parse(msTestElement, parameterConfig); + return msHTTPElement; } @Test diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/MsProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/MsProcessor.java index a938eae2e7..d0ed6fd108 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/MsProcessor.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/MsProcessor.java @@ -2,8 +2,8 @@ package io.metersphere.project.api.processor; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.metersphere.project.dto.environment.processors.RequestScriptProcessor; -import io.metersphere.project.dto.environment.processors.ScenarioScriptProcessor; +import io.metersphere.project.dto.environment.processors.EnvRequestScriptProcessor; +import io.metersphere.project.dto.environment.processors.EnvScenarioScriptProcessor; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import lombok.Data; @@ -17,8 +17,8 @@ import lombok.Data; * SQL {@link SQLProcessor} * TIME_WAITING {@link TimeWaitingProcessor} * EXTRACT {@link ExtractPostProcessor} - * SCENARIO_SCRIPT {@link ScenarioScriptProcessor} - * REQUEST_SCRIPT {@link RequestScriptProcessor} + * ENV_SCENARIO_SCRIPT {@link EnvScenarioScriptProcessor} + * ENV_REQUEST_SCRIPT {@link EnvRequestScriptProcessor} *

  * @Author: jianxing
  * @CreateTime: 2023-11-07  10:17
@@ -27,8 +27,8 @@ import lombok.Data;
 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "processorType")
 @JsonSubTypes({
         @JsonSubTypes.Type(value = ScriptProcessor.class),
-        @JsonSubTypes.Type(value = ScenarioScriptProcessor.class),
-        @JsonSubTypes.Type(value = RequestScriptProcessor.class),
+        @JsonSubTypes.Type(value = EnvScenarioScriptProcessor.class),
+        @JsonSubTypes.Type(value = EnvRequestScriptProcessor.class),
         @JsonSubTypes.Type(value = SQLProcessor.class),
         @JsonSubTypes.Type(value = TimeWaitingProcessor.class),
         @JsonSubTypes.Type(value = ExtractPostProcessor.class),
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/ScriptProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/ScriptProcessor.java
index 34715b80aa..e4a94ecf09 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/ScriptProcessor.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/api/processor/ScriptProcessor.java
@@ -7,6 +7,8 @@ import io.metersphere.system.valid.EnumValue;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.List;
 
@@ -32,6 +34,7 @@ public class ScriptProcessor extends MsProcessor {
     /**
      * 是否启用公共脚本
      * 默认为 false
+     * 环境脚本无须配置
      */
     private Boolean enableCommonScript = false;
     /**
@@ -44,4 +47,11 @@ public class ScriptProcessor extends MsProcessor {
      */
     @Valid
     private List params;
+
+    public boolean isValid() {
+        if (BooleanUtils.isTrue(enableCommonScript) && StringUtils.isBlank(scriptId)) {
+            return false;
+        }
+        return StringUtils.isNotBlank(script);
+    }
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java
index 4fa36cca14..a95ec88f5b 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java
@@ -10,47 +10,32 @@ import io.metersphere.project.dto.environment.variables.CommonVariables;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import java.io.Serial;
-import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 @Data
-public class EnvironmentConfig implements Serializable {
-    @Serial
-    private static final long serialVersionUID = 1L;
+public class EnvironmentConfig {
     @Schema(description = "公共参数 请求超时时间、响应超时时间")
-    private CommonParams commonParams;
+    private CommonParams commonParams = new CommonParams();
     @Schema(description = "环境变量")
-    private List commonVariables;
+    private List commonVariables = new ArrayList<>(0);
     @Schema(description = "HTTP配置")
-    private List httpConfig;
+    private List httpConfig = new ArrayList<>(0);
     @Schema(description = "数据库配置")
-    private List dataSources;
+    private List dataSources = new ArrayList<>(0);
+
     @Schema(description = "Host配置")
-    private HostConfig hostConfig;
+    private HostConfig hostConfig = new HostConfig();
     @Schema(description = "认证配置")
-    private AuthConfig authConfig;
+    private AuthConfig authConfig = new AuthConfig();
     @Schema(description = "全局前置脚本")
-    private EnvProcessorConfig preProcessorConfig;
+    private EnvProcessorConfig preProcessorConfig = new EnvProcessorConfig();
     @Schema(description = "全局后置脚本")
-    private EnvProcessorConfig postProcessorConfig;
+    private EnvProcessorConfig postProcessorConfig = new EnvProcessorConfig();
     @Schema(description = "全局断言")
-    private MsEnvAssertionConfig assertionConfig;
+    private MsEnvAssertionConfig assertionConfig = new MsEnvAssertionConfig();
     @Schema(description = "插件自定义的配置项,key为插件ID,value 为对应配置")
-    private Map> pluginConfigMap;
-
-
-    public EnvironmentConfig() {
-        this.commonParams = new CommonParams();
-        this.commonVariables = List.of(new CommonVariables());
-        this.httpConfig = List.of(new HttpConfig());
-        this.dataSources = List.of(new DataSource());
-        this.hostConfig = new HostConfig();
-        this.authConfig = new AuthConfig();
-        this.preProcessorConfig = new EnvProcessorConfig();
-        this.postProcessorConfig = new EnvProcessorConfig();
-        this.assertionConfig = new MsEnvAssertionConfig();
-    }
-
+    private Map> pluginConfigMap = HashMap.newHashMap(0);
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentInfoDTO.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentInfoDTO.java
index 6e79ead8ac..f8e73fac9f 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentInfoDTO.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentInfoDTO.java
@@ -28,7 +28,7 @@ public class EnvironmentInfoDTO implements Serializable {
     private String name;
     @Schema(description = "环境配置")
     @NotNull(message = "{environment_config_is_null}", groups = {Created.class, Updated.class})
-    private EnvironmentConfig config;
+    private EnvironmentConfig config = new EnvironmentConfig();
     @Schema(description = "是否是mock环境")
     private Boolean mock;
     @Schema(description = "描述")
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/MsEnvAssertionConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/MsEnvAssertionConfig.java
index 09fa6eb205..b8b88cd579 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/MsEnvAssertionConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/MsEnvAssertionConfig.java
@@ -3,6 +3,9 @@ package io.metersphere.project.dto.environment;
 import io.metersphere.project.api.assertion.MsAssertion;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -11,9 +14,12 @@ import java.util.List;
  * @CreateTime: 2023-11-23  17:26
  */
 @Data
-public class MsEnvAssertionConfig {
+public class MsEnvAssertionConfig  implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     /**
      * 断言列表
      */
-    private List assertions;
+    private List assertions = new ArrayList<>(0);
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/auth/AuthConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/auth/AuthConfig.java
index 2a8d1672d4..311624b97c 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/auth/AuthConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/auth/AuthConfig.java
@@ -18,7 +18,7 @@ public class AuthConfig implements Serializable {
     private String verification;
 
     @Schema(description = "SSL配置")
-    private KeyStoreConfig sslConfig;
+    private KeyStoreConfig sslConfig = new KeyStoreConfig();
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/host/HostConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/host/HostConfig.java
index 6fcae307a7..4331b78592 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/host/HostConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/host/HostConfig.java
@@ -5,6 +5,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 @Data
@@ -12,7 +13,7 @@ public class HostConfig implements Serializable {
     @Schema(description = "启用Host")
     private Boolean enable;
     @Schema(description = "Host列表")
-    private List hosts;
+    private List hosts = new ArrayList<>(0);
     @Serial
     private static final long serialVersionUID = 1L;
 
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvPlanProcessorConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvPlanProcessorConfig.java
index 2628eac470..4a6bf5c9dc 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvPlanProcessorConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvPlanProcessorConfig.java
@@ -4,6 +4,9 @@ import io.metersphere.project.api.processor.MsProcessor;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -12,10 +15,12 @@ import java.util.List;
  * @CreateTime: 2024-02-01  14:53
  */
 @Data
-public class ApiEnvPlanProcessorConfig {
+public class ApiEnvPlanProcessorConfig  implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
 
     // 预留其他配置
 
     @Schema(description = "前后置列表")
-    private List processors;
+    private List processors = new ArrayList<>(0);
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvProcessorConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvProcessorConfig.java
index 5c37278973..d88eea599a 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvProcessorConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvProcessorConfig.java
@@ -3,16 +3,22 @@ package io.metersphere.project.dto.environment.processors;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 /**
  * @Author: jianxing
  * @CreateTime: 2024-02-01  14:49
  */
 @Data
-public class ApiEnvProcessorConfig {
+public class ApiEnvProcessorConfig  implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     @Schema(description = "测试计划级前后置配置")
-    private ApiEnvPlanProcessorConfig planProcessorConfig;
+    private ApiEnvPlanProcessorConfig planProcessorConfig = new ApiEnvPlanProcessorConfig();
     @Schema(description = "场景级前后置配置")
-    private ApiEnvScenarioProcessorConfig scenarioProcessorConfig;
+    private ApiEnvScenarioProcessorConfig scenarioProcessorConfig = new ApiEnvScenarioProcessorConfig();
     @Schema(description = "请求级前后置配置")
-    private ApiEnvRequestProcessorConfig requestProcessorConfig;
+    private ApiEnvRequestProcessorConfig requestProcessorConfig = new ApiEnvRequestProcessorConfig();
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvRequestProcessorConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvRequestProcessorConfig.java
index c25a4785bc..d6d3b8e009 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvRequestProcessorConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvRequestProcessorConfig.java
@@ -4,6 +4,9 @@ import io.metersphere.project.api.processor.MsProcessor;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -12,10 +15,12 @@ import java.util.List;
  * @CreateTime: 2024-02-01  14:53
  */
 @Data
-public class ApiEnvRequestProcessorConfig {
+public class ApiEnvRequestProcessorConfig  implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
 
     // 预留其他配置
 
     @Schema(description = "前后置列表")
-    private List processors;
+    private List processors = new ArrayList<>(0);
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvScenarioProcessorConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvScenarioProcessorConfig.java
index 8fff4836f2..4e4e1928f0 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvScenarioProcessorConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiEnvScenarioProcessorConfig.java
@@ -4,6 +4,9 @@ import io.metersphere.project.api.processor.MsProcessor;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -12,10 +15,12 @@ import java.util.List;
  * @CreateTime: 2024-02-01  14:53
  */
 @Data
-public class ApiEnvScenarioProcessorConfig {
+public class ApiEnvScenarioProcessorConfig  implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
 
     // 预留其他配置
 
     @Schema(description = "前后置列表")
-    private List processors;
+    private List processors = new ArrayList<>(0);
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvProcessorConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvProcessorConfig.java
index 219772e497..88bb8e8720 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvProcessorConfig.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvProcessorConfig.java
@@ -3,11 +3,17 @@ package io.metersphere.project.dto.environment.processors;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.io.Serial;
+import java.io.Serializable;
+
 /**
  * 环境的前后置配置
  */
 @Data
-public class EnvProcessorConfig {
+public class EnvProcessorConfig implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     @Schema(description = "接口测试前后置配置")
-    private ApiEnvProcessorConfig apiProcessorConfig;
+    private ApiEnvProcessorConfig apiProcessorConfig = new ApiEnvProcessorConfig();
 }
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/RequestScriptProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvRequestScriptProcessor.java
similarity index 73%
rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/RequestScriptProcessor.java
rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvRequestScriptProcessor.java
index aeafc8213e..07a7ccc283 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/RequestScriptProcessor.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvRequestScriptProcessor.java
@@ -6,17 +6,18 @@ import io.metersphere.project.api.processor.ScriptProcessor;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @Data
-@JsonTypeName("REQUEST_SCRIPT")
-public class RequestScriptProcessor extends ScriptProcessor {
+@JsonTypeName("ENV_REQUEST_SCRIPT")
+public class EnvRequestScriptProcessor extends ScriptProcessor {
 
     /**
      * 忽略的请求协议列表
      */
     @Schema(description = "忽略请求")
-    private List ignoreProtocols;
+    private List ignoreProtocols = new ArrayList<>(0);
     /**
      * 是否是步骤内前置脚本前
      */
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScriptProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvScenarioScriptProcessor.java
similarity index 80%
rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScriptProcessor.java
rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvScenarioScriptProcessor.java
index 7e94316e87..807d8532e9 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScriptProcessor.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/EnvScenarioScriptProcessor.java
@@ -7,8 +7,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 @Data
-@JsonTypeName("SCENARIO_SCRIPT")
-public class ScenarioScriptProcessor extends ScriptProcessor {
+@JsonTypeName("ENV_SCENARIO_SCRIPT")
+public class EnvScenarioScriptProcessor extends ScriptProcessor {
 
     /**
      * 是否关联场景结果,默认否
diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java
index 0f9af762c2..c76b767893 100644
--- a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java
+++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java
@@ -5,6 +5,7 @@ import io.metersphere.project.domain.Project;
 import io.metersphere.project.domain.ProjectExample;
 import io.metersphere.project.dto.environment.*;
 import io.metersphere.project.dto.environment.datasource.DataSource;
+import io.metersphere.project.dto.environment.http.HttpConfig;
 import io.metersphere.project.mapper.ExtEnvironmentMapper;
 import io.metersphere.project.mapper.ProjectMapper;
 import io.metersphere.sdk.constants.DefaultRepositoryDir;
@@ -191,7 +192,12 @@ public class EnvironmentService {
             String baseUrl = baseSystemConfigDTO.getUrl();
             if (StringUtils.isNotEmpty(baseUrl)) {
                 Project project = projectMapper.selectByPrimaryKey(environment.getProjectId());
-                environmentInfoDTO.getConfig().getHttpConfig().getFirst().setUrl(StringUtils.join(baseUrl, MOCK_EVN_SOCKET, project.getNum()));
+                List httpConfigs = environmentInfoDTO.getConfig().getHttpConfig();
+                if (CollectionUtils.isEmpty(httpConfigs)) {
+                    HttpConfig httpConfig = new HttpConfig();
+                    httpConfig.setUrl(StringUtils.join(baseUrl, MOCK_EVN_SOCKET, project.getNum()));
+                    httpConfigs.add(new HttpConfig());
+                }
             }
         }
 
diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java
index 5974b2a5fe..5a9c41ffd7 100644
--- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java
+++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java
@@ -317,18 +317,18 @@ public class EnvironmentControllerTests extends BaseTest {
         ApiEnvPlanProcessorConfig apiEnvPlanProcessorConfig = new ApiEnvPlanProcessorConfig();
         apiEnvPlanProcessorConfig.setProcessors(List.of(scriptProcessor, sqlProcessor));
         apiScript.setPlanProcessorConfig(apiEnvPlanProcessorConfig);
-        ScenarioScriptProcessor scenarioScript = new ScenarioScriptProcessor();
+        EnvScenarioScriptProcessor scenarioScript = new EnvScenarioScriptProcessor();
         scenarioScript.setScript("script");
         scenarioScript.setName("场景级别脚本");
         ApiEnvScenarioProcessorConfig apiEnvScenarioProcessorConfig = new ApiEnvScenarioProcessorConfig();
         apiEnvScenarioProcessorConfig.setProcessors(List.of(scenarioScript, sqlProcessor));
         apiScript.setScenarioProcessorConfig(apiEnvScenarioProcessorConfig);
-        RequestScriptProcessor stepScript = new RequestScriptProcessor();
+        EnvRequestScriptProcessor stepScript = new EnvRequestScriptProcessor();
         stepScript.setScript("script");
         stepScript.setName("步骤级别前置脚本前");
         stepScript.setBeforeStepScript(true);
         stepScript.setIgnoreProtocols(List.of("HTTP"));
-        RequestScriptProcessor stepScriptAfter = new RequestScriptProcessor();
+        EnvRequestScriptProcessor stepScriptAfter = new EnvRequestScriptProcessor();
         stepScriptAfter.setScript("script");
         stepScriptAfter.setName("步骤级别前置脚本后");
         stepScriptAfter.setBeforeStepScript(false);
diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/ApiPluginService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/ApiPluginService.java
index b7ae44a35a..7041d13628 100644
--- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/ApiPluginService.java
+++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/ApiPluginService.java
@@ -94,4 +94,24 @@ public class ApiPluginService {
         }
         return testElementPluginMap;
     }
+
+    /**
+     * 返回 MsTestElement 实现类与接口协议的映射
+     * @return
+     */
+    public Map, String> getTestElementProtocolMap() {
+        // 过滤协议插件
+        List protocolPlugins = pluginLoadService.getMsPluginManager()
+                .getPlugins()
+                .stream()
+                .filter(plugin -> plugin.getPlugin() instanceof AbstractProtocolPlugin)
+                .toList();
+
+        Map, String> testElementProtocolMap = new HashMap<>();
+        for (PluginWrapper plugin : protocolPlugins) {
+            List> extensionClasses = plugin.getPluginManager().getExtensionClasses(MsTestElement.class);
+            extensionClasses.forEach(clazz -> testElementProtocolMap.put((Class) clazz, ((AbstractProtocolPlugin) plugin.getPlugin()).getProtocol()));
+        }
+        return testElementProtocolMap;
+    }
 }