You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2020/04/26 12:55:46 UTC
[jmeter] branch master updated: Add a 'Median' field to the
dashboard and make the response time percentile fields support
floating-point numbers (#567)
This is an automated email from the ASF dual-hosted git repository.
pmouawad pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
The following commit(s) were added to refs/heads/master by this push:
new 9a8ca62 Add a 'Median' field to the dashboard and make the response time percentile fields support floating-point numbers (#567)
9a8ca62 is described below
commit 9a8ca629dec1bf70444161988481399332434173
Author: Keith Mo <ke...@gmail.com>
AuthorDate: Sun Apr 26 20:55:36 2020 +0800
Add a 'Median' field to the dashboard and make the response time percentile fields support floating-point numbers (#567)
* add median field and fix percentiles
* fix imports
* fix style
Contributed by Keith Mo keithmork
---
bin/report-template/content/js/dashboard.js.fmkr | 14 ++++---
.../jmeter/report/dashboard/JsonExporter.java | 13 ++++---
.../jmeter/report/dashboard/SamplingStatistic.java | 15 ++++++++
.../processor/StatisticsSummaryConsumer.java | 40 +++++++++++---------
.../report/processor/StatisticsSummaryData.java | 13 ++++++-
...sponseTimePercentilesOverTimeGraphConsumer.java | 43 ++++++++++++++--------
.../java/org/apache/jmeter/util/JMeterUtils.java | 18 +++++++++
.../apache/jmeter/resources/messages.properties | 3 +-
.../apache/jmeter/resources/messages_fr.properties | 3 +-
...TimePercentilesOverTimeGraphConsumerSpec.groovy | 3 +-
.../apache/jmeter/gui/report/HTMLReportExpect.json | 3 ++
11 files changed, 118 insertions(+), 50 deletions(-)
diff --git a/bin/report-template/content/js/dashboard.js.fmkr b/bin/report-template/content/js/dashboard.js.fmkr
index 94cd0f2..31836ad 100644
--- a/bin/report-template/content/js/dashboard.js.fmkr
+++ b/bin/report-template/content/js/dashboard.js.fmkr
@@ -40,7 +40,7 @@ function summaryTableHeader(header) {
cell = document.createElement('th');
cell.setAttribute("data-sorter", false);
- cell.colSpan = 6;
+ cell.colSpan = 7;
cell.innerHTML = "Response Times (ms)";
newRow.appendChild(cell);
@@ -197,16 +197,18 @@ $(document).ready(function() {
case 4:
// Mean
case 7:
- // Percentile 1
+ // Median
case 8:
- // Percentile 2
+ // Percentile 1
case 9:
- // Percentile 3
+ // Percentile 2
case 10:
- // Throughput
+ // Percentile 3
case 11:
- // Kbytes/s
+ // Throughput
case 12:
+ // Kbytes/s
+ case 13:
// Sent Kbytes/s
item = item.toFixed(2);
break;
diff --git a/src/core/src/main/java/org/apache/jmeter/report/dashboard/JsonExporter.java b/src/core/src/main/java/org/apache/jmeter/report/dashboard/JsonExporter.java
index d93b25b..8fffcec 100644
--- a/src/core/src/main/java/org/apache/jmeter/report/dashboard/JsonExporter.java
+++ b/src/core/src/main/java/org/apache/jmeter/report/dashboard/JsonExporter.java
@@ -125,12 +125,13 @@ public class JsonExporter extends AbstractDataExporter {
statistic.setMeanResTime((Double) ((ValueResultData)listResultData.get(4)).getValue());
statistic.setMinResTime((Long) ((ValueResultData)listResultData.get(5)).getValue());
statistic.setMaxResTime((Long) ((ValueResultData)listResultData.get(6)).getValue());
- statistic.setPct1ResTime((Double) ((ValueResultData)listResultData.get(7)).getValue());
- statistic.setPct2ResTime((Double) ((ValueResultData)listResultData.get(8)).getValue());
- statistic.setPct3ResTime((Double) ((ValueResultData)listResultData.get(9)).getValue());
- statistic.setThroughput((Double) ((ValueResultData)listResultData.get(10)).getValue());
- statistic.setReceivedKBytesPerSec((Double) ((ValueResultData)listResultData.get(11)).getValue());
- statistic.setSentKBytesPerSec((Double) ((ValueResultData)listResultData.get(12)).getValue());
+ statistic.setMedianResTime((Double) ((ValueResultData)listResultData.get(7)).getValue());
+ statistic.setPct1ResTime((Double) ((ValueResultData)listResultData.get(8)).getValue());
+ statistic.setPct2ResTime((Double) ((ValueResultData)listResultData.get(9)).getValue());
+ statistic.setPct3ResTime((Double) ((ValueResultData)listResultData.get(10)).getValue());
+ statistic.setThroughput((Double) ((ValueResultData)listResultData.get(11)).getValue());
+ statistic.setReceivedKBytesPerSec((Double) ((ValueResultData)listResultData.get(12)).getValue());
+ statistic.setSentKBytesPerSec((Double) ((ValueResultData)listResultData.get(13)).getValue());
statistics.put(statistic.getTransaction(), statistic);
}
}
diff --git a/src/core/src/main/java/org/apache/jmeter/report/dashboard/SamplingStatistic.java b/src/core/src/main/java/org/apache/jmeter/report/dashboard/SamplingStatistic.java
index ff4a77b..eb0d209 100644
--- a/src/core/src/main/java/org/apache/jmeter/report/dashboard/SamplingStatistic.java
+++ b/src/core/src/main/java/org/apache/jmeter/report/dashboard/SamplingStatistic.java
@@ -28,6 +28,7 @@ public class SamplingStatistic {
private long errorCount;
private float errorPct;
private double meanResTime;
+ private double medianResTime;
private double minResTime;
private double maxResTime;
private double pct1ResTime;
@@ -112,6 +113,20 @@ public class SamplingStatistic {
}
/**
+ * @return medianResTime
+ */
+ public double getMedianResTime() {
+ return medianResTime;
+ }
+
+ /**
+ * @param medianResTime the meanResTime to set
+ */
+ public void setMedianResTime(double medianResTime) {
+ this.medianResTime = medianResTime;
+ }
+
+ /**
* @return the minResTime
*/
public double getMinResTime() {
diff --git a/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryConsumer.java b/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryConsumer.java
index 1ea06ba..2223bd8 100644
--- a/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryConsumer.java
+++ b/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryConsumer.java
@@ -17,6 +17,8 @@
package org.apache.jmeter.report.processor;
+import java.math.BigDecimal;
+
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.util.JMeterUtils;
@@ -27,6 +29,7 @@ import org.apache.jmeter.util.JMeterUtils;
* <li>errors</li>
* <li>error %</li>
* <li>mean response time</li>
+ * <li>median response time</li>
* <li>percentile 1 (90% by default)</li>
* <li>percentile 2 (95% by default)</li>
* <li>percentile 3 (99% by default)</li>
@@ -41,13 +44,16 @@ import org.apache.jmeter.util.JMeterUtils;
*/
public class StatisticsSummaryConsumer extends
AbstractSummaryConsumer<StatisticsSummaryData> {
+ private static final String PCT1_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct1", "90");
+ private static final String PCT2_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct2", "95");
+ private static final String PCT3_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct3", "99");
- private static final int PERCENTILE_INDEX1 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct1", 90);
- private static final int PERCENTILE_INDEX2 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct2", 95);
- private static final int PERCENTILE_INDEX3 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct3", 99);
+ private static final double PERCENTILE_INDEX1 = new BigDecimal(PCT1_LABEL).doubleValue();
+ private static final double PERCENTILE_INDEX2 = new BigDecimal(PCT2_LABEL).doubleValue();
+ private static final double PERCENTILE_INDEX3 = new BigDecimal(PCT3_LABEL).doubleValue();
/**
* Instantiates a new statistics summary consumer.
@@ -79,6 +85,7 @@ public class StatisticsSummaryConsumer extends
data.getPercentile2().addValue(elapsedTime);
data.getPercentile3().addValue(elapsedTime);
data.getMean().addValue(elapsedTime);
+ data.getMedian().addValue(elapsedTime);
data.setMin(elapsedTime);
data.setMax(elapsedTime);
@@ -139,6 +146,7 @@ public class StatisticsSummaryConsumer extends
result.addResult(new ValueResultData(data.getMean().getResult()));
result.addResult(new ValueResultData(data.getMin()));
result.addResult(new ValueResultData(data.getMax()));
+ result.addResult(new ValueResultData(data.getMedian().getResult()));
result.addResult(new ValueResultData(data.getPercentile1().getResult()));
result.addResult(new ValueResultData(data.getPercentile2().getResult()));
result.addResult(new ValueResultData(data.getPercentile3().getResult()));
@@ -182,18 +190,10 @@ public class StatisticsSummaryConsumer extends
JMeterUtils.getResString("reportgenerator_summary_statistics_mean")));
titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_min")));
titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_max")));
- titles.addResult(new ValueResultData(
- String.format(
- JMeterUtils.getResString("reportgenerator_summary_statistics_percentile_fmt"),
- PERCENTILE_INDEX1)));
- titles.addResult(new ValueResultData(
- String.format(
- JMeterUtils.getResString("reportgenerator_summary_statistics_percentile_fmt"),
- PERCENTILE_INDEX2)));
- titles.addResult(new ValueResultData(
- String.format(
- JMeterUtils.getResString("reportgenerator_summary_statistics_percentile_fmt"),
- PERCENTILE_INDEX3)));
+ titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_median")));
+ titles.addResult(new ValueResultData(formatPercentile(PCT1_LABEL)));
+ titles.addResult(new ValueResultData(formatPercentile(PCT2_LABEL)));
+ titles.addResult(new ValueResultData(formatPercentile(PCT3_LABEL)));
titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_throughput")));
titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_kbytes")));
titles.addResult(new ValueResultData(JMeterUtils.getResString("reportgenerator_summary_statistics_sent_kbytes")));
@@ -201,4 +201,8 @@ public class StatisticsSummaryConsumer extends
return titles;
}
+ private String formatPercentile(String percentileLabel) {
+ return String.format(JMeterUtils.getResString("reportgenerator_summary_statistics_percentile_fmt"),
+ percentileLabel);
+ }
}
diff --git a/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryData.java b/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryData.java
index ca95a49..a217c37 100644
--- a/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryData.java
+++ b/src/core/src/main/java/org/apache/jmeter/report/processor/StatisticsSummaryData.java
@@ -33,6 +33,7 @@ public class StatisticsSummaryData {
private long errors = 0L;
private long total = 0L;
private final MeanAggregator mean;
+ private final PercentileAggregator median;
private final PercentileAggregator percentile1;
private final PercentileAggregator percentile2;
private final PercentileAggregator percentile3;
@@ -191,12 +192,13 @@ public class StatisticsSummaryData {
* @param percentileIndex2 value of second percentile
* @param percentileIndex3 value of third percentile
*/
- public StatisticsSummaryData(long percentileIndex1, long percentileIndex2,
- long percentileIndex3) {
+ public StatisticsSummaryData(double percentileIndex1, double percentileIndex2,
+ double percentileIndex3) {
percentile1 = new PercentileAggregator(percentileIndex1);
percentile2 = new PercentileAggregator(percentileIndex2);
percentile3 = new PercentileAggregator(percentileIndex3);
mean = new MeanAggregator();
+ median = new PercentileAggregator(50);
}
/**
@@ -260,6 +262,13 @@ public class StatisticsSummaryData {
}
/**
+ * @return the median response times
+ */
+ public PercentileAggregator getMedian() {
+ return median;
+ }
+
+ /**
* @return the sentBytes
*/
public long getSentBytes() {
diff --git a/src/core/src/main/java/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumer.java b/src/core/src/main/java/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumer.java
index c8a3d91..2598292 100644
--- a/src/core/src/main/java/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumer.java
+++ b/src/core/src/main/java/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumer.java
@@ -17,11 +17,14 @@
package org.apache.jmeter.report.processor.graph.impl;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import org.apache.jmeter.report.processor.AggregatorFactory;
import org.apache.jmeter.report.processor.MaxAggregatorFactory;
+import org.apache.jmeter.report.processor.MedianAggregatorFactory;
import org.apache.jmeter.report.processor.MinAggregatorFactory;
import org.apache.jmeter.report.processor.PercentileAggregatorFactory;
import org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer;
@@ -40,14 +43,14 @@ import org.apache.jmeter.util.JMeterUtils;
*/
public class ResponseTimePercentilesOverTimeGraphConsumer
extends AbstractOverTimeGraphConsumer {
- private static final int PERCENTILE_INDEX1 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct1", 90);
- private static final int PERCENTILE_INDEX2 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct2", 95);
- private static final int PERCENTILE_INDEX3 = JMeterUtils.getPropDefault(
- "aggregate_rpt_pct3", 99);
+ private static final String PCT1_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct1", "90");
+ private static final String PCT2_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct2", "95");
+ private static final String PCT3_LABEL = JMeterUtils.getPropDefault(
+ "aggregate_rpt_pct3", "99");
- private static final String PERCENTILE_FORMAT = "%dth percentile";
+ private static final String PERCENTILE_FORMAT = "%sth percentile";
@Override
protected TimeStampKeysSelector createTimeStampKeysSelector() {
@@ -62,18 +65,19 @@ public class ResponseTimePercentilesOverTimeGraphConsumer
groupInfos.put("aggregate_report_min", createMinGroupInfo());
groupInfos.put("aggregate_report_max", createMaxGroupInfo());
+ groupInfos.put("aggregate_report_median", createMedianGroupInfo());
groupInfos.put("aggregate_rpt_pct1",
- createPercentileGroupInfo("aggregate_rpt_pct1", PERCENTILE_INDEX1));
+ createPercentileGroupInfo("aggregate_rpt_pct1", PCT1_LABEL));
groupInfos.put("aggregate_rpt_pct2",
- createPercentileGroupInfo("aggregate_rpt_pct2", PERCENTILE_INDEX2));
+ createPercentileGroupInfo("aggregate_rpt_pct2", PCT2_LABEL));
groupInfos.put("aggregate_rpt_pct3",
- createPercentileGroupInfo("aggregate_rpt_pct3", PERCENTILE_INDEX3));
+ createPercentileGroupInfo("aggregate_rpt_pct3", PCT3_LABEL));
return groupInfos;
}
- private String formatPercentile(int percentile) {
- return String.format(PERCENTILE_FORMAT, percentile);
+ private String formatPercentile(String percentileLabel) {
+ return String.format(PERCENTILE_FORMAT, percentileLabel);
}
private GroupInfo createMinGroupInfo() {
@@ -88,10 +92,19 @@ public class ResponseTimePercentilesOverTimeGraphConsumer
return createGroupInfo(new MaxAggregatorFactory(), seriesSelector);
}
- private GroupInfo createPercentileGroupInfo(String propKey, int defaultValue) {
- String seriesName = formatPercentile(defaultValue);
+ private GroupInfo createMedianGroupInfo() {
+ StaticSeriesSelector seriesSelector = new StaticSeriesSelector();
+ seriesSelector.setSeriesName("Median");
+ return createGroupInfo(new MedianAggregatorFactory(), seriesSelector);
+ }
+
+ private GroupInfo createPercentileGroupInfo(String propKey, String label) {
+ String seriesName = formatPercentile(label);
+ double defaultValue = new BigDecimal(label)
+ .divide(new BigDecimal("100"), 6, RoundingMode.CEILING)
+ .doubleValue();
- int property = JMeterUtils.getPropDefault(propKey, defaultValue);
+ double property = JMeterUtils.getPropDefault(propKey, defaultValue);
PercentileAggregatorFactory factory = new PercentileAggregatorFactory();
factory.setPercentileIndex(property);
StaticSeriesSelector seriesSelector = new StaticSeriesSelector();
diff --git a/src/core/src/main/java/org/apache/jmeter/util/JMeterUtils.java b/src/core/src/main/java/org/apache/jmeter/util/JMeterUtils.java
index fc9d021..2f6360a 100644
--- a/src/core/src/main/java/org/apache/jmeter/util/JMeterUtils.java
+++ b/src/core/src/main/java/org/apache/jmeter/util/JMeterUtils.java
@@ -765,6 +765,24 @@ public class JMeterUtils implements UnitTestManager {
}
/**
+ * Get a double value with default if not present.
+ *
+ * @param propName
+ * the name of the property.
+ * @param defaultVal
+ * the default value.
+ * @return The PropDefault value
+ */
+ public static double getPropDefault(String propName, double defaultVal) {
+ try {
+ return Float.parseFloat(appProperties.getProperty(propName, Double.toString(defaultVal)).trim());
+ } catch (Exception e) {
+ log.warn("Exception '{}' occurred when fetching double property:'{}', defaulting to: {}", e.getMessage(), propName, defaultVal);
+ }
+ return defaultVal;
+ }
+
+ /**
* Get a String value with default if not present.
*
* @param propName
diff --git a/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties b/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
index feccfc7..1489b45 100644
--- a/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
+++ b/src/core/src/main/resources/org/apache/jmeter/resources/messages.properties
@@ -974,8 +974,9 @@ reportgenerator_summary_statistics_sent_kbytes=Sent
reportgenerator_summary_statistics_label=Label
reportgenerator_summary_statistics_max=Max
reportgenerator_summary_statistics_mean=Average
+reportgenerator_summary_statistics_median=Median
reportgenerator_summary_statistics_min=Min
-reportgenerator_summary_statistics_percentile_fmt=%dth pct
+reportgenerator_summary_statistics_percentile_fmt=%sth pct
reportgenerator_summary_statistics_throughput=Transactions/s
reportgenerator_summary_total=Total
request_data=Request Data
diff --git a/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties b/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
index 5dab3c4..9e04a2d 100644
--- a/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
+++ b/src/core/src/main/resources/org/apache/jmeter/resources/messages_fr.properties
@@ -957,8 +957,9 @@ reportgenerator_summary_statistics_kbytes=Reçues
reportgenerator_summary_statistics_label=Libellé
reportgenerator_summary_statistics_max=Max
reportgenerator_summary_statistics_mean=Temps moyen
+reportgenerator_summary_statistics_median=Médiane
reportgenerator_summary_statistics_min=Min
-reportgenerator_summary_statistics_percentile_fmt=%d%% centile
+reportgenerator_summary_statistics_percentile_fmt=%s%% centile
reportgenerator_summary_statistics_sent_kbytes=Envoyés
reportgenerator_summary_statistics_throughput=Débit
reportgenerator_summary_total=Total
diff --git a/src/core/src/test/groovy/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumerSpec.groovy b/src/core/src/test/groovy/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumerSpec.groovy
index 9ea7f08..2036bf0 100644
--- a/src/core/src/test/groovy/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumerSpec.groovy
+++ b/src/core/src/test/groovy/org/apache/jmeter/report/processor/graph/impl/ResponseTimePercentilesOverTimeGraphConsumerSpec.groovy
@@ -28,7 +28,8 @@ class ResponseTimePercentilesOverTimeGraphConsumerSpec extends JMeterSpec {
'aggregate_report_max',
'aggregate_rpt_pct1',
'aggregate_rpt_pct2',
- 'aggregate_rpt_pct3'] as Set
+ 'aggregate_rpt_pct3',
+ 'aggregate_report_median'] as Set
def sut = new ResponseTimePercentilesOverTimeGraphConsumer()
diff --git a/src/dist-check/src/test/resources/org/apache/jmeter/gui/report/HTMLReportExpect.json b/src/dist-check/src/test/resources/org/apache/jmeter/gui/report/HTMLReportExpect.json
index c0421e5..25505fb 100644
--- a/src/dist-check/src/test/resources/org/apache/jmeter/gui/report/HTMLReportExpect.json
+++ b/src/dist-check/src/test/resources/org/apache/jmeter/gui/report/HTMLReportExpect.json
@@ -5,6 +5,7 @@
"errorCount" : 3,
"errorPct" : 100.0,
"meanResTime" : 199.66666666666666,
+ "medianResTime":170.0,
"minResTime" : 100.0,
"maxResTime" : 329.0,
"pct1ResTime" : 329.0,
@@ -20,6 +21,7 @@
"errorCount" : 3,
"errorPct" : 1.1764706,
"meanResTime" : 235.47450980392148,
+ "medianResTime":232.0,
"minResTime" : 100.0,
"maxResTime" : 353.0,
"pct1ResTime" : 337.0,
@@ -35,6 +37,7 @@
"errorCount" : 0,
"errorPct" : 0.0,
"meanResTime" : 235.90079365079367,
+ "medianResTime":232.0,
"minResTime" : 101.0,
"maxResTime" : 353.0,
"pct1ResTime" : 337.0,