feat(性能测试): 支持自由组合场景
This commit is contained in:
parent
d18c1aa9ed
commit
329ed8dd77
|
@ -2,7 +2,7 @@ package io.metersphere.base.mapper.ext;
|
|||
|
||||
import io.metersphere.base.domain.LoadTest;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.LoadTestFileDTO;
|
||||
import io.metersphere.performance.dto.LoadTestFileDTO;
|
||||
import io.metersphere.track.request.testplan.QueryTestPlanRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
select * from load_test lt where lt.project_id = #{projectId} ORDER BY num DESC LIMIT 1;
|
||||
</select>
|
||||
|
||||
<select id="getProjectFiles" resultType="io.metersphere.dto.LoadTestFileDTO">
|
||||
<select id="getProjectFiles" resultType="io.metersphere.performance.dto.LoadTestFileDTO">
|
||||
SELECT file_metadata.*, load_test.id as testId, load_test.name as testName
|
||||
FROM load_test
|
||||
JOIN load_test_file ON load_test.id = load_test_file.test_id
|
||||
|
|
|
@ -12,8 +12,9 @@ import io.metersphere.commons.utils.SessionUtils;
|
|||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.DashboardTestDTO;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.LoadTestFileDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.LoadTestFileDTO;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.FileService;
|
||||
|
@ -108,11 +109,16 @@ public class PerformanceTestController {
|
|||
}
|
||||
|
||||
@GetMapping("/get-jmx-content/{testId}")
|
||||
public String getJmxContent(@PathVariable String testId) {
|
||||
public List<LoadTestExportJmx> getJmxContent(@PathVariable String testId) {
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getJmxContent(testId);
|
||||
}
|
||||
|
||||
@PostMapping("/export/jmx")
|
||||
public List<LoadTestExportJmx> exportJmx(@RequestBody List<String> fileIds) {
|
||||
return performanceTestService.exportJmx(fileIds);
|
||||
}
|
||||
|
||||
@GetMapping("/project/{loadType}/{projectId}/{goPage}/{pageSize}")
|
||||
public Pager<List<LoadTestFileDTO>> getProjectFiles(@PathVariable String projectId, @PathVariable String loadType,
|
||||
@PathVariable int goPage, @PathVariable int pageSize) {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.performance.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class LoadTestExportJmx {
|
||||
private String name;
|
||||
private String jmx;
|
||||
|
||||
public LoadTestExportJmx(String name, String jmx) {
|
||||
this.name = name;
|
||||
this.jmx = jmx;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.metersphere.dto;
|
||||
package io.metersphere.performance.dto;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import lombok.Getter;
|
|
@ -23,9 +23,22 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.reflections8.Reflections;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -77,22 +90,17 @@ public class EngineFactory {
|
|||
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
|
||||
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId());
|
||||
}
|
||||
FileMetadata jmxFile = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JMX.name()))
|
||||
.findFirst().orElseGet(() -> {
|
||||
throw new RuntimeException(Translator.get("run_load_test_file_not_found") + loadTest.getId());
|
||||
});
|
||||
|
||||
List<FileMetadata> jmxFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JMX.name())).collect(Collectors.toList());
|
||||
List<FileMetadata> csvFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.CSV.name())).collect(Collectors.toList());
|
||||
List<FileMetadata> jarFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JAR.name())).collect(Collectors.toList());
|
||||
final FileContent fileContent = fileService.getFileContent(jmxFile.getId());
|
||||
if (fileContent == null) {
|
||||
MSException.throwException(Translator.get("run_load_test_file_content_not_found") + loadTest.getId());
|
||||
}
|
||||
// 合并上传的jmx
|
||||
byte[] jmxBytes = mergeJmx(jmxFiles);
|
||||
final EngineContext engineContext = new EngineContext();
|
||||
engineContext.setTestId(loadTest.getId());
|
||||
engineContext.setTestName(loadTest.getName());
|
||||
engineContext.setNamespace(loadTest.getProjectId());
|
||||
engineContext.setFileType(jmxFile.getType());
|
||||
engineContext.setFileType(FileType.JMX.name());
|
||||
engineContext.setResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
engineContext.setStartTime(startTime);
|
||||
engineContext.setReportId(reportId);
|
||||
|
@ -146,7 +154,7 @@ public class EngineFactory {
|
|||
MSException.throwException("File type unknown");
|
||||
}
|
||||
|
||||
try (ByteArrayInputStream source = new ByteArrayInputStream(fileContent.getFile())) {
|
||||
try (ByteArrayInputStream source = new ByteArrayInputStream(jmxBytes)) {
|
||||
String content = engineSourceParser.parse(engineContext, source);
|
||||
engineContext.setContent(content);
|
||||
} catch (MSException e) {
|
||||
|
@ -178,6 +186,63 @@ public class EngineFactory {
|
|||
return engineContext;
|
||||
}
|
||||
|
||||
public static byte[] mergeJmx(List<FileMetadata> jmxFiles) {
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
Element hashTree = null;
|
||||
Document rootDocument = null;
|
||||
for (FileMetadata fileMetadata : jmxFiles) {
|
||||
FileContent fileContent = fileService.getFileContent(fileMetadata.getId());
|
||||
final InputSource inputSource = new InputSource(new ByteArrayInputStream(fileContent.getFile()));
|
||||
if (hashTree == null) {
|
||||
rootDocument = docBuilder.parse(inputSource);
|
||||
Element jmeterTestPlan = rootDocument.getDocumentElement();
|
||||
NodeList childNodes = jmeterTestPlan.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
// jmeterTestPlan的子元素肯定是<hashTree></hashTree>
|
||||
hashTree = (Element) node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Document document = docBuilder.parse(inputSource);
|
||||
Element jmeterTestPlan = document.getDocumentElement();
|
||||
NodeList childNodes = jmeterTestPlan.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
// jmeterTestPlan的子元素肯定是<hashTree></hashTree>
|
||||
Element secondHashTree = (Element) node;
|
||||
NodeList secondChildNodes = secondHashTree.getChildNodes();
|
||||
for (int j = 0; j < secondChildNodes.getLength(); j++) {
|
||||
Node item = secondChildNodes.item(j);
|
||||
Node newNode = item.cloneNode(true);
|
||||
rootDocument.adoptNode(newNode);
|
||||
hashTree.appendChild(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return documentToBytes(rootDocument);
|
||||
} catch (Exception e) {
|
||||
MSException.throwException(e);
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
private static byte[] documentToBytes(Document document) throws TransformerException {
|
||||
DOMSource domSource = new DOMSource(document);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamResult result = new StreamResult(out);
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.transform(domSource, result);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
@Resource
|
||||
private void setFileService(FileService fileService) {
|
||||
|
|
|
@ -16,10 +16,11 @@ import io.metersphere.controller.request.OrderRequest;
|
|||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.DashboardTestDTO;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.LoadTestFileDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.PerformanceTestJob;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.LoadTestFileDTO;
|
||||
import io.metersphere.performance.engine.Engine;
|
||||
import io.metersphere.performance.engine.EngineFactory;
|
||||
import io.metersphere.performance.engine.producer.LoadTestProducer;
|
||||
|
@ -131,23 +132,13 @@ public class PerformanceTestService {
|
|||
checkQuota(request, true);
|
||||
LoadTestWithBLOBs loadTest = saveLoadTest(request);
|
||||
|
||||
// 新选择了一个文件,删除原来的文件
|
||||
List<FileMetadata> importFiles = request.getUpdatedFileList();
|
||||
List<String> importFileIds = importFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
|
||||
// 导入项目里其他的文件
|
||||
this.importFiles(importFileIds, loadTest.getId());
|
||||
// 保存上传的问题件
|
||||
// 保存上传的文件
|
||||
this.saveUploadFiles(files, loadTest.getId());
|
||||
// 直接上传了jmx,用于API导入的场景
|
||||
String jmx = request.getJmx();
|
||||
if (StringUtils.isNotBlank(jmx)) {
|
||||
byte[] bytes = jmx.getBytes(StandardCharsets.UTF_8);
|
||||
FileMetadata fileMetadata = fileService.saveFile(bytes, request.getName() + ".jmx", (long) bytes.length);
|
||||
LoadTestFile loadTestFile = new LoadTestFile();
|
||||
loadTestFile.setTestId(loadTest.getId());
|
||||
loadTestFile.setFileId(fileMetadata.getId());
|
||||
loadTestFileMapper.insert(loadTestFile);
|
||||
}
|
||||
|
||||
return loadTest.getId();
|
||||
}
|
||||
|
||||
|
@ -222,16 +213,6 @@ public class PerformanceTestService {
|
|||
List<String> addFileIds = ListUtils.subtract(updatedFileIds, originFileIds);
|
||||
this.importFiles(addFileIds, request.getId());
|
||||
this.saveUploadFiles(files, request.getId());
|
||||
// 直接上传了jmx,用于API导入的场景
|
||||
String jmx = request.getJmx();
|
||||
if (StringUtils.isNotBlank(jmx)) {
|
||||
byte[] bytes = jmx.getBytes(StandardCharsets.UTF_8);
|
||||
FileMetadata fileMetadata = fileService.saveFile(bytes, request.getName() + ".jmx", (long) bytes.length);
|
||||
LoadTestFile loadTestFile = new LoadTestFile();
|
||||
loadTestFile.setTestId(request.getId());
|
||||
loadTestFile.setFileId(fileMetadata.getId());
|
||||
loadTestFileMapper.insert(loadTestFile);
|
||||
}
|
||||
|
||||
loadTest.setName(request.getName());
|
||||
loadTest.setProjectId(request.getProjectId());
|
||||
|
@ -391,15 +372,16 @@ public class PerformanceTestService {
|
|||
return Optional.ofNullable(loadTestWithBLOBs).orElse(new LoadTestWithBLOBs()).getLoadConfiguration();
|
||||
}
|
||||
|
||||
public String getJmxContent(String testId) {
|
||||
public List<LoadTestExportJmx> getJmxContent(String testId) {
|
||||
List<FileMetadata> fileMetadataList = fileService.getFileMetadataByTestId(testId);
|
||||
List<LoadTestExportJmx> results = new ArrayList<>();
|
||||
for (FileMetadata metadata : fileMetadataList) {
|
||||
if (FileType.JMX.name().equals(metadata.getType())) {
|
||||
FileContent fileContent = fileService.getFileContent(metadata.getId());
|
||||
return new String(fileContent.getFile());
|
||||
results.add(new LoadTestExportJmx(metadata.getName(), new String(fileContent.getFile(), StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<LoadTestWithBLOBs> selectByTestResourcePoolId(String resourcePoolId) {
|
||||
|
@ -557,4 +539,18 @@ public class PerformanceTestService {
|
|||
}
|
||||
return extLoadTestMapper.getProjectFiles(projectId, loadTypes);
|
||||
}
|
||||
|
||||
public List<LoadTestExportJmx> exportJmx(List<String> fileIds) {
|
||||
if (CollectionUtils.isEmpty(fileIds)) {
|
||||
return null;
|
||||
}
|
||||
List<LoadTestExportJmx> results = new ArrayList<>();
|
||||
fileIds.forEach(id -> {
|
||||
FileMetadata fileMetadata = fileService.getFileMetadataById(id);
|
||||
FileContent fileContent = fileService.getFileContent(id);
|
||||
results.add(new LoadTestExportJmx(fileMetadata.getName(), new String(fileContent.getFile(), StandardCharsets.UTF_8)));
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ public class TestPlanRequest {
|
|||
|
||||
private String description;
|
||||
|
||||
private String jmx;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Long updateTime;
|
||||
|
|
|
@ -117,6 +117,7 @@ import echarts from "echarts";
|
|||
import MsChart from "@/business/components/common/chart/MsChart";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
|
||||
const HANDLER = "handler";
|
||||
const TARGET_LEVEL = "TargetLevel";
|
||||
const RAMP_UP = "RampUp";
|
||||
const STEPS = "Steps";
|
||||
|
@ -204,6 +205,9 @@ export default {
|
|||
case DELETED:
|
||||
this.threadGroups[i].deleted = item.value;
|
||||
break;
|
||||
case HANDLER:
|
||||
this.threadGroups[i].handler = item.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -241,13 +245,13 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.result = this.$get('/performance/get-jmx-content/' + this.report.testId, (response) => {
|
||||
if (response.data) {
|
||||
this.threadGroups = findThreadGroup(response.data);
|
||||
response.data.forEach(d => {
|
||||
this.threadGroups = this.threadGroups.concat(findThreadGroup(d.jmx, d.name));
|
||||
this.threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.getLoadConfig();
|
||||
}
|
||||
});
|
||||
this.getLoadConfig();
|
||||
});
|
||||
},
|
||||
calculateTotalChart() {
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
<template>
|
||||
<el-dialog :close-on-click-modal="false"
|
||||
:destroy-on-close="true"
|
||||
:title="$t('load_test.exist_jmx')" width="70%"
|
||||
:visible.sync="loadFileVisible">
|
||||
|
||||
<el-table v-loading="projectLoadingResult.loading"
|
||||
class="basic-config"
|
||||
:data="existFiles"
|
||||
@select-all="handleSelectAll"
|
||||
@select="handleSelectionChange">
|
||||
|
||||
<el-table-column type="selection"/>
|
||||
<el-table-column
|
||||
prop="testName"
|
||||
:label="$t('load_test.test')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.file_name')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:label="$t('load_test.file_type')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('load_test.last_modify_time')">
|
||||
<template v-slot:default="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span class="last-modified">{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<ms-table-pagination :change="getProjectFiles" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer @cancel="close" @confirm="handleImport"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
|
||||
export default {
|
||||
name: "ExistFiles",
|
||||
components: {MsTablePagination, MsDialogFooter},
|
||||
props: {
|
||||
fileList: Array,
|
||||
tableData: Array,
|
||||
uploadList: Array,
|
||||
scenarios: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadFileVisible: false,
|
||||
projectLoadingResult: {},
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
loadType: 'jmx',
|
||||
existFiles: [],
|
||||
selectIds: new Set,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(loadType) {
|
||||
this.loadFileVisible = true;
|
||||
this.loadType = loadType;
|
||||
this.getProjectFiles();
|
||||
},
|
||||
close() {
|
||||
this.loadFileVisible = false;
|
||||
this.selectIds.clear();
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
if (selection.length > 0) {
|
||||
this.existFiles.forEach(item => {
|
||||
this.selectIds.add(item.id);
|
||||
});
|
||||
} else {
|
||||
this.existFiles.forEach(item => {
|
||||
if (this.selectIds.has(item.id)) {
|
||||
this.selectIds.delete(item.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleSelectionChange(selection, row) {
|
||||
if (this.selectIds.has(row.id)) {
|
||||
this.selectIds.delete(row.id);
|
||||
} else {
|
||||
this.selectIds.add(row.id);
|
||||
}
|
||||
},
|
||||
getProjectFiles() {
|
||||
this.projectLoadingResult = this.$get('/performance/project/' + this.loadType + '/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, res => {
|
||||
let data = res.data;
|
||||
this.total = data.itemCount;
|
||||
this.existFiles = data.listObject;
|
||||
})
|
||||
},
|
||||
handleImport() {
|
||||
if (this.selectIds.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rows = this.existFiles.filter(f => this.selectIds.has(f.id));
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
if (this.tableData.filter(f => f.name === row.name).length > 0) {
|
||||
this.$error(this.$t('load_test.delete_file'));
|
||||
this.selectIds.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.loadType === 'resource') {
|
||||
rows.forEach(row => {
|
||||
this.fileList.push(row);
|
||||
this.tableData.push(row);
|
||||
})
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadFileVisible = false;
|
||||
this.selectIds.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
this.projectLoadingResult = this.$post('/performance/export/jmx', [...this.selectIds], (response) => {
|
||||
let data = response.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
data.forEach(d => {
|
||||
let threadGroups = findThreadGroup(d.jmx, d.name);
|
||||
threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
this.scenarios.push(tg);
|
||||
});
|
||||
let file = new File([d.jmx], d.name);
|
||||
this.fileList.push(file);
|
||||
this.uploadList.push(file);
|
||||
this.tableData.push({
|
||||
name: file.name,
|
||||
size: (file.size / 1024).toFixed(2) + ' KB',
|
||||
type: 'JMX',
|
||||
updateTime: file.lastModified,
|
||||
});
|
||||
});
|
||||
|
||||
this.$emit('fileChange', this.scenarios);
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadFileVisible = false;
|
||||
this.selectIds.clear();
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<el-dialog :title="$t('load_test.scenario_list')"
|
||||
:close-on-click-modal="false"
|
||||
:destroy-on-close="true"
|
||||
width="60%" :visible.sync="loadApiAutomationVisible"
|
||||
:modal="true">
|
||||
|
||||
<el-table v-loading="projectLoadingResult.loading" class="basic-config"
|
||||
:data="apiScenarios"
|
||||
@select-all="handleSelectAll"
|
||||
@select="handleSelectionChange">
|
||||
<el-table-column type="selection"/>
|
||||
<el-table-column
|
||||
prop="num"
|
||||
label="ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.scenario_name')">
|
||||
</el-table-column>
|
||||
<el-table-column prop="tags" min-width="120px"
|
||||
:label="$t('api_test.automation.tag')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :content="itemName"
|
||||
style="margin-left: 5px"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('load_test.last_modify_time')">
|
||||
<template v-slot:default="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span class="last-modified">{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<ms-table-pagination :change="getProjectScenarios" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer @cancel="close" @confirm="handleImport"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import MsTag from "@/business/components/common/components/MsTag";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
|
||||
export default {
|
||||
name: "ExistScenarios",
|
||||
components: {MsTag, MsTablePagination, MsDialogFooter},
|
||||
props: {
|
||||
fileList: Array,
|
||||
tableData: Array,
|
||||
uploadList: Array,
|
||||
scenarios: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadApiAutomationVisible: false,
|
||||
projectLoadingResult: {},
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
apiScenarios: [],
|
||||
selectIds: new Set,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.loadApiAutomationVisible = true;
|
||||
this.getProjectScenarios();
|
||||
},
|
||||
close() {
|
||||
this.loadApiAutomationVisible = false;
|
||||
this.selectIds.clear();
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
if (selection.length > 0) {
|
||||
this.apiScenarios.forEach(item => {
|
||||
this.selectIds.add(item.id);
|
||||
});
|
||||
} else {
|
||||
this.apiScenarios.forEach(item => {
|
||||
if (this.selectIds.has(item.id)) {
|
||||
this.selectIds.delete(item.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleSelectionChange(selection, row) {
|
||||
if (this.selectIds.has(row.id)) {
|
||||
this.selectIds.delete(row.id);
|
||||
} else {
|
||||
this.selectIds.add(row.id);
|
||||
}
|
||||
},
|
||||
getProjectScenarios() {
|
||||
let condition = {
|
||||
projectId: getCurrentProjectID(),
|
||||
filters: {status: ["Prepare", "Underway", "Completed"]}
|
||||
}
|
||||
this.projectLoadingResult = this.$post('/api/automation/list/' + this.currentPage + "/" + this.pageSize, condition, res => {
|
||||
let data = res.data;
|
||||
this.total = data.itemCount;
|
||||
this.apiScenarios = data.listObject;
|
||||
this.apiScenarios.forEach(item => {
|
||||
if (item.tags && item.tags.length > 0) {
|
||||
item.tags = JSON.parse(item.tags);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
handleImport() {
|
||||
if (this.selectIds.size === 0) {
|
||||
return;
|
||||
}
|
||||
let rows = this.apiScenarios.filter(f => this.selectIds.has(f.id));
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
if (this.tableData.filter(f => f.name === row.name + ".jmx").length > 0) {
|
||||
this.$error(this.$t('load_test.delete_file'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
let condition = {
|
||||
projectId: getCurrentProjectID(),
|
||||
ids: [...this.selectIds],
|
||||
};
|
||||
this.projectLoadingResult = this.$post('api/automation/export/jmx', condition, response => {
|
||||
let data = response.data;
|
||||
data.forEach(d => {
|
||||
let threadGroups = findThreadGroup(d.jmx, d.name + ".jmx")
|
||||
threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
this.scenarios.push(tg);
|
||||
});
|
||||
let file = new File([d.jmx], d.name + ".jmx");
|
||||
this.fileList.push(file);
|
||||
this.uploadList.push(file);
|
||||
this.tableData.push({
|
||||
name: file.name,
|
||||
size: (file.size / 1024).toFixed(2) + ' KB',
|
||||
type: 'JMX',
|
||||
updateTime: file.lastModified,
|
||||
});
|
||||
})
|
||||
|
||||
this.$emit('fileChange', this.scenarios);
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadApiAutomationVisible = false;
|
||||
})
|
||||
this.selectIds.clear();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -8,6 +8,7 @@
|
|||
style="padding-right: 10px;"
|
||||
accept=".jmx"
|
||||
action=""
|
||||
multiple
|
||||
:limit="fileNumLimit"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUploadJmx"
|
||||
|
@ -83,7 +84,7 @@
|
|||
<ms-table-button :is-tester-permission="true" icon="el-icon-circle-plus-outline"
|
||||
:content="$t('load_test.load_exist_file')" @click="loadFile()"/>
|
||||
</el-row>
|
||||
<el-table class="basic-config" :data="tableData.filter(f => !f.name.toUpperCase().endsWith('.JMX'))">
|
||||
<el-table class="basic-config" :data="tableData">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.file_name')">
|
||||
|
@ -116,79 +117,36 @@
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog :title="$t('load_test.exist_jmx')" width="70%" :visible.sync="loadFileVisible">
|
||||
<exist-files ref="existFiles"
|
||||
@fileChange="fileChange"
|
||||
:file-list="fileList"
|
||||
:table-data="tableData"
|
||||
:upload-list="uploadList"
|
||||
:scenarios="threadGroups"/>
|
||||
|
||||
<el-table class="basic-config" :data="existFiles" v-loading="projectLoadingResult.loading">
|
||||
<el-table-column
|
||||
prop="testName"
|
||||
:label="$t('load_test.test')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.file_name')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:label="$t('load_test.file_type')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('load_test.last_modify_time')">
|
||||
<template v-slot:default="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span class="last-modified">{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator-button :is-tester-permission="true"
|
||||
:tip="$t('api_test.api_import.label')"
|
||||
icon="el-icon-upload"
|
||||
@exec="handleImport(scope.row)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<ms-table-pagination :change="getProjectFiles" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-dialog>
|
||||
<el-dialog :title="$t('load_test.scenario_list')" width="60%" :visible.sync="loadApiAutomationVisible">
|
||||
<exist-scenarios ref="existScenarios"
|
||||
@fileChange="fileChange"
|
||||
:file-list="fileList"
|
||||
:table-data="tableData"
|
||||
:upload-list="uploadList"
|
||||
:scenarios="threadGroups"/>
|
||||
|
||||
<el-table class="basic-config" :data="apiScenarios" v-loading="projectLoadingResult.loading">
|
||||
<el-table-column
|
||||
prop="num"
|
||||
label="ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('load_test.scenario_name')">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator-button :is-tester-permission="true"
|
||||
:tip="$t('api_test.api_import.label')"
|
||||
icon="el-icon-upload"
|
||||
@exec="handleImportApi(scope.row)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<ms-table-pagination :change="getProjectFiles" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Message} from "element-ui";
|
||||
import {findTestPlan, findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import ExistFiles from "@/business/components/performance/test/components/ExistFiles";
|
||||
import ExistScenarios from "@/business/components/performance/test/components/ExistScenarios";
|
||||
|
||||
export default {
|
||||
name: "PerformanceBasicConfig",
|
||||
components: {MsTableOperatorButton, MsTablePagination, MsTableButton},
|
||||
components: {ExistScenarios, ExistFiles, MsDialogFooter, MsTableOperatorButton, MsTablePagination, MsTableButton},
|
||||
props: {
|
||||
test: {
|
||||
type: Object
|
||||
|
@ -215,9 +173,9 @@ export default {
|
|||
pageSize: 5,
|
||||
total: 0,
|
||||
existFiles: [],
|
||||
loadType: 'jmx',
|
||||
apiScenarios: [],
|
||||
loadApiAutomationVisible: false,
|
||||
selectIds: new Set(),
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -230,19 +188,6 @@ export default {
|
|||
if (this.test.id) {
|
||||
this.getFileMetadata(this.test)
|
||||
}
|
||||
},
|
||||
uploadList() {
|
||||
let self = this;
|
||||
let fileList = self.uploadList.filter(f => f.name.endsWith(".jmx"));
|
||||
if (fileList.length > 0) {
|
||||
let file = fileList[0];
|
||||
let jmxReader = new FileReader();
|
||||
jmxReader.onload = (event) => {
|
||||
self.threadGroups = findThreadGroup(event.target.result);
|
||||
self.$emit('fileChange', self.threadGroups);
|
||||
};
|
||||
jmxReader.readAsText(file);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -256,7 +201,6 @@ export default {
|
|||
Message.error({message: this.$t('load_test.related_file_not_found'), showClose: true});
|
||||
return;
|
||||
}
|
||||
console.log(files);
|
||||
// deep copy
|
||||
this.fileList = JSON.parse(JSON.stringify(files));
|
||||
this.tableData = JSON.parse(JSON.stringify(files));
|
||||
|
@ -265,40 +209,12 @@ export default {
|
|||
});
|
||||
})
|
||||
},
|
||||
deleteExistJmx: function () {
|
||||
// 只能上传一个jmx
|
||||
let jmxs = this.tableData.filter(f => {
|
||||
let type = f.name.substring(f.name.lastIndexOf(".") + 1);
|
||||
return type.toUpperCase() === 'JMX';
|
||||
});
|
||||
for (let i = 0; i < jmxs.length; i++) {
|
||||
let index = this.tableData.indexOf(jmxs[i]);
|
||||
if (index > -1) {
|
||||
this.tableData.splice(index, 1);
|
||||
}
|
||||
let index2 = this.uploadList.indexOf(jmxs[i]);
|
||||
if (index2 > -1) {
|
||||
this.uploadList.splice(index2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
jmxs = this.fileList.filter(f => {
|
||||
let type = f.name.substring(f.name.lastIndexOf(".") + 1);
|
||||
return type.toUpperCase() === 'JMX';
|
||||
});
|
||||
for (let i = 0; i < jmxs.length; i++) {
|
||||
let index3 = this.fileList.indexOf(jmxs[i]);
|
||||
if (index3 > -1) {
|
||||
this.fileList.splice(index3, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeUploadJmx(file) {
|
||||
if (!this.fileValidator(file)) {
|
||||
/// todo: 显示错误信息
|
||||
return false;
|
||||
}
|
||||
this.deleteExistJmx();
|
||||
if (this.tableData.filter(f => f.name === file.name).length > 0) {
|
||||
this.$error(this.$t('load_test.delete_file'));
|
||||
return false;
|
||||
|
@ -337,7 +253,16 @@ export default {
|
|||
return true;
|
||||
},
|
||||
handleUpload(uploadResources) {
|
||||
this.uploadList.push(uploadResources.file);
|
||||
let self = this;
|
||||
let file = uploadResources.file;
|
||||
self.uploadList.push(file);
|
||||
|
||||
let jmxReader = new FileReader();
|
||||
jmxReader.onload = (event) => {
|
||||
self.threadGroups = self.threadGroups.concat(findThreadGroup(event.target.result, file.name));
|
||||
self.$emit('fileChange', self.threadGroups);
|
||||
};
|
||||
jmxReader.readAsText(file);
|
||||
},
|
||||
handleDownload(file) {
|
||||
let data = {
|
||||
|
@ -369,78 +294,6 @@ export default {
|
|||
Message.error({message: e.message, showClose: true});
|
||||
});
|
||||
},
|
||||
handleImport(row) {
|
||||
if (this.tableData.filter(f => f.name === row.name).length > 0) {
|
||||
this.$error(this.$t('load_test.delete_file'));
|
||||
return;
|
||||
}
|
||||
if (this.loadType === 'resource') {
|
||||
this.fileList.push(row);
|
||||
this.tableData.push(row);
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadFileVisible = false;
|
||||
return;
|
||||
}
|
||||
this.result = this.$get('/performance/get-jmx-content/' + row.testId, (response) => {
|
||||
if (response.data) {
|
||||
let testPlan = findTestPlan(response.data);
|
||||
testPlan.elements.forEach(e => {
|
||||
if (e.attributes.name === 'TestPlan.serialize_threadgroups') {
|
||||
this.serializeThreadgroups = Boolean(e.elements[0].text);
|
||||
}
|
||||
});
|
||||
this.threadGroups = findThreadGroup(response.data);
|
||||
this.threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.$emit('fileChange', this.threadGroups);
|
||||
}
|
||||
this.deleteExistJmx();
|
||||
this.fileList.push(row);
|
||||
this.tableData.push(row);
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadFileVisible = false;
|
||||
});
|
||||
},
|
||||
countStrToBit(str) {
|
||||
let count = 0
|
||||
const arr = str.split('')
|
||||
arr.forEach(item => {
|
||||
count += Math.ceil(item.charCodeAt().toString(2).length / 8)
|
||||
})
|
||||
return count
|
||||
},
|
||||
handleImportApi(row) {
|
||||
let condition = {
|
||||
projectId: getCurrentProjectID(),
|
||||
ids: [row.id]
|
||||
};
|
||||
this.projectLoadingResult = this.$post('api/automation/export/jmx', condition, response => {
|
||||
let data = response.data[0];
|
||||
this.threadGroups = findThreadGroup(data.jmx);
|
||||
this.threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.$emit('fileChange', this.threadGroups);
|
||||
this.deleteExistJmx();
|
||||
let bytes = this.countStrToBit(data.jmx);
|
||||
this.fileList.push({
|
||||
name: this.test.name + ".jmx",
|
||||
size: bytes,
|
||||
type: "JMX",
|
||||
updateTime: new Date().getTime(),
|
||||
});
|
||||
this.tableData.push({
|
||||
name: this.test.name + ".jmx",
|
||||
size: (bytes / 1024).toFixed(2) + ' KB',
|
||||
type: "JMX",
|
||||
updateTime: new Date().getTime(),
|
||||
});
|
||||
this.test.jmx = data.jmx;
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.loadApiAutomationVisible = false;
|
||||
})
|
||||
},
|
||||
handleDelete(file) {
|
||||
this.$alert(this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
|
@ -465,6 +318,12 @@ export default {
|
|||
if (i > -1) {
|
||||
this.uploadList.splice(i, 1);
|
||||
}
|
||||
|
||||
let jmxIndex = this.threadGroups.findIndex(tg => tg.handler === file.name);
|
||||
while (jmxIndex !== -1) {
|
||||
this.threadGroups.splice(jmxIndex, 1);
|
||||
jmxIndex = this.threadGroups.findIndex(tg => tg.handler === file.name);
|
||||
}
|
||||
},
|
||||
handleDeleteThreadGroup(tg) {
|
||||
this.$alert(this.$t('load_test.delete_threadgroup_confirm') + tg.attributes.testname + "?", '', {
|
||||
|
@ -490,74 +349,23 @@ export default {
|
|||
return this.fileList;// 表示修改了已经上传的文件列表
|
||||
},
|
||||
loadJMX() {
|
||||
this.loadFileVisible = true;
|
||||
this.loadType = "jmx";
|
||||
this.getProjectFiles();
|
||||
this.$refs.existFiles.open('jmx');
|
||||
},
|
||||
loadFile() {
|
||||
this.loadFileVisible = true;
|
||||
this.loadType = "resource";
|
||||
this.getProjectFiles();
|
||||
this.$refs.existFiles.open('resource');
|
||||
},
|
||||
loadApiAutomation() {
|
||||
this.loadApiAutomationVisible = true;
|
||||
this.getProjectScenarios();
|
||||
this.$refs.existScenarios.open();
|
||||
},
|
||||
getProjectFiles() {
|
||||
this.projectLoadingResult = this.$get('/performance/project/' + this.loadType + '/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, res => {
|
||||
let data = res.data;
|
||||
this.total = data.itemCount;
|
||||
this.existFiles = data.listObject;
|
||||
})
|
||||
fileChange(threadGroups) {
|
||||
this.$emit('fileChange', threadGroups);
|
||||
},
|
||||
getProjectScenarios() {
|
||||
let condition = {
|
||||
projectId: getCurrentProjectID(),
|
||||
filters: {status: ["Prepare", "Underway", "Completed"]}
|
||||
}
|
||||
this.projectLoadingResult = this.$post('/api/automation/list/' + this.currentPage + "/" + this.pageSize, condition, res => {
|
||||
let data = res.data;
|
||||
this.total = data.itemCount;
|
||||
this.apiScenarios = data.listObject;
|
||||
})
|
||||
},
|
||||
|
||||
validConfig() {
|
||||
let newJmxNum = 0, oldJmxNum = 0, newCsvNum = 0, oldCsvNum = 0, newJarNum = 0, oldJarNum = 0;
|
||||
if (this.uploadList.length > 0) {
|
||||
this.uploadList.forEach(f => {
|
||||
if (f.name.toLowerCase().endsWith(".jmx")) {
|
||||
newJmxNum++;
|
||||
}
|
||||
if (f.name.toLowerCase().endsWith(".csv")) {
|
||||
newCsvNum++;
|
||||
}
|
||||
if (f.name.toLowerCase().endsWith(".jar")) {
|
||||
newJarNum++;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this.fileList.length > 0) {
|
||||
this.fileList.forEach(f => {
|
||||
if (f.name.toLowerCase().endsWith(".jmx")) {
|
||||
oldJmxNum++;
|
||||
}
|
||||
if (f.name.toLowerCase().endsWith(".csv")) {
|
||||
oldCsvNum++;
|
||||
}
|
||||
if (f.name.toLowerCase().endsWith(".jar")) {
|
||||
oldJarNum++;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (newCsvNum + oldCsvNum + newJarNum + oldJarNum > this.fileNumLimit - 1) {
|
||||
if (this.uploadList.length + this.fileList.length > this.fileNumLimit) {
|
||||
this.handleExceed();
|
||||
return false;
|
||||
}
|
||||
if (newJmxNum + oldJmxNum !== 1) {
|
||||
this.$error(this.$t('load_test.jmx_is_null'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.threadGroups.filter(tg => tg.attributes.enabled == 'true').length === 0) {
|
||||
this.$error(this.$t('load_test.threadgroup_at_least_one'));
|
||||
return false;
|
||||
|
|
|
@ -128,8 +128,9 @@
|
|||
<script>
|
||||
import echarts from "echarts";
|
||||
import MsChart from "@/business/components/common/chart/MsChart";
|
||||
import {findTestPlan, findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
|
||||
const HANDLER = "handler";
|
||||
const TARGET_LEVEL = "TargetLevel";
|
||||
const RAMP_UP = "RampUp";
|
||||
const ITERATE_RAMP_UP = "iterateRampUpTime";
|
||||
|
@ -181,7 +182,6 @@ export default {
|
|||
resourcePools: [],
|
||||
activeNames: ["0"],
|
||||
threadGroups: [],
|
||||
serializeThreadgroups: false,
|
||||
resourcePoolResourceLength: 1
|
||||
}
|
||||
},
|
||||
|
@ -262,6 +262,9 @@ export default {
|
|||
case DELETED:
|
||||
this.threadGroups[i].deleted = item.value;
|
||||
break;
|
||||
case HANDLER:
|
||||
this.threadGroups[i].handler = item.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -281,21 +284,17 @@ export default {
|
|||
},
|
||||
getJmxContent() {
|
||||
if (this.testId) {
|
||||
let threadGroups = [];
|
||||
this.$get('/performance/get-jmx-content/' + this.testId, (response) => {
|
||||
if (response.data) {
|
||||
let testPlan = findTestPlan(response.data);
|
||||
testPlan.elements.forEach(e => {
|
||||
if (e.attributes.name === 'TestPlan.serialize_threadgroups') {
|
||||
this.serializeThreadgroups = Boolean(e.elements[0].text);
|
||||
}
|
||||
});
|
||||
this.threadGroups = findThreadGroup(response.data);
|
||||
this.threadGroups.forEach(tg => {
|
||||
response.data.forEach(d => {
|
||||
threadGroups = threadGroups.concat(findThreadGroup(d.jmx, d.name));
|
||||
threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.$emit('fileChange', this.threadGroups);
|
||||
this.getLoadConfig();
|
||||
}
|
||||
});
|
||||
this.threadGroups = threadGroups;
|
||||
this.$emit('fileChange', threadGroups);
|
||||
this.getLoadConfig();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -523,6 +522,7 @@ export default {
|
|||
let result = [];
|
||||
for (let i = 0; i < this.threadGroups.length; i++) {
|
||||
result.push([
|
||||
{key: HANDLER, value: this.threadGroups[i].handler},
|
||||
{key: TARGET_LEVEL, value: this.threadGroups[i].threadNumber},
|
||||
{key: RAMP_UP, value: this.threadGroups[i].rampUpTime},
|
||||
{key: STEPS, value: this.threadGroups[i].step},
|
||||
|
|
|
@ -21,12 +21,13 @@ let travel = function (elements, threadGroups) {
|
|||
}
|
||||
}
|
||||
|
||||
export function findThreadGroup(jmxContent) {
|
||||
export function findThreadGroup(jmxContent, handler) {
|
||||
let jmxJson = JSON.parse(xml2json(jmxContent));
|
||||
let threadGroups = [];
|
||||
travel(jmxJson.elements, threadGroups);
|
||||
threadGroups.forEach(tg => {
|
||||
tg.deleted = 'false';
|
||||
tg.handler = handler;
|
||||
tg.enabled = tg.attributes.enabled;
|
||||
})
|
||||
return threadGroups;
|
||||
|
|
|
@ -499,7 +499,7 @@ export default {
|
|||
scenario_name: 'Scenario Name',
|
||||
upload_jmx: 'Upload JMX',
|
||||
exist_jmx: 'Existed Files',
|
||||
other_resource: 'Other Files',
|
||||
other_resource: 'Resource Files',
|
||||
upload_file: 'Upload Files',
|
||||
load_exist_file: 'Load Project Files',
|
||||
load_exist_jmx: 'Load Project JMX',
|
||||
|
|
|
@ -501,7 +501,7 @@ export default {
|
|||
scenario_name: "场景名称",
|
||||
upload_jmx: '上传 JMX 文件',
|
||||
exist_jmx: '已存在的文件',
|
||||
other_resource: '其他资源',
|
||||
other_resource: '资源文件',
|
||||
upload_file: '上传新文件',
|
||||
load_exist_file: '加载已有文件',
|
||||
load_exist_jmx: '加载已有 JMX 文件',
|
||||
|
|
|
@ -498,7 +498,7 @@ export default {
|
|||
scenario_name: '場景名稱',
|
||||
upload_jmx: '上傳 JMX文件',
|
||||
exist_jmx: '已存在的文件',
|
||||
other_resource: '其他資源',
|
||||
other_resource: '資源文件',
|
||||
upload_file: '上傳新文件',
|
||||
load_exist_file: '加載已有文件',
|
||||
load_exist_jmx: '加載已有 JMX 文件',
|
||||
|
|
Loading…
Reference in New Issue