报告测试概览
This commit is contained in:
parent
9e26edb62c
commit
5f1c561db6
|
@ -9,6 +9,7 @@ import io.metersphere.commons.utils.Pager;
|
||||||
import io.metersphere.controller.request.ReportRequest;
|
import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
import io.metersphere.report.base.Errors;
|
import io.metersphere.report.base.Errors;
|
||||||
|
import io.metersphere.report.base.TestOverview;
|
||||||
import io.metersphere.report.dto.ErrorsTop5DTO;
|
import io.metersphere.report.dto.ErrorsTop5DTO;
|
||||||
import io.metersphere.report.dto.RequestStatisticsDTO;
|
import io.metersphere.report.dto.RequestStatisticsDTO;
|
||||||
import io.metersphere.service.ReportService;
|
import io.metersphere.service.ReportService;
|
||||||
|
@ -70,5 +71,10 @@ public class ReportController {
|
||||||
return reportService.getReportErrorsTOP5(reportId);
|
return reportService.getReportErrorsTOP5(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/content/testoverview/{reportId}")
|
||||||
|
public TestOverview getTestOverview(@PathVariable String reportId) {
|
||||||
|
return reportService.getTestOverview(reportId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,17 @@ package io.metersphere.report;
|
||||||
import com.opencsv.bean.CsvToBean;
|
import com.opencsv.bean.CsvToBean;
|
||||||
import com.opencsv.bean.CsvToBeanBuilder;
|
import com.opencsv.bean.CsvToBeanBuilder;
|
||||||
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
|
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
|
||||||
import io.metersphere.report.base.Errors;
|
import io.metersphere.report.base.*;
|
||||||
import io.metersphere.report.base.ErrorsTop5;
|
|
||||||
import io.metersphere.report.base.Metric;
|
|
||||||
import io.metersphere.report.base.RequestStatistics;
|
|
||||||
import io.metersphere.report.dto.ErrorsTop5DTO;
|
import io.metersphere.report.dto.ErrorsTop5DTO;
|
||||||
import io.metersphere.report.dto.RequestStatisticsDTO;
|
import io.metersphere.report.dto.RequestStatisticsDTO;
|
||||||
|
import org.apache.bcel.verifier.statics.LONG_Upper;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class JtlResolver {
|
public class JtlResolver {
|
||||||
|
@ -144,14 +143,14 @@ public class JtlResolver {
|
||||||
return statisticsDTO;
|
return statisticsDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aggregate Report
|
// report - Aggregate Report
|
||||||
public static RequestStatisticsDTO getRequestStatistics(String jtlString) {
|
public static RequestStatisticsDTO getRequestStatistics(String jtlString) {
|
||||||
List<Metric> totalLines = resolver(jtlString);
|
List<Metric> totalLines = resolver(jtlString);
|
||||||
Map<String, List<Metric>> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
Map<String, List<Metric>> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
||||||
return getOneRpsResult(map);
|
return getOneRpsResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errors
|
// report - Errors
|
||||||
public static List<Errors> getErrorsList(String jtlString) {
|
public static List<Errors> getErrorsList(String jtlString) {
|
||||||
List<Metric> totalLines = resolver(jtlString);
|
List<Metric> totalLines = resolver(jtlString);
|
||||||
List<Metric> falseList = totalLines.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
List<Metric> falseList = totalLines.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
||||||
|
@ -180,6 +179,7 @@ public class JtlResolver {
|
||||||
return metric.getResponseCode() + "/" + metric.getResponseMessage();
|
return metric.getResponseCode() + "/" + metric.getResponseMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// report - Errors Top 5
|
||||||
public static ErrorsTop5DTO getErrorsTop5DTO(String jtlString) {
|
public static ErrorsTop5DTO getErrorsTop5DTO(String jtlString) {
|
||||||
List<Metric> totalLines = resolver(jtlString);
|
List<Metric> totalLines = resolver(jtlString);
|
||||||
ErrorsTop5DTO top5DTO = new ErrorsTop5DTO();
|
ErrorsTop5DTO top5DTO = new ErrorsTop5DTO();
|
||||||
|
@ -228,4 +228,45 @@ public class JtlResolver {
|
||||||
return top5DTO;
|
return top5DTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// report - TestOverview
|
||||||
|
public static TestOverview getTestOverview(String jtlString) {
|
||||||
|
TestOverview testOverview = new TestOverview();
|
||||||
|
List<Metric> total = JtlResolver.resolver(jtlString);
|
||||||
|
Map<String, List<Metric>> collect = total.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||||
|
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
||||||
|
Integer max = 0;
|
||||||
|
Integer totalElapsed = 0;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<String, List<Metric>> entry = iterator.next();
|
||||||
|
List<Metric> list = entry.getValue();
|
||||||
|
if (list.size() > max) {
|
||||||
|
max = list.size();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Metric metric = list.get(i);
|
||||||
|
String elapsed = metric.getElapsed();
|
||||||
|
totalElapsed += Integer.valueOf(elapsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(total, Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
||||||
|
Long timestamp1 = Long.valueOf(total.get(0).getTimestamp());
|
||||||
|
Long timestamp2 = Long.valueOf(total.get(total.size()-1).getTimestamp());
|
||||||
|
Long seconds = (timestamp2 - timestamp1) / 1000;
|
||||||
|
DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
double avgThroughput = (double)total.size() / seconds;
|
||||||
|
|
||||||
|
List<Metric> falseList = total.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
||||||
|
double errors = (double)falseList.size() / total.size() * 100;
|
||||||
|
|
||||||
|
testOverview.setMaxUsers(String.valueOf(max));
|
||||||
|
testOverview.setAvgThroughput(df.format(avgThroughput));
|
||||||
|
testOverview.setErrors(df.format(errors));
|
||||||
|
double avg = (double)totalElapsed / total.size() / 1000; // s
|
||||||
|
testOverview.setAvgResponseTime(df.format(avg));
|
||||||
|
// testOverview.setResponseTime90();
|
||||||
|
// testOverview.setAvgBandwidth();
|
||||||
|
return testOverview;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package io.metersphere.report.base;
|
||||||
|
|
||||||
|
public class TestOverview {
|
||||||
|
|
||||||
|
private String maxUsers;
|
||||||
|
private String avgThroughput; // Hits/s
|
||||||
|
private String errors;
|
||||||
|
private String avgResponseTime; // s
|
||||||
|
private String responseTime90;
|
||||||
|
private String avgBandwidth;
|
||||||
|
|
||||||
|
public String getMaxUsers() {
|
||||||
|
return maxUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxUsers(String maxUsers) {
|
||||||
|
this.maxUsers = maxUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvgThroughput() {
|
||||||
|
return avgThroughput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvgThroughput(String avgThroughput) {
|
||||||
|
this.avgThroughput = avgThroughput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrors(String errors) {
|
||||||
|
this.errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvgResponseTime() {
|
||||||
|
return avgResponseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvgResponseTime(String avgResponseTime) {
|
||||||
|
this.avgResponseTime = avgResponseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResponseTime90() {
|
||||||
|
return responseTime90;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseTime90(String responseTime90) {
|
||||||
|
this.responseTime90 = responseTime90;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvgBandwidth() {
|
||||||
|
return avgBandwidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvgBandwidth(String avgBandwidth) {
|
||||||
|
this.avgBandwidth = avgBandwidth;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
import io.metersphere.report.JtlResolver;
|
import io.metersphere.report.JtlResolver;
|
||||||
import io.metersphere.report.base.Errors;
|
import io.metersphere.report.base.Errors;
|
||||||
|
import io.metersphere.report.base.TestOverview;
|
||||||
import io.metersphere.report.dto.ErrorsTop5DTO;
|
import io.metersphere.report.dto.ErrorsTop5DTO;
|
||||||
import io.metersphere.report.dto.RequestStatisticsDTO;
|
import io.metersphere.report.dto.RequestStatisticsDTO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -66,4 +67,11 @@ public class ReportService {
|
||||||
ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content);
|
ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content);
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestOverview getTestOverview(String id) {
|
||||||
|
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
|
String content = loadTestReport.getContent();
|
||||||
|
TestOverview testOverview = JtlResolver.getTestOverview(content);
|
||||||
|
return testOverview;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<el-tabs v-model="active" type="border-card" :stretch="true">
|
<el-tabs v-model="active" type="border-card" :stretch="true">
|
||||||
<el-tab-pane :label="$t('report.test_overview')">
|
<el-tab-pane :label="$t('report.test_overview')">
|
||||||
<ms-report-test-overview />
|
<ms-report-test-overview :id="reportId"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('report.test_request_statistics')">
|
<el-tab-pane :label="$t('report.test_request_statistics')">
|
||||||
<ms-report-request-statistics :id="reportId"/>
|
<ms-report-request-statistics :id="reportId"/>
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
<ms-report-error-log :id="reportId"/>
|
<ms-report-error-log :id="reportId"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('report.test_log_details')">
|
<el-tab-pane :label="$t('report.test_log_details')">
|
||||||
<ms-report-log-details />
|
<ms-report-log-details :id="reportId"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-1">
|
<el-card shadow="always" class="ms-card-index-1">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">40</span>
|
<span class="ms-card-data-digital">{{maxUsers}}</span>
|
||||||
<span class="ms-card-data-unit"> VU</span>
|
<span class="ms-card-data-unit"> VU</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">Max Users</span>
|
<span class="ms-card-desc">Max Users</span>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-2">
|
<el-card shadow="always" class="ms-card-index-2">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">5.4</span>
|
<span class="ms-card-data-digital">{{avgThroughput}}</span>
|
||||||
<span class="ms-card-data-unit"> Hits/s</span>
|
<span class="ms-card-data-unit"> Hits/s</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">Avg.Throughput</span>
|
<span class="ms-card-desc">Avg.Throughput</span>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-3">
|
<el-card shadow="always" class="ms-card-index-3">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">0.41</span>
|
<span class="ms-card-data-digital">{{errors}}</span>
|
||||||
<span class="ms-card-data-unit"> %</span>
|
<span class="ms-card-data-unit"> %</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">Errors</span>
|
<span class="ms-card-desc">Errors</span>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-4">
|
<el-card shadow="always" class="ms-card-index-4">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">1.28</span>
|
<span class="ms-card-data-digital">{{avgResponseTime}}</span>
|
||||||
<span class="ms-card-data-unit"> s</span>
|
<span class="ms-card-data-unit"> s</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">Avg.Response Time</span>
|
<span class="ms-card-desc">Avg.Response Time</span>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-5">
|
<el-card shadow="always" class="ms-card-index-5">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">1.41</span>
|
<span class="ms-card-data-digital">{{responseTime90}}</span>
|
||||||
<span class="ms-card-data-unit"> s</span>
|
<span class="ms-card-data-unit"> s</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">90% Response Time</span>
|
<span class="ms-card-desc">90% Response Time</span>
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card shadow="always" class="ms-card-index-6">
|
<el-card shadow="always" class="ms-card-index-6">
|
||||||
<span class="ms-card-data">
|
<span class="ms-card-data">
|
||||||
<span class="ms-card-data-digital">817.29</span>
|
<span class="ms-card-data-digital">{{avgBandwidth}}</span>
|
||||||
<span class="ms-card-data-unit"> KiB/s</span>
|
<span class="ms-card-data-unit"> KiB/s</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="ms-card-desc">Avg.Bandwidth</span>
|
<span class="ms-card-desc">Avg.Bandwidth</span>
|
||||||
|
@ -73,6 +73,12 @@
|
||||||
name: "TestOverview",
|
name: "TestOverview",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
maxUsers: "0",
|
||||||
|
avgThroughput: "0",
|
||||||
|
errors: "0",
|
||||||
|
avgResponseTime: "0",
|
||||||
|
responseTime90: "0",
|
||||||
|
avgBandwidth: "0",
|
||||||
option1: {
|
option1: {
|
||||||
legend: {
|
legend: {
|
||||||
top: 20,
|
top: 20,
|
||||||
|
@ -146,6 +152,41 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initTableData() {
|
||||||
|
this.$get("/report/content/testoverview/" + this.id, res => {
|
||||||
|
let data = res.data;
|
||||||
|
this.maxUsers = data.maxUsers;
|
||||||
|
this.avgThroughput = data.avgThroughput;
|
||||||
|
this.errors = data.errors;
|
||||||
|
this.avgResponseTime = data.avgResponseTime;
|
||||||
|
// this.responseTime90 = data.responseTime90;
|
||||||
|
// this.avgBandwidth = data.avgBandwidth;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initTableData()
|
||||||
|
},
|
||||||
|
props: ['id'],
|
||||||
|
watch: {
|
||||||
|
'$route'(to) {
|
||||||
|
if (to.name === "perReportView") {
|
||||||
|
let reportId = to.path.split('/')[4];
|
||||||
|
if(reportId){
|
||||||
|
this.$get("/report/content/testoverview/" + reportId, res => {
|
||||||
|
let data = res.data;
|
||||||
|
this.maxUsers = data.maxUsers;
|
||||||
|
this.avgThroughput = data.avgThroughput;
|
||||||
|
this.errors = data.errors;
|
||||||
|
this.avgResponseTime = data.avgResponseTime;
|
||||||
|
// this.responseTime90 = data.responseTime90;
|
||||||
|
// this.avgBandwidth = data.avgBandwidth;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue