diff --git a/backend/src/main/java/io/metersphere/controller/ReportController.java b/backend/src/main/java/io/metersphere/controller/ReportController.java index aa60c78fd9..57a62f5c32 100644 --- a/backend/src/main/java/io/metersphere/controller/ReportController.java +++ b/backend/src/main/java/io/metersphere/controller/ReportController.java @@ -9,6 +9,7 @@ import io.metersphere.commons.utils.Pager; import io.metersphere.controller.request.ReportRequest; import io.metersphere.dto.ReportDTO; import io.metersphere.report.base.Errors; +import io.metersphere.report.base.TestOverview; import io.metersphere.report.dto.ErrorsTop5DTO; import io.metersphere.report.dto.RequestStatisticsDTO; import io.metersphere.service.ReportService; @@ -70,5 +71,10 @@ public class ReportController { return reportService.getReportErrorsTOP5(reportId); } + @GetMapping("/content/testoverview/{reportId}") + public TestOverview getTestOverview(@PathVariable String reportId) { + return reportService.getTestOverview(reportId); + } + } diff --git a/backend/src/main/java/io/metersphere/report/JtlResolver.java b/backend/src/main/java/io/metersphere/report/JtlResolver.java index b4b0c87f0c..888d860d54 100644 --- a/backend/src/main/java/io/metersphere/report/JtlResolver.java +++ b/backend/src/main/java/io/metersphere/report/JtlResolver.java @@ -3,18 +3,17 @@ package io.metersphere.report; import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; import com.opencsv.bean.HeaderColumnNameMappingStrategy; -import io.metersphere.report.base.Errors; -import io.metersphere.report.base.ErrorsTop5; -import io.metersphere.report.base.Metric; -import io.metersphere.report.base.RequestStatistics; +import io.metersphere.report.base.*; import io.metersphere.report.dto.ErrorsTop5DTO; import io.metersphere.report.dto.RequestStatisticsDTO; +import org.apache.bcel.verifier.statics.LONG_Upper; import org.apache.commons.lang3.StringUtils; import java.io.Reader; import java.io.StringReader; import java.text.DecimalFormat; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; public class JtlResolver { @@ -144,14 +143,14 @@ public class JtlResolver { return statisticsDTO; } - // Aggregate Report + // report - Aggregate Report public static RequestStatisticsDTO getRequestStatistics(String jtlString) { List totalLines = resolver(jtlString); Map> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel)); return getOneRpsResult(map); } - // Errors + // report - Errors public static List getErrorsList(String jtlString) { List totalLines = resolver(jtlString); List 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(); } + // report - Errors Top 5 public static ErrorsTop5DTO getErrorsTop5DTO(String jtlString) { List totalLines = resolver(jtlString); ErrorsTop5DTO top5DTO = new ErrorsTop5DTO(); @@ -228,4 +228,45 @@ public class JtlResolver { return top5DTO; } + // report - TestOverview + public static TestOverview getTestOverview(String jtlString) { + TestOverview testOverview = new TestOverview(); + List total = JtlResolver.resolver(jtlString); + Map> collect = total.stream().collect(Collectors.groupingBy(Metric::getTimestamp)); + Iterator>> iterator = collect.entrySet().iterator(); + Integer max = 0; + Integer totalElapsed = 0; + while (iterator.hasNext()) { + Map.Entry> entry = iterator.next(); + List 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 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; + } + } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/report/base/TestOverview.java b/backend/src/main/java/io/metersphere/report/base/TestOverview.java new file mode 100644 index 0000000000..9ef2b2c3dc --- /dev/null +++ b/backend/src/main/java/io/metersphere/report/base/TestOverview.java @@ -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; + } +} diff --git a/backend/src/main/java/io/metersphere/service/ReportService.java b/backend/src/main/java/io/metersphere/service/ReportService.java index cdd842ed6a..76145cfced 100644 --- a/backend/src/main/java/io/metersphere/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/service/ReportService.java @@ -8,6 +8,7 @@ import io.metersphere.controller.request.ReportRequest; import io.metersphere.dto.ReportDTO; import io.metersphere.report.JtlResolver; import io.metersphere.report.base.Errors; +import io.metersphere.report.base.TestOverview; import io.metersphere.report.dto.ErrorsTop5DTO; import io.metersphere.report.dto.RequestStatisticsDTO; import org.springframework.stereotype.Service; @@ -66,4 +67,11 @@ public class ReportService { ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content); return errors; } + + public TestOverview getTestOverview(String id) { + LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id); + String content = loadTestReport.getContent(); + TestOverview testOverview = JtlResolver.getTestOverview(content); + return testOverview; + } } diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 522f861dce..c153d20254 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -35,7 +35,7 @@ - + @@ -44,7 +44,7 @@ - + diff --git a/frontend/src/business/components/performance/report/components/TestOverview.vue b/frontend/src/business/components/performance/report/components/TestOverview.vue index 1745b0bca7..fa034e5361 100644 --- a/frontend/src/business/components/performance/report/components/TestOverview.vue +++ b/frontend/src/business/components/performance/report/components/TestOverview.vue @@ -4,7 +4,7 @@ - 40 + {{maxUsers}} VU Max Users @@ -13,7 +13,7 @@ - 5.4 + {{avgThroughput}} Hits/s Avg.Throughput @@ -22,7 +22,7 @@ - 0.41 + {{errors}} % Errors @@ -31,7 +31,7 @@ - 1.28 + {{avgResponseTime}} s Avg.Response Time @@ -40,7 +40,7 @@ - 1.41 + {{responseTime90}} s 90% Response Time @@ -49,7 +49,7 @@ - 817.29 + {{avgBandwidth}} KiB/s Avg.Bandwidth @@ -73,6 +73,12 @@ name: "TestOverview", data() { return { + maxUsers: "0", + avgThroughput: "0", + errors: "0", + avgResponseTime: "0", + responseTime90: "0", + avgBandwidth: "0", option1: { legend: { 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; + }) + } + } + } } }