fix(接口测试): 修复导出场景jmx性能测试无法执行问题

This commit is contained in:
fit2-zhao 2022-01-24 14:40:57 +08:00 committed by fit2-zhao
parent 2d807f97cc
commit 825042f978
6 changed files with 59 additions and 34 deletions

View File

@ -358,7 +358,7 @@ public class ApiAutomationController {
@PostMapping(value = "/export/jmx") @PostMapping(value = "/export/jmx")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EXPORT_SCENARIO) @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EXPORT_SCENARIO)
@MsAuditLog(module = "api_automation", type = OperLogConstants.EXPORT, sourceId = "#request.id", title = "#request.name", project = "#request.projectId") @MsAuditLog(module = "api_automation", type = OperLogConstants.EXPORT, sourceId = "#request.id", title = "#request.name", project = "#request.projectId")
public List<ApiScenrioExportJmx> exportJmx(@RequestBody ApiScenarioBatchRequest request) { public List<ApiScenarioExportJmxDTO> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
return apiAutomationService.exportJmx(request); return apiAutomationService.exportJmx(request);
} }

View File

@ -8,7 +8,7 @@ import java.util.List;
@Getter @Getter
@Setter @Setter
public class ApiScenrioExportJmx { public class ApiScenarioExportJmxDTO {
private String name; private String name;
private String id; private String id;
private String jmx; private String jmx;
@ -17,7 +17,7 @@ public class ApiScenrioExportJmx {
//性能测试引用场景时需要场景下的附件 //性能测试引用场景时需要场景下的附件
private List<FileMetadata> fileMetadataList; private List<FileMetadata> fileMetadataList;
public ApiScenrioExportJmx(String name, String jmx) { public ApiScenarioExportJmxDTO(String name, String jmx) {
this.name = name; this.name = name;
this.jmx = jmx; this.jmx = jmx;
} }

View File

@ -40,6 +40,8 @@ import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.save.SaveService; import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.AbstractTestElement; import org.apache.jmeter.testelement.AbstractTestElement;
import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -597,4 +599,28 @@ public class ElementUtil {
sampler.setProperty("MS-RESOURCE-ID", ElementUtil.getResourceId(id, config, parent, indexPath)); sampler.setProperty("MS-RESOURCE-ID", ElementUtil.getResourceId(id, config, parent, indexPath));
LoggerUtil.debug("mqtt sampler resourceId :" + sampler.getPropertyAsString("MS-RESOURCE-ID")); LoggerUtil.debug("mqtt sampler resourceId :" + sampler.getPropertyAsString("MS-RESOURCE-ID"));
} }
public static void accuracyHashTree(HashTree hashTree) {
Map<Object, HashTree> objects = new LinkedHashMap<>();
Object groupHashTree = hashTree;
if (hashTree != null && hashTree.size() > 0) {
for (Object key : hashTree.keySet()) {
if (key instanceof TestPlan) {
for (Object node : hashTree.get(key).keySet()) {
if (node instanceof ThreadGroup) {
groupHashTree = hashTree.get(key).get(node);
}
}
} else {
objects.put(key, hashTree.get(key));
}
}
}
if (!objects.isEmpty() && groupHashTree instanceof HashTree) {
for (Object key : objects.keySet()) {
hashTree.remove(key);
((HashTree) groupHashTree).add(key, objects.get(key));
}
}
}
} }

View File

@ -1,7 +1,6 @@
package io.metersphere.api.dto.definition.request.unknown; package io.metersphere.api.dto.definition.request.unknown;
import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.annotation.JSONType;
import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.dto.scenario.request.BodyFile; import io.metersphere.api.dto.scenario.request.BodyFile;
@ -24,7 +23,6 @@ import org.apache.jorphan.collections.HashTree;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -79,20 +77,9 @@ public class MsJmeterElement extends MsTestElement {
config.getCsvFilePaths().add(csvPath); config.getCsvFilePaths().add(csvPath);
} }
} }
if (scriptWrapper instanceof TestPlan && tree.size() > 0) {
for (Object obj : tree.keySet()) {
if (obj instanceof CSVDataSet) {
tree.remove(obj);
}
}
}
if (config.isOperating()) { if (config.isOperating()) {
elementTree = tree.add(scriptWrapper); elementTree = tree.add(scriptWrapper);
if ((scriptWrapper instanceof ThreadGroup)) {
ElementUtil.addCsvDataSet(elementTree, config.getVariables(), config, "shareMode.thread");
}
} else if (!(scriptWrapper instanceof TestPlan) && !(scriptWrapper instanceof ThreadGroup)) { } else if (!(scriptWrapper instanceof TestPlan) && !(scriptWrapper instanceof ThreadGroup)) {
elementTree = tree.add(scriptWrapper); elementTree = tree.add(scriptWrapper);
} }

View File

@ -865,6 +865,7 @@ public class ApiAutomationService {
if (scenario == null) { if (scenario == null) {
return null; return null;
} }
scenario.setId(apiScenario.getId());
GenerateHashTreeUtil.parse(apiScenario.getScenarioDefinition(), scenario); GenerateHashTreeUtil.parse(apiScenario.getScenarioDefinition(), scenario);
String environmentType = apiScenario.getEnvironmentType(); String environmentType = apiScenario.getEnvironmentType();
String environmentJson = apiScenario.getEnvironmentJson(); String environmentJson = apiScenario.getEnvironmentJson();
@ -876,8 +877,17 @@ public class ApiAutomationService {
scenario.setEnvironmentMap(envMap); scenario.setEnvironmentMap(envMap);
} }
// 针对导入的jmx 处理 // 针对导入的jmx 处理
if (CollectionUtils.isNotEmpty(scenario.getHashTree()) && (scenario.getHashTree().get(0) instanceof MsJmeterElement)) { boolean isUseElement = false;
if (CollectionUtils.isNotEmpty(scenario.getHashTree())) {
for (MsTestElement testElement : scenario.getHashTree()) {
if (testElement instanceof MsJmeterElement) {
isUseElement = true;
}
}
}
if (isUseElement) {
scenario.toHashTree(jmeterHashTree, scenario.getHashTree(), config); scenario.toHashTree(jmeterHashTree, scenario.getHashTree(), config);
ElementUtil.accuracyHashTree(jmeterHashTree);
return scenario.getJmx(jmeterHashTree); return scenario.getJmx(jmeterHashTree);
} else { } else {
MsThreadGroup group = new MsThreadGroup(); MsThreadGroup group = new MsThreadGroup();
@ -892,10 +902,12 @@ public class ApiAutomationService {
} }
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); LogUtil.error(ex);
MSException.throwException(ex.getMessage()); MSException.throwException(ex.getMessage());
} }
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config); testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
// 检查hashTree 准确性
return testPlan.getJmx(jmeterHashTree); return testPlan.getJmx(jmeterHashTree);
} }
@ -1475,21 +1487,21 @@ public class ApiAutomationService {
return result; return result;
} }
public List<ApiScenrioExportJmx> exportJmx(ApiScenarioBatchRequest request) { public List<ApiScenarioExportJmxDTO> exportJmx(ApiScenarioBatchRequest request) {
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request); List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request);
// 生成jmx // 生成jmx
List<ApiScenrioExportJmx> resList = new ArrayList<>(); List<ApiScenarioExportJmxDTO> resList = new ArrayList<>();
apiScenarioWithBLOBs.forEach(item -> { apiScenarioWithBLOBs.forEach(item -> {
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) { if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
String jmx = generateJmx(item); String jmx = generateJmx(item);
if (StringUtils.isNotEmpty(jmx)) { if (StringUtils.isNotEmpty(jmx)) {
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId()).getXml()); ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId()).getXml());
JmxInfoDTO dto = apiTestService.updateJmxString(jmx, item.getProjectId()); JmxInfoDTO dto = apiTestService.updateJmxString(jmx, item.getProjectId());
scenrioExportJmx.setId(item.getId()); scenariosExportJmx.setId(item.getId());
scenrioExportJmx.setVersion(item.getVersion()); scenariosExportJmx.setVersion(item.getVersion());
//扫描需要哪些文件 //扫描需要哪些文件
scenrioExportJmx.setFileMetadataList(dto.getFileMetadataList()); scenariosExportJmx.setFileMetadataList(dto.getFileMetadataList());
resList.add(scenrioExportJmx); resList.add(scenariosExportJmx);
} }
} }
}); });
@ -1503,24 +1515,24 @@ public class ApiAutomationService {
} }
public byte[] exportZip(ApiScenarioBatchRequest request) { public byte[] exportZip(ApiScenarioBatchRequest request) {
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request); List<ApiScenarioWithBLOBs> scenarios = getExportResult(request);
// 生成jmx // 生成jmx
Map<String, byte[]> files = new LinkedHashMap<>(); Map<String, byte[]> files = new LinkedHashMap<>();
apiScenarioWithBLOBs.forEach(item -> { scenarios.forEach(item -> {
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) { if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
String jmx = generateJmx(item); String jmx = generateJmx(item);
if (StringUtils.isNotEmpty(jmx)) { if (StringUtils.isNotEmpty(jmx)) {
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId()).getXml()); ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId()).getXml());
String fileName = item.getName() + ".jmx"; String fileName = item.getName() + ".jmx";
String jmxStr = scenrioExportJmx.getJmx(); String jmxStr = scenariosExportJmx.getJmx();
files.put(fileName, jmxStr.getBytes(StandardCharsets.UTF_8)); files.put(fileName, jmxStr.getBytes(StandardCharsets.UTF_8));
} }
} }
}); });
if (CollectionUtils.isNotEmpty(apiScenarioWithBLOBs)) { if (CollectionUtils.isNotEmpty(scenarios)) {
List<String> names = apiScenarioWithBLOBs.stream().map(ApiScenarioWithBLOBs::getName).collect(Collectors.toList()); List<String> names = scenarios.stream().map(ApiScenarioWithBLOBs::getName).collect(Collectors.toList());
request.setName(String.join(",", names)); request.setName(String.join(",", names));
List<String> ids = apiScenarioWithBLOBs.stream().map(ApiScenarioWithBLOBs::getId).collect(Collectors.toList()); List<String> ids = scenarios.stream().map(ApiScenarioWithBLOBs::getId).collect(Collectors.toList());
request.setId(JSON.toJSONString(ids)); request.setId(JSON.toJSONString(ids));
} }
return FileUtils.listBytesToZip(files); return FileUtils.listBytesToZip(files);

View File

@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import io.metersphere.api.dto.JmxInfoDTO; import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.automation.ApiScenarioBatchRequest; import io.metersphere.api.dto.automation.ApiScenarioBatchRequest;
import io.metersphere.api.dto.automation.ApiScenrioExportJmx; import io.metersphere.api.dto.automation.ApiScenarioExportJmxDTO;
import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.api.service.ApiTestCaseService; import io.metersphere.api.service.ApiTestCaseService;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
@ -795,7 +795,7 @@ public class PerformanceTestService {
if (!CollectionUtils.isEmpty(scenarioIds)) { if (!CollectionUtils.isEmpty(scenarioIds)) {
ApiScenarioBatchRequest scenarioRequest = new ApiScenarioBatchRequest(); ApiScenarioBatchRequest scenarioRequest = new ApiScenarioBatchRequest();
scenarioRequest.setIds(scenarioIds); scenarioRequest.setIds(scenarioIds);
List<ApiScenrioExportJmx> apiScenrioExportJmxes = apiAutomationService.exportJmx(scenarioRequest); List<ApiScenarioExportJmxDTO> apiScenrioExportJmxes = apiAutomationService.exportJmx(scenarioRequest);
deleteLoadTestFiles(loadTest.getId()); deleteLoadTestFiles(loadTest.getId());