fix(接口测试): 引用原场景参数,变量优先级有误
--bug=1039759 --user=陈建星 【场景】-引用的场景配置使用原场景参数并优先原场景参数时,当前场景步骤参数优先级高于原场景参数 https://www.tapd.cn/55049933/s/1502253
This commit is contained in:
parent
820862bcaf
commit
da8d506311
|
@ -1,61 +1,63 @@
|
|||
package io.metersphere.api.parser.jmeter;
|
||||
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||
import io.metersphere.jmeter.mock.Mock;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Argument;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.modifiers.UserParameters;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-03-05 21:06
|
||||
*/
|
||||
public class JmeterTestElementParserHelper {
|
||||
|
||||
public static Arguments getArguments(String name) {
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(name + "_Arguments");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL));
|
||||
public static UserParameters getUserParameters(String name) {
|
||||
UserParameters userParameters = new UserParameters();
|
||||
userParameters.setEnabled(true);
|
||||
userParameters.setName(name + "_User Parameters");
|
||||
userParameters.setPerIteration(true);
|
||||
userParameters.setProperty(TestElement.TEST_CLASS, UserParameters.class.getName());
|
||||
userParameters.setProperty(TestElement.GUI_CLASS, JmeterAlias.USER_PARAMETERS_GUI);
|
||||
return userParameters;
|
||||
}
|
||||
|
||||
public static UserParameters getUserParameters(String name, List<? extends KeyValueParam> argumentList) {
|
||||
UserParameters arguments = getUserParameters(name);
|
||||
List<String> names = new LinkedList<>();
|
||||
List<Object> values = new LinkedList<>();
|
||||
List<Object> threadValues = new LinkedList<>();
|
||||
for (int i = 0; i < argumentList.size(); ++i) {
|
||||
String value = argumentList.get(i).getValue();
|
||||
String key = argumentList.get(i).getKey();
|
||||
names.add(key);
|
||||
values.add(Mock.buildFunctionCallString(value).replaceAll("[\r\n]", ""));
|
||||
}
|
||||
arguments.setNames(names);
|
||||
threadValues.add(values);
|
||||
arguments.setThreadLists(threadValues);
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static Arguments getArguments(String name, List<CommonVariables> argumentList) {
|
||||
Arguments arguments = getArguments(name);
|
||||
parse2ArgumentList(argumentList).forEach(arguments::addArgument);
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static List<Argument> parse2ArgumentList(List<CommonVariables> variables) {
|
||||
List<Argument> arguments = new ArrayList<>(variables.size());
|
||||
variables.forEach(variable -> {
|
||||
if (BooleanUtils.isFalse(variable.getEnable())) {
|
||||
return;
|
||||
}
|
||||
if (variable.isConstantValid()) {
|
||||
// 处理常量
|
||||
String value = StringUtils.isBlank(variable.getValue()) ? variable.getValue()
|
||||
: Mock.buildFunctionCallString(variable.getValue()).replaceAll("[\r\n]", "");
|
||||
arguments.add(new Argument(variable.getKey(), value, "="));
|
||||
} else if (variable.isListValid()) {
|
||||
// 处理 List 变量
|
||||
String[] arrays = variable.getValue().replaceAll("[\r\n]", "").split(",");
|
||||
for (int i = 0; i < arrays.length; i++) {
|
||||
arguments.add(new Argument(variable.getKey() + "_" + (i + 1), arrays[i], "="));
|
||||
}
|
||||
public static UserParameters getUserParameters(List<CommonVariables> constantVariables, List<CommonVariables> listVariables) {
|
||||
List<CommonVariables> variableResults = new ArrayList<>();
|
||||
listVariables.forEach(listVariable -> {
|
||||
String[] arrays = listVariable.getValue().replaceAll("[\r\n]", "").split(",");
|
||||
for (int i = 0; i < arrays.length; i++) {
|
||||
CommonVariables commonVariables = BeanUtils.copyBean(new CommonVariables(), listVariable);
|
||||
commonVariables.setKey(listVariable.getKey() + "_" + (i + 1));
|
||||
commonVariables.setValue(arrays[i]);
|
||||
variableResults.add(commonVariables);
|
||||
}
|
||||
});
|
||||
return arguments;
|
||||
variableResults.addAll(constantVariables);
|
||||
return getUserParameters(StringUtils.EMPTY, variableResults);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,9 +4,6 @@ package io.metersphere.api.parser.jmeter;
|
|||
import io.metersphere.api.constants.ApiConstants;
|
||||
import io.metersphere.api.dto.ApiParamConfig;
|
||||
import io.metersphere.api.dto.request.http.*;
|
||||
import io.metersphere.project.dto.environment.auth.BasicAuth;
|
||||
import io.metersphere.project.dto.environment.auth.DigestAuth;
|
||||
import io.metersphere.project.dto.environment.auth.HTTPAuthConfig;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.parser.jmeter.body.MsBodyConverter;
|
||||
import io.metersphere.api.parser.jmeter.body.MsBodyConverterFactory;
|
||||
|
@ -19,6 +16,9 @@ import io.metersphere.project.api.KeyValueEnableParam;
|
|||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
||||
import io.metersphere.project.dto.environment.GlobalParams;
|
||||
import io.metersphere.project.dto.environment.auth.BasicAuth;
|
||||
import io.metersphere.project.dto.environment.auth.DigestAuth;
|
||||
import io.metersphere.project.dto.environment.auth.HTTPAuthConfig;
|
||||
import io.metersphere.project.dto.environment.host.Host;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfig;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfigPathMatchRule;
|
||||
|
@ -29,8 +29,11 @@ import io.metersphere.sdk.util.LogUtils;
|
|||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.protocol.http.control.*;
|
||||
import org.apache.jmeter.modifiers.UserParameters;
|
||||
import org.apache.jmeter.protocol.http.control.AuthManager;
|
||||
import org.apache.jmeter.protocol.http.control.Authorization;
|
||||
import org.apache.jmeter.protocol.http.control.DNSCacheManager;
|
||||
import org.apache.jmeter.protocol.http.control.HeaderManager;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
@ -89,8 +92,8 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
HashTree httpTree = tree.add(sampler);
|
||||
|
||||
// 处理环境变量
|
||||
Arguments envArguments = getEnvArguments(msHTTPElement, envConfig);
|
||||
Optional.ofNullable(envArguments).ifPresent(httpTree::add);
|
||||
UserParameters userParameters = getEnvUserParameters(msHTTPElement, envConfig);
|
||||
Optional.ofNullable(userParameters).ifPresent(httpTree::add);
|
||||
|
||||
// 处理请求头
|
||||
HeaderManager httpHeader = getHttpHeader(msHTTPElement, apiParamConfig, httpConfig);
|
||||
|
@ -190,7 +193,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
* @param msHTTPElement
|
||||
* @param envInfo
|
||||
*/
|
||||
private Arguments getEnvArguments(MsHTTPElement msHTTPElement, EnvironmentInfoDTO envInfo) {
|
||||
private UserParameters getEnvUserParameters(MsHTTPElement msHTTPElement, EnvironmentInfoDTO envInfo) {
|
||||
if (envInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -200,7 +203,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
return null;
|
||||
}
|
||||
|
||||
return JmeterTestElementParserHelper.getArguments(msHTTPElement.getName(), envVariables);
|
||||
return JmeterTestElementParserHelper.getUserParameters(msHTTPElement.getName(), envVariables);
|
||||
}
|
||||
|
||||
private String getPath(MsHTTPElement msHTTPElement, HttpConfig httpConfig) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.dto.request.processors.MsProcessorConfig;
|
|||
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioStepConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioVariable;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||
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;
|
||||
|
@ -23,7 +24,8 @@ import io.metersphere.sdk.util.BeanUtils;
|
|||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.control.CriticalSectionController;
|
||||
import org.apache.jmeter.modifiers.UserParameters;
|
||||
import org.apache.jmeter.protocol.http.control.CookieManager;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
@ -32,6 +34,7 @@ import org.apache.jorphan.collections.HashTree;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -52,13 +55,18 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
ApiScenarioParamConfig config = getEnableConfig(msScenario, (ApiScenarioParamConfig) msParameter);
|
||||
EnvironmentInfoDTO envInfo = config.getEnvConfig(msScenario.getProjectId());
|
||||
|
||||
if (isRef(msScenario.getRefType())) {
|
||||
// 引用的场景中可能包含变量,场景包一层临界控制器,解决变量冲突
|
||||
tree = addCriticalSectionController(tree, msScenario);
|
||||
}
|
||||
|
||||
if (isRootScenario(msScenario.getRefType()) && msScenario.getScenarioConfig().getOtherConfig().getEnableGlobalCookie()) {
|
||||
// 根场景,设置共享cookie
|
||||
tree.add(getCookieManager());
|
||||
}
|
||||
|
||||
// 添加场景和环境变量
|
||||
addArguments(tree, msScenario, envInfo, config);
|
||||
addUserParameters(tree, msScenario, envInfo, config);
|
||||
|
||||
// 添加环境的前置
|
||||
addEnvScenarioProcessor(tree, msScenario, config, envInfo, true);
|
||||
|
@ -77,6 +85,24 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
addScenarioAssertions(tree, msScenario, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加临界控制器,解决变量冲突
|
||||
* @param tree
|
||||
* @param msScenario
|
||||
* @return
|
||||
*/
|
||||
public HashTree addCriticalSectionController(HashTree tree, MsScenario msScenario) {
|
||||
String name = msScenario.getName();
|
||||
boolean enable = msScenario.getEnable();
|
||||
CriticalSectionController criticalSectionController = new CriticalSectionController();
|
||||
criticalSectionController.setName(StringUtils.isNotEmpty(name) ? "Csc_" + name : "Scenario Critical Section Controller");
|
||||
criticalSectionController.setLockName(UUID.randomUUID().toString());
|
||||
criticalSectionController.setEnabled(enable);
|
||||
criticalSectionController.setProperty(TestElement.TEST_CLASS, CriticalSectionController.class.getName());
|
||||
criticalSectionController.setProperty(TestElement.GUI_CLASS, JmeterAlias.CRITICAL_SECTION_CONTROLLER_GUI);
|
||||
return tree.add(criticalSectionController);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加场景和环境变量
|
||||
*
|
||||
|
@ -84,7 +110,7 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
* @param msScenario
|
||||
* @param envInfo
|
||||
*/
|
||||
private void addArguments(HashTree tree, MsScenario msScenario, EnvironmentInfoDTO envInfo, ApiScenarioParamConfig config) {
|
||||
private void addUserParameters(HashTree tree, MsScenario msScenario, EnvironmentInfoDTO envInfo, ApiScenarioParamConfig config) {
|
||||
// 如果是根场景获取场景变量
|
||||
List<CommonVariables> commonVariables = getCommonVariables(msScenario.getScenarioConfig());
|
||||
|
||||
|
@ -132,9 +158,8 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
return;
|
||||
}
|
||||
|
||||
Arguments arguments = JmeterTestElementParserHelper.getArguments(msScenario.getName());
|
||||
JmeterTestElementParserHelper.parse2ArgumentList(constantVariables).forEach(arguments::addArgument);
|
||||
JmeterTestElementParserHelper.parse2ArgumentList(listVariables).forEach(arguments::addArgument);
|
||||
UserParameters arguments = JmeterTestElementParserHelper.getUserParameters(constantVariables, listVariables);
|
||||
|
||||
tree.add(arguments);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,4 +23,5 @@ public class JmeterAlias {
|
|||
public static final String ARGUMENTS_PANEL = "ArgumentsPanel";
|
||||
public static final String BEAN_SHELL_ASSERTION_GUI = "BeanShellAssertionGui";
|
||||
public static final String BEAN_SHELL_SAMPLER_GUI = "BeanShellSamplerGui";
|
||||
public static final String CRITICAL_SECTION_CONTROLLER_GUI = "CriticalSectionControllerGui";
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.metersphere.api.dto.ApiParamConfig;
|
|||
import io.metersphere.api.parser.jmeter.JmeterTestElementParserHelper;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterProperty;
|
||||
import io.metersphere.jmeter.mock.Mock;
|
||||
import io.metersphere.plugin.api.constants.ElementProperty;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
|
@ -15,7 +14,7 @@ import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
|||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.modifiers.UserParameters;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
||||
|
@ -72,7 +71,7 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter<Scri
|
|||
testElement.setProperty(JmeterProperty.SCRIPT_LANGUAGE, scriptLanguage.toLowerCase());
|
||||
}
|
||||
|
||||
public static Arguments getScriptArguments(ScriptProcessor scriptProcessor) {
|
||||
public static UserParameters getScriptArguments(ScriptProcessor scriptProcessor) {
|
||||
if (scriptProcessor == null || !scriptProcessor.isEnableCommonScript() || !scriptProcessor.isValid()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -91,11 +90,7 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter<Scri
|
|||
return null;
|
||||
}
|
||||
|
||||
Arguments arguments = JmeterTestElementParserHelper.getArguments(scriptProcessor.getName());
|
||||
for (KeyValueParam param : params) {
|
||||
arguments.addArgument(param.getKey(), Mock.buildFunctionCallString(param.getValue()), "=");
|
||||
}
|
||||
return arguments;
|
||||
return JmeterTestElementParserHelper.getUserParameters(scriptProcessor.getName(), params);
|
||||
}
|
||||
|
||||
public static boolean isJSR233(ScriptProcessor scriptProcessor) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.project.dto.environment.variables;
|
|||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.sdk.constants.VariableTypeConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
@ -11,17 +12,13 @@ import java.io.Serializable;
|
|||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class CommonVariables implements Serializable {
|
||||
public class CommonVariables extends KeyValueParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Schema(description = "id")
|
||||
private String id;
|
||||
@Schema(description = "变量名")
|
||||
private String key;
|
||||
@Schema(description = "变量类型 CONSTANT LIST JSON")
|
||||
private String paramType = VariableTypeConstants.CONSTANT.name();
|
||||
@Schema(description = "变量值")
|
||||
private String value;
|
||||
@Schema(description = "状态")
|
||||
private Boolean enable = true;
|
||||
@Schema(description = "描述")
|
||||
|
@ -32,17 +29,18 @@ public class CommonVariables implements Serializable {
|
|||
|
||||
@JsonIgnore
|
||||
public boolean isConstantValid() {
|
||||
return StringUtils.equals(this.paramType, VariableTypeConstants.CONSTANT.name()) && StringUtils.isNotEmpty(key);
|
||||
return (StringUtils.equals(this.paramType, VariableTypeConstants.CONSTANT.name()) || StringUtils.isBlank(paramType))
|
||||
&& isValid();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isListValid() {
|
||||
return StringUtils.equals(this.paramType, VariableTypeConstants.LIST.name()) && StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value) && value.indexOf(",") != -1;
|
||||
return StringUtils.equals(this.paramType, VariableTypeConstants.LIST.name()) && isValid() && isNotBlankValue() && getValue().indexOf(",") != -1;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isJsonValid() {
|
||||
return StringUtils.equals(this.paramType, VariableTypeConstants.JSON.name()) && StringUtils.isNotEmpty(key);
|
||||
return StringUtils.equals(this.paramType, VariableTypeConstants.JSON.name()) && isValid();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue