Commit f7d837d1 authored by Captain.B's avatar Captain.B Committed by 刘瑞斌
Browse files

refactor(性能测试): 切割csv文件

parent 0d7df4b6
dev dependabot/maven/backend/com.thoughtworks.xstream-xstream-1.4.18 dependabot/maven/backend/org.apache.commons-commons-compress-1.21 dependabot/maven/backend/org.jsoup-jsoup-1.14.2 dev-workstation feat_api_custom_field feat_custom_field feat_custom_function feat_environment_group feat_environment_group_copy feat_jmeter_definition_import feat_plugin feat_remove_organization feat_timing_clean feat_vc feat_vc_testtrack fix_definition_import fix_lyh_v1.17 fix_stop_scenario master pr@dev@feat@四种协议test、case页面优化 pr@dev@feat_add_issueremark pr@dev@feat_sync pr@dev@feat_参数添加长度描述 pr@dev@feat_同步禅道缺陷 pr@dev@feat_同步第三方平台缺陷状态 pr@dev@feat_工作空间多项目环境组合 pr@dev@feat_性能测试版本对比页面修改_自动执行 pr@dev@feat_报告模板打包成一个html pr@dev@feat_接口定义、批量场景转性能测试一键更新 pr@dev@feat_接口测试_文档结构断言 pr@dev@feat_接口用例列表添加批量执行 pr@dev@feat_测试计划报告分享 pr@dev@feat_测试计划用例自定义排序 pr@dev@feat_用例支持自定义排序 pr@dev@feat_脑图保存临时节点 pr@dev@feat_脑图用例没保存提示 pr@dev@feat_需求_plugin pr@dev@fix pr@dev@fix77 pr@dev@fix_ pr@dev@fix_23 pr@dev@fix_APIBackendListenerClient优化 pr@dev@fix_api_homepage pr@dev@fix_bug09 pr@dev@fix_bug_07202243 pr@dev@fix_bug_0726 pr@dev@fix_jira提交空的非必填字段报错 pr@dev@fix_json-schema中填写的必填和字段描述不能被导出 pr@dev@fix_postman导入报错 pr@dev@fix_report_permission pr@dev@fix_scenario_load_test pr@dev@fix_sql版本冲突 pr@dev@fix_sql脚本中带了库名 pr@dev@fix_sql错误 pr@dev@fix_swagger未导入到指定模块 pr@dev@fix_xmind格式导入优化标签 pr@dev@fix_zentao pr@dev@fix_—swagger导入报错 pr@dev@fix_从公共用例库移除_再编辑用例发现无法加到公共用例库了 pr@dev@fix_代码扫描图标不显示 pr@dev@fix_修复条件控制器变量值中有换行导致判断失败问题 pr@dev@fix_修复环境设置中编辑下模块和路径匹配时模块和路径允许为空的缺陷 pr@dev@fix_修改SQL中大小写与实际表名不一致问题 pr@dev@fix_修改db版本号 pr@dev@fix_修改prometheus内存使用率查询公式 pr@dev@fix_关联测试保存失效 pr@dev@fix_删除用例后数量统计错误 pr@dev@fix_删除项目清理定时任务 pr@dev@fix_功能用例版本切换 pr@dev@fix_同步缺陷失败 pr@dev@fix_回退问题PR pr@dev@fix_场景导入按钮失效 pr@dev@fix_失败继续无效 pr@dev@fix_导出场景文件名为null pr@dev@fix_应用管理没有自动保存 pr@dev@fix_开多个窗口编辑场景样式错乱 pr@dev@fix_批量操作数量显示错误 pr@dev@fix_接口case优化 pr@dev@fix_接口定义_列表筛选 pr@dev@fix_接口定义_用例执行 pr@dev@fix_接口定义_用例批量 pr@dev@fix_接口定义导入order字段为空 pr@dev@fix_接口定义导入用例id重复 pr@dev@fix_接口导入MS格式报空指针 pr@dev@fix_接口模块名带有斜杠导出导入异常 pr@dev@fix_接口测试_复制接口 pr@dev@fix_接口测试_安全漏洞 pr@dev@fix_接口测试_引用问题 pr@dev@fix_接口用例在定义后面 pr@dev@fix_接口自动化_步骤 pr@dev@fix_接口详情-变更历史无变更详情日志 pr@dev@fix_操作日志_增删改查除系统设置中的操作均无法跳转 pr@dev@fix_操作日志列表报错 pr@dev@fix_新增测试阶段字段在筛选列表中未更新 pr@dev@fix_测试执行打印错误日志 pr@dev@fix_测试用例关联缺陷列表状态没更新 pr@dev@fix_测试用例导入更新文本错误 pr@dev@fix_测试用例显示了已删除的缺陷 pr@dev@fix_测试计划-场景测试执行结果筛选失败 pr@dev@fix_测试计划-用例状态过滤失效 pr@dev@fix_测试计划实际结果无法编辑 pr@dev@fix_测试计划性能测试sql pr@dev@fix_测试计划报告报错 pr@dev@fix_测试计划页面优化 pr@dev@fix_测试跟踪_功能用例_公共用例库_选择修改用例责任人后,新的责任人仍不可编辑和删除该用例 pr@dev@fix_用例导入文件限制改为100M pr@dev@fix_用例导入无法显示责任人 pr@dev@fix_用例评审_测试计划_关注人支持多选 pr@dev@fix_编辑场景滑动滚动条控制台报错 pr@dev@fix_编辑用例点击关联缺陷缺少数据 pr@dev@fix_脑图创建用例自定义ID为空 pr@dev@fix_脑图无法删除用例 pr@dev@fix_自定义表头国际化问题 pr@dev@fix_被引用的数据删除显示重复 pr@dev@fix_选中模块后删除用例会显示全部用例 pr@dev@refactor_case_import pr@dev@refactor_jira缺陷描述支持图片 pr@dev@refactor_load_test pr@dev@refactor_menu_pos pr@dev@refactor_postman导入变量格式转换 pr@dev@refactor_swagger2导入之后默认值没有导入 pr@dev@refactor_swagger导入body参数的顺序不变 pr@dev@refactor_swagger导入弃用接口打上Deleted标签 pr@dev@refactor_tapd详情支持图片 pr@dev@refactor_user_search pr@dev@refactor_修改数据库连接池默认配置 pr@dev@refactor_勾选批量操作提示 pr@dev@refactor_升级Jython版本 pr@dev@refactor_右上角的帮助文档,修改为新页面打开 pr@dev@refactor_场景导入页面高度优化 pr@dev@refactor_接口定时任务编辑页面样式优化 pr@dev@refactor_样式优化 pr@dev@refactor_步骤描述格式优化 pr@dev@refactor_测试用例页面创建人显示名称 pr@dev@refactor_用例上传大小限制改为50M pr@dev@refactor_缺陷列表增加用例数字段 pr@dev@refactor_缺陷列表添加过滤排序条件 pr@dev@refactor_缺陷列表点击关联用例跳转到用例列表过滤 pr@dev@refactor_获取场景报告接口效率优化 pr@dev@refactor_规范建表语句 pr@dev@refactor_请求头加描述 pr@dev@refactor_重构测试计划-场景测试 pr@dev@refactor_重构测试计划-性能测试页面 pr@dev@refactor_重构测试计划-接口测试页面 pr@dev@refactor_首页定时任务展示优化 pr@dev@style_调整多处样式使布局更加紧凑 pr@dev@内置函数构造器优化增加mock数据说明示例及场景变量 pr@dev@去掉测试跟踪及接口测试首页tips pr@dev@构建完成后清理构建产物 pr@dev@编辑用例页面mock显示优化 pr@master@fix_代码扫描图标不显示 pr@v1.11@feat_接口定义、批量场景转性能测试一键更新 pr@v1.11@feat_接口用例列表添加批量执行 pr@v1.11@fix_postman导入报错 pr@v1.11@fix_report_permission pr@v1.11@fix_review_bug_0726 pr@v1.11@fix_zentao pr@v1.11@fix_—swagger导入报错 pr@v1.11@fix_修改prometheus内存使用率查询公式 pr@v1.11@fix_关联测试保存失效 pr@v1.11@fix_删除项目清理定时任务 pr@v1.11@fix_接口自动化_步骤 pr@v1.11@fix_测试执行打印错误日志 pr@v1.11@fix_测试用例导入更新文本错误 pr@v1.11@fix_测试用例显示了已删除的缺陷 pr@v1.11@fix_测试计划报告报错 pr@v1.11@fix_消息通知 pr@v1.11@fix_用例导入文件限制改为100M pr@v1.11@fix_脑图无法删除用例 pr@v1.11@fix_自动化_执行 pr@v1.11@fix_自定义表头国际化问题 pr@v1.11@refactor_修改数据库连接池默认配置 pr@v1.11@编辑用例页面mock显示优化 pr@v1.12@fix_json-schema中填写的必填和字段描述不能被导出 pr@v1.12@fix_修复条件控制器变量值中有换行导致判断失败问题 pr@v1.12@fix_接口定义_用例批量 pr@v1.12@fix_接口自动化_循环执行问题 pr@v1.12@fix_接口自动化_执行问题 pr@v1.12@fix_接口自动化_拖拽 pr@v1.12@fix_测试计划实际结果无法编辑 pr@v1.12@refactor_swagger2导入之后默认值没有导入 pr@v1.12@refactor_swagger导入弃用接口打上Deleted标签 pr@v1.12@refactor_升级Jython版本 pr@v1.12@refactor_步骤描述格式优化 pr@v1.14@fix_接口测试_复制接口 pr@v1.14@fix_用例评审_测试计划_关注人支持多选 pr@v1.15@fix_sync pr@v1.16@fix_scenario_load pr@v1.16@fix_接口测试_安全漏洞 pr@v1.16@fix_接口测试_引用问题 pr@v1.16@fix_接口详情-变更历史无变更详情日志 pr@v1.16@fix_测试跟踪_功能用例_公共用例库_选择修改用例责任人后,新的责任人仍不可编辑和删除该用例 pr@v1.16@refactor_获取场景报告接口效率优化 pr@v1.17@feat_我的工作台加版本筛选 pr@v1.17@fix pr@v1.17@fix_功能用例版本切换 pr@v1.17@fix_新增测试阶段字段在筛选列表中未更新 pr@v1.18@fix_修复环境设置中编辑下模块和路径匹配时模块和路径允许为空的缺陷 refactor refactor_environment_group refactor_group_member refactor_project_setting refactor_user_batch refactor_ws_notice_template repr@dev@7c38db9ad34ad57c62b4ff6126a7b0cc051d2d87@feat_测试计划导出html repr@dev_V1.10_v1.11@40cd10d7ebcfd984dcbf159aa43136493bf6cc0b@fix_接口定义批量操作报错 repr@dev_master_v1.16@ repr@dev_v1.0@0cf2d0a69ee2872@fix repr@dev_v1.0@71d32d30@refactor_rampup repr@dev_v1.0@c350f1c137b500@fix77 repr@dev_v1.0@e6f921547ae76395@fixdev_bug repr@dev_v1.0@fdabf2cb4@fix_缺陷数量 repr@dev_v1.10@32de68664756f019@fix_定时同步跳转 repr@dev_v1.10@3ca0e91480b41667c@fix repr@dev_v1.10@9dc0f51ea06584447020dcd946d291115362a1b1@feat_脑图用例没保存提示 repr@dev_v1.10@cff1e95686ce@fix_dev repr@dev_v1.11@8cbdf7cb54ce7ea2097b43990f4f0f25602548ad@fix_其他平台缺陷添加取消关联缺陷 repr@dev_v1.11@dx@fix_接口自动化_执行报告处理 repr@dev_v1.11_v1.10@b590ba7d7a2079d331805573c279f71572f40fd4@fix_测试执行打印错误日志 repr@dev_v1.12@28a030cf@fix_接口定义_批量执行 repr@dev_v1.12@9f49f57a@fix_接口自动化_拖拽 repr@dev_v1.14@@fix_【接口定义】-添加mock函数时值生成优化+页面翻译“return” repr@dev_v1.14@f7409212@fix_接口测试_CSV优化 repr@dev_v1.14_v1.16@fc598de402cffa8744ee656948f715c31e7d58a2@refactor_场景资源池执行添加日志打印 repr@dev_v1.16@1abe60fc@fix_接口测试_循环控制器 repr@dev_v1.16@22a21ac3@fix_接口测试_自动化步骤 repr@dev_v1.16@5d8ba4eb@fix_接口详情-变更历史无变更详情日志 repr@dev_v1.16@6de996ff@fix_接口定义_开启过多时环境与接口名称重叠 repr@dev_v1.16@a009bb38@fix_接口测试_场景执行 repr@dev_v1.16@e15672af3dc95618192ee81aedbefffdfd377b8a@fix_代码扫描图标不显示 repr@dev_v1.16@e43c11a7@fix_应用管理没有保存 repr@dev_v1.16@e43c11a7@fix_应用管理没有自动保存 repr@dev_v1.16_v1.17@430a1864ffe9800240f4fbd9b0c92991305c0baa@fix_脑图创建的用例导出状态和责任人为空 repr@dev_v1.16_v1.17@91c1b2a7@fix_接口测试_插件步骤 repr@dev_v1.17@0d05cd92d9a1b005aac8c07594625f3cda8319080d05cd92d9a1b005aac8c07594625f3cda831908@feat_测试跟踪用例版本相关 repr@dev_v1.17@0d05cd92d9a1b005aac8c07594625f3cda831908@fix_功能用例版本管理回收站 repr@dev_v1.18@abc86b09@fix_lyh_dev repr@devev_v1.16@31e9453dccbf5b363f72b9a2c4d6b1f40d9e92f5@fix_tapd不显示图片 repr@v1.11_dev@6fd05b82@fix_envparam repr@v1.16@fix_JSONPATH断言等有200个字符限制 repr@v1.16_dev@09a4129d@fix_接口测试_调试状态 repr@v1.16_dev@11eb4bc6@feat_error_report repr@v1.16_dev@6a89622f@fix_接口测试_JSON校验处理 repr@v1.16_dev@d5cf72dc@fix_接口测试_场景报告 repr@v1.16_dev@e2e90011@fix_testplan_用例执行 repr@v1.16_dev@ef78a7eb@fix_xpack_code repr@v1.16_v1.17_dev@bfb01376@fix_bugs_import_api repr@v1.16_v1.17_dev@dd1880fa@fix_bugs_0118 seleniumdocker获取报告图表 ui v1.11 v1.12 v1.13 v1.14 v1.15 v1.16 v1.17 v1.18 工作空间多项目环境组合 v1.18.2-rc2 v1.18.2-rc1 v1.18.2-rc0 v1.18.2-arm64 v1.18.1 v1.18.0 v1.17.3 v1.17.2 v1.17.1 v1.17.0 v1.16.6 v1.16.5 v1.16.4 v1.16.3 v1.16.2 v1.16.1 v1.16.0 v1.15.4 v1.15.3 v1.15.2 v1.15.1 v1.15.0 v1.14.7 v1.14.6 v1.14.5 v1.14.4 v1.14.3 v1.14.2 v1.14.1 v1.14.0 v1.14.0-rc3 v1.14.0-rc2 v1.14.0-rc1 v1.13.2 v1.13.1 v1.13.0 v1.12.3 v1.12.2 v1.12.1 v1.12.1-rc1 v1.12.0 v1.12.0-rc3 v1.12.0-rc2 v1.12.0-rc1 v1.11.3 v1.11.2 v1.11.2-rc1 v1.11.1 v1.11.0 v1.11-rc1
No related merge requests found
Showing with 277 additions and 140 deletions
+277 -140
......@@ -12,6 +12,7 @@ public class EngineContext {
private String resourcePoolId;
private String reportId;
private Integer resourceIndex;
private double[] ratios;
private Map<String, Object> properties = new HashMap<>();
private Map<String, byte[]> testResourceFiles = new HashMap<>();
......@@ -92,6 +93,13 @@ public class EngineContext {
this.resourceIndex = resourceIndex;
}
public double[] getRatios() {
return ratios;
}
public void setRatios(double[] ratios) {
this.ratios = ratios;
}
public Map<String, byte[]> getTestResourceFiles() {
return testResourceFiles;
......
......@@ -117,6 +117,7 @@ public class EngineFactory {
engineContext.setResourcePoolId(loadTest.getTestResourcePoolId());
engineContext.setReportId(reportId);
engineContext.setResourceIndex(resourceIndex);
engineContext.setRatios(ratios);
if (StringUtils.isNotEmpty(loadTest.getLoadConfiguration())) {
final JSONArray jsonArray = JSONObject.parseArray(loadTest.getLoadConfiguration());
......@@ -166,6 +167,15 @@ public class EngineFactory {
MSException.throwException("File type unknown");
}
if (CollectionUtils.isNotEmpty(resourceFiles)) {
Map<String, byte[]> data = new HashMap<>();
resourceFiles.forEach(cf -> {
FileContent csvContent = fileService.getFileContent(cf.getId());
data.put(cf.getName(), csvContent.getFile());
});
engineContext.setTestResourceFiles(data);
}
try (ByteArrayInputStream source = new ByteArrayInputStream(jmxBytes)) {
String content = engineSourceParser.parse(engineContext, source);
engineContext.setContent(content);
......@@ -177,15 +187,6 @@ public class EngineFactory {
MSException.throwException(e);
}
if (CollectionUtils.isNotEmpty(resourceFiles)) {
Map<String, byte[]> data = new HashMap<>();
resourceFiles.forEach(cf -> {
FileContent csvContent = fileService.getFileContent(cf.getId());
data.put(cf.getName(), csvContent.getFile());
});
engineContext.setTestResourceFiles(data);
}
return engineContext;
}
......
......@@ -4,9 +4,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.jmeter.utils.ScriptEngineUtils;
import io.metersphere.config.KafkaProperties;
import io.metersphere.i18n.Translator;
import io.metersphere.jmeter.utils.ScriptEngineUtils;
import io.metersphere.performance.engine.EngineContext;
import io.metersphere.performance.parse.xml.reader.DocumentParser;
import org.apache.commons.lang3.BooleanUtils;
......@@ -22,8 +22,10 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
public class JmeterDocumentParser implements DocumentParser {
private final static String HASH_TREE_ELEMENT = "hashTree";
......@@ -267,10 +269,73 @@ public class JmeterDocumentParser implements DocumentParser {
if (StringUtils.equals(filenameTag, "filename")) {
// 截取文件名
handleFilename(item);
// 切割CSV文件
splitCsvFile(item);
break;
}
}
}
}
private void splitCsvFile(Node item) {
Object csvConfig = context.getProperty("csvConfig");
if (csvConfig == null) {
return;
}
double[] ratios = context.getRatios();
int resourceIndex = context.getResourceIndex();
String filename = item.getTextContent();
byte[] content = context.getTestResourceFiles().get(filename);
StringTokenizer tokenizer = new StringTokenizer(new String(content), "\n");
if (!tokenizer.hasMoreTokens()) {
return;
}
StringBuilder csv = new StringBuilder();
Object config = ((JSONObject) csvConfig).get(filename);
boolean csvSplit = ((JSONObject) (config)).getBooleanValue("csvSplit");
if (!csvSplit) {
return;
}
boolean csvHasHeader = ((JSONObject) (config)).getBooleanValue("csvHasHeader");
if (csvHasHeader) {
String header = tokenizer.nextToken();
csv.append(header).append("\n");
}
int count = tokenizer.countTokens();
long current, offset = 0;
// 计算偏移量
for (int k = 0; k < resourceIndex; k++) {
offset += Math.round(count * ratios[k]);
}
if (resourceIndex + 1 == ratios.length) {
current = count - offset; // 最后一个点可以分到的数量
} else {
current = Math.round(count * ratios[resourceIndex]); // 当前节点可以分到的数量
}
long index = 0;
while (tokenizer.hasMoreTokens()) {
if (current == 0) { // 节点一个都没有分到,把所有的数据都给这个节点(极端情况)
String line = tokenizer.nextToken();
csv.append(line).append("\n");
} else {
if (index < offset) {
index++;
continue;
}
if (index > current + offset) {
break;
}
String line = tokenizer.nextToken();
csv.append(line).append("\n");
}
index++;
}
// 替换文件
context.getTestResourceFiles().put(filename, csv.toString().getBytes(StandardCharsets.UTF_8));
}
private void processResponseAssertion(Element element) {
......
......@@ -316,6 +316,7 @@ export default {
fileChange(threadGroups) {
let handler = this.$refs.pressureConfig;
let csvSet = new Set;
threadGroups.forEach(tg => {
tg.threadNumber = tg.threadNumber || 10;
tg.duration = tg.duration || 10;
......@@ -325,12 +326,21 @@ export default {
tg.threadType = tg.threadType || 'DURATION';
tg.iterateNum = tg.iterateNum || 1;
tg.iterateRampUp = tg.iterateRampUp || 10;
if (tg.csvFiles) {
tg.csvFiles.map(item => csvSet.add(item));
}
});
let csvFiles = [];
for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true});
}
this.$set(handler, "threadGroups", threadGroups);
this.$refs.basicConfig.threadGroups = threadGroups;
this.$refs.pressureConfig.threadGroups = threadGroups;
this.$refs.advancedConfig.csvFiles = csvFiles;
handler.calculateTotalChart();
},
......
<template>
<div>
<!-- 基本配置 -->
<el-row>
<el-col :span="6">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.connect_timeout') }}</div>
</el-form-item>
<el-form-item>
<el-input-number
:disabled="readOnly" size="mini" v-model="timeout"
:min="0"/>
</el-form-item>
<el-form-item>
ms
</el-form-item>
</el-form>
</el-col>
<el-col :span="6">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.response_timeout') }}</div>
</el-form-item>
<el-form-item>
<el-input-number
:disabled="readOnly" size="mini" :min="0"
v-model="responseTimeout"/>
</el-form-item>
<el-form-item>
ms
</el-form-item>
</el-form>
</el-col>
<el-col :span="6">
<el-form :inline="true">
<el-form-item>
<div>
{{ $t('load_test.granularity') }}
<el-popover
placement="left"
width="300"
trigger="hover">
<el-table :data="granularityData">
<el-table-column property="start" :label="$t('load_test.duration')">
<template v-slot:default="scope">
<span>{{ scope.row.start }}S - {{ scope.row.end }}S</span>
</template>
</el-table-column>
<el-table-column property="granularity" :label="$t('load_test.granularity')"/>
</el-table>
<i slot="reference" class="el-icon-info pointer"/>
</el-popover>
</div>
</el-form-item>
<el-form-item>
<el-select v-model="granularity" :placeholder="$t('commons.please_select')" size="mini"
clearable>
<el-option v-for="op in granularityData" :key="op.granularity" :label="op.granularity"
:value="op.granularity"></el-option>
</el-select>
</el-form-item>
</el-form>
</el-col>
<el-col :span="6">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.custom_http_code') }}</div>
</el-form-item>
<el-form-item>
<el-input
:disabled="readOnly" size="mini" v-model="statusCodeStr"
:placeholder="$t('load_test.separated_by_commas')"
@input="checkStatusCode"></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<!-- csv 配置 -->
<el-row>
<el-col :span="8">
<h3>CSVDataSet</h3>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="csvFiles" size="mini" class="tb-edit" align="center" border highlight-current-row>
<el-table-column
align="center"
prop="name"
:label="$t('commons.name')">
</el-table-column>
<el-table-column align="center" prop="csvSplit" :label="$t('load_test.csv_split')">
<template v-slot:default="{row}">
<el-switch :disabled="readOnly" v-model="row.csvSplit"/>
</template>
</el-table-column>
<el-table-column align="center" prop="csvHasHeader" :label="$t('load_test.csv_has_header')">
<template v-slot:default="{row}">
<el-switch :disabled="readOnly || !row.csvSplit" v-model="row.csvHasHeader"/>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<!-- 参数列表 -->
<el-row>
<el-col :span="8">
<h3>{{ $t('load_test.params') }}</h3>
......@@ -74,82 +179,6 @@
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.connect_timeout') }}</div>
</el-form-item>
<el-form-item>
<el-input-number :disabled="readOnly" size="mini" v-model="timeout"
:min="0"></el-input-number>
</el-form-item>
<el-form-item>
ms
</el-form-item>
</el-form>
</el-col>
<el-col :span="8">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.response_timeout') }}</div>
</el-form-item>
<el-form-item>
<el-input-number :disabled="readOnly" size="mini" :min="0"
v-model="responseTimeout"></el-input-number>
</el-form-item>
<el-form-item>
ms
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form :inline="true">
<el-form-item>
<div>{{ $t('load_test.custom_http_code') }}</div>
</el-form-item>
<el-form-item>
<el-input :disabled="readOnly" size="mini" v-model="statusCodeStr"
:placeholder="$t('load_test.separated_by_commas')"
@input="checkStatusCode"></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form :inline="true">
<el-form-item>
<div>
{{ $t('load_test.granularity') }}
<el-popover
placement="bottom"
width="400"
trigger="hover">
<el-table :data="granularityData">
<el-table-column property="start" :label="$t('load_test.duration')">
<template v-slot:default="scope">
<span>{{ scope.row.start }}S - {{ scope.row.end }}S</span>
</template>
</el-table-column>
<el-table-column property="granularity" :label="$t('load_test.granularity')"/>
</el-table>
<i slot="reference" class="el-icon-info pointer"/>
</el-popover>
</div>
</el-form-item>
<el-form-item>
<el-select v-model="granularity" :placeholder="$t('commons.please_select')" size="mini" clearable>
<el-option v-for="op in granularityData" :key="op.granularity" :label="op.granularity"
:value="op.granularity"></el-option>
</el-select>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<h3>监控集成</h3>
......@@ -158,54 +187,57 @@
</el-button>
</el-col>
</el-row>
<el-col :span="24">
<el-table :data="monitorParams" size="mini" class="tb-edit" align="center" border highlight-current-row>
<el-table-column
align="center"
prop="name"
label="名称">
</el-table-column>
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="environmentName"-->
<!-- label="所属环境">-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="authStatus"-->
<!-- label="认证状态">-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="monitorStatus"-->
<!-- label="监控状态">-->
<el-table-column
align="center"
prop="ip"
label="IP">
</el-table-column>
<el-table-column
align="center"
prop="port"
label="Port">
</el-table-column>
<el-table-column
align="center"
prop="description"
label="描述">
</el-table-column>
<el-table-column align="center" :label="$t('load_test.operating')">
<template v-slot:default="{row, $index}">
<ms-table-operator-button :disabled="readOnly" tip="编辑" icon="el-icon-edit"
type="primary"
@exec="modifyMonitor(row, $index)"/>
<ms-table-operator-button :disabled="readOnly" :tip="$t('commons.delete')" icon="el-icon-delete"
type="danger"
@exec="delMonitor(row, $index)"/>
</template>
</el-table-column>
</el-table>
</el-col>
<el-row>
<el-col :span="24">
<el-table :data="monitorParams" size="mini" class="tb-edit" align="center" border highlight-current-row>
<el-table-column
align="center"
prop="name"
label="名称">
</el-table-column>
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="environmentName"-->
<!-- label="所属环境">-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="authStatus"-->
<!-- label="认证状态">-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- align="center"-->
<!-- prop="monitorStatus"-->
<!-- label="监控状态">-->
<el-table-column
align="center"
prop="ip"
label="IP">
</el-table-column>
<el-table-column
align="center"
prop="port"
label="Port">
</el-table-column>
<el-table-column
align="center"
prop="description"
label="描述">
</el-table-column>
<el-table-column align="center" :label="$t('load_test.operating')">
<template v-slot:default="{row, $index}">
<ms-table-operator-button :disabled="readOnly" tip="编辑" icon="el-icon-edit"
type="primary"
@exec="modifyMonitor(row, $index)"/>
<ms-table-operator-button :disabled="readOnly" :tip="$t('commons.delete')" icon="el-icon-delete"
type="danger"
@exec="delMonitor(row, $index)"/>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<edit-monitor ref="monitorDialog" :testId="testId" :list.sync="monitorParams"/>
</div>
......@@ -227,6 +259,8 @@ export default {
domains: [],
params: [],
monitorParams: [],
csvFiles: [],
csvConfig: [],
statusCodeStr: '',
granularity: undefined,
granularityData: [
......@@ -257,6 +291,14 @@ export default {
if (this.testId) {
this.getAdvancedConfig();
}
},
csvFiles() {
if (this.csvConfig && this.csvFiles) {
this.csvFiles.forEach(f => {
f.csvSplit = this.csvConfig[f.name].csvSplit;
f.csvHasHeader = this.csvConfig[f.name].csvHasHeader;
});
}
}
},
methods: {
......@@ -272,6 +314,7 @@ export default {
this.params = data.params || [];
this.granularity = data.granularity;
this.monitorParams = data.monitorParams || [];
this.csvConfig = data.csvConfig;
}
});
},
......@@ -357,6 +400,10 @@ export default {
responseTimeout: this.responseTimeout,
statusCode: statusCode,
params: this.params,
csvConfig: this.csvFiles.reduce((result, curr) => {
result[curr.name] = {csvHasHeader: curr.csvHasHeader, csvSplit: curr.csvSplit};
return result;
}, {}),
domains: this.domains,
granularity: this.granularity,
monitorParams: this.monitorParams
......
......@@ -649,6 +649,8 @@ export default {
load_api_automation_jmx: 'Import API automation scenario',
project_file_exist: "The file already exists in the project, please import it directly",
project_file_update_type_error: 'Updated file types must be consistent',
csv_has_header: 'Contains Title',
csv_split: 'CSV Split',
report: {
diff: "Compare",
set_default: 'Set to Default',
......
......@@ -617,9 +617,9 @@ export default {
param_is_duplicate: '参数名不能重复',
domain_ip_is_empty: '域名和IP不能为空',
param_name_value_is_empty: '参数名和参数值不能为空',
connect_timeout: '建立连接超时时间',
response_timeout: '响应超时时间',
custom_http_code: '自定义 HTTP 响应成功状态',
connect_timeout: '连接超时',
response_timeout: '响应超时',
custom_http_code: '自定义响应',
separated_by_commas: '按逗号分隔',
create: '创建测试',
run: '一键运行',
......@@ -647,6 +647,8 @@ export default {
threadgroup_at_least_one: '至少启用一个线程组',
load_api_automation_jmx: '引用接口自动化场景',
project_file_exist: "项目中已存在该文件,请直接引用",
csv_has_header: '包含表头',
csv_split: 'CSV分割',
report: {
diff: "对比",
set_default: '恢复默认',
......
......@@ -617,9 +617,9 @@ export default {
param_is_duplicate: '參數名不能重復',
domain_ip_is_empty: '域名和IP不能為空',
param_name_value_is_empty: '參數名和參數值不能為空',
connect_timeout: '建立連接超時時間',
response_timeout: '響應超時時間',
custom_http_code: '自定義 HTTP 響應成功狀態',
connect_timeout: '連接超時',
response_timeout: '響應超時',
custom_http_code: '自定義響應',
separated_by_commas: '按逗號分隔',
create: '創建測試',
run: '一鍵運行',
......@@ -647,6 +647,8 @@ export default {
threadgroup_at_least_one: '至少啟用一個線程組',
load_api_automation_jmx: '引用接口自動化場景',
project_file_exist: "項目中已存在該文件,請直接引用",
csv_has_header: '包含表头',
csv_split: 'CSV分割',
report: {
diff: "對比",
set_default: '恢復默認',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment