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 2017/03/28 18:59:34 UTC
svn commit: r1789193 - in /jmeter/trunk: bin/
src/core/org/apache/jmeter/report/config/
src/core/org/apache/jmeter/report/dashboard/ test/resources/
test/src/org/apache/jmeter/report/dashboard/ xdocs/ xdocs/usermanual/
Author: pmouawad
Date: Tue Mar 28 18:59:34 2017
New Revision: 1789193
URL: http://svn.apache.org/viewvc?rev=1789193&view=rev
Log:
Bug 60112 - Report / Dashboard : Add ability to customize APDEX thresholds per Transaction name
Contributed by Stephane Leplus
This closes #287
Bugzilla Id: 60112
Added:
jmeter/trunk/test/resources/reportgenerator_test.properties (with props)
jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/
jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java (with props)
Modified:
jmeter/trunk/bin/reportgenerator.properties
jmeter/trunk/src/core/org/apache/jmeter/report/config/ReportGeneratorConfiguration.java
jmeter/trunk/src/core/org/apache/jmeter/report/dashboard/ReportGenerator.java
jmeter/trunk/xdocs/changes.xml
jmeter/trunk/xdocs/usermanual/generating-dashboard.xml
Modified: jmeter/trunk/bin/reportgenerator.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/reportgenerator.properties?rev=1789193&r1=1789192&r2=1789193&view=diff
==============================================================================
--- jmeter/trunk/bin/reportgenerator.properties (original)
+++ jmeter/trunk/bin/reportgenerator.properties Tue Mar 28 18:59:34 2017
@@ -38,6 +38,16 @@
# Sets the tolerance threshold for the APDEX calculation (in milliseconds).
#jmeter.reportgenerator.apdex_tolerated_threshold=1500
+# Sets satisfaction and tolerance threshold to specific samples.
+# Use sample names or regular expression.
+# Format is : sample_name:satisfaction|tolerance[;]
+# Notice the colon between sample name and values, the pipe between thresholds and the
+# semicolon at the end to separate different samples. Don't forget to escape after
+# semicolon to span multiple lines. Ex :
+#jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000,\
+# samples12:3000|4000;\
+# scenar01-12:5000|6000
+
# Regular Expression which Indicates which samples to keep for graphs and statistics generation.
# Empty value means no filtering
#jmeter.reportgenerator.sample_filter=
Modified: jmeter/trunk/src/core/org/apache/jmeter/report/config/ReportGeneratorConfiguration.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/report/config/ReportGeneratorConfiguration.java?rev=1789193&r1=1789192&r2=1789193&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/report/config/ReportGeneratorConfiguration.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/report/config/ReportGeneratorConfiguration.java Tue Mar 28 18:59:34 2017
@@ -15,6 +15,7 @@
* limitations under the License.
*
*/
+
package org.apache.jmeter.report.config;
import java.io.File;
@@ -71,6 +72,10 @@ public class ReportGeneratorConfiguratio
private static final String REPORT_GENERATOR_KEY_APDEX_TOLERATED_THRESHOLD = REPORT_GENERATOR_KEY_PREFIX
+ KEY_DELIMITER + "apdex_tolerated_threshold";
private static final Long REPORT_GENERATOR_KEY_APDEX_TOLERATED_THRESHOLD_DEFAULT = Long.valueOf(1500L);
+
+ // Apdex per transaction Thresholds
+ private static final String REPORT_GENERATOR_KEY_APDEX_PER_TRANSACTION = REPORT_GENERATOR_KEY_PREFIX
+ + KEY_DELIMITER + "apdex_per_transaction";
// Exclude Transaction Controller from Top5 Errors by Sampler consumer
private static final String REPORT_GENERATOR_KEY_EXCLUDE_TC_FROM_TOP5_ERRORS_BY_SAMPLER = REPORT_GENERATOR_KEY_PREFIX
@@ -275,6 +280,7 @@ public class ReportGeneratorConfiguratio
private File tempDirectory;
private long apdexSatisfiedThreshold;
private long apdexToleratedThreshold;
+ private Map<String, Long[]> apdexPerTransaction = new HashMap<>();
private Pattern filteredSamplesPattern;
private boolean ignoreTCFromTop5ErrorsBySampler;
private Map<String, ExporterConfiguration> exportConfigurations = new HashMap<>();
@@ -355,6 +361,25 @@ public class ReportGeneratorConfiguratio
public final void setApdexToleratedThreshold(long apdexToleratedThreshold) {
this.apdexToleratedThreshold = apdexToleratedThreshold;
}
+
+ /**
+ * Gets the apdex per transaction map
+ *
+ * @return the apdex per transaction map
+ */
+ public Map<String, Long[]> getApdexPerTransaction() {
+ return apdexPerTransaction;
+ }
+
+ /**
+ * Sets the apdex per transaction map.
+ *
+ * @param apdexPerTransaction
+ * a map containing thresholds for one or more samples
+ */
+ public void setApdexPerTransaction(Map<String, Long[]> apdexPerTransaction) {
+ this.apdexPerTransaction = apdexPerTransaction;
+ }
/**
* Gets the export configurations.
@@ -612,6 +637,12 @@ public class ReportGeneratorConfiguratio
REPORT_GENERATOR_KEY_APDEX_TOLERATED_THRESHOLD_DEFAULT,
long.class).longValue();
configuration.setApdexToleratedThreshold(apdexToleratedThreshold);
+
+ // Load apdex per transactions, overriden by user
+ final String apdexPerTransaction = getOptionalProperty(props,
+ REPORT_GENERATOR_KEY_APDEX_PER_TRANSACTION,
+ String.class);
+ configuration.setApdexPerTransaction(getApdexPerTransactionParts(apdexPerTransaction));
final boolean ignoreTCFromTop5ErrorsBySampler = getRequiredProperty(
props,
@@ -689,6 +720,41 @@ public class ReportGeneratorConfiguratio
return configuration;
}
+
+ /**
+ * Parses a string coming from properties to fill a map containing
+ * sample names as keys and an array of 2 longs [satisfied, tolerated] as values.
+ * The sample name can be a regex supplied by the user.
+ * @param apdexPerTransaction, the string coming from properties
+ * @return {@link Map} containing for each sample name or sample name regex an array of Long corresponding to satisfied and tolerated apdex thresholds.
+ */
+ public static Map<String, Long[]> getApdexPerTransactionParts(String apdexPerTransaction) {
+ Map <String, Long[]> specificApdexes = new HashMap<>();
+ if (StringUtils.isEmpty(apdexPerTransaction) ||
+ apdexPerTransaction.trim().length()==0) {
+ log.info(
+ "apdex_per_transaction : {} is empty, not APDEX per transaction customization");
+ } else {
+ // data looks like : sample(\d+):1000|2000;samples12:3000|4000;scenar01-12:5000|6000
+ String[] parts = apdexPerTransaction.split("[;]");
+ for (String chunk : parts) {
+ int colonSeparator = chunk.lastIndexOf(":");
+ int pipeSeparator = chunk.lastIndexOf("|");
+ if (colonSeparator == -1 || pipeSeparator == -1 ||
+ pipeSeparator <= colonSeparator) {
+ log.error(
+ "error parsing property apdex_per_transaction around chunk {}. "
+ + "Wrong format, should have been: 'sample:satisfiedMs|toleratedMS', ignoring", chunk);
+ continue;
+ }
+ String key = chunk.substring(0, colonSeparator).trim();
+ Long satisfied = Long.valueOf(chunk.substring(colonSeparator + 1, pipeSeparator).trim());
+ Long tolerated = Long.valueOf(chunk.substring(pipeSeparator + 1).trim());
+ specificApdexes.put(key, new Long[] {satisfied, tolerated});
+ }
+ }
+ return specificApdexes;
+ }
/**
* @return the reportTitle
Modified: jmeter/trunk/src/core/org/apache/jmeter/report/dashboard/ReportGenerator.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/report/dashboard/ReportGenerator.java?rev=1789193&r1=1789192&r2=1789193&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/report/dashboard/ReportGenerator.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/report/dashboard/ReportGenerator.java Tue Mar 28 18:59:34 2017
@@ -57,6 +57,7 @@ import org.apache.jmeter.report.processo
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.util.JMeterUtils;
+import org.apache.oro.text.regex.PatternMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -432,10 +433,29 @@ public class ReportGenerator {
apdexSummaryConsumer.setHasOverallResult(true);
apdexSummaryConsumer.setThresholdSelector(sampleName -> {
ApdexThresholdsInfo info = new ApdexThresholdsInfo();
+ // set default values anyway for safety
info.setSatisfiedThreshold(configuration
.getApdexSatisfiedThreshold());
info.setToleratedThreshold(configuration
.getApdexToleratedThreshold());
+ // see if the sample name is in the special cases targeted
+ // by property jmeter.reportgenerator.apdex_per_transaction
+ // key in entry below can be a hardcoded name or a regex
+ for (Map.Entry<String, Long[]> entry : configuration.getApdexPerTransaction().entrySet()) {
+ org.apache.oro.text.regex.Pattern regex = JMeterUtils.getPatternCache().getPattern(entry.getKey());
+ PatternMatcher matcher = JMeterUtils.getMatcher();
+ if (matcher.matches(sampleName, regex)) {
+ Long satisfied = entry.getValue()[0];
+ Long tolerated = entry.getValue()[1];
+ if(log.isDebugEnabled()) {
+ log.debug("Found match for sampleName:{}, Regex:{}, satisfied value:{}, tolerated value:{}",
+ entry.getKey(), satisfied, tolerated);
+ }
+ info.setSatisfiedThreshold(satisfied);
+ info.setToleratedThreshold(tolerated);
+ break;
+ }
+ }
return info;
});
return apdexSummaryConsumer;
Added: jmeter/trunk/test/resources/reportgenerator_test.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/reportgenerator_test.properties?rev=1789193&view=auto
==============================================================================
--- jmeter/trunk/test/resources/reportgenerator_test.properties (added)
+++ jmeter/trunk/test/resources/reportgenerator_test.properties Tue Mar 28 18:59:34 2017
@@ -0,0 +1,144 @@
+################################################################################
+# Apache JMeter Property file for Report Generator
+################################################################################
+
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+
+################################################################################
+#
+# THIS FILE SHOULD NOT BE MODIFIED
+#
+# This avoids having to re-apply the modifications when upgrading JMeter
+# Instead only user.properties should be modified:
+# 1/ copy the property you want to modify to user.properties from here
+# 2/ Change its value there
+#
+################################################################################
+
+#---------------------------------------------------------------------------
+# Reporting configuration
+#---------------------------------------------------------------------------
+
+# Sets the satisfaction threshold for the APDEX calculation (in milliseconds).
+#jmeter.reportgenerator.apdex_satisfied_threshold=500
+
+# Sets the tolerance threshold for the APDEX calculation (in milliseconds).
+#jmeter.reportgenerator.apdex_tolerated_threshold=1500
+
+# Regular Expression which Indicates which samples to keep for graphs and statistics generation.
+# Empty value means no filtering
+#jmeter.reportgenerator.sample_filter=
+
+# Sets the temporary directory used by the generation process if it needs file I/O operations.
+#jmeter.reportgenerator.temp_dir=temp
+
+# Sets the size of the sliding window used by percentile evaluation.
+# Caution : higher value provides a better accuracy but needs more memory.
+#jmeter.reportgenerator.statistic_window = 200000
+
+# Configure this property to change the report title
+#jmeter.reportgenerator.report_title=Apache JMeter Dashboard
+
+# Defines the overall granularity for over time graphs
+jmeter.reportgenerator.overall_granularity=60000
+
+# Response Time Percentiles graph definition
+jmeter.reportgenerator.graph.responseTimePercentiles.classname=org.apache.jmeter.report.processor.graph.impl.ResponseTimePercentilesGraphConsumer
+jmeter.reportgenerator.graph.responseTimePercentiles.title=Response Time Percentiles
+
+# Response Time Distribution graph definition
+jmeter.reportgenerator.graph.responseTimeDistribution.classname=org.apache.jmeter.report.processor.graph.impl.ResponseTimeDistributionGraphConsumer
+jmeter.reportgenerator.graph.responseTimeDistribution.title=Response Time Distribution
+jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity=500
+
+# Active Threads Over Time graph definition
+jmeter.reportgenerator.graph.activeThreadsOverTime.classname=org.apache.jmeter.report.processor.graph.impl.ActiveThreadsGraphConsumer
+jmeter.reportgenerator.graph.activeThreadsOverTime.title=Active Threads Over Time
+jmeter.reportgenerator.graph.activeThreadsOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Time VS Threads graph definition
+jmeter.reportgenerator.graph.timeVsThreads.classname=org.apache.jmeter.report.processor.graph.impl.TimeVSThreadGraphConsumer
+jmeter.reportgenerator.graph.timeVsThreads.title=Time VS Threads
+
+# Bytes Throughput Over Time graph definition
+jmeter.reportgenerator.graph.bytesThroughputOverTime.classname=org.apache.jmeter.report.processor.graph.impl.BytesThroughputGraphConsumer
+jmeter.reportgenerator.graph.bytesThroughputOverTime.title=Bytes Throughput Over Time
+jmeter.reportgenerator.graph.bytesThroughputOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Response Time Over Time graph definition
+jmeter.reportgenerator.graph.responseTimesOverTime.classname=org.apache.jmeter.report.processor.graph.impl.ResponseTimeOverTimeGraphConsumer
+jmeter.reportgenerator.graph.responseTimesOverTime.title=Response Time Over Time
+jmeter.reportgenerator.graph.responseTimesOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Latencies Over Time graph definition
+jmeter.reportgenerator.graph.latenciesOverTime.classname=org.apache.jmeter.report.processor.graph.impl.LatencyOverTimeGraphConsumer
+jmeter.reportgenerator.graph.latenciesOverTime.title=Latencies Over Time
+jmeter.reportgenerator.graph.latenciesOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Response Time Vs Request graph definition
+jmeter.reportgenerator.graph.responseTimeVsRequest.classname=org.apache.jmeter.report.processor.graph.impl.ResponseTimeVSRequestGraphConsumer
+jmeter.reportgenerator.graph.responseTimeVsRequest.title=Response Time Vs Request
+jmeter.reportgenerator.graph.responseTimeVsRequest.exclude_controllers=true
+jmeter.reportgenerator.graph.responseTimeVsRequest.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Latencies Vs Request graph definition
+jmeter.reportgenerator.graph.latencyVsRequest.classname=org.apache.jmeter.report.processor.graph.impl.LatencyVSRequestGraphConsumer
+jmeter.reportgenerator.graph.latencyVsRequest.title=Latencies Vs Request
+jmeter.reportgenerator.graph.latencyVsRequest.exclude_controllers=true
+jmeter.reportgenerator.graph.latencyVsRequest.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Hits Per Second graph definition
+jmeter.reportgenerator.graph.hitsPerSecond.classname=org.apache.jmeter.report.processor.graph.impl.HitsPerSecondGraphConsumer
+jmeter.reportgenerator.graph.hitsPerSecond.title=Hits Per Second
+jmeter.reportgenerator.graph.hitsPerSecond.exclude_controllers=true
+jmeter.reportgenerator.graph.hitsPerSecond.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Codes Per Second graph definition
+jmeter.reportgenerator.graph.codesPerSecond.classname=org.apache.jmeter.report.processor.graph.impl.CodesPerSecondGraphConsumer
+jmeter.reportgenerator.graph.codesPerSecond.title=Codes Per Second
+jmeter.reportgenerator.graph.codesPerSecond.exclude_controllers=true
+jmeter.reportgenerator.graph.codesPerSecond.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# Transactions Per Second graph definition
+jmeter.reportgenerator.graph.transactionsPerSecond.classname=org.apache.jmeter.report.processor.graph.impl.TransactionsPerSecondGraphConsumer
+jmeter.reportgenerator.graph.transactionsPerSecond.title=Transactions Per Second
+jmeter.reportgenerator.graph.transactionsPerSecond.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
+
+# HTML Export
+jmeter.reportgenerator.exporter.html.classname=org.apache.jmeter.report.dashboard.HtmlTemplateExporter
+
+jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000;\
+ samples12:3000|4000;\
+ scenar01-12:5000|6000
+
+# Sets the source directory of templated files from which the html pages are generated.
+#jmeter.reportgenerator.exporter.html.property.template_dir=report-template
+
+# Sets the destination directory for generated html pages.
+# This will be overridden by the command line option -o
+#jmeter.reportgenerator.exporter.html.property.output_dir=report-output
+
+# Regular Expression which Indicates which graph series are filtered in display
+# Empty value means no filtering
+#jmeter.reportgenerator.exporter.html.series_filter=
+
+# Indicates whether series filter apply only on sample series or to all series
+# setting this to false can lead to empty graphs if series_filter does not
+# contain required series
+#jmeter.reportgenerator.exporter.html.filters_only_sample_series=true
+
+# Indicates whether only controller samples are displayed on graphs that support it.
+#jmeter.reportgenerator.exporter.html.show_controllers_only=false
Propchange: jmeter/trunk/test/resources/reportgenerator_test.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/test/resources/reportgenerator_test.properties
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java?rev=1789193&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java Tue Mar 28 18:59:34 2017
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.report.dashboard;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.jmeter.report.config.ReportGeneratorConfiguration;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.oro.text.regex.PatternMatcher;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jodd.props.Props;
+
+public class ApdexPerTransactionTest {
+
+ private static final Logger log = LoggerFactory.getLogger(ApdexPerTransactionTest.class);
+
+ // prop in the file mixes comma, semicolon and spans several lines.
+ // it also includes hardcoded sample names mixed with regexes
+ private static final String apdexString = "sample(\\d+):1000|2000;samples12:3000|4000;scenar01-12:5000|6000";
+
+ @Test
+ public void testgetApdexPerTransactionProperty() {
+ final Properties merged = new Properties();
+ final Props props = new Props();
+ final String REPORT_GENERATOR_KEY_PREFIX = "jmeter.reportgenerator";
+ final char KEY_DELIMITER = '.';
+ final String REPORT_GENERATOR_KEY_APDEX_PER_TRANSACTION = REPORT_GENERATOR_KEY_PREFIX
+ + KEY_DELIMITER + "apdex_per_transaction";
+
+ File rgp = new File("test/resources/", "reportgenerator_test.properties");
+ merged.putAll(loadProps(rgp));
+ props.load(merged);
+ final String apdexPerTransaction = getOptionalProperty(props,
+ REPORT_GENERATOR_KEY_APDEX_PER_TRANSACTION,
+ String.class);
+ assertEquals(apdexString, apdexPerTransaction);
+
+ }
+
+ @Test
+ public void testGetApdexPerTransactionParts() {
+ Map<String, Long[]> apdex = ReportGeneratorConfiguration.getApdexPerTransactionParts(apdexString);
+ assertNotNull("map should not be null", apdex);
+ assertEquals(3, apdex.size());
+ Set<String> keys = apdex.keySet();
+ assertTrue(keys.contains("samples12"));
+ assertTrue(keys.contains("scenar01-12"));
+ assertTrue(keys.contains("sample(\\d+)"));
+ assertArrayEquals(new Long[] {1000L, 2000L}, apdex.get("sample(\\d+)"));
+ }
+
+ @Test
+ public void testGetApdexPerTransactionPartsOneCustomization() {
+ Map<String, Long[]> apdex = ReportGeneratorConfiguration.getApdexPerTransactionParts("sample(\\d+):1000|2000");
+ assertNotNull("map should not be null", apdex);
+ assertEquals(1, apdex.size());
+ Set<String> keys = apdex.keySet();
+ assertTrue(keys.contains("sample(\\d+)"));
+ assertArrayEquals(new Long[] {1000L, 2000L}, apdex.get("sample(\\d+)"));
+ }
+
+ @Test
+ public void testSampleNameMatching() {
+ /* matching pairs :
+ * sample(\d+) sample2
+ * sample(\d+) sample12
+ * scenar01-12 scenar01-12
+ * samples12 samples12
+ * */
+
+ String[] sampleNames = {"sample2","sample12", "scenar01-12", "samples12"};
+
+ Map<String, Long[]> apdex = ReportGeneratorConfiguration.getApdexPerTransactionParts(apdexString);
+ for (String sampleName : sampleNames) {
+ boolean hasMatched = false;
+ for (Map.Entry<String, Long[]> entry : apdex.entrySet()) {
+ org.apache.oro.text.regex.Pattern regex = JMeterUtils.getPatternCache().getPattern(entry.getKey());
+ PatternMatcher matcher = JMeterUtils.getMatcher();
+ if(matcher.matches(sampleName, regex)) {
+ hasMatched= true;
+ }
+ }
+ assertTrue(hasMatched);
+ }
+
+ }
+
+ private static Properties loadProps(File file) {
+ final Properties props = new Properties();
+ try (FileInputStream inStream = new FileInputStream(file)) {
+ props.load(inStream);
+ } catch (IOException e) {
+ log.error("Problem loading properties. " + e); // NOSONAR
+ }
+ return props;
+ }
+
+ private static String getOptionalProperty(Props props,
+ String key, Class clazz) {
+ String property = getProperty(props, key, null, clazz);
+ if (property != null) {
+ }
+ return property;
+ }
+
+ private static String getProperty(Props props, String key,
+ String defaultValue, Class clazz)
+ {
+ String value = props.getValue(key);
+ if (value == null) {
+ return defaultValue;
+ }
+ return value;
+ }
+}
Propchange: jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1789193&r1=1789192&r2=1789193&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Tue Mar 28 18:59:34 2017
@@ -289,6 +289,7 @@ listeners hold and a rework of the way G
<h3>Report / Dashboard</h3>
<ul>
<li><bug>60637</bug>Improve Statistics table design <figure image="dashboard/report_statistics.png" ></figure></li>
+ <li><bug>60112</bug>Report / Dashboard : Add ability to customize APDEX thresholds per Transaction name. Contributed by Stephane Leplus (s.leplus at ubik-ingenierie.com)</li>
</ul>
<h3>General</h3>
@@ -446,6 +447,7 @@ listeners hold and a rework of the way G
<li>Bartosz Siewniak (barteksiewniak at gmail.com)</li>
<li>Kimono (kimono.outfit.am at gmail.com)</li>
<li>Michael Osipov (michaelo at apache.org)</li>
+<li>Stephane Leplus (s.leplus at ubik-ingenierie.com)</li>
</ul>
<p>We also thank bug reporters who helped us improve JMeter. <br/>
For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes:</p>
Modified: jmeter/trunk/xdocs/usermanual/generating-dashboard.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/generating-dashboard.xml?rev=1789193&r1=1789192&r2=1789193&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/generating-dashboard.xml (original)
+++ jmeter/trunk/xdocs/usermanual/generating-dashboard.xml Tue Mar 28 18:59:34 2017
@@ -163,6 +163,20 @@ jmeter.save.saveservice.timestamp_format
(in ms).<br/>
Default: <code>1500</code>
</property>
+ <property name="jmeter.reportgenerator.apdex_per_transaction" required="No">
+ Sets satisfaction and tolerance threshold to specific samples.<br/>
+ Use sample names or regular expression.<br/>
+ Format is <code>sample_name:satisfaction|tolerance[;]</code>(in ms).<br/>
+ <note>
+ Notice the colon between sample name and values, the pipe between thresholds and the
+ semicolon at the end to separate different samples. Don't forget to escape after
+ semicolon to span multiple lines.
+ </note>
+ Example:
+ <source>jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000,\
+ samples12:3000|4000;\
+ scenar01-12:5000|6000</source>
+ </property>
<property name="sample_filter" required="No">
Sets the filter of samples to keep for generating
graphs and statistics. An empty value deactivates the
Re: svn commit: r1789193 - in /jmeter/trunk: bin/ src/core/org/apache/jmeter/report/config/
src/core/org/apache/jmeter/report/dashboard/ test/resources/
test/src/org/apache/jmeter/report/dashboard/ xdocs/ xdocs/usermanual/
Posted by sebb <se...@gmail.com>.
On 28 March 2017 at 19:59, <pm...@apache.org> wrote:
> Author: pmouawad
> Date: Tue Mar 28 18:59:34 2017
> New Revision: 1789193
>
> URL: http://svn.apache.org/viewvc?rev=1789193&view=rev
> Log:
> Bug 60112 - Report / Dashboard : Add ability to customize APDEX thresholds per Transaction name
> Contributed by Stephane Leplus
> This closes #287
> Bugzilla Id: 60112
>
==============================================================================
> --- jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java (added)
> +++ jmeter/trunk/test/src/org/apache/jmeter/report/dashboard/ApdexPerTransactionTest.java Tue Mar 28 18:59:34 2017
> @@ -0,0 +1,144 @@
> + private static String getOptionalProperty(Props props,
> + String key, Class clazz) {
> + String property = getProperty(props, key, null, clazz);
> + if (property != null) {
> + }
What is the point of the previous statement?
> + return property;
> + }
> +
> + private static String getProperty(Props props, String key,
> + String defaultValue, Class clazz)
The clazz parameter is not used.
Why not?
If the parameter is not needed here, then it's also not needed by the
previous method.
> + {
> + String value = props.getValue(key);
> + if (value == null) {
> + return defaultValue;
> + }
> + return value;
> + }
> +}
>
Note: this class is the one that fails on Windows.