refactor(性能测试): 报告页面显示更多内容
This commit is contained in:
parent
7a23956f63
commit
4439b17ae0
|
@ -82,9 +82,6 @@
|
|||
<el-divider/>
|
||||
<div ref="resume">
|
||||
<el-tabs v-model="active">
|
||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||
<ms-performance-pressure-config :is-read-only="true" :report="report"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('report.test_overview')">
|
||||
<ms-report-test-overview :report="report" ref="testOverview"/>
|
||||
</el-tab-pane>
|
||||
|
@ -103,6 +100,9 @@
|
|||
<el-tab-pane :label="$t('report.test_monitor_details')">
|
||||
<monitor-card :report="report"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('测试配置')">
|
||||
<ms-test-configuration :report="report" :test="test" :test-id="testId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
|
@ -131,7 +131,6 @@ import MsReportLogDetails from './components/LogDetails';
|
|||
import MsReportRequestStatistics from './components/RequestStatistics';
|
||||
import MsReportTestDetails from './components/TestDetails';
|
||||
import MsReportTestOverview from './components/TestOverview';
|
||||
import MsPerformancePressureConfig from "./components/PerformancePressureConfig";
|
||||
import MsContainer from "../../common/components/MsContainer";
|
||||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
|
||||
|
@ -141,11 +140,13 @@ import MsPerformanceReportExport from "./PerformanceReportExport";
|
|||
import {Message} from "element-ui";
|
||||
import SameTestReports from "@/business/components/performance/report/components/SameTestReports";
|
||||
import MonitorCard from "@/business/components/performance/report/components/MonitorCard";
|
||||
import MsTestConfiguration from "@/business/components/performance/report/components/TestConfiguration";
|
||||
|
||||
|
||||
export default {
|
||||
name: "PerformanceReportView",
|
||||
components: {
|
||||
MsTestConfiguration,
|
||||
MonitorCard,
|
||||
SameTestReports,
|
||||
MsPerformanceReportExport,
|
||||
|
@ -156,7 +157,6 @@ export default {
|
|||
MsContainer,
|
||||
MsMainContainer,
|
||||
MsReportTestDetails,
|
||||
MsPerformancePressureConfig
|
||||
},
|
||||
props: {
|
||||
perReportId: String
|
||||
|
@ -164,7 +164,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
result: {},
|
||||
active: '1',
|
||||
active: '0',
|
||||
reportId: '',
|
||||
status: '',
|
||||
reportName: '',
|
||||
|
@ -182,7 +182,7 @@ export default {
|
|||
websocket: null,
|
||||
dialogFormVisible: false,
|
||||
reportExportVisible: false,
|
||||
testPlan: {testResourcePoolId: null},
|
||||
test: {testResourcePoolId: null},
|
||||
refreshTime: localStorage.getItem("reportRefreshTime") || "10",
|
||||
refreshTimes: [
|
||||
{value: '1', label: '1s'},
|
||||
|
@ -414,6 +414,7 @@ export default {
|
|||
if (data) {
|
||||
this.status = data.status;
|
||||
this.$set(this, "report", data);
|
||||
this.$set(this.test, "testResourcePoolId", data.testResourcePoolId);
|
||||
this.checkReportStatus(data.status);
|
||||
if (this.status === "Completed" || this.status === "Running") {
|
||||
this.initReportTimeInfo();
|
||||
|
|
|
@ -1,695 +0,0 @@
|
|||
<template>
|
||||
<div v-loading="result.loading" class="pressure-config-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
|
||||
<el-collapse v-model="activeNames" accordion>
|
||||
<el-collapse-item :name="index"
|
||||
v-for="(threadGroup, index) in threadGroups.filter(th=>th.enabled === 'true' && th.deleted=='false')"
|
||||
:key="index">
|
||||
<template slot="title">
|
||||
<el-row>
|
||||
<el-col :span="14">
|
||||
<el-tooltip :content="threadGroup.attributes.testname" placement="top">
|
||||
<div style="padding-right:20px; font-size: 16px;" class="wordwrap">
|
||||
{{ threadGroup.attributes.testname }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-tag type="primary" size="mini" v-if="threadGroup.threadType === 'DURATION'">
|
||||
{{ $t('load_test.thread_num') }}{{ threadGroup.threadNumber }},
|
||||
{{ $t('load_test.duration') }}:
|
||||
<span v-if="threadGroup.durationHours">
|
||||
{{ threadGroup.durationHours }}{{ $t('schedule.cron.hours') }}
|
||||
</span>
|
||||
<span v-if="threadGroup.durationMinutes">
|
||||
{{ threadGroup.durationMinutes }}{{ $t('schedule.cron.minutes') }}
|
||||
</span>
|
||||
<span v-if="threadGroup.durationSeconds">
|
||||
{{ threadGroup.durationSeconds }}{{ $t('schedule.cron.seconds') }}
|
||||
</span>
|
||||
</el-tag>
|
||||
<el-tag type="primary" size="mini" v-if="threadGroup.threadType === 'ITERATION'">
|
||||
{{ $t('load_test.thread_num') }} {{ threadGroup.threadNumber }},
|
||||
{{ $t('load_test.iterate_num') }} {{ threadGroup.iterateNum }}
|
||||
</el-tag>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-form :inline="true" label-width="100px">
|
||||
<el-form-item :label="$t('load_test.thread_num')">
|
||||
<el-input-number
|
||||
:disabled="true"
|
||||
:placeholder="$t('load_test.input_thread_num')"
|
||||
v-model="threadGroup.threadNumber"
|
||||
:min="1"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<br>
|
||||
<el-form-item :label="$t('load_test.run_mode')">
|
||||
<el-radio-group v-model="threadGroup.threadType" size="mini" :disabled="true">
|
||||
<el-radio-button label="DURATION">{{ $t('load_test.by_duration') }}</el-radio-button>
|
||||
<el-radio-button label="ITERATION">{{ $t('load_test.by_iteration') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<br>
|
||||
<div v-if="threadGroup.threadType === 'DURATION'">
|
||||
<el-form-item :label="$t('load_test.duration')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
v-model="threadGroup.durationHours"
|
||||
:min="0"
|
||||
:max="9999"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('schedule.cron.hours')" label-width="40px"/>
|
||||
<el-form-item>
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
v-model="threadGroup.durationMinutes"
|
||||
:min="0"
|
||||
:max="59"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('schedule.cron.minutes')" label-width="40px"/>
|
||||
<el-form-item>
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
v-model="threadGroup.durationSeconds"
|
||||
:min="0"
|
||||
:max="59"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('schedule.cron.seconds')" label-width="20px"/>
|
||||
<br>
|
||||
<el-form-item :label="$t('load_test.rps_limit_enable')">
|
||||
<el-switch v-model="threadGroup.rpsLimitEnable" @change="calculateTotalChart()"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('load_test.rps_limit')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true || !threadGroup.rpsLimitEnable"
|
||||
v-model="threadGroup.rpsLimit"
|
||||
@change="calculateTotalChart()"
|
||||
:min="1"
|
||||
:max="99999"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<div v-if="threadGroup.tgType === 'com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup'">
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
:min="1"
|
||||
|
||||
:max="getDuration(threadGroup)"
|
||||
v-model="threadGroup.rampUpTime"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Step" label-width="50px">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
:min="1"
|
||||
:max="Math.min(threadGroup.threadNumber, threadGroup.rampUpTime)"
|
||||
v-model="threadGroup.step"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div v-if="threadGroup.tgType === 'ThreadGroup'">
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
|
||||
:min="1"
|
||||
:max="getDuration(threadGroup)"
|
||||
v-model="threadGroup.rampUpTime"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="threadGroup.threadType === 'ITERATION'">
|
||||
<el-form-item :label="$t('load_test.iterate_num')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
v-model="threadGroup.iterateNum"
|
||||
:min="1"
|
||||
:max="9999999"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<br>
|
||||
<el-form-item :label="$t('load_test.rps_limit_enable')">
|
||||
<el-switch v-model="threadGroup.rpsLimitEnable" @change="calculateTotalChart()"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('load_test.rps_limit')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true || !threadGroup.rpsLimitEnable"
|
||||
v-model="threadGroup.rpsLimit"
|
||||
:min="1"
|
||||
:max="99999"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<br>
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="true"
|
||||
:min="1"
|
||||
v-model="threadGroup.iterateRampUp"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="resourcePoolType === 'NODE'">
|
||||
<el-form-item :label="$t('load_test.resource_strategy')">
|
||||
<el-radio-group v-model="threadGroup.strategy" :disabled="true" size="mini">
|
||||
<el-radio-button label="auto">{{ $t('load_test.auto_ratio') }}</el-radio-button>
|
||||
<el-radio-button label="specify">{{ $t('load_test.specify_resource') }}</el-radio-button>
|
||||
<el-radio-button label="custom">{{ $t('load_test.custom_ratio') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div v-if="threadGroup.strategy === 'auto'"></div>
|
||||
<div v-else-if="threadGroup.strategy === 'specify'">
|
||||
<el-form-item :label="$t('load_test.specify_resource')">
|
||||
<el-select v-model="threadGroup.resourceNodeIndex" :disabled="true" size="mini">
|
||||
<el-option
|
||||
v-for="(node, index) in resourceNodes"
|
||||
:key="node.ip"
|
||||
:label="node.ip"
|
||||
:value="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-table class="adjust-table" :data="threadGroup.resourceNodes" :max-height="200">
|
||||
<el-table-column type="index" width="50"/>
|
||||
<el-table-column prop="ip" label="IP"/>
|
||||
<el-table-column prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"/>
|
||||
<el-table-column prop="ratio" :label="$t('test_track.home.percentage')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-input-number size="mini" v-model="row.ratio" :min="0" :step=".1" controls-position="right"
|
||||
:max="1"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<ms-chart class="chart-container" ref="chart1" :options="options" :autoresize="true"></ms-chart>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsChart from "@/business/components/common/chart/MsChart";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
import {
|
||||
getOldPerformanceJmxContent,
|
||||
getPerformanceJmxContent,
|
||||
getPerformanceLoadConfig,
|
||||
getPerformanceReport,
|
||||
getShareOldPerformanceJmxContent,
|
||||
getSharePerformanceJmxContent,
|
||||
getSharePerformanceLoadConfig,
|
||||
getSharePerformanceReport
|
||||
} from "@/network/load-test";
|
||||
|
||||
const HANDLER = "handler";
|
||||
const THREAD_GROUP_TYPE = "tgType";
|
||||
const TARGET_LEVEL = "TargetLevel";
|
||||
const RAMP_UP = "RampUp";
|
||||
const STEPS = "Steps";
|
||||
const DURATION = "duration";
|
||||
const DURATION_HOURS = "durationHours";
|
||||
const DURATION_MINUTES = "durationMinutes";
|
||||
const DURATION_SECONDS = "durationSeconds";
|
||||
const UNIT = "unit";
|
||||
const RPS_LIMIT = "rpsLimit";
|
||||
const RPS_LIMIT_ENABLE = "rpsLimitEnable";
|
||||
const THREAD_TYPE = "threadType";
|
||||
const ITERATE_NUM = "iterateNum";
|
||||
const ITERATE_RAMP_UP = "iterateRampUpTime";
|
||||
const ENABLED = "enabled";
|
||||
const DELETED = "deleted";
|
||||
const STRATEGY = "strategy";
|
||||
const RESOURCE_NODE_INDEX = "resourceNodeIndex";
|
||||
const RATIOS = "ratios";
|
||||
|
||||
|
||||
const hexToRgb = function (hex) {
|
||||
return 'rgb(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5))
|
||||
+ ',' + parseInt('0x' + hex.slice(5, 7)) + ')';
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "MsPerformancePressureConfig",
|
||||
components: {MsChart},
|
||||
props: ['report', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
threadNumber: 0,
|
||||
duration: 0,
|
||||
rampUpTime: 0,
|
||||
step: 0,
|
||||
rpsLimit: 0,
|
||||
rpsLimitEnable: false,
|
||||
options: {},
|
||||
resourcePool: null,
|
||||
resourcePools: [],
|
||||
activeNames: ["0"],
|
||||
threadGroups: [],
|
||||
resourcePoolType: null,
|
||||
resourceNodes: [],
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
this.getJmxContent();
|
||||
},
|
||||
created() {
|
||||
this.getResourcePools();
|
||||
},
|
||||
methods: {
|
||||
getResourcePools() {
|
||||
this.result = this.$get('/testresourcepool/list/quota/valid', response => {
|
||||
this.resourcePools = response.data;
|
||||
|
||||
this.resourcePoolChange();
|
||||
});
|
||||
},
|
||||
resourcePoolChange() {
|
||||
let result = this.resourcePools.filter(p => p.id === this.report.testResourcePoolId);
|
||||
if (result.length === 1) {
|
||||
let threadNumber = 0;
|
||||
this.resourceNodes = [];
|
||||
this.resourcePoolType = result[0].type;
|
||||
result[0].resources.forEach(resource => {
|
||||
let config = JSON.parse(resource.configuration);
|
||||
threadNumber += config.maxConcurrency;
|
||||
this.resourceNodes.push(config);
|
||||
});
|
||||
this.threadGroups.forEach(tg => {
|
||||
let tgRatios = tg.ratios;
|
||||
let resourceNodes = JSON.parse(JSON.stringify(this.resourceNodes));
|
||||
let ratios = resourceNodes.map(n => n.maxConcurrency).reduce((total, curr) => {
|
||||
total += curr;
|
||||
return total;
|
||||
}, 0);
|
||||
let preSum = 0;
|
||||
for (let i = 0; i < resourceNodes.length; i++) {
|
||||
let n = resourceNodes[i];
|
||||
if (resourceNodes.length === tgRatios.length) {
|
||||
n.ratio = tgRatios[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i === resourceNodes.length - 1) {
|
||||
n.ratio = (1 - preSum).toFixed(2);
|
||||
} else {
|
||||
n.ratio = (n.maxConcurrency / ratios).toFixed(2);
|
||||
preSum += Number.parseFloat(n.ratio);
|
||||
}
|
||||
}
|
||||
this.$set(tg, "resourceNodes", resourceNodes);
|
||||
if (tg.resourceNodeIndex > resourceNodes.length - 1) {
|
||||
this.$set(tg, "resourceNodeIndex", 0);
|
||||
}
|
||||
});
|
||||
this.calculateTotalChart();
|
||||
}
|
||||
},
|
||||
calculateLoadConfiguration: function (data) {
|
||||
for (let i = 0; i < this.threadGroups.length; i++) {
|
||||
let d = data[i];
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
d.forEach(item => {
|
||||
switch (item.key) {
|
||||
case TARGET_LEVEL:
|
||||
this.threadGroups[i].threadNumber = item.value;
|
||||
break;
|
||||
case RAMP_UP:
|
||||
this.threadGroups[i].rampUpTime = item.value;
|
||||
break;
|
||||
case ITERATE_RAMP_UP:
|
||||
this.threadGroups[i].iterateRampUp = item.value;
|
||||
break;
|
||||
case DURATION:
|
||||
this.threadGroups[i].duration = item.value;
|
||||
break;
|
||||
case DURATION_HOURS:
|
||||
this.threadGroups[i].durationHours = item.value;
|
||||
break;
|
||||
case DURATION_MINUTES:
|
||||
this.threadGroups[i].durationMinutes = item.value;
|
||||
break;
|
||||
case DURATION_SECONDS:
|
||||
this.threadGroups[i].durationSeconds = item.value;
|
||||
break;
|
||||
case UNIT:
|
||||
this.threadGroups[i].unit = item.value;
|
||||
break;
|
||||
case STEPS:
|
||||
this.threadGroups[i].step = item.value;
|
||||
break;
|
||||
case RPS_LIMIT:
|
||||
this.threadGroups[i].rpsLimit = item.value;
|
||||
break;
|
||||
case RPS_LIMIT_ENABLE:
|
||||
this.threadGroups[i].rpsLimitEnable = item.value;
|
||||
break;
|
||||
case THREAD_TYPE:
|
||||
this.threadGroups[i].threadType = item.value;
|
||||
break;
|
||||
case ITERATE_NUM:
|
||||
this.threadGroups[i].iterateNum = item.value;
|
||||
break;
|
||||
case ENABLED:
|
||||
this.threadGroups[i].enabled = item.value;
|
||||
break;
|
||||
case DELETED:
|
||||
this.threadGroups[i].deleted = item.value;
|
||||
break;
|
||||
case HANDLER:
|
||||
this.threadGroups[i].handler = item.value;
|
||||
break;
|
||||
case THREAD_GROUP_TYPE:
|
||||
this.threadGroups[i].tgType = item.value;
|
||||
break;
|
||||
case STRATEGY:
|
||||
this.threadGroups[i].strategy = item.value;
|
||||
break;
|
||||
case RESOURCE_NODE_INDEX:
|
||||
this.threadGroups[i].resourceNodeIndex = item.value;
|
||||
break;
|
||||
case RATIOS:
|
||||
this.threadGroups[i].ratios = item.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < this.threadGroups.length; i++) {
|
||||
let tg = this.threadGroups[i];
|
||||
tg.durationHours = Math.floor(tg.duration / 3600);
|
||||
tg.durationMinutes = Math.floor((tg.duration / 60 % 60));
|
||||
tg.durationSeconds = Math.floor((tg.duration % 60));
|
||||
}
|
||||
|
||||
this.resourcePoolChange();
|
||||
this.calculateTotalChart();
|
||||
}
|
||||
},
|
||||
getLoadConfig() {
|
||||
if (!this.report.id && !this.planReportTemplate) {
|
||||
return;
|
||||
}
|
||||
if (this.planReportTemplate) {
|
||||
this.handleGetLoadConfig(this.planReportTemplate);
|
||||
} else if (this.isShare) {
|
||||
this.result = getSharePerformanceReport(this.shareId, this.report.id, data => {
|
||||
this.handleGetLoadConfig(data);
|
||||
});
|
||||
} else {
|
||||
this.result = getPerformanceReport(this.report.id, data => {
|
||||
this.handleGetLoadConfig(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
handleGetLoadConfig(data) {
|
||||
if (data) {
|
||||
if (data.loadConfiguration) {
|
||||
let d = JSON.parse(data.loadConfiguration);
|
||||
this.calculateLoadConfiguration(d);
|
||||
} else {
|
||||
if (this.planReportTemplate) {
|
||||
if (this.planReportTemplate.loadConfig) {
|
||||
let data = JSON.parse(this.planReportTemplate.fixLoadConfiguration);
|
||||
this.calculateLoadConfiguration(data);
|
||||
}
|
||||
} else if (this.isShare) {
|
||||
this.result = getSharePerformanceLoadConfig(this.shareId, this.report.id, data => {
|
||||
if (data) {
|
||||
data = JSON.parse(data);
|
||||
this.calculateLoadConfiguration(data);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.result = getPerformanceLoadConfig(this.report.id, data => {
|
||||
if (data) {
|
||||
data = JSON.parse(data);
|
||||
this.calculateLoadConfiguration(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$error(this.$t('report.not_exist'));
|
||||
}
|
||||
},
|
||||
getJmxContent() {
|
||||
// console.log(this.report.testId);
|
||||
if (!this.report.testId && !this.planReportTemplate) {
|
||||
return;
|
||||
}
|
||||
if (this.planReportTemplate) {
|
||||
if (this.planReportTemplate.jmxContent) {
|
||||
this.handleGetJmxContent(JSON.parse(this.planReportTemplate.jmxContent));
|
||||
}
|
||||
} else if (this.isShare) {
|
||||
this.result = getSharePerformanceJmxContent(this.shareId, this.report.id, data => {
|
||||
this.handleGetJmxContent(data);
|
||||
});
|
||||
} else {
|
||||
this.result = getPerformanceJmxContent(this.report.id, data => {
|
||||
this.handleGetJmxContent(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
handleGetJmxContent(d) {
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
let threadGroups = [];
|
||||
threadGroups = threadGroups.concat(findThreadGroup(d.jmx, d.name));
|
||||
threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.threadGroups = threadGroups;
|
||||
this.getLoadConfig();
|
||||
|
||||
// 兼容数据
|
||||
if (!threadGroups || threadGroups.length === 0) {
|
||||
if (this.planReportTemplate) {
|
||||
this.planReportTemplate.fixJmxContent.forEach(d => this.handleGetOldJmxContent(d, threadGroups));
|
||||
} else if (this.isShare) {
|
||||
this.result = getShareOldPerformanceJmxContent(this.shareId, this.report.testId, data => {
|
||||
data.forEach(d => this.handleGetOldJmxContent(d, threadGroups));
|
||||
});
|
||||
} else {
|
||||
this.result = getOldPerformanceJmxContent(this.report.testId, data => {
|
||||
data.forEach(d => this.handleGetOldJmxContent(d, threadGroups));
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
handleGetOldJmxContent(d, threadGroups) {
|
||||
threadGroups = threadGroups.concat(findThreadGroup(d.jmx, d.name));
|
||||
threadGroups.forEach(tg => {
|
||||
tg.options = {};
|
||||
});
|
||||
this.threadGroups = threadGroups;
|
||||
this.getLoadConfig();
|
||||
},
|
||||
calculateTotalChart() {
|
||||
let handler = this;
|
||||
if (handler.duration < handler.rampUpTime) {
|
||||
handler.rampUpTime = handler.duration;
|
||||
}
|
||||
if (handler.rampUpTime < handler.step) {
|
||||
handler.step = handler.rampUpTime;
|
||||
}
|
||||
let color = ['#60acfc', '#32d3eb', '#5bc49f', '#feb64d', '#ff7c7c', '#9287e7', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
|
||||
handler.options = {
|
||||
color: color,
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: []
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
series: []
|
||||
};
|
||||
|
||||
|
||||
for (let i = 0; i < handler.threadGroups.length; i++) {
|
||||
if (handler.threadGroups[i].enabled === 'false' ||
|
||||
handler.threadGroups[i].deleted === 'true' ||
|
||||
handler.threadGroups[i].threadType === 'ITERATION') {
|
||||
continue;
|
||||
}
|
||||
let seriesData = {
|
||||
name: handler.threadGroups[i].attributes.testname,
|
||||
data: [],
|
||||
type: 'line',
|
||||
step: 'start',
|
||||
smooth: false,
|
||||
symbolSize: 5,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
itemStyle: {
|
||||
color: hexToRgb(color[i % color.length]),
|
||||
borderColor: 'rgba(137,189,2,0.27)',
|
||||
borderWidth: 12
|
||||
},
|
||||
};
|
||||
|
||||
let tg = handler.threadGroups[i];
|
||||
|
||||
let timePeriod = Math.floor(tg.rampUpTime / tg.step);
|
||||
let timeInc = timePeriod;
|
||||
|
||||
let threadPeriod = Math.floor(tg.threadNumber / tg.step);
|
||||
let threadInc1 = Math.floor(tg.threadNumber / tg.step);
|
||||
let threadInc2 = Math.ceil(tg.threadNumber / tg.step);
|
||||
let inc2count = tg.threadNumber - tg.step * threadInc1;
|
||||
|
||||
let times = 1;
|
||||
switch (tg.unit) {
|
||||
case 'M':
|
||||
times *= 60;
|
||||
break;
|
||||
case 'H':
|
||||
times *= 3600;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
let duration = tg.duration * times;
|
||||
for (let j = 0; j <= duration; j++) {
|
||||
// x 轴
|
||||
let xAxis = handler.options.xAxis.data;
|
||||
if (xAxis.indexOf(j) < 0) {
|
||||
xAxis.push(j);
|
||||
}
|
||||
|
||||
if (tg.tgType === 'ThreadGroup') {
|
||||
seriesData.step = undefined;
|
||||
|
||||
if (j === 0) {
|
||||
seriesData.data.push([0, 0]);
|
||||
}
|
||||
if (j >= tg.rampUpTime) {
|
||||
xAxis.push(duration);
|
||||
|
||||
seriesData.data.push([j, tg.threadNumber]);
|
||||
seriesData.data.push([duration, tg.threadNumber]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
seriesData.step = 'start';
|
||||
if (j > timePeriod) {
|
||||
timePeriod += timeInc;
|
||||
if (inc2count > 0) {
|
||||
threadPeriod = threadPeriod + threadInc2;
|
||||
inc2count--;
|
||||
} else {
|
||||
threadPeriod = threadPeriod + threadInc1;
|
||||
}
|
||||
if (threadPeriod > tg.threadNumber) {
|
||||
threadPeriod = tg.threadNumber;
|
||||
// 预热结束
|
||||
xAxis.push(duration);
|
||||
seriesData.data.push([duration, threadPeriod]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
seriesData.data.push([j, threadPeriod]);
|
||||
}
|
||||
}
|
||||
handler.options.series.push(seriesData);
|
||||
}
|
||||
},
|
||||
getDuration(tg) {
|
||||
tg.duration = tg.durationHours * 60 * 60 + tg.durationMinutes * 60 + tg.durationSeconds;
|
||||
return tg.duration;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
report: {
|
||||
handler() {
|
||||
this.getJmxContent();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
if (this.planReportTemplate) {
|
||||
this.getJmxContent();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.pressure-config-container .el-input {
|
||||
width: 130px;
|
||||
|
||||
}
|
||||
|
||||
.pressure-config-container .config-form-label {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.pressure-config-container .input-bottom-border input {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #DCDFE6;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.el-col .el-form {
|
||||
margin-top: 15px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-col {
|
||||
margin-top: 15px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 60px;
|
||||
}
|
||||
|
||||
.wordwrap {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<el-tabs>
|
||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||
<performance-pressure-config :is-read-only="true" :test="test" :test-id="testId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('load_test.advanced_config')">
|
||||
<performance-advanced-config :is-read-only="true" :test-id="testId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PerformancePressureConfig from "@/business/components/performance/test/components/PerformancePressureConfig";
|
||||
import PerformanceAdvancedConfig from "@/business/components/performance/test/components/PerformanceAdvancedConfig";
|
||||
import PerformanceBasicConfig from "@/business/components/performance/test/components/PerformanceBasicConfig";
|
||||
|
||||
export default {
|
||||
name: "TestConfiguration",
|
||||
components: {PerformanceBasicConfig, PerformancePressureConfig, PerformanceAdvancedConfig},
|
||||
props: {
|
||||
report: Object,
|
||||
test: Object,
|
||||
testId: String,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -3,13 +3,13 @@
|
|||
<!-- 基本配置 -->
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form :inline="true">
|
||||
<el-form :inline="true" :disabled="isReadOnly">
|
||||
<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"
|
||||
size="mini" v-model="timeout"
|
||||
controls-position="right"
|
||||
:min="0"/>
|
||||
</el-form-item>
|
||||
|
@ -19,13 +19,13 @@
|
|||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form :inline="true">
|
||||
<el-form :inline="true" :disabled="isReadOnly">
|
||||
<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"
|
||||
size="mini" :min="0"
|
||||
controls-position="right"
|
||||
v-model="responseTimeout"/>
|
||||
</el-form-item>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form :inline="true">
|
||||
<el-form :inline="true" :disabled="isReadOnly">
|
||||
<el-form-item>
|
||||
<div>
|
||||
{{ $t('load_test.granularity') }}
|
||||
|
@ -65,13 +65,13 @@
|
|||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form :inline="true">
|
||||
<el-form :inline="true" :disabled="isReadOnly">
|
||||
<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"
|
||||
size="mini" v-model="statusCodeStr"
|
||||
:placeholder="$t('load_test.separated_by_commas')"
|
||||
@input="checkStatusCode"></el-input>
|
||||
</el-form-item>
|
||||
|
@ -83,7 +83,9 @@
|
|||
<el-row type="flex" justify="start">
|
||||
<el-col :span="8">
|
||||
<h3>{{ $t('load_test.domain_bind') }}</h3>
|
||||
<el-button :disabled="readOnly" icon="el-icon-circle-plus-outline" plain size="mini" @click="add('domains')">
|
||||
<el-button icon="el-icon-circle-plus-outline"
|
||||
:disabled="isReadOnly"
|
||||
plain size="mini" @click="add('domains')">
|
||||
{{ $t('commons.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -98,7 +100,7 @@
|
|||
<template v-slot:default="{row}">
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
class="edit-input"
|
||||
|
@ -116,7 +118,7 @@
|
|||
<template v-slot:default="{row}">
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
class="edit-input"
|
||||
:rows="1"
|
||||
|
@ -132,7 +134,7 @@
|
|||
show-overflow-tooltip>
|
||||
<template v-slot:default="{row}">
|
||||
<el-switch
|
||||
:disabled="readOnly"
|
||||
:disabled="isReadOnly"
|
||||
size="mini"
|
||||
v-model="row.enable"
|
||||
inactive-color="#DCDFE6"
|
||||
|
@ -142,8 +144,8 @@
|
|||
</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="$t('commons.delete')" icon="el-icon-delete"
|
||||
type="danger"
|
||||
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||
type="danger" :disabled="isReadOnly"
|
||||
@exec="del(row, 'domains', $index)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -167,12 +169,12 @@
|
|||
</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"/>
|
||||
<el-switch :disabled="isReadOnly" 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"/>
|
||||
<el-switch :disabled="isReadOnly || !row.csvSplit" v-model="row.csvHasHeader"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -183,7 +185,9 @@
|
|||
<el-row>
|
||||
<el-col :span="8">
|
||||
<h3>{{ $t('load_test.params') }}</h3>
|
||||
<el-button :disabled="readOnly" icon="el-icon-circle-plus-outline" plain size="mini" @click="add('params')">
|
||||
<el-button icon="el-icon-circle-plus-outline"
|
||||
:disabled="isReadOnly"
|
||||
plain size="mini" @click="add('params')">
|
||||
{{ $t('commons.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -198,7 +202,7 @@
|
|||
<template v-slot:default="{row}">
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
class="edit-input"
|
||||
|
@ -213,13 +217,9 @@
|
|||
:label="$t('load_test.param_value')"
|
||||
show-overflow-tooltip align="center">
|
||||
<template v-slot:default="{row}">
|
||||
<!-- <template v-if="row.edit">
|
||||
<el-input v-model="row.value" class="edit-input" size="mini"/>
|
||||
</template>
|
||||
<span v-else>{{ row.value }}</span>-->
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
class="edit-input"
|
||||
:rows="1"
|
||||
|
@ -235,7 +235,7 @@
|
|||
show-overflow-tooltip>
|
||||
<template v-slot:default="{row}">
|
||||
<el-switch
|
||||
:disabled="readOnly"
|
||||
:disabled="isReadOnly"
|
||||
size="mini"
|
||||
v-model="row.enable"
|
||||
inactive-color="#DCDFE6">
|
||||
|
@ -244,8 +244,9 @@
|
|||
</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="$t('commons.delete')" icon="el-icon-delete"
|
||||
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||
type="danger"
|
||||
:disabled="isReadOnly"
|
||||
@exec="del(row, 'params', $index)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -257,7 +258,9 @@
|
|||
<el-row>
|
||||
<el-col :span="8">
|
||||
<h3>JMeter Properties</h3>
|
||||
<el-button :disabled="readOnly" icon="el-icon-circle-plus-outline" plain size="mini" @click="add('properties')">
|
||||
<el-button icon="el-icon-circle-plus-outline"
|
||||
:disabled="isReadOnly"
|
||||
plain size="mini" @click="add('properties')">
|
||||
{{ $t('commons.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -272,7 +275,7 @@
|
|||
<template v-slot:default="{row}">
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
class="edit-input"
|
||||
|
@ -287,13 +290,9 @@
|
|||
:label="$t('load_test.param_value')"
|
||||
show-overflow-tooltip align="center">
|
||||
<template v-slot:default="{row}">
|
||||
<!-- <template v-if="row.edit">
|
||||
<el-input v-model="row.value" class="edit-input" size="mini"/>
|
||||
</template>
|
||||
<span v-else>{{ row.value }}</span>-->
|
||||
<el-input
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
v-if="!isReadOnly"
|
||||
type="textarea"
|
||||
class="edit-input"
|
||||
:rows="1"
|
||||
|
@ -309,7 +308,7 @@
|
|||
show-overflow-tooltip>
|
||||
<template v-slot:default="{row}">
|
||||
<el-switch
|
||||
:disabled="readOnly"
|
||||
:disabled="isReadOnly"
|
||||
size="mini"
|
||||
v-model="row.enable"
|
||||
inactive-color="#DCDFE6">
|
||||
|
@ -318,8 +317,9 @@
|
|||
</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="$t('commons.delete')" icon="el-icon-delete"
|
||||
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||
type="danger"
|
||||
:disabled="isReadOnly"
|
||||
@exec="del(row, 'properties', $index)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -331,10 +331,12 @@
|
|||
<el-row>
|
||||
<el-col :span="8">
|
||||
<h3>{{ $t('commons.monitor') }}</h3>
|
||||
<el-button :disabled="readOnly" icon="el-icon-circle-plus-outline" plain size="mini" @click="addMonitor">
|
||||
<el-button icon="el-icon-circle-plus-outline" :disabled="isReadOnly"
|
||||
plain size="mini" @click="addMonitor">
|
||||
{{ $t('commons.add') }}
|
||||
</el-button>
|
||||
<el-button :disabled="readOnly" icon="el-icon-circle-plus-outline" plain size="mini"
|
||||
<el-button icon="el-icon-circle-plus-outline" plain size="mini"
|
||||
:disabled="isReadOnly"
|
||||
@click="batchAddMonitor">
|
||||
{{ $t('commons.batch_add') }}
|
||||
</el-button>
|
||||
|
@ -348,20 +350,6 @@
|
|||
prop="name"
|
||||
:label="$t('commons.name')">
|
||||
</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"
|
||||
|
@ -379,10 +367,12 @@
|
|||
</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"
|
||||
<ms-table-operator-button tip="编辑" icon="el-icon-edit"
|
||||
type="primary"
|
||||
:disabled="isReadOnly"
|
||||
@exec="modifyMonitor(row, $index)"/>
|
||||
<ms-table-operator-button :disabled="readOnly" :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||
:disabled="isReadOnly"
|
||||
type="danger"
|
||||
@exec="delMonitor(row, $index)"/>
|
||||
</template>
|
||||
|
@ -399,7 +389,6 @@
|
|||
<script>
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton.vue";
|
||||
import EditMonitor from "@/business/components/performance/test/components/EditMonitor";
|
||||
import {hasPermission} from "@/common/js/utils";
|
||||
import BatchAddMonitor from "@/business/components/performance/test/components/BatchAddMonitor";
|
||||
|
||||
export default {
|
||||
|
@ -429,17 +418,21 @@ export default {
|
|||
{start: 60001, end: 180000, granularity: 1800},
|
||||
{start: 180001, end: 360000, granularity: 3600},
|
||||
],
|
||||
readOnly: false,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
testId: String,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.testId) {
|
||||
this.getAdvancedConfig();
|
||||
}
|
||||
this.readOnly = !hasPermission('PROJECT_PERFORMANCE_TEST:READ+EDIT');
|
||||
},
|
||||
watch: {
|
||||
testId() {
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
<div v-loading="result.loading" class="pressure-config-container">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form :inline="true">
|
||||
<el-form :inline="true" :disabled="isReadOnly">
|
||||
<el-form-item :label="$t('load_test.select_resource_pool')">
|
||||
<el-select v-model="resourcePool" :disabled="isReadOnly" size="mini" @change="resourcePoolChange">
|
||||
<el-select v-model="resourcePool" size="mini" @change="resourcePoolChange">
|
||||
<el-option
|
||||
v-for="item in resourcePools"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:disabled="!item.performance"
|
||||
:value="item.id">
|
||||
v-for="item in resourcePools"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:disabled="!item.performance"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -22,7 +22,6 @@
|
|||
</el-form-item>
|
||||
<el-form-item v-if="autoStop" :label="$t('load_test.reaches_duration')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
v-model="autoStopDelay"
|
||||
:min="1"
|
||||
:max="9999"
|
||||
|
@ -67,10 +66,10 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-form :inline="true" label-width="100px">
|
||||
<el-form :inline="true" label-width="100px" :disabled="isReadOnly">
|
||||
<el-form-item :label="$t('load_test.thread_num')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-model="threadGroup.threadNumber"
|
||||
@change="calculateTotalChart()"
|
||||
:min="1"
|
||||
|
@ -79,18 +78,20 @@
|
|||
</el-form-item>
|
||||
<br>
|
||||
<el-form-item :label="$t('load_test.on_sample_error')">
|
||||
<el-select v-model="threadGroup.onSampleError" :disabled="isReadOnly" size="mini">
|
||||
<el-select v-model="threadGroup.onSampleError" size="mini">
|
||||
<el-option
|
||||
v-for="item in onSampleErrors"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
v-for="item in onSampleErrors"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<br>
|
||||
<el-form-item :label="$t('load_test.run_mode')">
|
||||
<el-radio-group v-model="threadGroup.threadType" @change="calculateTotalChart()" size="mini">
|
||||
<el-radio-group v-model="threadGroup.threadType"
|
||||
@change="calculateTotalChart()"
|
||||
size="mini">
|
||||
<el-radio-button label="DURATION">{{ $t('load_test.by_duration') }}</el-radio-button>
|
||||
<el-radio-button label="ITERATION">{{ $t('load_test.by_iteration') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
@ -98,7 +99,7 @@
|
|||
<div v-if="threadGroup.threadType === 'DURATION'">
|
||||
<el-form-item :label="$t('load_test.duration')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-model="threadGroup.durationHours"
|
||||
:min="0"
|
||||
:max="9999"
|
||||
|
@ -108,7 +109,7 @@
|
|||
<el-form-item :label="$t('schedule.cron.hours')" label-width="40px"/>
|
||||
<el-form-item>
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-model="threadGroup.durationMinutes"
|
||||
:min="0"
|
||||
:max="59"
|
||||
|
@ -118,7 +119,7 @@
|
|||
<el-form-item :label="$t('schedule.cron.minutes')" label-width="40px"/>
|
||||
<el-form-item>
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-model="threadGroup.durationSeconds"
|
||||
:min="0"
|
||||
:max="59"
|
||||
|
@ -142,7 +143,7 @@
|
|||
<div v-if="threadGroup.tgType === 'com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup'">
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
:min="1"
|
||||
v-if="rampUpTimeVisible"
|
||||
:max="getDuration(threadGroup)"
|
||||
|
@ -152,7 +153,7 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="Step" label-width="50px">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
:min="1"
|
||||
:max="Math.min(threadGroup.threadNumber, threadGroup.rampUpTime)"
|
||||
v-model="threadGroup.step"
|
||||
|
@ -164,7 +165,7 @@
|
|||
<div v-if="threadGroup.tgType === 'ThreadGroup'">
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-if="rampUpTimeVisible"
|
||||
:min="1"
|
||||
:max="getDuration(threadGroup)"
|
||||
|
@ -178,7 +179,7 @@
|
|||
<div v-if="threadGroup.threadType === 'ITERATION'">
|
||||
<el-form-item :label="$t('load_test.iterate_num')">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
v-model="threadGroup.iterateNum"
|
||||
:min="1"
|
||||
:max="9999999"
|
||||
|
@ -200,7 +201,7 @@
|
|||
<br>
|
||||
<el-form-item label="Ramp-Up">
|
||||
<el-input-number controls-position="right"
|
||||
:disabled="isReadOnly"
|
||||
|
||||
:min="1"
|
||||
v-model="threadGroup.iterateRampUp"
|
||||
size="mini"/>
|
||||
|
@ -209,7 +210,7 @@
|
|||
<!-- 资源池自己配置各个节点的并发 -->
|
||||
<div v-if="resourcePoolType === 'NODE'">
|
||||
<el-form-item :label="$t('load_test.resource_strategy')">
|
||||
<el-radio-group v-model="threadGroup.strategy" :disabled="isReadOnly" size="mini">
|
||||
<el-radio-group v-model="threadGroup.strategy" size="mini">
|
||||
<el-radio-button label="auto">{{ $t('load_test.auto_ratio') }}</el-radio-button>
|
||||
<el-radio-button label="specify">{{ $t('load_test.specify_resource') }}</el-radio-button>
|
||||
<el-radio-button label="custom">{{ $t('load_test.custom_ratio') }}</el-radio-button>
|
||||
|
@ -218,12 +219,12 @@
|
|||
<div v-if="threadGroup.strategy === 'auto'"></div>
|
||||
<div v-else-if="threadGroup.strategy === 'specify'">
|
||||
<el-form-item :label="$t('load_test.specify_resource')">
|
||||
<el-select v-model="threadGroup.resourceNodeIndex" :disabled="isReadOnly" size="mini">
|
||||
<el-select v-model="threadGroup.resourceNodeIndex" size="mini">
|
||||
<el-option
|
||||
v-for="(node, index) in resourceNodes"
|
||||
:key="node.ip"
|
||||
:label="node.ip"
|
||||
:value="index">
|
||||
v-for="(node, index) in resourceNodes"
|
||||
:key="node.ip"
|
||||
:label="node.ip"
|
||||
:value="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -235,7 +236,9 @@
|
|||
<el-table-column prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"/>
|
||||
<el-table-column prop="ratio" :label="$t('test_track.home.percentage')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-input-number size="mini" v-model="row.ratio" :min="0" :step=".1" controls-position="right"
|
||||
<el-input-number size="mini" v-model="row.ratio"
|
||||
|
||||
:min="0" :step=".1" controls-position="right"
|
||||
:max="1"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -257,7 +260,6 @@
|
|||
<script>
|
||||
import MsChart from "@/business/components/common/chart/MsChart";
|
||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
import {hasPermission} from "@/common/js/utils";
|
||||
|
||||
const HANDLER = "handler";
|
||||
const THREAD_GROUP_TYPE = "tgType";
|
||||
|
@ -287,7 +289,7 @@ const RATIOS = "ratios";
|
|||
|
||||
const hexToRgb = function (hex) {
|
||||
return 'rgb(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5))
|
||||
+ ',' + parseInt('0x' + hex.slice(5, 7)) + ')';
|
||||
+ ',' + parseInt('0x' + hex.slice(5, 7)) + ')';
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -299,6 +301,12 @@ export default {
|
|||
},
|
||||
testId: {
|
||||
type: String
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -321,7 +329,6 @@ export default {
|
|||
serializeThreadGroups: false,
|
||||
autoStop: false,
|
||||
autoStopDelay: 30,
|
||||
isReadOnly: false,
|
||||
rampUpTimeVisible: true,
|
||||
};
|
||||
},
|
||||
|
@ -344,13 +351,15 @@ export default {
|
|||
}
|
||||
this.resourcePool = this.test.testResourcePoolId;
|
||||
this.getResourcePools();
|
||||
this.isReadOnly = !hasPermission('PROJECT_PERFORMANCE_TEST:READ+EDIT');
|
||||
},
|
||||
watch: {
|
||||
test(n) {
|
||||
if (n.testResourcePoolId) {
|
||||
this.resourcePool = n.testResourcePoolId;
|
||||
}
|
||||
test: {
|
||||
handler(n) {
|
||||
if (n.testResourcePoolId) {
|
||||
this.resourcePool = n.testResourcePoolId;
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
testId() {
|
||||
if (this.testId) {
|
||||
|
@ -570,8 +579,8 @@ export default {
|
|||
let tg = handler.threadGroups[i];
|
||||
|
||||
if (tg.enabled === 'false' ||
|
||||
tg.deleted === 'true' ||
|
||||
tg.threadType === 'ITERATION') {
|
||||
tg.deleted === 'true' ||
|
||||
tg.threadType === 'ITERATION') {
|
||||
continue;
|
||||
}
|
||||
if (this.getDuration(tg) < tg.rampUpTime) {
|
||||
|
@ -686,7 +695,7 @@ export default {
|
|||
}
|
||||
|
||||
if (!tg.threadNumber || !tg.duration
|
||||
|| !tg.rampUpTime || !tg.step || !tg.iterateNum) {
|
||||
|| !tg.rampUpTime || !tg.step || !tg.iterateNum) {
|
||||
this.$warning(this.$t('load_test.pressure_config_params_is_empty'));
|
||||
this.$emit('changeActive', '1');
|
||||
return false;
|
||||
|
|
|
@ -48,10 +48,6 @@
|
|||
<el-divider/>
|
||||
<div ref="resume">
|
||||
<el-tabs v-model="active">
|
||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||
<ms-performance-pressure-config :is-share="isShare" :plan-report-template="planReportTemplate"
|
||||
:share-id="shareId" :is-read-only="true" :report="report"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('report.test_overview')">
|
||||
<ms-report-test-overview :report="report" :is-share="isShare" :plan-report-template="planReportTemplate"
|
||||
:share-id="shareId" ref="testOverview"/>
|
||||
|
@ -77,6 +73,9 @@
|
|||
<monitor-card :report="report" :is-share="isShare" :plan-report-template="planReportTemplate"
|
||||
:share-id="shareId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('测试配置')">
|
||||
<ms-test-configuration :report="report" :test="test" :test-id="testId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
|
@ -112,7 +111,6 @@ import MsReportRequestStatistics from "@/business/components/performance/report/
|
|||
import MsReportTestOverview from "@/business/components/performance/report/components/TestOverview";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||
import MsPerformancePressureConfig from "@/business/components/performance/report/components/PerformancePressureConfig";
|
||||
import MonitorCard from "@/business/components/performance/report/components/MonitorCard";
|
||||
import MsReportTestDetails from '@/business/components/performance/report/components/TestDetails';
|
||||
import {
|
||||
|
@ -121,11 +119,13 @@ import {
|
|||
getSharePerformanceReport,
|
||||
getSharePerformanceReportTime
|
||||
} from "@/network/load-test";
|
||||
import MsTestConfiguration from "@/business/components/performance/report/components/TestConfiguration";
|
||||
|
||||
|
||||
export default {
|
||||
name: "LoadCaseReportView",
|
||||
components: {
|
||||
MsTestConfiguration,
|
||||
MonitorCard,
|
||||
MsPerformanceReportExport,
|
||||
MsReportErrorLog,
|
||||
|
@ -135,12 +135,11 @@ export default {
|
|||
MsReportTestDetails,
|
||||
MsContainer,
|
||||
MsMainContainer,
|
||||
MsPerformancePressureConfig
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
active: '1',
|
||||
active: '0',
|
||||
status: '',
|
||||
reportName: '',
|
||||
testId: '',
|
||||
|
@ -158,6 +157,7 @@ export default {
|
|||
reportExportVisible: false,
|
||||
testPlan: {testResourcePoolId: null},
|
||||
show: true,
|
||||
test: {testResourcePoolId: null},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -393,6 +393,7 @@ export default {
|
|||
if (data) {
|
||||
this.status = data.status;
|
||||
this.$set(this, "report", data);
|
||||
this.$set(this.test, "testResourcePoolId", data.testResourcePoolId);
|
||||
this.checkReportStatus(data.status);
|
||||
if (this.status === "Completed" || this.status === "Running") {
|
||||
this.initReportTimeInfo();
|
||||
|
|
Loading…
Reference in New Issue