feat(性能测试): 测试报告分享
--story=1005620 --user=刘瑞斌 性能测试报告新增分享链接功能 https://www.tapd.cn/55049933/s/1102910
This commit is contained in:
parent
24d153ca90
commit
97eedd5b42
|
@ -60,6 +60,7 @@ public class ShiroUtils {
|
|||
filterChainDefinitionMap.put("/echartPic/**", "anon");
|
||||
filterChainDefinitionMap.put("/share/**", "anon");
|
||||
filterChainDefinitionMap.put("/sharePlanReport", "anon");
|
||||
filterChainDefinitionMap.put("/sharePerformanceReport", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/system/theme", "anon");
|
||||
filterChainDefinitionMap.put("/system/save/baseurl/**", "anon");
|
||||
|
|
|
@ -41,4 +41,9 @@ public class IndexController {
|
|||
public String shareRedirect() {
|
||||
return "share-plan-report.html";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/sharePerformanceReport")
|
||||
public String sharePerformanceRedirect() {
|
||||
return "share-performance-report.html";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,12 @@ import io.metersphere.api.service.ShareInfoService;
|
|||
import io.metersphere.base.domain.IssuesDao;
|
||||
import io.metersphere.base.domain.LoadTestReportLog;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.commons.constants.ResourceStatusEnum;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.resourcepool.QueryResourcePoolRequest;
|
||||
import io.metersphere.dto.LogDetailDTO;
|
||||
import io.metersphere.dto.TestResourcePoolDTO;
|
||||
import io.metersphere.performance.base.*;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
|
@ -22,6 +25,7 @@ import io.metersphere.performance.dto.Monitor;
|
|||
import io.metersphere.performance.service.MetricQueryService;
|
||||
import io.metersphere.performance.service.PerformanceReportService;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.service.TestResourcePoolService;
|
||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanLoadCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanSimpleReportDTO;
|
||||
|
@ -64,6 +68,8 @@ public class ShareController {
|
|||
TestPlanReportService testPlanReportService;
|
||||
@Resource
|
||||
MetricQueryService metricService;
|
||||
@Resource
|
||||
private TestResourcePoolService testResourcePoolService;
|
||||
|
||||
@GetMapping("/issues/plan/get/{shareId}/{planId}")
|
||||
public List<IssuesDao> getIssuesByPlanoId(@PathVariable String shareId, @PathVariable String planId) {
|
||||
|
@ -112,11 +118,13 @@ public class ShareController {
|
|||
shareInfoService.validate(shareId, planId);
|
||||
return testPlanApiCaseService.getFailureCases(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/test/plan/api/case/list/errorReport/{shareId}/{planId}")
|
||||
public List<TestPlanFailureApiDTO> getErrorReportApiCaseList(@PathVariable String shareId, @PathVariable String planId) {
|
||||
shareInfoService.validate(shareId, planId);
|
||||
return testPlanApiCaseService.getErrorReportCases(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/test/plan/api/case/list/all/{shareId}/{planId}")
|
||||
public List<TestPlanFailureApiDTO> getApiAllList(@PathVariable String shareId, @PathVariable String planId) {
|
||||
shareInfoService.validate(shareId, planId);
|
||||
|
@ -171,6 +179,16 @@ public class ShareController {
|
|||
return testPlanLoadCaseService.isExistReport(request);
|
||||
}
|
||||
|
||||
@GetMapping("/performance/report/get-advanced-config/{shareId}/{reportId}")
|
||||
public String getAdvancedConfig(@PathVariable String shareId, @PathVariable String reportId) {
|
||||
return performanceReportService.getAdvancedConfiguration(reportId);
|
||||
}
|
||||
|
||||
@GetMapping("/performance/report/get-jmx-content/{reportId}")
|
||||
public List<LoadTestExportJmx> getJmxContents(@PathVariable String reportId) {
|
||||
return performanceReportService.getJmxContent(reportId);
|
||||
}
|
||||
|
||||
@GetMapping("/performance/report/get-jmx-content/{shareId}/{reportId}")
|
||||
public LoadTestExportJmx getJmxContent(@PathVariable String shareId, @PathVariable String reportId) {
|
||||
return performanceReportService.getJmxContent(reportId).get(0);
|
||||
|
@ -259,4 +277,16 @@ public class ShareController {
|
|||
//checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getLoadConfiguration(testId);
|
||||
}
|
||||
|
||||
@GetMapping("/performance/report/get-load-config/{reportId}")
|
||||
public String getLoadConfiguration(@PathVariable String reportId) {
|
||||
return performanceReportService.getLoadConfiguration(reportId);
|
||||
}
|
||||
|
||||
@GetMapping("/testresourcepool/list/quota/valid")
|
||||
public List<TestResourcePoolDTO> getTestResourcePools() {
|
||||
QueryResourcePoolRequest resourcePoolRequest = new QueryResourcePoolRequest();
|
||||
resourcePoolRequest.setStatus(ResourceStatusEnum.VALID.name());
|
||||
return testResourcePoolService.listResourcePools(resourcePoolRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,25 @@
|
|||
v-permission="['PROJECT_PERFORMANCE_REPORT:READ+EXPORT']">
|
||||
{{ $t('test_track.plan_view.export_report') }}
|
||||
</el-button>
|
||||
<el-popover
|
||||
v-permission="['PROJECT_PERFORMANCE_REPORT:READ+EXPORT']"
|
||||
style="padding: 0 10px;"
|
||||
placement="bottom"
|
||||
width="300">
|
||||
<p>{{ shareUrl }}</p>
|
||||
<span style="color: red;float: left;margin-left: 10px;">{{
|
||||
$t('test_track.report.valid_for_24_hours')
|
||||
}}</span>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button type="primary" size="mini" :disabled="!shareUrl"
|
||||
v-clipboard:copy="shareUrl">{{ $t("commons.copy") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" :disabled="isReadOnly" type="danger" plain size="mini"
|
||||
@click="handleShare(report)">
|
||||
{{ $t('分享报告') }}
|
||||
</el-button>
|
||||
</el-popover>
|
||||
<el-button :disabled="report.status !== 'Completed'" type="default" plain
|
||||
size="mini" v-permission="['PROJECT_PERFORMANCE_REPORT:READ+COMPARE']"
|
||||
@click="compareReports()">
|
||||
|
@ -141,6 +160,7 @@ 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";
|
||||
import {generateShareInfoWithExpired} from "@/network/share";
|
||||
|
||||
|
||||
export default {
|
||||
|
@ -195,6 +215,7 @@ export default {
|
|||
{value: '300', label: '5m'}
|
||||
],
|
||||
testDeleted: false,
|
||||
shareUrl: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -346,6 +367,15 @@ export default {
|
|||
}, 1000);
|
||||
});
|
||||
},
|
||||
handleShare(report) {
|
||||
let pram = {};
|
||||
pram.customData = report.id;
|
||||
pram.shareType = 'PERFORMANCE_REPORT';
|
||||
generateShareInfoWithExpired(pram, (data) => {
|
||||
let thisHost = window.location.host;
|
||||
this.shareUrl = thisHost + "/sharePerformanceReport" + data.shareUrl;
|
||||
});
|
||||
},
|
||||
exportReportReset() {
|
||||
this.reportExportVisible = false;
|
||||
this.result.loading = false;
|
||||
|
|
|
@ -140,7 +140,11 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.path.split('/')[4];
|
||||
if (this.report) {
|
||||
this.id = this.report.id;
|
||||
} else {
|
||||
this.id = this.$route.path.split('/')[4];
|
||||
}
|
||||
this.getResource();
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<el-tabs>
|
||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||
<performance-pressure-config :is-read-only="true" :test="test" :report-id="reportId"/>
|
||||
<performance-pressure-config :is-read-only="true" :test="test" :report="report" :report-id="reportId"
|
||||
:is-share="isShare" :share-id="shareId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('load_test.advanced_config')">
|
||||
<performance-advanced-config :is-read-only="true" :report-id="reportId"/>
|
||||
<performance-advanced-config :is-read-only="true" :report-id="reportId" :report="report" :is-share="isShare"
|
||||
:share-id="shareId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
@ -21,6 +23,9 @@ export default {
|
|||
test: Object,
|
||||
testId: String,
|
||||
reportId: String,
|
||||
report: Object,
|
||||
isShare: Boolean,
|
||||
shareId: String,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -241,47 +241,47 @@
|
|||
<el-row>
|
||||
<el-col :offset="2" :span="20">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column label="Label" align="center">
|
||||
<el-table-column
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="Aggregate" align="center">
|
||||
<el-table-column
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
</el-table-column>
|
||||
<el-table-column label="Range" align="center">
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
/>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -686,7 +686,11 @@ export default {
|
|||
}
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.path.split('/')[4];
|
||||
if (this.report) {
|
||||
this.id = this.report.id;
|
||||
} else {
|
||||
this.id = this.$route.path.split('/')[4];
|
||||
}
|
||||
this.initTableData();
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -504,7 +504,9 @@ export default {
|
|||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
isShare: Boolean,
|
||||
shareId: String,
|
||||
},
|
||||
mounted() {
|
||||
if (this.testId) {
|
||||
|
@ -534,6 +536,9 @@ export default {
|
|||
if (type) {
|
||||
url = '/performance/report/get-advanced-config/' + this.reportId;
|
||||
}
|
||||
if (this.isShare) {
|
||||
url = '/share/performance/report/get-advanced-config/' + this.shareId + '/' + this.reportId;
|
||||
}
|
||||
this.$get(url, (response) => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data);
|
||||
|
|
|
@ -305,12 +305,17 @@ export default {
|
|||
reportId: {
|
||||
type: String
|
||||
},
|
||||
report: {
|
||||
type: Object
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
isShare: Boolean,
|
||||
shareId: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -354,7 +359,12 @@ export default {
|
|||
} else {
|
||||
this.calculateTotalChart();
|
||||
}
|
||||
this.resourcePool = this.test.testResourcePoolId;
|
||||
if (this.test) {
|
||||
this.resourcePool = this.test.testResourcePoolId;
|
||||
}
|
||||
if (this.report) {
|
||||
this.resourcePool = this.report.testResourcePoolId;
|
||||
}
|
||||
this.getResourcePools();
|
||||
},
|
||||
watch: {
|
||||
|
@ -382,10 +392,17 @@ export default {
|
|||
}
|
||||
this.getResourcePools();
|
||||
},
|
||||
report() {
|
||||
this.resourcePool = this.report.testResourcePoolId;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getResourcePools() {
|
||||
this.result = this.$get('/testresourcepool/list/quota/valid', response => {
|
||||
let url = '/testresourcepool/list/quota/valid';
|
||||
if (this.isShare) {
|
||||
url = '/share/testresourcepool/list/quota/valid';
|
||||
}
|
||||
this.result = this.$get(url, response => {
|
||||
this.resourcePools = response.data;
|
||||
// 如果当前的资源池无效 设置 null
|
||||
if (response.data.filter(p => p.id === this.resourcePool).length === 0) {
|
||||
|
@ -406,6 +423,9 @@ export default {
|
|||
if (!url) {
|
||||
return;
|
||||
}
|
||||
if (this.isShare) {
|
||||
url = '/share/performance/report/get-load-config/' + this.reportId;
|
||||
}
|
||||
this.$get(url, (response) => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data);
|
||||
|
@ -519,6 +539,9 @@ export default {
|
|||
if (!url) {
|
||||
return;
|
||||
}
|
||||
if (this.isShare) {
|
||||
url = '/share/performance/report/get-jmx-content/' + this.reportId;
|
||||
}
|
||||
let threadGroups = [];
|
||||
this.$get(url, (response) => {
|
||||
response.data.forEach(d => {
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
:share-id="shareId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('report.test_config')">
|
||||
<ms-test-configuration :report-id="reportId"/>
|
||||
<ms-test-configuration :report-id="reportId" :report="report" :is-share="isShare" :share-id="shareId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import Vue from 'vue';
|
||||
import ElementUI, {Button, Card, Col, Form, FormItem, Input, Main, Popover, Row, Table, TableColumn} from 'element-ui';
|
||||
import '@/assets/theme/index.css';
|
||||
import '@/common/css/menu-header.css';
|
||||
import '@/common/css/main.css';
|
||||
import i18n from "@/i18n/i18n";
|
||||
import chart from "@/common/js/chart";
|
||||
import filters from "@/common/js/filter";
|
||||
import icon from "@/common/js/icon";
|
||||
import message from "@/common/js/message";
|
||||
import ajax from "@/common/js/ajax";
|
||||
|
||||
|
||||
function performanceReportUse(id, template) {
|
||||
Vue.use(ElementUI, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
});
|
||||
|
||||
Vue.use(Row);
|
||||
Vue.use(Col);
|
||||
Vue.use(Form);
|
||||
Vue.use(FormItem);
|
||||
Vue.use(Input);
|
||||
Vue.use(Button);
|
||||
Vue.use(chart);
|
||||
Vue.use(Main);
|
||||
Vue.use(Card);
|
||||
Vue.use(TableColumn);
|
||||
Vue.use(Table);
|
||||
Vue.use(filters);
|
||||
Vue.use(icon);
|
||||
Vue.use(message);
|
||||
Vue.use(ajax);
|
||||
Vue.use(Popover);
|
||||
|
||||
new Vue({
|
||||
el: id,
|
||||
i18n,
|
||||
render: h => h(template)
|
||||
});
|
||||
}
|
||||
|
||||
export default performanceReportUse;
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<load-case-report-view :is-plan-report="true" :share-id="shareId" :is-share="isShare" :report-id="reportId"
|
||||
ref="loadCaseReportView"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getShareId} from "@/common/js/utils";
|
||||
import {getShareInfo} from "@/network/share";
|
||||
import LoadCaseReportView from "@/business/components/track/plan/view/comonents/load/LoadCaseReportView";
|
||||
|
||||
export default {
|
||||
name: "SharePerformanceReportTemplate",
|
||||
components: {LoadCaseReportView},
|
||||
data() {
|
||||
return {
|
||||
reportId: '',
|
||||
shareId: '',
|
||||
isShare: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.shareId = getShareId();
|
||||
getShareInfo(this.shareId, (data) => {
|
||||
if (!data) {
|
||||
this.$error('连接已失效,请重新获取!');
|
||||
return;
|
||||
}
|
||||
if (data.shareType === 'PERFORMANCE_REPORT') {
|
||||
this.reportId = data.customData;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Performance Report</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sharePerformanceReport"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
import SharePerformanceReportTemplate from "@/template/report/performance/share/SharePerformanceReportTemplate";
|
||||
import performanceReportUse from "@/template/report/performance/performanceReportUse";
|
||||
|
||||
performanceReportUse('#sharePerformanceReport', SharePerformanceReportTemplate);
|
|
@ -39,6 +39,11 @@ module.exports = {
|
|||
template: "src/template/report/plan/share/share-plan-report.html",
|
||||
filename: "share-plan-report.html",
|
||||
},
|
||||
sharePerformanceReport: {
|
||||
entry: "src/template/report/performance/share/share-performance-report.js",
|
||||
template: "src/template/report/performance/share/share-performance-report.html",
|
||||
filename: "share-performance-report.html",
|
||||
},
|
||||
enterpriseReport: {
|
||||
entry: "src/template/enterprise/share/share-enterprise-report.js",
|
||||
template: "src/template/enterprise/share/share-enterprise-report.html",
|
||||
|
|
Loading…
Reference in New Issue