fix(接口测试): 修复多层嵌套引用场景禁用状态不生效问题
【[接口测试]github24932接口自动化,场景内引用多层级场景时,设置场景步骤为“禁用”状态会失效】https://www.tapd.cn/55049933/bugtrace/bugs/view?bug_id=1155049933001026993 Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
parent
aeb7688084
commit
6ec19ba734
|
@ -28,6 +28,7 @@ import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
|||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ElementConstants;
|
||||
import io.metersphere.commons.constants.MsHashTreeConstants;
|
||||
import io.metersphere.commons.constants.PropertyConstant;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
|
@ -68,7 +69,6 @@ import org.apache.jorphan.collections.HashTree;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -82,6 +82,8 @@ public class ElementUtil {
|
|||
private static final String ASSERTIONS = ElementConstants.ASSERTIONS;
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
private static final String TEST_BEAN_GUI = "TestBeanGUI";
|
||||
private final static String SCENARIO_REF = "SCENARIO-REF-STEP";
|
||||
|
||||
public final static List<String> scriptList = new ArrayList<String>() {{
|
||||
this.add(ElementConstants.JSR223);
|
||||
this.add(ElementConstants.JSR223_PRE);
|
||||
|
@ -91,7 +93,6 @@ public class ElementUtil {
|
|||
public static final String CLAZZ = "clazzName";
|
||||
|
||||
|
||||
|
||||
public static Map<String, EnvironmentConfig> getEnvironmentConfig(String environmentId, String projectId) {
|
||||
BaseEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(BaseEnvironmentService.class);
|
||||
ApiTestEnvironmentWithBLOBs environment = apiTestEnvironmentService.get(environmentId);
|
||||
|
@ -463,73 +464,74 @@ public class ElementUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<JSONObject> mergeHashTree(List<JSONObject> sourceHashTree, List<JSONObject> targetHashTree) {
|
||||
public static List<JSONObject> mergeHashTree(List<JSONObject> sources, List<JSONObject> targets) {
|
||||
try {
|
||||
List<String> sourceIds = new ArrayList<>();
|
||||
List<String> delIds = new ArrayList<>();
|
||||
Map<String, JSONObject> updateMap = new HashMap<>();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(targetHashTree)) {
|
||||
for (int i = 0; i < targetHashTree.size(); i++) {
|
||||
JSONObject item = targetHashTree.get(i);
|
||||
item.put("disabled", true);
|
||||
if (StringUtils.isNotEmpty(item.optString("id"))) {
|
||||
updateMap.put(item.optString("id"), item);
|
||||
if (CollectionUtils.isNotEmpty(targets)) {
|
||||
for (int i = 0; i < targets.size(); i++) {
|
||||
JSONObject item = targets.get(i);
|
||||
item.put(MsHashTreeConstants.DISABLED, true);
|
||||
item.put(ElementConstants.REF_ENABLE, true);
|
||||
if (StringUtils.isNotEmpty(item.optString(ElementConstants.ID))) {
|
||||
updateMap.put(item.optString(ElementConstants.ID), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 找出待更新内容和源已经被删除的内容
|
||||
if (CollectionUtils.isNotEmpty(sourceHashTree)) {
|
||||
for (int i = 0; i < sourceHashTree.size(); i++) {
|
||||
JSONObject source = sourceHashTree.get(i);
|
||||
if (source != null) {
|
||||
sourceIds.add(source.optString("id"));
|
||||
if (!StringUtils.equals(source.optString("label"), "SCENARIO-REF-STEP") && StringUtils.isNotEmpty(source.optString("id"))) {
|
||||
if (updateMap.containsKey(source.optString("id"))) {
|
||||
sourceHashTree.set(i, updateMap.get(source.optString("id")));
|
||||
if (CollectionUtils.isNotEmpty(sources)) {
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
JSONObject object = sources.get(i);
|
||||
if (object == null) {
|
||||
continue;
|
||||
}
|
||||
sourceIds.add(object.optString(ElementConstants.ID));
|
||||
if (!StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
||||
&& StringUtils.isNotEmpty(object.optString(ElementConstants.ID))) {
|
||||
if (updateMap.containsKey(object.optString(ElementConstants.ID))) {
|
||||
sources.set(i, updateMap.get(object.optString(ElementConstants.ID)));
|
||||
updateMap.remove(object.optString(ElementConstants.ID));
|
||||
} else {
|
||||
delIds.add(source.optString("id"));
|
||||
delIds.add(object.optString(ElementConstants.ID));
|
||||
}
|
||||
}
|
||||
// 历史数据兼容
|
||||
if (!source.has("id") && !StringUtils.equals(source.optString("label"), "SCENARIO-REF-STEP") && i < targetHashTree.size()) {
|
||||
sourceHashTree.set(i, targetHashTree.get(i));
|
||||
if (!object.has(ElementConstants.ID)
|
||||
&& !StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
||||
&& i < targets.size()) {
|
||||
sources.set(i, targets.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加少的步骤
|
||||
if (MapUtils.isNotEmpty(updateMap)) {
|
||||
updateMap.forEach((k, v) -> {
|
||||
sources.add(v);
|
||||
});
|
||||
}
|
||||
|
||||
// 删除多余的步骤
|
||||
for (int i = 0; i < sourceHashTree.size(); i++) {
|
||||
JSONObject source = sourceHashTree.get(i);
|
||||
if (delIds.contains(source.optString("id"))) {
|
||||
sourceHashTree.remove(i);
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
JSONObject source = sources.get(i);
|
||||
if (delIds.contains(source.optString(ElementConstants.ID))) {
|
||||
sources.remove(i);
|
||||
}
|
||||
}
|
||||
// 补充新增的源引用步骤
|
||||
if (CollectionUtils.isNotEmpty(targetHashTree)) {
|
||||
for (int i = 0; i < targetHashTree.size(); i++) {
|
||||
JSONObject item = sourceHashTree.get(i);
|
||||
if (!sourceIds.contains(item.optString("id"))) {
|
||||
sourceHashTree.add(item);
|
||||
if (CollectionUtils.isNotEmpty(targets)) {
|
||||
for (int i = 0; i < targets.size(); i++) {
|
||||
JSONObject item = sources.get(i);
|
||||
if (!sourceIds.contains(item.optString(ElementConstants.ID))) {
|
||||
sources.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return targetHashTree;
|
||||
return targets;
|
||||
}
|
||||
return sourceHashTree;
|
||||
}
|
||||
|
||||
public static String hashTreeToString(HashTree hashTree) {
|
||||
try (ByteArrayOutputStream bas = new ByteArrayOutputStream()) {
|
||||
SaveService.saveTree(hashTree, bas);
|
||||
return bas.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
io.metersphere.plugin.core.utils.LogUtil.warn("HashTree error, can't log jmx scenarioDefinition");
|
||||
}
|
||||
return null;
|
||||
return sources;
|
||||
}
|
||||
|
||||
public static String getResourceId(String resourceId, ParameterConfig config, MsTestElement parent, String indexPath) {
|
||||
|
@ -1170,4 +1172,15 @@ public class ElementUtil {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static boolean isEnable(MsTestElement element, ParameterConfig config) {
|
||||
String path = ElementUtil.getFullIndexPath(element, "");
|
||||
if (StringUtils.isNotBlank(path) && path.endsWith("_")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
String key = StringUtils.join(element.getId(), "_", path);
|
||||
if (config.getKeyMap().containsKey(key)) {
|
||||
return config.getKeyMap().get(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.metersphere.environment.service.BaseEnvironmentService;
|
|||
import io.metersphere.plugin.core.MsParameter;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.MsHashTreeService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -27,7 +28,6 @@ import org.apache.commons.lang3.BooleanUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -72,7 +72,7 @@ public class MsScenario extends MsTestElement {
|
|||
if (this.getReferenced() != null && this.getReferenced().equals(MsTestElementConstants.Deleted.name())) {
|
||||
return;
|
||||
} else if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())
|
||||
&& !this.setRefScenario(hashTree)) {
|
||||
&& !this.setRefScenario(hashTree, config)) {
|
||||
return;
|
||||
}
|
||||
// 设置共享cookie
|
||||
|
@ -137,6 +137,7 @@ public class MsScenario extends MsTestElement {
|
|||
}
|
||||
if ((this.variableEnable == null && this.mixEnable == null)
|
||||
|| BooleanUtils.isTrue(this.variableEnable) || BooleanUtils.isTrue(this.mixEnable)) {
|
||||
newConfig.setKeyMap(config.getKeyMap());
|
||||
ElementUtil.addCsvDataSet(scenarioTree, variables, this.isEnvironmentEnable() ? newConfig : config, "shareMode.group");
|
||||
ElementUtil.addCounter(scenarioTree, variables);
|
||||
ElementUtil.addRandom(scenarioTree, variables);
|
||||
|
@ -205,13 +206,21 @@ public class MsScenario extends MsTestElement {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean setRefScenario(List<MsTestElement> hashTree) {
|
||||
private boolean setRefScenario(List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
try {
|
||||
ApiScenarioMapper apiAutomationService = CommonBeanFactory.getBean(ApiScenarioMapper.class);
|
||||
ApiScenarioWithBLOBs scenario = apiAutomationService.selectByPrimaryKey(this.getId());
|
||||
if (scenario != null && StringUtils.isNotEmpty(scenario.getScenarioDefinition())) {
|
||||
JSONObject elementOrg = JSONUtil.parseObject(scenario.getScenarioDefinition());
|
||||
JSONObject element = setRefEnable(this, elementOrg);
|
||||
JSONObject element = JSONUtil.parseObject(scenario.getScenarioDefinition());
|
||||
String path = ElementUtil.getFullIndexPath(this, "");
|
||||
if (path.endsWith("_")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
element.put(MsHashTreeService.INDEX, path);
|
||||
boolean enable = config.getKeyMap().get(this.getId() + "_" + path);
|
||||
if (!enable) {
|
||||
return false;
|
||||
}
|
||||
// 历史数据处理
|
||||
ElementUtil.dataFormatting(element.optJSONArray(ElementConstants.HASH_TREE));
|
||||
this.setName(scenario.getName());
|
||||
|
@ -231,43 +240,11 @@ public class MsScenario extends MsTestElement {
|
|||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
LoggerUtil.error(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static JSONObject setRefEnable(MsTestElement targetElement, JSONObject orgElement) {
|
||||
if (JSONObject.NULL.equals(orgElement) || targetElement == null) {
|
||||
return orgElement;
|
||||
}
|
||||
if (!orgElement.optBoolean(MsHashTreeService.ENABLE)) {
|
||||
orgElement.put(MsHashTreeService.ENABLE, false);
|
||||
} else {
|
||||
orgElement.put(MsHashTreeService.ENABLE, targetElement.isEnable());
|
||||
}
|
||||
try {
|
||||
if (orgElement.has(MsHashTreeService.HASH_TREE)) {
|
||||
JSONArray orgJSONArray = orgElement.optJSONArray(MsHashTreeService.HASH_TREE);
|
||||
LinkedList<MsTestElement> hashTree = targetElement.getHashTree();
|
||||
if (orgJSONArray != null && CollectionUtils.isNotEmpty(hashTree)) {
|
||||
orgJSONArray.forEach(obj -> {
|
||||
JSONObject orgJsonObject = (JSONObject) obj;
|
||||
hashTree.forEach(targetObj -> {
|
||||
if (StringUtils.equals(orgJsonObject.optString(MsHashTreeService.ID), targetObj.getId())
|
||||
&& StringUtils.equals(orgJsonObject.optString(MsHashTreeService.INDEX), targetObj.getIndex())) {
|
||||
setRefEnable(targetObj, orgJsonObject);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex, ex.getMessage());
|
||||
return orgElement;
|
||||
}
|
||||
return orgElement;
|
||||
}
|
||||
|
||||
private void setNewConfig(Map<String, EnvironmentConfig> envConfig, ParameterConfig newConfig) {
|
||||
if (this.isEnvironmentEnable()) {
|
||||
ApiScenarioMapper apiScenarioMapper = CommonBeanFactory.getBean(ApiScenarioMapper.class);
|
||||
|
|
|
@ -102,6 +102,10 @@ public class ParameterConfig extends MsParameter {
|
|||
private List<String> excludeScenarioIds = new ArrayList<>();
|
||||
|
||||
private List<String> csvFilePaths = new ArrayList<>();
|
||||
/**
|
||||
* 启用或禁用记录
|
||||
*/
|
||||
private Map<String, Boolean> keyMap = new HashMap<>();
|
||||
|
||||
|
||||
public boolean isEffective(String projectId) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.dto.definition.request.sampler;
|
||||
|
||||
import io.metersphere.api.dto.definition.request.ElementUtil;
|
||||
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||
import io.metersphere.commons.constants.ElementConstants;
|
||||
import io.metersphere.plugin.core.MsParameter;
|
||||
|
@ -37,6 +38,9 @@ public class MsDebugSampler extends MsTestElement {
|
|||
if (!config.isOperating() && !this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (!ElementUtil.isEnable(this, config)) {
|
||||
return;
|
||||
}
|
||||
final HashTree groupTree = tree.add(debugSampler());
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
|
|
|
@ -71,6 +71,9 @@ public class MsDubboSampler extends MsTestElement {
|
|||
if (this.getReferenced() != null && "Deleted".equals(this.getReferenced())) {
|
||||
return;
|
||||
}
|
||||
if (!ElementUtil.isEnable(this, config)) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
boolean ref = this.setRefElement();
|
||||
if (!ref) {
|
||||
|
|
|
@ -96,12 +96,16 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
if (StringUtils.isEmpty(this.getEnvironmentId())) {
|
||||
this.setEnvironmentId(this.useEnvironment);
|
||||
}
|
||||
|
||||
// 非导出操作,且不是启用状态则跳过执行Ms
|
||||
if (!config.isOperating() && !this.isEnable()) {
|
||||
return;
|
||||
} else if (config.isOperating() && StringUtils.isNotEmpty(config.getOperatingSampleTestName())) {
|
||||
this.setName(config.getOperatingSampleTestName());
|
||||
}
|
||||
if (!ElementUtil.isEnable(this, config)) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
boolean ref = this.setRefElement();
|
||||
if (!ref) {
|
||||
|
|
|
@ -66,6 +66,9 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
} else if (config.isOperating() && StringUtils.isNotEmpty(config.getOperatingSampleTestName())) {
|
||||
this.setName(config.getOperatingSampleTestName());
|
||||
}
|
||||
if (!ElementUtil.isEnable(this, config)) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
boolean ref = this.setRefElement();
|
||||
if (!ref) {
|
||||
|
|
|
@ -90,6 +90,9 @@ public class MsTCPSampler extends MsTestElement {
|
|||
} else if (config.isOperating() && StringUtils.isNotEmpty(config.getOperatingSampleTestName())) {
|
||||
this.setName(config.getOperatingSampleTestName());
|
||||
}
|
||||
if (!ElementUtil.isEnable(this, config)) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
boolean ref = this.setRefElement();
|
||||
if (!ref) {
|
||||
|
|
|
@ -34,10 +34,7 @@ import io.metersphere.dto.*;
|
|||
import io.metersphere.environment.service.BaseEnvGroupProjectService;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.RedisTemplateService;
|
||||
import io.metersphere.service.ServiceUtils;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.service.*;
|
||||
import io.metersphere.service.definition.TcpApiParamService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.service.scenario.ApiScenarioReportStructureService;
|
||||
|
@ -451,6 +448,9 @@ public class ApiScenarioExecuteService {
|
|||
uploadBodyFiles(request.getBodyFileRequestIds(), bodyFiles);
|
||||
FileUtils.createBodyFiles(request.getScenarioFileIds(), scenarioFiles);
|
||||
this.testElement(request);
|
||||
Map<String, Boolean> keyMap = MsHashTreeService.getIndexKeyMap(request.getTestElement(), "");
|
||||
config.setKeyMap(keyMap);
|
||||
|
||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||
String runMode = StringUtils.isEmpty(request.getRunMode()) ? ApiRunMode.SCENARIO.name() : request.getRunMode();
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree);
|
||||
|
|
|
@ -31,6 +31,10 @@ public class ElementConstants {
|
|||
public static final String ASSERTIONS = "Assertions";
|
||||
public static final String EXTRACT = "Extract";
|
||||
public static final String STEP_CREATED = "Created";
|
||||
public static final String INDEX = "index";
|
||||
public static final String ID = "id";
|
||||
public static final String REF_ENABLE = "refEnable";
|
||||
|
||||
public final static List<String> REQUESTS = new ArrayList<String>() {{
|
||||
this.add(ElementConstants.HTTP_SAMPLER);
|
||||
this.add(ElementConstants.DUBBO_SAMPLER);
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.metersphere.dto.ProjectJarConfig;
|
|||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.environment.service.BaseEnvGroupProjectService;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.MsHashTreeService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import io.metersphere.vo.BooleanPool;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
@ -159,6 +160,9 @@ public class GenerateHashTreeUtil {
|
|||
if (runRequest.isRetryEnable() && runRequest.getRetryNum() > 0) {
|
||||
config.setRetryNum(runRequest.getRetryNum());
|
||||
}
|
||||
|
||||
Map<String, Boolean> keyMap = MsHashTreeService.getIndexKeyMap(element, "");
|
||||
config.setKeyMap(keyMap);
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
||||
|
||||
LoggerUtil.info("场景资源:" + item.getName() + ", 生成执行脚本JMX成功", runRequest.getReportId());
|
||||
|
|
|
@ -19,15 +19,18 @@ import io.metersphere.commons.utils.JSON;
|
|||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.dto.ProjectConfig;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.definition.ApiDefinitionService;
|
||||
import io.metersphere.service.definition.ApiTestCaseService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -97,6 +100,8 @@ public class MsHashTreeService {
|
|||
private static final String DATASOURCEID = "dataSourceId";
|
||||
private static final String RESULT_VARIABLE = "resultVariable";
|
||||
private static final String ENV_Id = "environmentId";
|
||||
private static final String PARENT_INDEX = "parentIndex";
|
||||
|
||||
|
||||
private final static String JSON_PATH="jsonPath";
|
||||
private final static String JSR223="jsr223";
|
||||
|
@ -310,7 +315,7 @@ public class MsHashTreeService {
|
|||
}
|
||||
}
|
||||
|
||||
private JSONObject setRefScenario(JSONObject element) {
|
||||
private JSONObject setRefScenario(JSONObject element, Map<String, Boolean> keyMap) {
|
||||
boolean enable = element.has(ENABLE) ? element.optBoolean(ENABLE) : true;
|
||||
if (!element.has(MIX_ENABLE)) {
|
||||
element.put(MIX_ENABLE, false);
|
||||
|
@ -327,7 +332,21 @@ public class MsHashTreeService {
|
|||
element.put(ENV_MAP, JSON.parseObject(scenarioWithBLOBs.getEnvironmentJson(), Map.class));
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(element.optString(REFERENCED), REF)) {
|
||||
element = setRefEnable(element, JSONUtil.parseObject(scenarioWithBLOBs.getScenarioDefinition()));
|
||||
JSONObject object = JSONUtil.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||
object.put(PARENT_INDEX, element.optString(PARENT_INDEX));
|
||||
object.put(INDEX, element.optString(INDEX));
|
||||
if (object.has(ENABLE) && BooleanUtils.isFalse(object.optBoolean(ENABLE))) {
|
||||
enable = false;
|
||||
object.put(REF_ENABLE, true);
|
||||
} else {
|
||||
String indexStr = object.has(PARENT_INDEX) && StringUtils.isNotBlank(object.optString(PARENT_INDEX)) ?
|
||||
StringUtils.join(object.optString(PARENT_INDEX), "_", object.optString(INDEX)) : object.optString(INDEX);
|
||||
if (keyMap.containsKey(element.optString(ID) + indexStr)) {
|
||||
enable = keyMap.get(element.optString(ID) + indexStr);
|
||||
object.put(ENABLE, enable);
|
||||
}
|
||||
}
|
||||
element = object;
|
||||
element.put(REFERENCED, REF);
|
||||
element.put(NAME, scenarioWithBLOBs.getName());
|
||||
}
|
||||
|
@ -354,69 +373,76 @@ public class MsHashTreeService {
|
|||
return element;
|
||||
}
|
||||
|
||||
public static JSONObject setRefEnable(JSONObject targetElement, JSONObject orgElement) {
|
||||
if (orgElement == null || targetElement == null) {
|
||||
return orgElement;
|
||||
public static Map<String, Boolean> getIndexKeyMap(JSONObject element, String parentIndex) {
|
||||
Map<String, Boolean> indexKeyMap = new HashMap<>();
|
||||
StringBuilder builder = new StringBuilder(parentIndex);
|
||||
if (element.has(ENABLE) && element.has(ID) && element.has(INDEX)) {
|
||||
builder.append("_").append(element.getString(INDEX));
|
||||
String key = StringUtils.join(element.optString(ID), builder.toString());
|
||||
indexKeyMap.put(key, element.optBoolean(ENABLE));
|
||||
}
|
||||
if (!orgElement.optBoolean(ENABLE)) {
|
||||
orgElement.put(ENABLE, false);
|
||||
orgElement.put(REF_ENABLE, true);
|
||||
} else {
|
||||
orgElement.put(ENABLE, targetElement.optBoolean(ENABLE));
|
||||
}
|
||||
if (targetElement.optBoolean(REF_ENABLE)) {
|
||||
orgElement.put(REF_ENABLE, targetElement.optBoolean(REF_ENABLE));
|
||||
}
|
||||
try {
|
||||
if (orgElement.has(HASH_TREE)) {
|
||||
JSONArray org = orgElement.optJSONArray(HASH_TREE);
|
||||
JSONArray target = targetElement.optJSONArray(HASH_TREE);
|
||||
if (org != null && target != null) {
|
||||
org.forEach(obj -> {
|
||||
JSONObject childOrg = (JSONObject) obj;
|
||||
target.forEach(targetObj -> {
|
||||
JSONObject childTarget = (JSONObject) targetObj;
|
||||
if (StringUtils.equals(childOrg.optString(ID), childTarget.optString(ID))
|
||||
&& StringUtils.equals(childOrg.optString(INDEX), childTarget.optString(INDEX))) {
|
||||
setRefEnable(childTarget, childOrg);
|
||||
}
|
||||
});
|
||||
if (element.has(HASH_TREE)) {
|
||||
element.getJSONArray(HASH_TREE).forEach(item -> {
|
||||
JSONObject obj = (JSONObject) item;
|
||||
indexKeyMap.putAll(getIndexKeyMap(obj, builder.toString()));
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e, e.getMessage());
|
||||
return orgElement;
|
||||
}
|
||||
return orgElement;
|
||||
return indexKeyMap;
|
||||
}
|
||||
|
||||
public void dataFormatting(JSONArray hashTree, List<String> caseIds) {
|
||||
public void dataFormatting(JSONArray hashTree, List<String> caseIds, Map<String, Boolean> keyMap, String parentIndex) {
|
||||
for (int i = 0; i < hashTree.length(); i++) {
|
||||
JSONObject element = hashTree.optJSONObject(i);
|
||||
// 设置父级索引
|
||||
element.put(PARENT_INDEX, parentIndex);
|
||||
|
||||
if (element != null && StringUtils.equalsIgnoreCase(element.optString(TYPE), SCENARIO)) {
|
||||
element = this.setRefScenario(element);
|
||||
element = this.setRefScenario(element, keyMap);
|
||||
hashTree.put(i, element);
|
||||
} else if (element != null && ElementConstants.REQUESTS.contains(element.optString(TYPE))) {
|
||||
setCaseEnable(element, keyMap, parentIndex);
|
||||
this.getCaseIds(element, caseIds);
|
||||
hashTree.put(i, element);
|
||||
}
|
||||
if (element.has(HASH_TREE)) {
|
||||
JSONArray elementJSONArray = element.optJSONArray(HASH_TREE);
|
||||
dataFormatting(elementJSONArray, caseIds);
|
||||
String indexStr = StringUtils.join(parentIndex, "_", element.optString(INDEX));
|
||||
dataFormatting(elementJSONArray, caseIds, keyMap, indexStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dataFormatting(JSONObject element, List<String> caseIds) {
|
||||
if (element != null && StringUtils.equalsIgnoreCase(element.optString(TYPE), SCENARIO)) {
|
||||
element = this.setRefScenario(element);
|
||||
} else if (element != null && ElementConstants.REQUESTS.contains(element.optString(TYPE))) {
|
||||
public void dataFormatting(JSONObject element, List<String> caseIds, Map<String, Boolean> keyMap) {
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
// 设置父级索引
|
||||
String parentIndex = element.has(PARENT_INDEX) ?
|
||||
StringUtils.join(element.optString(PARENT_INDEX), "_", element.optString(INDEX))
|
||||
: element.optString(INDEX);
|
||||
|
||||
element.put(PARENT_INDEX, parentIndex);
|
||||
if (StringUtils.equalsIgnoreCase(element.optString(TYPE), SCENARIO)) {
|
||||
element = this.setRefScenario(element, keyMap);
|
||||
} else if (ElementConstants.REQUESTS.contains(element.optString(TYPE))) {
|
||||
setCaseEnable(element, keyMap, parentIndex);
|
||||
this.getCaseIds(element, caseIds);
|
||||
}
|
||||
if (element != null && element.has(HASH_TREE)) {
|
||||
if (element.has(HASH_TREE)) {
|
||||
JSONArray elementJSONArray = element.optJSONArray(HASH_TREE);
|
||||
dataFormatting(elementJSONArray, caseIds);
|
||||
dataFormatting(elementJSONArray, caseIds, keyMap, parentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCaseEnable(JSONObject element, Map<String, Boolean> keyMap, String parentIndex) {
|
||||
if (element.has(ENABLE) && BooleanUtils.isFalse(element.optBoolean(ENABLE))) {
|
||||
element.put(ENABLE, false);
|
||||
element.put(REF_ENABLE, true);
|
||||
} else {
|
||||
String indexStr = StringUtils.join(element.optString(ID), parentIndex, "_", element.optString(INDEX));
|
||||
if (keyMap.containsKey(indexStr)) {
|
||||
element.put(ENABLE, keyMap.get(indexStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,4 +473,19 @@ public class MsHashTreeService {
|
|||
}
|
||||
}
|
||||
|
||||
public static Map<String, Boolean> getIndexKeyMap(MsTestElement element, String parentIndex) {
|
||||
Map<String, Boolean> indexKeyMap = new HashMap<>();
|
||||
StringBuilder builder = new StringBuilder(parentIndex);
|
||||
if (StringUtils.isNotBlank(element.getId()) && StringUtils.isNotBlank(element.getIndex())) {
|
||||
builder.append("_").append(element.getIndex());
|
||||
String key = StringUtils.join(element.getId(), builder.toString());
|
||||
indexKeyMap.put(key, element.isEnable());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(element.getHashTree())) {
|
||||
element.getHashTree().forEach(item -> {
|
||||
indexKeyMap.putAll(getIndexKeyMap(item, builder.toString()));
|
||||
});
|
||||
}
|
||||
return indexKeyMap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,9 @@ public class ApiScenarioReportStructureService {
|
|||
MsHashTreeService hashTreeService = CommonBeanFactory.getBean(MsHashTreeService.class);
|
||||
assert hashTreeService != null;
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
hashTreeService.dataFormatting(element, caseIds);
|
||||
Map<String, Boolean> keyMap = MsHashTreeService.getIndexKeyMap(element,element.optString(ElementConstants.INDEX));
|
||||
|
||||
hashTreeService.dataFormatting(element, caseIds, keyMap);
|
||||
// 处理用例
|
||||
hashTreeService.caseFormatting(element, caseIds, null);
|
||||
|
||||
|
|
|
@ -757,7 +757,8 @@ public class ApiScenarioService {
|
|||
if (StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
||||
JSONObject element = JSONUtil.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
hashTreeService.dataFormatting(element, caseIds);
|
||||
Map<String, Boolean> keyMap = MsHashTreeService.getIndexKeyMap(element, element.optString(ElementConstants.INDEX));
|
||||
hashTreeService.dataFormatting(element, caseIds, keyMap);
|
||||
// 处理用例
|
||||
hashTreeService.caseFormatting(element, caseIds, getConfig(scenarioWithBLOBs));
|
||||
ElementUtil.dataFormatting(element);
|
||||
|
@ -885,7 +886,8 @@ public class ApiScenarioService {
|
|||
JSONObject element = JSONUtil.parseObject(dto.getScenarioDefinition());
|
||||
// 获取所有case
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
hashTreeService.dataFormatting(element, caseIds);
|
||||
Map<String, Boolean> keyMap = MsHashTreeService.getIndexKeyMap(element, element.optString(ElementConstants.INDEX));
|
||||
hashTreeService.dataFormatting(element, caseIds, keyMap);
|
||||
// 处理用例
|
||||
hashTreeService.caseFormatting(element, caseIds, null);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
v-model="data.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="data.refEnable || !showVersion || isDeleted" />
|
||||
:disabled="data.refEnable || !showVersion || isDeleted || isEnabled()" />
|
||||
</el-tooltip>
|
||||
|
||||
<el-button
|
||||
|
@ -302,6 +302,9 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
isEnabled() {
|
||||
return this.stepFilter.get("ALlSamplerStep").indexOf(this.data.type) !== -1 && this.data.caseEnable;
|
||||
},
|
||||
active() {
|
||||
this.$emit('active');
|
||||
},
|
||||
|
|
|
@ -308,6 +308,7 @@ export default {
|
|||
arr[i].disabled = disabled;
|
||||
arr[i].isCopy = false;
|
||||
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
|
||||
arr[i].caseEnable = disabled;
|
||||
// 处理子请求环境
|
||||
let typeArray = ['JDBCPostProcessor', 'JDBCSampler', 'JDBCPreProcessor'];
|
||||
if (typeArray.indexOf(arr[i].type) !== -1) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<api-json-path-suggest-button
|
||||
:open-tip="$t('api_test.request.assertions.json_path_suggest')"
|
||||
:clear-tip="$t('api_test.request.assertions.json_path_clear')"
|
||||
:is-read-only="request.caseEnable"
|
||||
@open="suggestJsonOpen"
|
||||
@clear="clearJson" />
|
||||
</span>
|
||||
|
@ -16,6 +17,7 @@
|
|||
<el-select
|
||||
class="assertion-item"
|
||||
v-model="type"
|
||||
:disabled="request.caseEnable"
|
||||
:placeholder="$t('api_test.request.assertions.select_type')"
|
||||
size="small">
|
||||
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT" />
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
</el-select>
|
||||
<el-button
|
||||
size="mini"
|
||||
:disabled="request.caseEnable"
|
||||
@click="add"
|
||||
type="primary"
|
||||
v-if="tabType !== 'assertionsRule'"
|
||||
|
|
Loading…
Reference in New Issue