Merge branch 'dev' of https://github.com/fit2cloudrd/metersphere-server into dev
This commit is contained in:
commit
e018f744db
|
@ -3,8 +3,6 @@ package io.metersphere.commons.constants;
|
||||||
public class RoleConstants {
|
public class RoleConstants {
|
||||||
public final static String ADMIN = "admin";
|
public final static String ADMIN = "admin";
|
||||||
public final static String ORG_ADMIN = "org_admin";
|
public final static String ORG_ADMIN = "org_admin";
|
||||||
// 组织内其它角色
|
|
||||||
public final static String ORG_OTHER = "org_other";
|
|
||||||
public final static String TEST_VIEWER = "test_viewer";
|
public final static String TEST_VIEWER = "test_viewer";
|
||||||
public final static String TEST_MANAGER = "test_manager";
|
public final static String TEST_MANAGER = "test_manager";
|
||||||
public final static String TEST_USER = "test_user";
|
public final static String TEST_USER = "test_user";
|
||||||
|
|
|
@ -82,6 +82,11 @@ public class ReportController {
|
||||||
return reportService.getLoadChartData(reportId);
|
return reportService.getLoadChartData(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/content/res_chart/{reportId}")
|
||||||
|
public ChartsData getResponseTimeChartData(@PathVariable String reportId) {
|
||||||
|
return reportService.getResponseTimeChartData(reportId);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/{reportId}")
|
@GetMapping("/{reportId}")
|
||||||
public LoadTestReport getLoadTestReport(@PathVariable String reportId) {
|
public LoadTestReport getLoadTestReport(@PathVariable String reportId) {
|
||||||
return reportService.getLoadTestReport(reportId);
|
return reportService.getLoadTestReport(reportId);
|
||||||
|
|
|
@ -89,7 +89,8 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
processCheckoutConfigTestElement(ele);
|
processCheckoutConfigTestElement(ele);
|
||||||
processCheckoutDnsCacheManager(ele);
|
processCheckoutDnsCacheManager(ele);
|
||||||
processCheckoutArguments(ele);
|
processCheckoutArguments(ele);
|
||||||
processCheckoutResponseAssertion(ele);
|
// TODO: 2020/4/3 使用断言导致backend-listener不可用
|
||||||
|
// processCheckoutResponseAssertion(ele);
|
||||||
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
|
||||||
processConcurrencyThreadGroup(ele);
|
processConcurrencyThreadGroup(ele);
|
||||||
processCheckoutTimer(ele);
|
processCheckoutTimer(ele);
|
||||||
|
@ -111,7 +112,8 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
} else if (nodeNameEquals(ele, ARGUMENTS)) {
|
} else if (nodeNameEquals(ele, ARGUMENTS)) {
|
||||||
processArguments(ele);
|
processArguments(ele);
|
||||||
} else if (nodeNameEquals(ele, RESPONSE_ASSERTION)) {
|
} else if (nodeNameEquals(ele, RESPONSE_ASSERTION)) {
|
||||||
processResponseAssertion(ele);
|
// TODO: 2020/4/3 使用断言导致backend-listener不可用
|
||||||
|
// processResponseAssertion(ele);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,13 +125,12 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
Node item = childNodes.item(i);
|
Node item = childNodes.item(i);
|
||||||
if (item instanceof Element && nodeNameEquals(item, "collectionProp")) {
|
if (item instanceof Element && nodeNameEquals(item, "collectionProp")) {
|
||||||
removeChildren(item);
|
|
||||||
Document document = item.getOwnerDocument();
|
Document document = item.getOwnerDocument();
|
||||||
Object params = context.getProperty("statusCode");
|
Object params = context.getProperty("statusCode");
|
||||||
if (params instanceof List) {
|
if (params instanceof List) {
|
||||||
HashSet set = new HashSet((List) params);
|
HashSet set = new HashSet((List) params);
|
||||||
for (Object p : set) {
|
for (Object p : set) {
|
||||||
element.appendChild(createStringProp(document, p.toString(), p.toString()));
|
item.appendChild(createStringProp(document, p.toString(), p.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,6 +153,15 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
Node item = childNodes.item(i);
|
Node item = childNodes.item(i);
|
||||||
if (nodeNameEquals(item, RESPONSE_ASSERTION)) {
|
if (nodeNameEquals(item, RESPONSE_ASSERTION)) {
|
||||||
// 如果已经存在,不再添加
|
// 如果已经存在,不再添加
|
||||||
|
removeChildren(item);
|
||||||
|
Element collectionProp = document.createElement(COLLECTION_PROP);
|
||||||
|
collectionProp.setAttribute("name", "Asserion.test_strings");
|
||||||
|
//
|
||||||
|
item.appendChild(collectionProp);
|
||||||
|
item.appendChild(createStringProp(document, "Assertion.custom_message", ""));
|
||||||
|
item.appendChild(createStringProp(document, "Assertion.test_field", "Assertion.response_code"));
|
||||||
|
item.appendChild(createBoolProp(document, "Assertion.assume_success", false));
|
||||||
|
item.appendChild(createIntProp(document, "Assertion.test_type", 40));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,9 +189,9 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
//
|
//
|
||||||
responseAssertion.appendChild(collectionProp);
|
responseAssertion.appendChild(collectionProp);
|
||||||
responseAssertion.appendChild(createStringProp(document, "Assertion.custom_message", ""));
|
responseAssertion.appendChild(createStringProp(document, "Assertion.custom_message", ""));
|
||||||
responseAssertion.appendChild(createStringProp(document, "Assertion.test_field", ""));
|
responseAssertion.appendChild(createStringProp(document, "Assertion.test_field", "Assertion.response_code"));
|
||||||
responseAssertion.appendChild(createBoolProp(document, "Assertion.assume_success", false));
|
responseAssertion.appendChild(createBoolProp(document, "Assertion.assume_success", false));
|
||||||
responseAssertion.appendChild(createIntProp(document, "Assertion.test_type", 33));
|
responseAssertion.appendChild(createIntProp(document, "Assertion.test_type", 40));
|
||||||
hashTree.appendChild(responseAssertion);
|
hashTree.appendChild(responseAssertion);
|
||||||
hashTree.appendChild(document.createElement(HASH_TREE_ELEMENT));
|
hashTree.appendChild(document.createElement(HASH_TREE_ELEMENT));
|
||||||
}
|
}
|
||||||
|
@ -352,7 +362,7 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
Node item = childNodes.item(i);
|
Node item = childNodes.item(i);
|
||||||
if (item instanceof Element && nodeNameEquals(item, "collectionProp")) {
|
if (item instanceof Element && nodeNameEquals(item, "collectionProp")) {
|
||||||
removeChildren(item);
|
//
|
||||||
Document document = item.getOwnerDocument();
|
Document document = item.getOwnerDocument();
|
||||||
Object params = context.getProperty("params");
|
Object params = context.getProperty("params");
|
||||||
if (params instanceof List) {
|
if (params instanceof List) {
|
||||||
|
@ -377,31 +387,33 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
|
|
||||||
private void processDnsCacheManager(Element ele) {
|
private void processDnsCacheManager(Element ele) {
|
||||||
|
|
||||||
|
Object domains = context.getProperty("domains");
|
||||||
|
if (!(domains instanceof List)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (((List) domains).size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
NodeList childNodes = ele.getChildNodes();
|
NodeList childNodes = ele.getChildNodes();
|
||||||
for (int i = 0, size = childNodes.getLength(); i < size; i++) {
|
for (int i = 0, size = childNodes.getLength(); i < size; i++) {
|
||||||
Node item = childNodes.item(i);
|
Node item = childNodes.item(i);
|
||||||
if (item instanceof Element && nodeNameEquals(item, "collectionProp")
|
if (item instanceof Element && nodeNameEquals(item, "collectionProp")
|
||||||
&& org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.hosts")) {
|
&& org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.hosts")) {
|
||||||
|
|
||||||
removeChildren(item);
|
|
||||||
Document document = item.getOwnerDocument();
|
Document document = item.getOwnerDocument();
|
||||||
Object domains = context.getProperty("domains");
|
for (Object d : (List) domains) {
|
||||||
if (domains instanceof List) {
|
JSONObject jsonObject = JSON.parseObject(d.toString());
|
||||||
for (Object d : (List) domains) {
|
if (!jsonObject.getBooleanValue("enable")) {
|
||||||
JSONObject jsonObject = JSON.parseObject(d.toString());
|
continue;
|
||||||
if (!jsonObject.getBooleanValue("enable")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Element elementProp = document.createElement("elementProp");
|
|
||||||
elementProp.setAttribute("name", jsonObject.getString("domain"));
|
|
||||||
elementProp.setAttribute("elementType", "StaticHost");
|
|
||||||
elementProp.appendChild(createStringProp(document, "StaticHost.Name", jsonObject.getString("domain")));
|
|
||||||
elementProp.appendChild(createStringProp(document, "StaticHost.Address", jsonObject.getString("ip")));
|
|
||||||
item.appendChild(elementProp);
|
|
||||||
}
|
}
|
||||||
|
Element elementProp = document.createElement("elementProp");
|
||||||
|
elementProp.setAttribute("name", jsonObject.getString("domain"));
|
||||||
|
elementProp.setAttribute("elementType", "StaticHost");
|
||||||
|
elementProp.appendChild(createStringProp(document, "StaticHost.Name", jsonObject.getString("domain")));
|
||||||
|
elementProp.appendChild(createStringProp(document, "StaticHost.Address", jsonObject.getString("ip")));
|
||||||
|
item.appendChild(elementProp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item instanceof Element && nodeNameEquals(item, "boolProp")
|
if (item instanceof Element && nodeNameEquals(item, "boolProp")
|
||||||
&& org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.isCustomResolver")) {
|
&& org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.isCustomResolver")) {
|
||||||
item.getFirstChild().setNodeValue("true");
|
item.getFirstChild().setNodeValue("true");
|
||||||
|
|
|
@ -4,11 +4,11 @@ import com.alibaba.fastjson.JSONObject;
|
||||||
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.commons.exception.MSException;
|
|
||||||
import io.metersphere.report.base.*;
|
import io.metersphere.report.base.*;
|
||||||
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.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;
|
||||||
|
@ -19,6 +19,9 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class JtlResolver {
|
public class JtlResolver {
|
||||||
|
|
||||||
|
private static final Integer ERRORS_TOP_SIZE = 5;
|
||||||
|
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
private static List<Metric> resolver(String jtlString) {
|
private static List<Metric> resolver(String jtlString) {
|
||||||
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
||||||
ms.setType(Metric.class);
|
ms.setType(Metric.class);
|
||||||
|
@ -36,60 +39,65 @@ public class JtlResolver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequestStatisticsDTO getRequestStatistics(String jtlString){
|
public static RequestStatisticsDTO getRequestStatistics(String jtlString) {
|
||||||
List<Metric> total = resolver(jtlString);
|
List<Integer> allElapseTimeList = new ArrayList<>();
|
||||||
Map<String, List<Metric>> map = total.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
|
||||||
List<RequestStatistics> requestStatisticsList = new ArrayList<>();
|
List<RequestStatistics> requestStatisticsList = new ArrayList<>();
|
||||||
Iterator<Map.Entry<String, List<Metric>>> iterator = map.entrySet().iterator();
|
DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
||||||
List<Integer> allelapse = new ArrayList<>();
|
|
||||||
DecimalFormat df = new DecimalFormat("0.00");
|
List<Metric> totalMetricList = resolver(jtlString);
|
||||||
int totalAverage = 0;
|
Map<String, List<Metric>> jtlLabelMap = totalMetricList.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
||||||
float allBytes = 0f;
|
Iterator<Map.Entry<String, List<Metric>>> iterator = jtlLabelMap.entrySet().iterator();
|
||||||
|
|
||||||
|
int totalElapsedTime = 0;
|
||||||
|
float totalBytes = 0f;
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Map.Entry<String, List<Metric>> entry = iterator.next();
|
Map.Entry<String, List<Metric>> entry = iterator.next();
|
||||||
String label = entry.getKey();
|
String label = entry.getKey();
|
||||||
List<Metric> list = entry.getValue();
|
List<Metric> metricList = entry.getValue();
|
||||||
int index=0;
|
|
||||||
int sumElapsed=0;
|
|
||||||
int failSize = 0;
|
|
||||||
// 以list为单位 total bytes
|
|
||||||
float totalBytes = 0f;
|
|
||||||
List<Integer> elapsedList = new ArrayList<>();
|
List<Integer> elapsedList = new ArrayList<>();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
|
int jtlSamplesSize = 0, oneLineElapsedTime = 0, failSize = 0;
|
||||||
|
float oneLineBytes = 0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < metricList.size(); i++) {
|
||||||
try {
|
try {
|
||||||
Metric row = list.get(i);
|
Metric row = metricList.get(i);
|
||||||
String elapsed = row.getElapsed();
|
String elapsed = row.getElapsed();
|
||||||
sumElapsed += Integer.parseInt(elapsed);
|
oneLineElapsedTime += Integer.parseInt(elapsed);
|
||||||
totalAverage += Integer.parseInt(elapsed);
|
totalElapsedTime += Integer.parseInt(elapsed);
|
||||||
elapsedList.add(Integer.valueOf(elapsed));
|
elapsedList.add(Integer.valueOf(elapsed));
|
||||||
allelapse.add(Integer.valueOf(elapsed));
|
allElapseTimeList.add(Integer.valueOf(elapsed));
|
||||||
String success = row.getSuccess();
|
|
||||||
if (!"true".equals(success)){
|
String isSuccess = row.getSuccess();
|
||||||
|
if (!"true".equals(isSuccess)) {
|
||||||
failSize++;
|
failSize++;
|
||||||
}
|
}
|
||||||
String bytes = row.getBytes();
|
String bytes = row.getBytes();
|
||||||
|
oneLineBytes += Float.parseFloat(bytes);
|
||||||
totalBytes += Float.parseFloat(bytes);
|
totalBytes += Float.parseFloat(bytes);
|
||||||
allBytes += Float.parseFloat(bytes);
|
jtlSamplesSize++;
|
||||||
index++;
|
} catch (Exception e) {
|
||||||
}catch (Exception e){
|
System.out.println("exception i:" + i);
|
||||||
System.out.println("exception i:"+i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(elapsedList);
|
Collections.sort(elapsedList);
|
||||||
|
|
||||||
int tp90 = elapsedList.size()*90/100;
|
int tp90 = elapsedList.size() * 90 / 100;
|
||||||
int tp95 = elapsedList.size()*95/100;
|
int tp95 = elapsedList.size() * 95 / 100;
|
||||||
int tp99 = elapsedList.size()*99/100;
|
int tp99 = elapsedList.size() * 99 / 100;
|
||||||
|
|
||||||
list.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
metricList.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
||||||
long time = Long.parseLong(list.get(list.size()-1).getTimestamp()) - Long.parseLong(list.get(0).getTimestamp()) + Long.parseLong(list.get(list.size()-1).getElapsed());
|
long time = Long.parseLong(metricList.get(metricList.size() - 1).getTimestamp()) - Long.parseLong(metricList.get(0).getTimestamp())
|
||||||
|
+ Long.parseLong(metricList.get(metricList.size() - 1).getElapsed());
|
||||||
|
|
||||||
RequestStatistics requestStatistics = new RequestStatistics();
|
RequestStatistics requestStatistics = new RequestStatistics();
|
||||||
requestStatistics.setRequestLabel(label);
|
requestStatistics.setRequestLabel(label);
|
||||||
requestStatistics.setSamples(index);
|
requestStatistics.setSamples(jtlSamplesSize);
|
||||||
|
|
||||||
String s = df.format((float)sumElapsed/index);
|
String average = decimalFormat.format((float) oneLineElapsedTime / jtlSamplesSize);
|
||||||
requestStatistics.setAverage(s+"");
|
requestStatistics.setAverage(average);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TP90的计算
|
* TP90的计算
|
||||||
|
@ -99,84 +107,93 @@ public class JtlResolver {
|
||||||
* 其余相似的指标还有TP95, TP99
|
* 其余相似的指标还有TP95, TP99
|
||||||
*/
|
*/
|
||||||
// todo tp90
|
// todo tp90
|
||||||
requestStatistics.setTp90(elapsedList.get(tp90)+"");
|
requestStatistics.setTp90(elapsedList.get(tp90) + "");
|
||||||
requestStatistics.setTp95(elapsedList.get(tp95)+"");
|
requestStatistics.setTp95(elapsedList.get(tp95) + "");
|
||||||
requestStatistics.setTp99(elapsedList.get(tp99)+"");
|
requestStatistics.setTp99(elapsedList.get(tp99) + "");
|
||||||
|
|
||||||
double avgHits = (double)list.size() / (time * 1.0 / 1000);
|
double avgHits = (double) metricList.size() / (time * 1.0 / 1000);
|
||||||
requestStatistics.setAvgHits(df.format(avgHits));
|
requestStatistics.setAvgHits(decimalFormat.format(avgHits));
|
||||||
|
|
||||||
requestStatistics.setMin(elapsedList.get(0)+"");
|
requestStatistics.setMin(elapsedList.get(0) + "");
|
||||||
requestStatistics.setMax(elapsedList.get(index-1)+"");
|
requestStatistics.setMax(elapsedList.get(jtlSamplesSize - 1) + "");
|
||||||
requestStatistics.setErrors(df.format(failSize * 100.0 / index)+"%");
|
requestStatistics.setErrors(decimalFormat.format(failSize * 100.0 / jtlSamplesSize) + "%");
|
||||||
requestStatistics.setKo(failSize);
|
requestStatistics.setKo(failSize);
|
||||||
/**
|
/**
|
||||||
* 所有的相同请求的bytes总和 / 1024 / 请求持续运行的时间=sum(bytes)/1024/total time
|
* 所有的相同请求的bytes总和 / 1024 / 请求持续运行的时间=sum(bytes)/1024/total time
|
||||||
* total time = 最大时间戳 - 最小时间戳 + 最后请求的响应时间
|
* total time = 最大时间戳 - 最小时间戳 + 最后请求的响应时间
|
||||||
*/
|
*/
|
||||||
requestStatistics.setKbPerSec(df.format(totalBytes * 1.0 / 1024 / (time * 1.0 / 1000)));
|
requestStatistics.setKbPerSec(decimalFormat.format(oneLineBytes * 1.0 / 1024 / (time * 1.0 / 1000)));
|
||||||
requestStatisticsList.add(requestStatistics);
|
requestStatisticsList.add(requestStatistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(allelapse);
|
Collections.sort(allElapseTimeList);
|
||||||
int totalTP90 = allelapse.size()*90/100;
|
int totalTP90 = allElapseTimeList.size() * 90 / 100;
|
||||||
int totalTP95 = allelapse.size()*95/100;
|
int totalTP95 = allElapseTimeList.size() * 95 / 100;
|
||||||
int totalTP99 = allelapse.size()*99/100;
|
int totalTP99 = allElapseTimeList.size() * 99 / 100;
|
||||||
|
|
||||||
Integer min = allelapse.get(0);
|
Integer min = allElapseTimeList.get(0);
|
||||||
Integer max = allelapse.get(allelapse.size() - 1);
|
Integer max = allElapseTimeList.get(allElapseTimeList.size() - 1);
|
||||||
|
|
||||||
int allSamples = requestStatisticsList.stream().mapToInt(RequestStatistics::getSamples).sum();
|
int allSamples = requestStatisticsList.stream().mapToInt(RequestStatistics::getSamples).sum();
|
||||||
int failSize = requestStatisticsList.stream().mapToInt(RequestStatistics::getKo).sum();
|
int failSize = requestStatisticsList.stream().mapToInt(RequestStatistics::getKo).sum();
|
||||||
|
|
||||||
double errors = (double)failSize / allSamples * 100;
|
double errors = (double) failSize / allSamples * 100;
|
||||||
String totalerrors = df.format(errors);
|
String totalErrors = decimalFormat.format(errors);
|
||||||
double average = (double)totalAverage / allSamples;
|
double average = (double) totalElapsedTime / allSamples;
|
||||||
String totalaverage = df.format(average);
|
String totalAverage = decimalFormat.format(average);
|
||||||
|
|
||||||
RequestStatisticsDTO statisticsDTO = new RequestStatisticsDTO();
|
RequestStatisticsDTO statisticsDTO = new RequestStatisticsDTO();
|
||||||
statisticsDTO.setRequestStatisticsList(requestStatisticsList);
|
statisticsDTO.setRequestStatisticsList(requestStatisticsList);
|
||||||
statisticsDTO.setTotalLabel("Total");
|
statisticsDTO.setTotalLabel("Total");
|
||||||
statisticsDTO.setTotalSamples(String.valueOf(allSamples));
|
statisticsDTO.setTotalSamples(String.valueOf(allSamples));
|
||||||
statisticsDTO.setTotalErrors(totalerrors + "%");
|
statisticsDTO.setTotalErrors(totalErrors + "%");
|
||||||
statisticsDTO.setTotalAverage(totalaverage);
|
statisticsDTO.setTotalAverage(totalAverage);
|
||||||
statisticsDTO.setTotalMin(String.valueOf(min));
|
statisticsDTO.setTotalMin(String.valueOf(min));
|
||||||
statisticsDTO.setTotalMax(String.valueOf(max));
|
statisticsDTO.setTotalMax(String.valueOf(max));
|
||||||
statisticsDTO.setTotalTP90(String.valueOf(allelapse.get(totalTP90)));
|
statisticsDTO.setTotalTP90(String.valueOf(allElapseTimeList.get(totalTP90)));
|
||||||
statisticsDTO.setTotalTP95(String.valueOf(allelapse.get(totalTP95)));
|
statisticsDTO.setTotalTP95(String.valueOf(allElapseTimeList.get(totalTP95)));
|
||||||
statisticsDTO.setTotalTP99(String.valueOf(allelapse.get(totalTP99)));
|
statisticsDTO.setTotalTP99(String.valueOf(allElapseTimeList.get(totalTP99)));
|
||||||
|
|
||||||
total.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
totalMetricList.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
||||||
long ms = Long.valueOf(total.get(total.size()-1).getTimestamp()) - Long.valueOf(total.get(0).getTimestamp()) + Long.parseLong(total.get(total.size()-1).getElapsed());
|
|
||||||
double avgThroughput = (double)total.size() / (ms * 1.0 / 1000);
|
long ms = Long.parseLong(totalMetricList.get(totalMetricList.size() - 1).getTimestamp()) - Long.parseLong(totalMetricList.get(0).getTimestamp())
|
||||||
statisticsDTO.setTotalAvgHits(df.format(avgThroughput));
|
+ Long.parseLong(totalMetricList.get(totalMetricList.size() - 1).getElapsed());
|
||||||
|
double avgThroughput = (double) totalMetricList.size() / (ms * 1.0 / 1000);
|
||||||
|
|
||||||
|
statisticsDTO.setTotalAvgHits(decimalFormat.format(avgThroughput));
|
||||||
|
statisticsDTO.setTotalAvgBandwidth(decimalFormat.format(totalBytes * 1.0 / 1024 / (ms * 1.0 / 1000)));
|
||||||
|
|
||||||
statisticsDTO.setTotalAvgBandwidth(df.format(allBytes * 1.0 / 1024 / (ms * 1.0 / 1000)));
|
|
||||||
return statisticsDTO;
|
return statisticsDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// report - Errors
|
|
||||||
public static List<Errors> getErrorsList(String jtlString) {
|
public static List<Errors> getErrorsList(String jtlString) {
|
||||||
List<Metric> totalLines = resolver(jtlString);
|
List<Metric> totalMetricList = resolver(jtlString);
|
||||||
List<Metric> falseList = totalLines.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
|
||||||
List<Errors> errorsList = new ArrayList<>();
|
List<Errors> errorsList = new ArrayList<>();
|
||||||
Map<String, List<Metric>> collect = falseList.stream().collect(Collectors.groupingBy(JtlResolver::getResponseCodeAndFailureMessage));
|
DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
||||||
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
|
||||||
DecimalFormat df = new DecimalFormat("0.00");
|
List<Metric> falseList = new ArrayList<>();
|
||||||
while (iterator.hasNext()) {
|
for (Metric metric : totalMetricList) {
|
||||||
Map.Entry<String, List<Metric>> next = iterator.next();
|
if (StringUtils.equals("false", metric.getSuccess())) {
|
||||||
|
falseList.add(metric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, List<Metric>> jtlMap = falseList.stream().collect(Collectors.groupingBy(JtlResolver::getResponseCodeAndFailureMessage));
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<Metric>> next : jtlMap.entrySet()) {
|
||||||
String key = next.getKey();
|
String key = next.getKey();
|
||||||
List<Metric> value = next.getValue();
|
List<Metric> metricList = next.getValue();
|
||||||
Errors errors = new Errors();
|
Errors errors = new Errors();
|
||||||
errors.setErrorType(key);
|
errors.setErrorType(key);
|
||||||
errors.setErrorNumber(String.valueOf(value.size()));
|
errors.setErrorNumber(String.valueOf(metricList.size()));
|
||||||
int errorSize = value.size();
|
int errorSize = metricList.size();
|
||||||
int errorAllSize = falseList.size();
|
int errorAllSize = falseList.size();
|
||||||
int allSamples = totalLines.size();
|
int allSamples = totalMetricList.size();
|
||||||
errors.setPrecentOfErrors(df.format((double)errorSize / errorAllSize * 100) + "%");
|
errors.setPrecentOfErrors(decimalFormat.format((double) errorSize / errorAllSize * 100) + "%");
|
||||||
errors.setPrecentOfAllSamples(df.format((double)errorSize / allSamples * 100) + "%");
|
errors.setPrecentOfAllSamples(decimalFormat.format((double) errorSize / allSamples * 100) + "%");
|
||||||
errorsList.add(errors);
|
errorsList.add(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorsList;
|
return errorsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,38 +201,46 @@ 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> totalMetricList = resolver(jtlString);
|
||||||
ErrorsTop5DTO top5DTO = new ErrorsTop5DTO();
|
ErrorsTop5DTO top5DTO = new ErrorsTop5DTO();
|
||||||
List<Metric> falseList = totalLines.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
|
||||||
Map<String, List<Metric>> collect = falseList.stream().collect(Collectors.groupingBy(JtlResolver::getResponseCodeAndFailureMessage));
|
|
||||||
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
|
||||||
List<ErrorsTop5> errorsTop5s = new ArrayList<>();
|
List<ErrorsTop5> errorsTop5s = new ArrayList<>();
|
||||||
while (iterator.hasNext()) {
|
|
||||||
Map.Entry<String, List<Metric>> next = iterator.next();
|
List<Metric> falseList = Objects.requireNonNull(totalMetricList).stream()
|
||||||
|
.filter(metric -> StringUtils.equals("false", metric.getSuccess()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Map<String, List<Metric>> collect = falseList.stream()
|
||||||
|
.collect(Collectors.groupingBy(JtlResolver::getResponseCodeAndFailureMessage));
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<Metric>> next : collect.entrySet()) {
|
||||||
String key = next.getKey();
|
String key = next.getKey();
|
||||||
List<Metric> value = next.getValue();
|
List<Metric> metricList = next.getValue();
|
||||||
|
List<Metric> list = new ArrayList<>();
|
||||||
|
for (Metric metric : totalMetricList) {
|
||||||
|
if (StringUtils.equals(metric.getLabel(), metricList.get(0).getLabel())) {
|
||||||
|
list.add(metric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ErrorsTop5 errorsTop5 = new ErrorsTop5();
|
ErrorsTop5 errorsTop5 = new ErrorsTop5();
|
||||||
List<Metric> list = totalLines.stream()
|
|
||||||
.filter(metric -> StringUtils.equals(metric.getLabel(), value.get(0).getLabel())).collect(Collectors.toList());
|
|
||||||
errorsTop5.setSamples(String.valueOf(list.size()));
|
errorsTop5.setSamples(String.valueOf(list.size()));
|
||||||
errorsTop5.setSample(value.get(0).getLabel());
|
errorsTop5.setSample(metricList.get(0).getLabel());
|
||||||
errorsTop5.setErrors(String.valueOf(value.size()));
|
errorsTop5.setErrors(String.valueOf(metricList.size()));
|
||||||
errorsTop5.setErrorsAllSize(value.size());
|
errorsTop5.setErrorsAllSize(metricList.size());
|
||||||
errorsTop5.setError(key);
|
errorsTop5.setError(key);
|
||||||
errorsTop5s.add(errorsTop5);
|
errorsTop5s.add(errorsTop5);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorsTop5s.sort((t0, t1) -> t1.getErrorsAllSize().compareTo(t0.getErrorsAllSize()));
|
errorsTop5s.sort((t0, t1) -> t1.getErrorsAllSize().compareTo(t0.getErrorsAllSize()));
|
||||||
|
|
||||||
if (errorsTop5s.size() >= 5) {
|
if (errorsTop5s.size() >= ERRORS_TOP_SIZE) {
|
||||||
errorsTop5s = errorsTop5s.subList(0, 5);
|
errorsTop5s = errorsTop5s.subList(0, ERRORS_TOP_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
top5DTO.setLabel("Total");
|
top5DTO.setLabel("Total");
|
||||||
top5DTO.setErrorsTop5List(errorsTop5s);
|
top5DTO.setErrorsTop5List(errorsTop5s);
|
||||||
top5DTO.setTotalSamples(String.valueOf(totalLines.size()));
|
top5DTO.setTotalSamples(String.valueOf(totalMetricList.size()));
|
||||||
top5DTO.setTotalErrors(String.valueOf(falseList.size()));
|
top5DTO.setTotalErrors(String.valueOf(falseList.size()));
|
||||||
int size = errorsTop5s.size();
|
int size = errorsTop5s.size();
|
||||||
// Total行 信息
|
// Total行 信息
|
||||||
|
@ -233,23 +258,26 @@ public class JtlResolver {
|
||||||
return top5DTO;
|
return top5DTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// report - TestOverview
|
|
||||||
public static TestOverview getTestOverview(String jtlString) {
|
public static TestOverview getTestOverview(String jtlString) {
|
||||||
TestOverview testOverview = new TestOverview();
|
TestOverview testOverview = new TestOverview();
|
||||||
List<Metric> total = JtlResolver.resolver(jtlString);
|
DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
||||||
Map<String, List<Metric>> collect = total.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
|
||||||
|
List<Metric> totalLineList = JtlResolver.resolver(jtlString);
|
||||||
|
Map<String, List<Metric>> collect = totalLineList.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||||
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
||||||
int max = 0;
|
|
||||||
int totalElapsed = 0;
|
int maxUsers = 0, totalElapsed = 0;
|
||||||
float totalBytes = 0f;
|
float totalBytes = 0f;
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Map.Entry<String, List<Metric>> entry = iterator.next();
|
Map.Entry<String, List<Metric>> entry = iterator.next();
|
||||||
List<Metric> list = entry.getValue();
|
List<Metric> metricList = entry.getValue();
|
||||||
if (list.size() > max) {
|
|
||||||
max = list.size();
|
if (metricList.size() > maxUsers) {
|
||||||
|
maxUsers = metricList.size();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
Metric metric = list.get(i);
|
for (Metric metric : metricList) {
|
||||||
String elapsed = metric.getElapsed();
|
String elapsed = metric.getElapsed();
|
||||||
totalElapsed += Integer.parseInt(elapsed);
|
totalElapsed += Integer.parseInt(elapsed);
|
||||||
String bytes = metric.getBytes();
|
String bytes = metric.getBytes();
|
||||||
|
@ -257,31 +285,30 @@ public class JtlResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
total.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
totalLineList.sort(Comparator.comparing(t0 -> Long.valueOf(t0.getTimestamp())));
|
||||||
DecimalFormat df = new DecimalFormat("0.00");
|
|
||||||
|
|
||||||
testOverview.setMaxUsers(String.valueOf(max));
|
testOverview.setMaxUsers(String.valueOf(maxUsers));
|
||||||
|
|
||||||
List<Metric> list90 = total.subList(0, total.size() * 9 / 10);
|
List<Metric> list90 = totalLineList.subList(0, totalLineList.size() * 9 / 10);
|
||||||
long sum = list90.stream().mapToLong(metric -> Long.parseLong(metric.getElapsed())).sum();
|
long sum = list90.stream().mapToLong(metric -> Long.parseLong(metric.getElapsed())).sum();
|
||||||
double avg90 = (double)sum / 1000 / list90.size();
|
double avg90 = (double) sum / 1000 / list90.size();
|
||||||
testOverview.setResponseTime90(df.format(avg90));
|
testOverview.setResponseTime90(decimalFormat.format(avg90));
|
||||||
|
|
||||||
Long timestamp1 = Long.valueOf(total.get(0).getTimestamp());
|
long timesStampStart = Long.parseLong(totalLineList.get(0).getTimestamp());
|
||||||
Long timestamp2 = Long.valueOf(total.get(total.size()-1).getTimestamp());
|
long timesStampEnd = Long.parseLong(totalLineList.get(totalLineList.size() - 1).getTimestamp());
|
||||||
long time = timestamp2 - timestamp1 + Long.parseLong(total.get(total.size()-1).getElapsed());
|
long time = timesStampEnd - timesStampStart + Long.parseLong(totalLineList.get(totalLineList.size() - 1).getElapsed());
|
||||||
double avgThroughput = (double)total.size() / (time * 1.0 / 1000);
|
double avgThroughput = (double) totalLineList.size() / (time * 1.0 / 1000);
|
||||||
testOverview.setAvgThroughput(df.format(avgThroughput));
|
testOverview.setAvgThroughput(decimalFormat.format(avgThroughput));
|
||||||
|
|
||||||
List<Metric> falseList = total.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
List<Metric> falseList = totalLineList.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
|
||||||
double errors = falseList.size() * 1.0 / total.size() * 100;
|
double errors = falseList.size() * 1.0 / totalLineList.size() * 100;
|
||||||
testOverview.setErrors(df.format(errors));
|
testOverview.setErrors(decimalFormat.format(errors));
|
||||||
|
|
||||||
double avg = totalElapsed * 1.0 / total.size() / 1000; // s
|
double avg = totalElapsed * 1.0 / totalLineList.size() / 1000;
|
||||||
testOverview.setAvgResponseTime(df.format(avg));
|
testOverview.setAvgResponseTime(decimalFormat.format(avg));
|
||||||
|
|
||||||
double bandwidth = totalBytes * 1.0 / time;
|
double bandwidth = totalBytes * 1.0 / time;
|
||||||
testOverview.setAvgBandwidth(df.format(bandwidth));
|
testOverview.setAvgBandwidth(decimalFormat.format(bandwidth));
|
||||||
|
|
||||||
return testOverview;
|
return testOverview;
|
||||||
}
|
}
|
||||||
|
@ -289,75 +316,96 @@ public class JtlResolver {
|
||||||
|
|
||||||
public static ChartsData getLoadChartData(String jtlString) {
|
public static ChartsData getLoadChartData(String jtlString) {
|
||||||
ChartsData data = new ChartsData();
|
ChartsData data = new ChartsData();
|
||||||
List<Metric> total = JtlResolver.resolver(jtlString);
|
List<Metric> totalMetricList = JtlResolver.resolver(jtlString);
|
||||||
|
|
||||||
List<String> users = new ArrayList<>();
|
List<String> users = new ArrayList<>();
|
||||||
List<String> hits = new ArrayList<>();
|
List<String> hits = new ArrayList<>();
|
||||||
List<String> erorrs = new ArrayList<>();
|
List<String> errors = new ArrayList<>();
|
||||||
List<String> timeList = new ArrayList<>();
|
List<String> timeList = new ArrayList<>();
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
Map<String, Object> resultMap = new HashMap<>(5);
|
||||||
|
|
||||||
// todo SimpleDateFormat
|
DecimalFormat decimalFormat = new DecimalFormat("0.0");
|
||||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
DecimalFormat df = new DecimalFormat("0.0");
|
|
||||||
|
|
||||||
total.sort(Comparator.comparing(metric -> Long.valueOf(metric.getTimestamp())));
|
if (totalMetricList != null) {
|
||||||
total.forEach(metric -> {
|
for (Metric metric : totalMetricList) {
|
||||||
metric.setTimestamp(stampToDate(metric.getTimestamp()));
|
metric.setTimestamp(stampToDate(metric.getTimestamp()));
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, List<Metric>> collect = total.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
|
||||||
List<Map.Entry<String, List<Metric>>> entries = new ArrayList<>(collect.entrySet());
|
|
||||||
Collections.sort(entries, new Comparator<Map.Entry<String, List<Metric>>>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Map.Entry<String, List<Metric>> t1, Map.Entry<String, List<Metric>> t2) {
|
|
||||||
Date date1 = null,date2 = null;
|
|
||||||
try {
|
|
||||||
date1 = simpleDateFormat.parse(t1.getKey());
|
|
||||||
date2 = simpleDateFormat.parse(t2.getKey());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return (int) (date1.getTime() - date2.getTime());
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
Map<String, List<Metric>> collect = Objects.requireNonNull(totalMetricList).stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||||
|
List<Map.Entry<String, List<Metric>>> entries = new ArrayList<>(collect.entrySet());
|
||||||
|
entries.sort(JtlResolver::sortByDate);
|
||||||
|
|
||||||
for (int i = 0; i < entries.size(); i++) {
|
for (Map.Entry<String, List<Metric>> entry : entries) {
|
||||||
int failSize = 0;
|
int failSize = 0;
|
||||||
Map.Entry<String, List<Metric>> map = entries.get(i);
|
List<Metric> metrics = entry.getValue();
|
||||||
List<Metric> metrics = map.getValue();
|
|
||||||
Map<String, List<Metric>> metricsMap = metrics.stream().collect(Collectors.groupingBy(Metric::getThreadName));
|
Map<String, List<Metric>> metricsMap = metrics.stream().collect(Collectors.groupingBy(Metric::getThreadName));
|
||||||
int maxUsers = metricsMap.size();
|
int maxUsers = metricsMap.size();
|
||||||
for (int j = 0; j < metrics.size(); j++) {
|
for (Metric metric : metrics) {
|
||||||
Metric metric = metrics.get(j);
|
String isSuccess = metric.getSuccess();
|
||||||
String success = metric.getSuccess();
|
if (!"true".equals(isSuccess)) {
|
||||||
if (!"true".equals(success)){
|
|
||||||
failSize++;
|
failSize++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// todo
|
// todo
|
||||||
timeList.add(map.getKey());
|
timeList.add(entry.getKey());
|
||||||
hits.add(df.format(metrics.size() * 1.0 / maxUsers));
|
hits.add(decimalFormat.format(metrics.size() * 1.0 / maxUsers));
|
||||||
users.add(String.valueOf(maxUsers));
|
users.add(String.valueOf(maxUsers));
|
||||||
erorrs.add(String.valueOf(failSize));
|
errors.add(String.valueOf(failSize));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resultMap.put("users", users);
|
resultMap.put("users", users);
|
||||||
resultMap.put("hits", hits);
|
resultMap.put("hits", hits);
|
||||||
resultMap.put("errors", erorrs);
|
resultMap.put("errors", errors);
|
||||||
|
|
||||||
JSONObject serices = new JSONObject(resultMap);
|
JSONObject serices = new JSONObject(resultMap);
|
||||||
data.setxAxis(StringUtils.join(",", timeList));
|
data.setxAxis(StringUtils.join(",", timeList));
|
||||||
data.setSerices(serices.toString());
|
data.setSerices(serices.toString());
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String stampToDate(String s){
|
public static ChartsData getResponseTimeChartData(String jtlString) {
|
||||||
String res;
|
ChartsData chartsData = new ChartsData();
|
||||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
List<Metric> totalMetricList = JtlResolver.resolver(jtlString);
|
||||||
|
|
||||||
|
totalMetricList.forEach(metric -> {
|
||||||
|
metric.setTimestamp(stampToDate(metric.getTimestamp()));
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, List<Metric>> metricMap = totalMetricList.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||||
|
List<Map.Entry<String, List<Metric>>> entries = new ArrayList<>(metricMap.entrySet());
|
||||||
|
entries.sort(JtlResolver::sortByDate);
|
||||||
|
|
||||||
|
List<String> resTimeList = new ArrayList<>();
|
||||||
|
List<String> timestampList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<Metric>> entry : entries) {
|
||||||
|
List<Metric> metricList = entry.getValue();
|
||||||
|
int sumElapsedTime = metricList.stream().mapToInt(metric -> Integer.parseInt(metric.getElapsed())).sum();
|
||||||
|
timestampList.add(entry.getKey());
|
||||||
|
resTimeList.add(String.valueOf(sumElapsedTime / metricList.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
chartsData.setxAxis(StringUtils.join(",", timestampList));
|
||||||
|
chartsData.setSerices(StringUtils.join(",", resTimeList));
|
||||||
|
return chartsData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String stampToDate(String s) {
|
||||||
long lt = Long.parseLong(s);
|
long lt = Long.parseLong(s);
|
||||||
Date date = new Date(lt);
|
Date date = new Date(lt);
|
||||||
res = simpleDateFormat.format(date);
|
return simpleDateFormat.format(date);
|
||||||
return res;
|
}
|
||||||
|
|
||||||
|
private static int sortByDate(Map.Entry<String, List<Metric>> map1, Map.Entry<String, List<Metric>> map2) {
|
||||||
|
Date date1 = null, date2 = null;
|
||||||
|
try {
|
||||||
|
date1 = simpleDateFormat.parse(map1.getKey());
|
||||||
|
date2 = simpleDateFormat.parse(map2.getKey());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return (int) (Objects.requireNonNull(date1).getTime() - Objects.requireNonNull(date2).getTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import io.metersphere.base.domain.LoadTestReportExample;
|
||||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
||||||
|
import io.metersphere.commons.constants.TestStatus;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.controller.request.ReportRequest;
|
import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
|
@ -52,6 +53,7 @@ public class ReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestStatisticsDTO getReport(String id) {
|
public RequestStatisticsDTO getReport(String id) {
|
||||||
|
checkReportStatus(id);
|
||||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
String content = loadTestReport.getContent();
|
String content = loadTestReport.getContent();
|
||||||
RequestStatisticsDTO requestStatistics = JtlResolver.getRequestStatistics(content);
|
RequestStatisticsDTO requestStatistics = JtlResolver.getRequestStatistics(content);
|
||||||
|
@ -59,6 +61,7 @@ public class ReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Errors> getReportErrors(String id) {
|
public List<Errors> getReportErrors(String id) {
|
||||||
|
checkReportStatus(id);
|
||||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
String content = loadTestReport.getContent();
|
String content = loadTestReport.getContent();
|
||||||
List<Errors> errors = JtlResolver.getErrorsList(content);
|
List<Errors> errors = JtlResolver.getErrorsList(content);
|
||||||
|
@ -66,6 +69,7 @@ public class ReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorsTop5DTO getReportErrorsTOP5(String id) {
|
public ErrorsTop5DTO getReportErrorsTOP5(String id) {
|
||||||
|
checkReportStatus(id);
|
||||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
String content = loadTestReport.getContent();
|
String content = loadTestReport.getContent();
|
||||||
ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content);
|
ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content);
|
||||||
|
@ -73,6 +77,7 @@ public class ReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestOverview getTestOverview(String id) {
|
public TestOverview getTestOverview(String id) {
|
||||||
|
checkReportStatus(id);
|
||||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
String content = loadTestReport.getContent();
|
String content = loadTestReport.getContent();
|
||||||
TestOverview testOverview = JtlResolver.getTestOverview(content);
|
TestOverview testOverview = JtlResolver.getTestOverview(content);
|
||||||
|
@ -80,19 +85,30 @@ public class ReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChartsData getLoadChartData(String id) {
|
public ChartsData getLoadChartData(String id) {
|
||||||
|
checkReportStatus(id);
|
||||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
String content = loadTestReport.getContent();
|
String content = loadTestReport.getContent();
|
||||||
ChartsData chartsData = JtlResolver.getLoadChartData(content);
|
ChartsData chartsData = JtlResolver.getLoadChartData(content);
|
||||||
return chartsData;
|
return chartsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void checkReportStatus(String id) {
|
public ChartsData getResponseTimeChartData(String id) {
|
||||||
// LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
checkReportStatus(id);
|
||||||
// String status=loadTestReport.getStatus();
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
// if (StringUtils.equals("Error",status)) {
|
String content = loadTestReport.getContent();
|
||||||
// MSException.throwException("test run error!");
|
ChartsData chartsData = JtlResolver.getResponseTimeChartData(content);
|
||||||
// }
|
return chartsData;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
public void checkReportStatus(String reportId) {
|
||||||
|
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||||
|
String reportStatus = loadTestReport.getStatus();
|
||||||
|
if (StringUtils.equals(TestStatus.Running.name(), reportStatus)) {
|
||||||
|
MSException.throwException("Reporting in progress...");
|
||||||
|
} else if (StringUtils.equals(TestStatus.Error.name(), reportStatus)) {
|
||||||
|
MSException.throwException("Report generation error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public LoadTestReport getLoadTestReport(String id) {
|
public LoadTestReport getLoadTestReport(String id) {
|
||||||
return extLoadTestReportMapper.selectByPrimaryKey(id);
|
return extLoadTestReportMapper.selectByPrimaryKey(id);
|
||||||
|
|
|
@ -129,7 +129,21 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableData: [{},{},{},{},{}],
|
tableData: [{},{},{},{},{}],
|
||||||
errorTotal: {},
|
errorTotal: {
|
||||||
|
label: '',
|
||||||
|
totalSamples: '',
|
||||||
|
totalErrors: '',
|
||||||
|
error1: '',
|
||||||
|
error1Size: '',
|
||||||
|
error2: '',
|
||||||
|
error2Size: '',
|
||||||
|
error3: '',
|
||||||
|
error3Size: '',
|
||||||
|
error4: '',
|
||||||
|
error4Size: '',
|
||||||
|
error5: '',
|
||||||
|
error5Size: ''
|
||||||
|
},
|
||||||
errorTop5: []
|
errorTop5: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -80,7 +80,19 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableData: [{},{},{},{},{}],
|
tableData: [{},{},{},{},{}],
|
||||||
totalInfo: {}
|
totalInfo: {
|
||||||
|
totalLabel: '',
|
||||||
|
totalSamples: '',
|
||||||
|
totalErrors: '',
|
||||||
|
totalAverage: '',
|
||||||
|
totalMin: '',
|
||||||
|
totalMax: '',
|
||||||
|
totalTP90: '',
|
||||||
|
totalTP95: '',
|
||||||
|
totalTP99: '',
|
||||||
|
totalAvgHits: '',
|
||||||
|
totalAvgBandwidth: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -22,11 +22,6 @@
|
||||||
width="150"
|
width="150"
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
|
||||||
prop="description"
|
|
||||||
:label="$t('commons.description')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="projectName"
|
prop="projectName"
|
||||||
:label="$t('load_test.project_name')"
|
:label="$t('load_test.project_name')"
|
||||||
|
@ -47,6 +42,29 @@
|
||||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:label="$t('commons.status')">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag size="mini" type="primary" v-if="row.status === 'Starting'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="success" v-else-if="row.status === 'Running'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tooltip placement="top" v-else-if="row.status === 'Error'" effect="light">
|
||||||
|
<template v-slot:content>
|
||||||
|
<div>{{row.description}}</div>
|
||||||
|
</template>
|
||||||
|
<el-tag size="mini" type="danger">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tag size="mini" type="info" v-else>
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
width="150"
|
width="150"
|
||||||
:label="$t('commons.operating')">
|
:label="$t('commons.operating')">
|
||||||
|
|
Loading…
Reference in New Issue