jmeter-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmoua...@apache.org
Subject svn commit: r1758867 - in /jmeter/trunk: bin/ bin/report-template/content/js/ bin/report-template/content/pages/ src/core/org/apache/jmeter/report/processor/graph/impl/ src/core/org/apache/jmeter/resources/ xdocs/
Date Thu, 01 Sep 2016 22:28:08 GMT
Author: pmouawad
Date: Thu Sep  1 22:28:08 2016
New Revision: 1758867

URL: http://svn.apache.org/viewvc?rev=1758867&view=rev
Log:
Bug 60079 - Report / Dashboard : Add a new "Response Time Overview" graph
Bugzilla Id: 60079

Added:
    jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java
  (with props)
Modified:
    jmeter/trunk/bin/report-template/content/js/graph.js.fmkr
    jmeter/trunk/bin/report-template/content/pages/ResponseTimes.html.fmkr
    jmeter/trunk/bin/reportgenerator.properties
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/bin/report-template/content/js/graph.js.fmkr
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/report-template/content/js/graph.js.fmkr?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/bin/report-template/content/js/graph.js.fmkr (original)
+++ jmeter/trunk/bin/report-template/content/js/graph.js.fmkr Thu Sep  1 22:28:08 2016
@@ -134,7 +134,11 @@ function prepareOptions(options, data) {
 }
 
 // Filter, mark series and sort data
-function prepareSeries(data){
+/**
+ * @param data
+ * @param noMatchColor if defined and true, series.color are not matched with index
+ */
+function prepareSeries(data, noMatchColor){
     var result = data.result;
 
     // Keep only series when needed
@@ -156,7 +160,9 @@ function prepareSeries(data){
     // Sort data and mark series
     $.each(result.series, function(index, series) {
         series.data.sort(compareByXCoordinate);
-        series.color = index;
+        if(!(noMatchColor && noMatchColor===true)) {
+	        series.color = index;
+	    }
     });
 }
 
@@ -355,6 +361,76 @@ function refreshResponseTimeDistribution
     }
 };
 
+
+var syntheticResponseTimeDistributionInfos = {
+        data: ${syntheticResponseTimeDistribution!"{}"},
+        getOptions: function() {
+            return {
+                legend: {
+                    noColumns: 2,
+                    show: true,
+                    container: '#legendSyntheticResponseTimeDistribution'
+                },
+                xaxis:{
+                    axisLabel: "Response times ranges",
+                    axisLabelUseCanvas: true,
+                    axisLabelFontSizePixels: 12,
+                    axisLabelFontFamily: 'Verdana, Arial',
+                    axisLabelPadding: 20,
+                    tickLength:0,
+                },
+                yaxis: {
+                    axisLabel: "Number of responses",
+                    axisLabelUseCanvas: true,
+                    axisLabelFontSizePixels: 12,
+                    axisLabelFontFamily: 'Verdana, Arial',
+                    axisLabelPadding: 20,
+                },
+                bars : {
+                    show: true,
+                    align: "center",
+                    barWidth: 0.5,
+                    fill:.75
+                },
+                grid: {
+                    hoverable: true // IMPORTANT! this is needed for tooltip to
+                                    // work
+                },
+                tooltip: true,
+                tooltipOpts: {
+                    content: function(label, xval, yval, flotItem){
+                        return yval + " " + label;
+                    }
+                },
+                colors: [  "red", "green", "orange","yellow"]                
+            };
+        },
+        createGraph: function() {
+            var data = this.data;
+            var options = this.getOptions();
+            prepareOptions(options, data);
+            options.xaxis.ticks = data.result.ticks;
+            $.plot($("#flotSyntheticResponseTimeDistribution"), prepareData(data.result.series,
$("#choicesSyntheticResponseTimeDistribution")), options);
+        }
+
+};
+
+// Response time distribution
+function refreshSyntheticResponseTimeDistribution() {
+    var infos = syntheticResponseTimeDistributionInfos;
+    prepareSeries(infos.data, true);
+    if (isGraph($("#flotSyntheticResponseTimeDistribution"))){
+        infos.createGraph();
+    }else{
+        var choiceContainer = $("#choicesSyntheticResponseTimeDistribution");
+        createLegend(choiceContainer, infos);
+        infos.createGraph();
+        $('#footerSyntheticResponseTimeDistribution .legendColorBox > div').each(function(i){
+            $(this).clone().prependTo(choiceContainer.find("li").eq(i));
+        });
+    }
+};
+
 var activeThreadsOverTimeInfos = {
         data: ${activeThreadsOverTime!"{}"},
         getOptions: function() {
@@ -1123,6 +1199,11 @@ function collapse(elem, collapsed){
                 refreshResponseTimeDistribution();
             }
             document.location.href="#responseTimeDistribution" ;
+        } else if (elem.id == "bodySyntheticResponseTimeDistribution") {
+            if (isGraph($(elem).find('.flot-chart-content')) == false) {
+                refreshSyntheticResponseTimeDistribution();
+            }
+            document.location.href="#syntheticResponseTimeDistribution" ;
         } else if (elem.id == "bodyActiveThreadsOverTime") {
             if (isGraph($(elem).find('.flot-chart-content')) == false) {
                 refreshActiveThreadsOverTime(true);
@@ -1205,6 +1286,9 @@ function toggleAll(id, checked){
     } else if ( id == "choicesTimeVsThreads"){
         choiceContainer = $("#choicesTimeVsThreads");
         refreshTimeVsThreads();
+    } else if ( id == "choicesSyntheticResponseTimeDistribution"){
+        choiceContainer = $("#choicesSyntheticResponseTimeDistribution");
+        refreshSyntheticResponseTimeDistribution();
     } else if ( id == "choicesResponseTimeDistribution"){
         choiceContainer = $("#choicesResponseTimeDistribution");
         refreshResponseTimeDistribution();

Modified: jmeter/trunk/bin/report-template/content/pages/ResponseTimes.html.fmkr
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/report-template/content/pages/ResponseTimes.html.fmkr?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/bin/report-template/content/pages/ResponseTimes.html.fmkr (original)
+++ jmeter/trunk/bin/report-template/content/pages/ResponseTimes.html.fmkr Thu Sep  1 22:28:08
2016
@@ -80,7 +80,11 @@
                                                 Response Time Percentiles
                                             </a>
                                         </li>
-
+                                        <li>
+                                            <a href="ResponseTimes.html#syntheticResponseTimeDistribution"
onclick="$('#bodySyntheticResponseTimeDistribution').collapse('show');">
+                                                Response Time Overview
+                                            </a>
+                                        </li>
                                         <li>
                                             <a href="ResponseTimes.html#activeThreadsOverTime"
onclick="$('#bodyActiveThreadsOverTime').collapse('show');">
                                                 Active Threads Over Time
@@ -190,6 +194,50 @@
 
                                 </ul>
                             </div>
+                        </div>
+                        <!-- /.panel-body -->
+                    </div>
+                    <!-- /.panel -->
+                </div>
+                <div class="col-lg-12 portlet" id="syntheticResponseTimeDistribution">
+                    <div class="panel panel-default">
+                        <div class="panel-heading portlet-header">
+                            <i class="fa fa-bar-chart-o fa-fw"></i>  <span
type="button" class="dropdown-toggle click-title span-title" data-toggle="collapse" href="#bodySyntheticResponseTimeDistribution"
aria-expanded="true" aria-controls="bodySyntheticResponseTimeDistribution">Response Time
Overview</span>
+                            <div class="pull-right">
+                                <div class="btn-group">
+                                    <a class="drag btn btn-link btn-xs">
+                                        <i class="glyphicon glyphicon-resize-vertical"></i>
+                                    </a>
+                                    <button type="button" class="btn btn-link btn-xs dropdown-toggle"
data-toggle="dropdown">
+                                        <i class="fa fa-wrench"></i>
+                                    </button>
+                                    <ul class="dropdown-menu dropdown-user">
+                                        <li><a href="#syntheticResponseTimeDistribution"
onClick="checkAll('choicesSyntheticResponseTimeDistribution');">Display all samples</a>
+                                        </li>
+                                        <li><a href="#syntheticResponseTimeDistribution"
onClick="uncheckAll('choicesSyntheticRResponseTimeDistribution');">Hide all samples</a>
+                                        </li>
+                                        <li><a href="#syntheticResponseTimeDistribution"
onclick="exportToPNG('flotSyntheticResponseTimesDistribution', this);">Save as PNG</a></li>
+                                    </ul>
+                                    <button type="button" class="btn btn-link btn-xs dropdown-toggle"
data-toggle="collapse" href="#bodySyntheticResponseTimeDistribution" aria-expanded="true"
aria-controls="bodySyntheticResponseTimeDistribution">
+                                        <i class="fa fa-chevron-down"></i>
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                        <!-- /.panel-heading -->
+                        <div class="collapse out portlet-content" id="bodySyntheticResponseTimeDistribution">
+                            <div class="panel-body" id="collapseSyntheticResponseTimeDistribution">
+
+                                <div class="flot-chart">
+                                    <div class="flot-chart-content" id="flotSyntheticResponseTimeDistribution"></div>
+                                </div>
+                            </div>
+                            <div class="panel-footer" id="footerSyntheticResponseTimeDistribution">
+                                <p id="legendSyntheticResponseTimeDistribution" hidden></p>
+                                <ul id="choicesSyntheticResponseTimeDistribution" class="legend">
+
+                                </ul>
+                            </div>
                         </div>
                         <!-- /.panel-body -->
                     </div>

Modified: jmeter/trunk/bin/reportgenerator.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/reportgenerator.properties?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/bin/reportgenerator.properties (original)
+++ jmeter/trunk/bin/reportgenerator.properties Thu Sep  1 22:28:08 2016
@@ -89,6 +89,12 @@ jmeter.reportgenerator.graph.responseTim
 jmeter.reportgenerator.graph.responseTimesOverTime.title=Response Time Over Time
 jmeter.reportgenerator.graph.responseTimesOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
 
+# Synthetic Response Time Distribution
+jmeter.reportgenerator.graph.syntheticResponseTimeDistribution.classname=org.apache.jmeter.report.processor.graph.impl.SyntheticResponseTimeDistributionGraphConsumer
+jmeter.reportgenerator.graph.syntheticResponseTimeDistribution.title=Synthetic Response Times
Distribution
+jmeter.reportgenerator.graph.syntheticResponseTimeDistribution.property.set_satified_threshold=${jmeter.reportgenerator.apdex_satisfied_threshold}
+jmeter.reportgenerator.graph.syntheticResponseTimeDistribution.property.set_tolerated_threshold=${jmeter.reportgenerator.apdex_tolerated_threshold}
+
 # 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

Added: jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java?rev=1758867&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java
(added)
+++ jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java
Thu Sep  1 22:28:08 2016
@@ -0,0 +1,160 @@
+/*
+ * 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.processor.graph.impl;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jmeter.report.core.Sample;
+import org.apache.jmeter.report.processor.ListResultData;
+import org.apache.jmeter.report.processor.MapResultData;
+import org.apache.jmeter.report.processor.SumAggregatorFactory;
+import org.apache.jmeter.report.processor.ValueResultData;
+import org.apache.jmeter.report.processor.graph.AbstractGraphConsumer;
+import org.apache.jmeter.report.processor.graph.AbstractSeriesSelector;
+import org.apache.jmeter.report.processor.graph.CountValueSelector;
+import org.apache.jmeter.report.processor.graph.GraphKeysSelector;
+import org.apache.jmeter.report.processor.graph.GroupInfo;
+import org.apache.jmeter.util.JMeterUtils;
+
+/**
+ * The class SyntheticResponseTimeDistributionGraphConsumer provides a graph to visualize
+ * the distribution of the response times on APDEX threshold
+ *
+ * @since 3.1
+ */
+public class SyntheticResponseTimeDistributionGraphConsumer extends
+        AbstractGraphConsumer {
+    private static final String FAILED_LABEL = JMeterUtils.getResString("response_time_distribution_failed_label");
+    private static final MessageFormat SATISFIED_LABEL = new MessageFormat(JMeterUtils.getResString("response_time_distribution_satified_label"));
+    private static final MessageFormat TOLERATED_LABEL = new MessageFormat(JMeterUtils.getResString("response_time_distribution_tolerated_label"));
+    private static final MessageFormat UNTOLERATED_LABEL = new MessageFormat(JMeterUtils.getResString("response_time_distribution_untolerated_label"));
+
+    private long satifiedThreshold;
+    private long toleratedThreshold;
+
+    private class SyntheticSeriesSelector extends AbstractSeriesSelector {
+        @Override
+        public Iterable<String> select(Sample sample) {
+            if(!sample.getSuccess()) {
+                return Arrays.asList(FAILED_LABEL);
+            } else {
+                long elapsedTime = sample.getElapsedTime();
+                if(elapsedTime<=getSatifiedThreshold()) {
+                    return Arrays.asList(SATISFIED_LABEL.format(new Object[] {Long.valueOf(getSatifiedThreshold())}));
+                } else if(elapsedTime <= getToleratedThreshold()) {
+                    return Arrays.asList(TOLERATED_LABEL.format(new Object[] {Long.valueOf(getSatifiedThreshold()),
Long.valueOf(getToleratedThreshold())}));
+                } else {
+                    return Arrays.asList(UNTOLERATED_LABEL.format(new Object[] {Long.valueOf(getToleratedThreshold())}));
+                }
+            }
+        }
+    }
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.report.csv.processor.impl.AbstractGraphConsumer#
+     * createKeysSelector()
+     */
+    @Override
+    protected final GraphKeysSelector createKeysSelector() {
+        return new GraphKeysSelector() {
+
+            @Override
+            public Double select(Sample sample) {
+                if(sample.getSuccess()) {
+                    long elapsedTime = sample.getElapsedTime();
+                    if(elapsedTime<=satifiedThreshold) {
+                        return Double.valueOf(0);
+                    } else if(elapsedTime <= toleratedThreshold) {
+                        return Double.valueOf(1);
+                    } else {
+                        return Double.valueOf(2);
+                    }
+                } else {
+                    return Double.valueOf(3);
+                }
+            }
+        };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.report.csv.processor.impl.AbstractGraphConsumer#
+     * createGroupInfos()
+     */
+    @Override
+    protected Map<String, GroupInfo> createGroupInfos() {
+        Map<String, GroupInfo> groupInfos = new HashMap<>(1);
+        SyntheticSeriesSelector syntheticSeriesSelector = new SyntheticSeriesSelector();
+        groupInfos.put(AbstractGraphConsumer.DEFAULT_GROUP, new GroupInfo(
+                new SumAggregatorFactory(), syntheticSeriesSelector,
+                new CountValueSelector(), false, false));
+
+        return groupInfos;
+    }
+
+    @Override
+    protected void initializeExtraResults(MapResultData parentResult) {
+        ListResultData listResultData = new ListResultData();
+        String[] messages = new String[]{
+                SATISFIED_LABEL.format(new Object[] {Long.valueOf(getSatifiedThreshold())}),
+                TOLERATED_LABEL.format(new Object[] {Long.valueOf(getSatifiedThreshold()),
Long.valueOf(getToleratedThreshold())}),
+                UNTOLERATED_LABEL.format(new Object[] {Long.valueOf(getToleratedThreshold())}),
+                FAILED_LABEL
+        };
+        for (int i = 0; i < messages.length; i++) {
+            ListResultData array = new ListResultData();
+            array.addResult(new ValueResultData(Integer.valueOf(i)));
+            array.addResult(new ValueResultData(messages[i]));   
+            listResultData.addResult(array);
+        }        
+        parentResult.setResult("ticks", listResultData);
+    }
+
+    /**
+     * @return the satifiedThreshold
+     */
+    public long getSatifiedThreshold() {
+        return satifiedThreshold;
+    }
+
+    /**
+     * @param satifiedThreshold the satifiedThreshold to set
+     */
+    public void setSatifiedThreshold(long satifiedThreshold) {
+        this.satifiedThreshold = satifiedThreshold;
+    }
+
+    /**
+     * @return the toleratedThreshold
+     */
+    public long getToleratedThreshold() {
+        return toleratedThreshold;
+    }
+
+    /**
+     * @param toleratedThreshold the toleratedThreshold to set
+     */
+    public void setToleratedThreshold(long toleratedThreshold) {
+        this.toleratedThreshold = toleratedThreshold;
+    }
+}

Propchange: jmeter/trunk/src/core/org/apache/jmeter/report/processor/graph/impl/SyntheticResponseTimeDistributionGraphConsumer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Thu Sep  1 22:28:08
2016
@@ -882,6 +882,10 @@ request_data=Request Data
 reset=Reset
 reset_gui=Reset Gui
 response_save_as_md5=Save response as MD5 hash?
+response_time_distribution_satified_label=Requests having response time <= {0}ms
+response_time_distribution_tolerated_label= Requests having response time > {0}ms and
<= {1}ms
+response_time_distribution_untolerated_label=Requests having response time > {0}ms
+response_time_distribution_failed_label=Requests in error
 restart=Restart
 resultaction_title=Result Status Action Handler
 resultsaver_addtimestamp=Add timestamp

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Thu Sep  1 22:28:08
2016
@@ -867,6 +867,10 @@ request_data=Donn\u00E9e requ\u00EAte
 reset=R\u00E9initialiser
 reset_gui=R\u00E9initialiser l'\u00E9l\u00E9ment
 response_save_as_md5=R\u00E9ponse en empreinte MD5
+response_time_distribution_satified_label=Requ\u00EAtes temps de réponse <= {0}ms
+response_time_distribution_tolerated_label=Requ\u00EAtes temps de réponse > {0}ms et
<= {1}ms
+response_time_distribution_untolerated_label=Requ\u00EAtes temps de r\u00E9ponse > {0}ms
+response_time_distribution_failed_label=Requ\u00EAtes en erreur
 restart=Red\u00E9marrer
 resultaction_title=Op\u00E9rateur R\u00E9sultats Action
 resultsaver_addtimestamp=Ajouter un timestamp

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1758867&r1=1758866&r2=1758867&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Thu Sep  1 22:28:08 2016
@@ -136,6 +136,7 @@ Summary
     <li><bug>59954</bug>Web Report/Dashboard : Add average metric</li>
     <li><bug>59956</bug>Web Report / Dashboard : Add ability to generate
a graph for a range of data</li>
     <li><bug>60065</bug>Report / Dashboard : Improve Dashboard Error Summary
by adding response message to "Type of error". Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
+    <li><bug>60079</bug>Report / Dashboard : Add a new "Response Time Overview"
graph</li>
 </ul>
 
 <ch_section>Non-functional changes</ch_section>



Mime
View raw message