feat: 重构运行结束之后更新环境变量方法

重构运行结束之后更新环境变量方法
This commit is contained in:
song-tianyang 2021-05-20 17:35:49 +08:00 committed by 刘瑞斌
parent d4e2f350b3
commit 5fb95c1f93
12 changed files with 172 additions and 39 deletions

View File

@ -4,7 +4,9 @@ import org.apache.commons.lang3.StringUtils;
public class RunningParamKeys {
public static final String API_ENVIRONMENT_ID = "${__metersphere_evn_id}";
public static final String RUNNING_DEBUG_SAMPLER_NAME = "RunningDebugSampler";
public static final String API_ENVIRONMENT_ID = "${__metersphere_env_id}";
public static final String RUNNING_PARAMS_PREFIX = "MS.ENV.";
public static String escapeExprSpecialWord(String keyword) {
if (StringUtils.isNotBlank(keyword)) {

View File

@ -132,6 +132,7 @@ public class MsScenario extends MsTestElement {
ApiTestEnvironmentWithBLOBs environment = environmentService.get(this.environmentMap.get(projectId));
if (environment != null && environment.getConfig() != null) {
EnvironmentConfig env = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
env.setApiEnvironmentid(environment.getId());
envConfig.put(projectId, env);
if (StringUtils.equals(environment.getName(), MockConfigStaticData.MOCK_EVN_NAME)) {
this.setMockEnvironment(true);

View File

@ -1,6 +1,8 @@
package io.metersphere.api.dto.definition.request;
import com.alibaba.fastjson.annotation.JSONType;
import io.metersphere.api.dto.RunningParamKeys;
import io.metersphere.api.dto.definition.request.sampler.MsDebugSampler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.collections.CollectionUtils;
@ -34,10 +36,14 @@ public class MsThreadGroup extends MsTestElement {
cookieManager.setControlledByThread(false);
groupTree.add(cookieManager);
}
if (CollectionUtils.isNotEmpty(hashTree)) {
hashTree.forEach(el -> {
for (MsTestElement el : hashTree) {
el.toHashTree(groupTree, el.getHashTree(), config);
});
}
MsDebugSampler el = new MsDebugSampler();
el.setName(RunningParamKeys.RUNNING_DEBUG_SAMPLER_NAME);
el.toHashTree(groupTree, el.getHashTree(), config);
}
}

View File

@ -31,7 +31,7 @@ public class MsJSR223PostProcessor extends MsTestElement {
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
//替换Metersphere环境变量
script = StringUtils.replace(script,RunningParamKeys.API_ENVIRONMENT_ID,"\""+this.getUseEnviroment()+"\"");
script = StringUtils.replace(script,RunningParamKeys.API_ENVIRONMENT_ID,"\""+RunningParamKeys.RUNNING_PARAMS_PREFIX+this.getUseEnviroment()+".\"");
// 非导出操作且不是启用状态则跳过执行
if (!config.isOperating() && !this.isEnable()) {

View File

@ -31,7 +31,7 @@ public class MsJSR223PreProcessor extends MsTestElement {
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
//替换Metersphere环境变量
script = StringUtils.replace(script,RunningParamKeys.API_ENVIRONMENT_ID,"\""+this.getUseEnviroment()+"\"");
script = StringUtils.replace(script,RunningParamKeys.API_ENVIRONMENT_ID,"\""+RunningParamKeys.RUNNING_PARAMS_PREFIX+this.getUseEnviroment()+".\"");
// 非导出操作且不是启用状态则跳过执行
if (!config.isOperating() && !this.isEnable()) {

View File

@ -0,0 +1,70 @@
package io.metersphere.api.dto.definition.request.sampler;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.sampler.DebugSampler;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@JSONType(typeName = "TCPSampler")
public class MsDebugSampler extends MsTestElement {
@JSONField(ordinal = 40)
private String type = "DebugSampler";
@JSONField(ordinal = 41)
private boolean displayJMeterProperties = false;
@JSONField(ordinal = 42)
private boolean displayJMeterVariables = true;
@JSONField(ordinal = 43)
private boolean displaySystemProperties = false;
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
// 非导出操作且不是启用状态则跳过执行
if (!config.isOperating() && !this.isEnable()) {
return;
}
final HashTree groupTree = tree.add(debugSampler());
if (CollectionUtils.isNotEmpty(hashTree)) {
hashTree.forEach(el -> {
// 给所有孩子加一个父亲标志
el.setParent(this);
el.toHashTree(groupTree, el.getHashTree(), config);
});
}
}
private DebugSampler debugSampler() {
DebugSampler debugSampler = new DebugSampler();
debugSampler.setEnabled(this.isEnable());
if (StringUtils.isEmpty(this.getName())) {
this.setName("DebugSampler");
}
debugSampler.setName(this.getName());
debugSampler.setProperty(TestElement.TEST_CLASS, DebugSampler.class.getName());
debugSampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
debugSampler.setDisplaySystemProperties(this.displaySystemProperties);
debugSampler.setDisplayJMeterVariables(this.displayJMeterVariables);
debugSampler.setDisplayJMeterProperties(this.displayJMeterProperties);
//上面三行直接Set属性会导致DebugSampler构建时取不到值可能是JMeter的Bug,需要SetProperty
debugSampler.setProperty("displayJMeterProperties",this.displayJMeterProperties);
debugSampler.setProperty("displayJMeterVariables",this.displayJMeterVariables);
debugSampler.setProperty("displaySystemProperties",this.displaySystemProperties);
return debugSampler;
}
}

View File

@ -204,6 +204,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
if (httpConfig == null && !isURL(this.getUrl())) {
MSException.throwException("未匹配到环境,请检查环境配置");
}
if(StringUtils.isEmpty(this.useEnvironment)){
this.useEnvironment = config.getConfig().get(this.getProjectId()).getApiEnvironmentid();
}
String url = httpConfig.getProtocol() + "://" + httpConfig.getSocket();
// 补充如果是完整URL 则用自身URL

View File

@ -11,6 +11,7 @@ import java.util.List;
@Data
public class EnvironmentConfig {
private String apiEnvironmentid;
private CommonConfig commonConfig;
private HttpConfig httpConfig;
private List<DatabaseConfig> databaseConfigs;

View File

@ -2,6 +2,7 @@ package io.metersphere.api.jmeter;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.RunningParamKeys;
import io.metersphere.api.dto.automation.ApiTestReportVariable;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.service.*;
@ -65,6 +66,8 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
private TestPlanApiCaseService testPlanApiCaseService;
private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService;
public String runMode = ApiRunMode.RUN.name();
// 测试ID
@ -129,6 +132,10 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
if (testPlanApiCaseService == null) {
LogUtil.error("testPlanApiCaseService is required");
}
apiEnvironmentRunningParamService = CommonBeanFactory.getBean(ApiEnvironmentRunningParamService.class);
if(apiEnvironmentRunningParamService == null){
LogUtil.error("apiEnvironmentRunningParamService is required");
}
super.setupTest(context);
}
@ -149,40 +156,45 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
queue.forEach(result -> {
// 线程名称: <场景名> <场景Index>-<请求Index>, 例如Scenario 2-1
String scenarioName = StringUtils.substringBeforeLast(result.getThreadName(), THREAD_SPLIT);
String index = StringUtils.substringAfterLast(result.getThreadName(), THREAD_SPLIT);
String scenarioId = StringUtils.substringBefore(index, ID_SPLIT);
ScenarioResult scenarioResult;
if (!scenarios.containsKey(scenarioId)) {
scenarioResult = new ScenarioResult();
try {
scenarioResult.setId(Integer.parseInt(scenarioId));
} catch (Exception e) {
scenarioResult.setId(0);
LogUtil.error("场景ID转换异常: " + e.getMessage());
if(StringUtils.equals(result.getSampleLabel(), RunningParamKeys.RUNNING_DEBUG_SAMPLER_NAME)){
String evnStr = result.getResponseDataAsString();
apiEnvironmentRunningParamService.parseEvn(evnStr);
}else {
String scenarioName = StringUtils.substringBeforeLast(result.getThreadName(), THREAD_SPLIT);
String index = StringUtils.substringAfterLast(result.getThreadName(), THREAD_SPLIT);
String scenarioId = StringUtils.substringBefore(index, ID_SPLIT);
ScenarioResult scenarioResult;
if (!scenarios.containsKey(scenarioId)) {
scenarioResult = new ScenarioResult();
try {
scenarioResult.setId(Integer.parseInt(scenarioId));
} catch (Exception e) {
scenarioResult.setId(0);
LogUtil.error("场景ID转换异常: " + e.getMessage());
}
scenarioResult.setName(scenarioName);
scenarios.put(scenarioId, scenarioResult);
} else {
scenarioResult = scenarios.get(scenarioId);
}
scenarioResult.setName(scenarioName);
scenarios.put(scenarioId, scenarioResult);
} else {
scenarioResult = scenarios.get(scenarioId);
if (result.isSuccessful()) {
scenarioResult.addSuccess();
testResult.addSuccess();
} else {
scenarioResult.addError(result.getErrorCount());
testResult.addError(result.getErrorCount());
}
RequestResult requestResult = getRequestResult(result);
scenarioResult.getRequestResults().add(requestResult);
scenarioResult.addResponseTime(result.getTime());
testResult.addPassAssertions(requestResult.getPassAssertions());
testResult.addTotalAssertions(requestResult.getTotalAssertions());
scenarioResult.addPassAssertions(requestResult.getPassAssertions());
scenarioResult.addTotalAssertions(requestResult.getTotalAssertions());
}
if (result.isSuccessful()) {
scenarioResult.addSuccess();
testResult.addSuccess();
} else {
scenarioResult.addError(result.getErrorCount());
testResult.addError(result.getErrorCount());
}
RequestResult requestResult = getRequestResult(result);
scenarioResult.getRequestResults().add(requestResult);
scenarioResult.addResponseTime(result.getTime());
testResult.addPassAssertions(requestResult.getPassAssertions());
testResult.addTotalAssertions(requestResult.getTotalAssertions());
scenarioResult.addPassAssertions(requestResult.getPassAssertions());
scenarioResult.addTotalAssertions(requestResult.getTotalAssertions());
});
testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId));

View File

@ -1253,6 +1253,7 @@ public class ApiAutomationService {
map.keySet().forEach(id -> {
ApiTestEnvironmentWithBLOBs environment = environmentService.get(map.get(id));
EnvironmentConfig env = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
env.setApiEnvironmentid(environment.getId());
envConfig.put(id, env);
});
}

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.commons.exception.MSException;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -26,7 +27,7 @@ public class ApiEnvironmentRunningParamService {
}
ApiTestEnvironmentWithBLOBs apiTestEnvironmentWithBLOBs = apiTestEnvironmentService.get(enviromentId);
if(apiTestEnvironmentWithBLOBs == null ){
MSException.throwException("Unable find environment!");
return;
}
JSONObject configObj = JSONObject.parseObject(apiTestEnvironmentWithBLOBs.getConfig());
@ -89,4 +90,40 @@ public class ApiEnvironmentRunningParamService {
apiTestEnvironmentService.update(apiTestEnvironmentWithBLOBs);
}
public void parseEvn(String envStr) {
String [] envStringArr = envStr.split("\n");
for (String env :envStringArr) {
if(StringUtils.contains(env,"=")){
String [] envItem = env.split("=");
if(envItem.length > 1){
String jmeterVarKey = envItem[0];
if(this.checkValidity(jmeterVarKey,"MS.ENV.")){
String [] envAndKeyArr = jmeterVarKey.substring("MS.ENV.".length()).split("\\.");
String envId = envAndKeyArr[0];
String [] keyArr = ArrayUtils.remove(envAndKeyArr,0);
String key = StringUtils.join(keyArr,".");
String [] valueArr = ArrayUtils.remove(envItem,0);
String value = StringUtils.join(valueArr,"=");
if(StringUtils.isNoneEmpty(envId,key,value)){
this.addParam(envId,key,value);
}
}
}
}
}
}
public boolean checkValidity (String str, String regex) {
if(str == null){
return false;
}
if(regex == null){
return true;
}
if (str.startsWith(regex)) {
return true;
} else {
return false;
}
}
}

View File

@ -51,7 +51,7 @@
},
{
title: this.$t('api_test.request.processor.param_environment_set_global_variable'),
value: 'io.metersphere.api.jmeter.RunningParam.setParam(${__metersphere_evn_id},"key","value")',
value: 'vars.put(${__metersphere_env_id}+"key","value")',
},
{
title: this.$t('api_test.request.processor.code_add_report_length'),