jmeter-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmoua...@apache.org
Subject svn commit: r1854942 - in /jmeter/trunk: bin/ bin/testfiles/ src/core/org/apache/jmeter/gui/ src/core/org/apache/jmeter/gui/action/ src/core/org/apache/jmeter/gui/util/ src/core/org/apache/jmeter/resources/ test/src/org/apache/jmeter/gui/ test/src/org/...
Date Wed, 06 Mar 2019 19:59:29 GMT
Author: pmouawad
Date: Wed Mar  6 19:59:29 2019
New Revision: 1854942

URL: http://svn.apache.org/viewvc?rev=1854942&view=rev
Log:
Bug 59896 - Report / Dashboard : Add a menu entry to generate a report on demand from a CSV file

Contributed by UbikLoadPack

This closes #453
Bugzilla Id: 59896

Added:
    jmeter/trunk/bin/testfiles/HTMLReportExpect.json
    jmeter/trunk/bin/testfiles/HTMLReportFalseTestFile.csv
    jmeter/trunk/bin/testfiles/HTMLReportTestFile.csv
    jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java   (with props)
    jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java   (with props)
    jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/gui/HtmlReportGUISpec.groovy
    jmeter/trunk/test/src/org/apache/jmeter/gui/action/HtmlReportGeneratorSpec.groovy
    jmeter/trunk/xdocs/images/screenshots/html_report_menu.png   (with props)
Modified:
    jmeter/trunk/bin/jmeter.properties
    jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
    jmeter/trunk/src/core/org/apache/jmeter/gui/util/FileDialoger.java
    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
    jmeter/trunk/xdocs/usermanual/generating-dashboard.xml
    jmeter/trunk/xdocs/usermanual/properties_reference.xml

Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Wed Mar  6 19:59:29 2019
@@ -1315,6 +1315,8 @@ jmeter.reportgenerator.apdex_satisfied_t
 # Change this parameter if you want to override the APDEX tolerance threshold.
 jmeter.reportgenerator.apdex_tolerated_threshold=1500
 
+# Timeout in milliseconds for Report generation when using Tools > Generate HTML report
+#generate_report_ui.generation_timeout=120000
 #---------------------------------------------------------------------------
 # Naming Policy configuration
 #---------------------------------------------------------------------------

Added: jmeter/trunk/bin/testfiles/HTMLReportExpect.json
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/HTMLReportExpect.json?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/bin/testfiles/HTMLReportExpect.json (added)
+++ jmeter/trunk/bin/testfiles/HTMLReportExpect.json Wed Mar  6 19:59:29 2019
@@ -0,0 +1,47 @@
+{
+  "JR-KO" : {
+    "transaction" : "JR-KO",
+    "sampleCount" : 3,
+    "errorCount" : 3,
+    "errorPct" : 100.0,
+    "meanResTime" : 199.66666666666666,
+    "minResTime" : 100.0,
+    "maxResTime" : 329.0,
+    "pct1ResTime" : 329.0,
+    "pct2ResTime" : 329.0,
+    "pct3ResTime" : 329.0,
+    "throughput" : 0.07922465471254654,
+    "receivedKBytesPerSec" : 0.0015473565373544248,
+    "sentKBytesPerSec" : 6.1894261494177E-4
+  },
+  "Total" : {
+    "transaction" : "Total",
+    "sampleCount" : 255,
+    "errorCount" : 3,
+    "errorPct" : 1.1764706,
+    "meanResTime" : 235.47450980392148,
+    "minResTime" : 100.0,
+    "maxResTime" : 353.0,
+    "pct1ResTime" : 337.0,
+    "pct2ResTime" : 339.2,
+    "pct3ResTime" : 353.0,
+    "throughput" : 4.2369361136495804,
+    "receivedKBytesPerSec" : 0.07457474869153444,
+    "sentKBytesPerSec" : 0.03310106338788735
+  },
+  "JR-OK" : {
+    "transaction" : "JR-OK",
+    "sampleCount" : 252,
+    "errorCount" : 0,
+    "errorPct" : 0.0,
+    "meanResTime" : 235.90079365079367,
+    "minResTime" : 101.0,
+    "maxResTime" : 353.0,
+    "pct1ResTime" : 337.0,
+    "pct2ResTime" : 339.35,
+    "pct3ResTime" : 353.0,
+    "throughput" : 4.187089806430174,
+    "receivedKBytesPerSec" : 0.0736011880036554,
+    "sentKBytesPerSec" : 0.03271163911273573
+  }
+}

Added: jmeter/trunk/bin/testfiles/HTMLReportFalseTestFile.csv
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/HTMLReportFalseTestFile.csv?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/bin/testfiles/HTMLReportFalseTestFile.csv (added)
+++ jmeter/trunk/bin/testfiles/HTMLReportFalseTestFile.csv Wed Mar  6 19:59:29 2019
@@ -0,0 +1,51 @@
+timeStamp,elapsed,label,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
+1549967385359,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385360,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385361,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385735,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385735,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385735,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385736,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0
+1549967385737,0,Requête HTTP,Groupe d'unités 1-1,text,false,,1110,0,1,1,http:/,0,0,0

Added: jmeter/trunk/bin/testfiles/HTMLReportTestFile.csv
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/HTMLReportTestFile.csv?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/bin/testfiles/HTMLReportTestFile.csv (added)
+++ jmeter/trunk/bin/testfiles/HTMLReportTestFile.csv Wed Mar  6 19:59:29 2019
@@ -0,0 +1,256 @@
+timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
+1551783627191,351,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783627543,192,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783627735,131,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783627866,261,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783628128,266,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783628395,279,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783628674,304,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783628979,353,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783629333,196,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783629530,139,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783629670,278,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783629949,303,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783630253,351,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783630605,194,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783630799,134,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783630934,268,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783631202,282,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783631485,308,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783631794,108,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783631903,217,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783632120,180,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783632301,107,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783632408,213,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783632622,171,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783632794,342,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783633137,176,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783633313,353,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783633666,196,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783633863,137,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783634001,275,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783634276,296,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783634573,336,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783634910,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783635075,328,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783635404,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783635552,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783635850,338,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783636189,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783636357,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783636695,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783636859,329,JR-KO,400,Bad request,Thread Group 1-1,text,false,,20,8,1,1,null,0,0,0
+1551783637189,147,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783637337,296,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783637634,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783637974,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783638142,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783638480,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783638644,329,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783638974,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783639122,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783639420,338,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783639759,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783639927,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783640264,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783640429,329,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783640758,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783640907,295,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783641203,336,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783641540,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783641705,328,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783642034,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783642182,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783642480,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783642819,169,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783642989,338,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783643327,166,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783643493,333,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783643827,156,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783643983,313,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783644297,116,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783644413,233,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783644647,211,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783644858,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783645027,336,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783645363,163,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783645527,325,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783645853,142,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783645995,285,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783646280,315,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783646596,120,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783646717,241,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783646958,227,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783647186,200,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783647386,146,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783647533,292,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783647826,331,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783648157,152,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783648310,304,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783648615,353,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783648968,199,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783649167,142,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783649310,284,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783649594,314,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783649909,118,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783650027,238,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783650265,220,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783650486,185,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783650671,116,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783650788,232,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783651021,210,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783651231,166,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783651398,332,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783651730,155,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783651886,309,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783652196,110,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783652307,221,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783652528,187,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783652715,121,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783652836,241,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783653078,227,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783653306,200,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783653506,146,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783653653,292,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783653945,330,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783654275,150,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783654425,300,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783654726,344,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783655071,180,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783655251,106,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783655358,212,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783655571,170,JR-KO,400,Bad request,Thread Group 1-1,text,false,,20,8,1,1,null,0,0,0
+1551783655741,340,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783656081,171,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783656253,342,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783656595,174,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783656770,348,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783657118,189,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783657307,123,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783657430,245,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783657675,235,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783657911,215,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783658126,176,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783658303,352,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783658656,195,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783658852,136,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783658989,272,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783659262,291,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783659553,327,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783659880,145,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783660025,290,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783660316,324,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783660641,140,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783660782,281,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783661063,307,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783661370,105,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783661476,210,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783661687,166,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783661853,333,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783662186,157,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783662343,313,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783662657,116,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783662774,232,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783663007,211,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783663219,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783663387,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783663725,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783663889,329,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783664218,149,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783664367,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783664664,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783665004,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783665172,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783665510,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783665675,328,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783666004,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783666152,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783666450,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783666789,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783666958,336,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783667295,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783667460,328,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783667789,148,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783667937,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783668234,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783668574,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783668742,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783669079,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783669244,328,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783669573,147,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783669720,295,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783670015,335,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783670351,162,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783670513,324,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783670837,137,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783670975,274,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783671249,294,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783671544,333,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783671877,157,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783672035,314,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783672349,118,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783672468,237,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783672705,220,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783672926,185,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783673111,116,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783673228,232,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783673460,210,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783673671,165,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783673836,331,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783674167,153,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783674320,305,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783674626,100,JR-KO,400,Bad request,Thread Group 1-1,text,false,,20,8,1,1,null,0,0,0
+1551783674727,201,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783674928,149,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783675077,297,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783675374,339,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783675714,168,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783675882,337,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783676219,164,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783676384,327,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783676712,146,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783676859,292,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783677152,331,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783677484,153,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783677638,306,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783677945,104,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783678050,208,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783678259,163,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783678422,327,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783678750,144,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783678894,289,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783679183,323,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783679507,135,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783679643,272,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783679915,290,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783680205,325,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783680530,141,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783680671,281,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783680952,307,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783681260,104,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783681365,208,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783681574,163,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783681738,326,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783682065,144,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783682209,289,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783682499,323,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783682822,137,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783682960,274,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783683234,293,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783683527,332,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783683859,155,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684014,309,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684323,108,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684432,216,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684648,178,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684827,101,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783684928,203,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783685132,151,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783685283,303,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783685587,350,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783685938,192,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783686130,131,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783686261,261,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783686523,267,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783686790,280,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0
+1551783687071,305,JR-OK,200,Good request,Thread Group 1-1,text,true,,18,8,1,1,null,0,0,0

Added: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java (added)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java Wed Mar  6 19:59:29 2019
@@ -0,0 +1,92 @@
+/*
+ * 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.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+
+import org.apache.jmeter.exceptions.IllegalUserActionException;
+import org.apache.jmeter.gui.action.AbstractAction;
+import org.apache.jmeter.gui.action.ActionNames;
+import org.apache.jmeter.gui.action.ActionRouter;
+import org.apache.jmeter.gui.plugin.MenuCreator;
+import org.apache.jmeter.util.JMeterUtils;
+
+public class HtmlReportAction extends AbstractAction implements MenuCreator {
+    private static Set<String> commands = new HashSet<>();
+    private HtmlReportUI htmlReportPanel;
+
+    static {
+        commands.add(ActionNames.HTML_REPORT);
+    }
+
+    public HtmlReportAction() {
+        super();
+    }
+
+    @Override
+    public void doAction(ActionEvent e) throws IllegalUserActionException {
+        htmlReportPanel = new HtmlReportUI();
+        htmlReportPanel.showInputDialog(getParentFrame(e));
+    }
+
+    @Override
+    public Set<String> getActionNames() {
+        return commands;
+    }
+
+    @Override
+    public JMenuItem[] getMenuItemsAtLocation(MENU_LOCATION location) {
+        if (location != MENU_LOCATION.TOOLS) {
+            return new JMenuItem[0];
+        }
+
+        JMenuItem menuItem = new JMenuItem(JMeterUtils.getResString("generate_report_ui.html_report_menu"), KeyEvent.VK_UNDEFINED);
+        menuItem.setName(ActionNames.HTML_REPORT);
+        menuItem.setActionCommand(ActionNames.HTML_REPORT);
+        menuItem.setAccelerator(null);
+        menuItem.addActionListener(ActionRouter.getInstance());
+        return new JMenuItem[] { menuItem };
+    }
+
+    @Override
+    public JMenu[] getTopLevelMenus() {
+        return new JMenu[0];
+    }
+
+    @Override
+    public boolean localeChanged(MenuElement menu) {
+        return false;
+    }
+
+    @Override
+    public void localeChanged() {
+        // NOOP
+    }
+
+    public HtmlReportUI getHtmlReportPanel() {
+        return htmlReportPanel;
+    }
+}

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportAction.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java (added)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java Wed Mar  6 19:59:29 2019
@@ -0,0 +1,252 @@
+/*
+ * 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.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+
+import org.apache.jmeter.gui.action.ActionNames;
+import org.apache.jmeter.gui.action.HtmlReportGenerator;
+import org.apache.jmeter.gui.util.EscapeDialog;
+import org.apache.jmeter.gui.util.FileDialoger;
+import org.apache.jmeter.gui.util.JSyntaxTextArea;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.ComponentUtil;
+import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HtmlReportUI implements ActionListener {
+    private static Set<String> commands = new HashSet<>();
+    private static final Logger LOGGER = LoggerFactory.getLogger(HtmlReportUI.class);
+
+    private static final String CREATE_REQUEST = "CREATE_REQUEST";
+    private static final String BROWSE_CSV = "BROWSE_CSV";
+    private static final String BROWSE_USER_PROPERTIES = "BROWSE_USER_PROPERTIES";
+    private static final String BROWSE_OUTPUT = "BROWSE_OUTPUT";
+
+    private EscapeDialog messageDialog;
+
+    private JTextField csvFilePathTextField;
+    private JTextField userPropertiesFilePathTextField;
+    private JTextField outputDirectoryPathTextField;
+    private JButton reportLaunchButton;
+    private JSyntaxTextArea reportArea;
+    private JButton csvFileButton;
+    private JButton outputDirectoryButton;
+    private JButton userPropertiesFileButton;
+
+    static {
+        commands.add(ActionNames.HTML_REPORT);
+    }
+
+    public HtmlReportUI() {
+        super();
+    }
+
+    public void showInputDialog(JFrame parent) {
+        setupInputDialog(parent);
+        launchInputDialog();
+    }
+
+    private void launchInputDialog() {
+        messageDialog.pack();
+        ComponentUtil.centerComponentInWindow(messageDialog);
+        messageDialog.setVisible(true);
+    }
+
+    public void setupInputDialog(JFrame parent) {
+        messageDialog = new EscapeDialog(parent, JMeterUtils.getResString("generate_report_ui.html_report_menu"), false);
+        setupContentPane();
+    }
+
+    private void setupContentPane() {
+        Container contentPane = messageDialog.getContentPane();
+        contentPane.setLayout(new BorderLayout());
+
+        contentPane.add(setupFileChooserPanel(), BorderLayout.NORTH);
+
+        reportArea = JSyntaxTextArea.getInstance(10, 60, true);
+        reportArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
+        reportArea.setEditable(false);
+        contentPane.add(reportArea, BorderLayout.CENTER);
+
+        contentPane.add(setupButtonPanel(), BorderLayout.SOUTH);
+    }
+
+    private JPanel setupFileChooserPanel() {
+        JPanel fileChooserPanel = new JPanel(new GridLayout(3, 3));
+        fileChooserPanel.add(new JLabel(JMeterUtils.getResString("generate_report_ui.csv_file")));
+
+        csvFilePathTextField = new JTextField();
+        fileChooserPanel.add(csvFilePathTextField);
+
+        this.csvFileButton = new JButton(JMeterUtils.getResString("browse"));
+        csvFileButton.setActionCommand(BROWSE_CSV);
+        csvFileButton.addActionListener(this);
+        fileChooserPanel.add(csvFileButton);
+
+        fileChooserPanel.add(new JLabel(JMeterUtils.getResString("generate_report_ui.user_properties_file")));
+
+        userPropertiesFilePathTextField = new JTextField();
+        fileChooserPanel.add(userPropertiesFilePathTextField);
+
+        this.userPropertiesFileButton = new JButton(JMeterUtils.getResString("browse"));
+        userPropertiesFileButton.setActionCommand(BROWSE_USER_PROPERTIES);
+        userPropertiesFileButton.addActionListener(this);
+        fileChooserPanel.add(userPropertiesFileButton);
+
+        fileChooserPanel.add(new JLabel(JMeterUtils.getResString("generate_report_ui.output_directory")));
+
+        outputDirectoryPathTextField = new JTextField();
+        fileChooserPanel.add(outputDirectoryPathTextField);
+
+        this.outputDirectoryButton = new JButton(JMeterUtils.getResString("browse"));
+        outputDirectoryButton.setActionCommand(BROWSE_OUTPUT);
+        outputDirectoryButton.addActionListener(this);
+        fileChooserPanel.add(outputDirectoryButton);
+        return fileChooserPanel;
+    }
+
+    private JPanel setupButtonPanel() {
+        JPanel buttonPanel = new JPanel(new GridLayout(1, 1));
+
+        reportLaunchButton = new JButton(JMeterUtils.getResString("generate_report_ui.html_report_request"));
+        reportLaunchButton.setActionCommand(CREATE_REQUEST);
+        reportLaunchButton.addActionListener(this);
+        buttonPanel.add(reportLaunchButton);
+        return buttonPanel;
+    }
+
+    private class ReportGenerationWorker extends SwingWorker<List<String>, String> {
+        private JButton reportLaunchButton;
+
+        public ReportGenerationWorker(JButton reportLaunchButton) {
+            this.reportLaunchButton = reportLaunchButton;
+        }
+        @Override
+        protected List<String> doInBackground() throws Exception {
+            HtmlReportGenerator htmlReportAction = new HtmlReportGenerator(csvFilePathTextField.getText(),
+                    userPropertiesFilePathTextField.getText(), outputDirectoryPathTextField.getText());
+            SwingUtilities.invokeAndWait(() -> reportLaunchButton.setEnabled(false));
+            return htmlReportAction.run();
+        }
+
+        @Override
+        protected void done() {
+            try {
+                reportLaunchButton.setEnabled(true);
+                reportToUser(get());
+            } catch (InterruptedException | ExecutionException exception) {
+                if (LOGGER.isErrorEnabled()) {
+                    LOGGER.error("Error during html report generation: {}", exception.getMessage(), exception);
+                }
+                reportToUser(Arrays.asList(exception.getMessage()));
+            }
+        }
+    }
+
+    private void addTextToReport(String errorMessage) {
+        reportArea.setText(reportArea.getText() + errorMessage + "\n");
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        switch (e.getActionCommand()) {
+        case CREATE_REQUEST:
+            try {
+                reportArea.setText(JMeterUtils.getResString("generate_report_ui.html_report_processing") + "\n");
+                reportLaunchButton.setForeground(Color.orange);
+                new ReportGenerationWorker(reportLaunchButton).execute();
+            } catch (Exception exception) {
+                if (LOGGER.isErrorEnabled()) {
+                    LOGGER.error("Error during html report generation: {}", exception.getMessage(), exception);
+                }
+            }
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("CSV file path {}\nuser.properties file path: {}\nOutput directory file path: {}",
+                        csvFilePathTextField.getText(), userPropertiesFilePathTextField.getText(),
+                        outputDirectoryPathTextField.getText());
+            }
+            break;
+        case BROWSE_USER_PROPERTIES:
+            userPropertiesFilePathTextField.setText(showFileChooser(userPropertiesFileButton.getParent(),
+                    userPropertiesFilePathTextField, false, new String[] { ".properties" }));
+            break;
+        case BROWSE_CSV:
+            csvFilePathTextField.setText(showFileChooser(csvFileButton.getParent(), csvFilePathTextField, false,
+                    new String[] { ".jtl", ".csv" }));
+            break;
+        case BROWSE_OUTPUT:
+            outputDirectoryPathTextField.setText(
+                    showFileChooser(outputDirectoryButton.getParent(), outputDirectoryPathTextField, true, null));
+            break;
+        default:
+            break;
+        }
+    }
+
+    void reportToUser(List<String> runErrors) {
+        if (runErrors.isEmpty()) {
+            addTextToReport(JMeterUtils.getResString(HtmlReportGenerator.HTML_REPORT_SUCCESS));
+            reportLaunchButton.setForeground(Color.green);
+        } else {
+            addTextToReport(String.join("\n", runErrors));
+            reportLaunchButton.setForeground(Color.red);
+        }
+    }
+
+    /**
+     * Show a file chooser to the user
+     * 
+     * @param locationTextField
+     *            the textField that will receive the path
+     * @param onlyDirectory
+     *            whether or not the file chooser will only display directories
+     * @param extensions File extensions to filter
+     * @return the path the user selected or, if the user cancelled the file
+     *         chooser, the previous path
+     */
+    private String showFileChooser(Component component, JTextField locationTextField, boolean onlyDirectory, String[] extensions) {
+        JFileChooser fileChooser = FileDialoger.promptToOpenFile(component, extensions, System.getProperty("user.home"), onlyDirectory);
+        if (fileChooser == null) {
+            return locationTextField.getText();
+        }
+        return fileChooser.getSelectedFile().getPath();
+    }
+}

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/HtmlReportUI.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java Wed Mar  6 19:59:29 2019
@@ -60,6 +60,7 @@ public final class ActionNames {
     public static final String FUNCTIONS        = "functions"; // $NON-NLS-1$
     public static final String HELP             = "help"; // $NON-NLS-1$
     public static final String HEAP_DUMP        = "heap_dump"; // $NON-NLS-1$
+    public static final String HTML_REPORT      = "html_report";
     public static final String LAF_PREFIX       = "laf:"; // Look and Feel prefix
     public static final String LINK_BUG_TRACKER = "link_bug_tracker:"; // URI of bug tracker
     public static final String LINK_COMP_REF    = "link_component_reference:"; // URI of component reference

Added: jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java (added)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java Wed Mar  6 19:59:29 2019
@@ -0,0 +1,186 @@
+/*
+ * 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.gui.action;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.exec.SystemCommand;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HtmlReportGenerator {
+
+    public static final String HTML_REPORT_SUCCESS = "generate_report_ui.html_report_success";
+    public static final String ERROR_GENERATING = "generate_report_ui.html_report_error";
+    public static final String NO_FILE = "generate_report_ui.no_such_file";
+    public static final String NO_DIRECTORY = "generate_report_ui.no_such_directory";
+    public static final String NOT_EMPTY_DIRECTORY = "generate_report_ui.directory_not_empty";
+    public static final String CANNOT_CREATE_DIRECTORY = "generate_report_ui.cannot_create_directory";
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HtmlReportGenerator.class);
+    private static final long COMMAND_TIMEOUT = JMeterUtils.getPropDefault("generate_report_ui.generation_timeout", 120000L);
+
+    private String csvFilePath;
+    private String userPropertiesFilePath;
+    private String outputDirectoryPath;
+
+    public HtmlReportGenerator(String csvFilePath, String userPropertiesFilePath, String outputDirectoryPath) {
+        this.csvFilePath = csvFilePath;
+        this.userPropertiesFilePath = userPropertiesFilePath;
+        if (outputDirectoryPath == null) {
+            this.outputDirectoryPath = JMeterUtils.getJMeterBinDir() + "/report-output/";
+        } else {
+            this.outputDirectoryPath = outputDirectoryPath;
+        }
+    }
+
+    /*
+     * Prepare and Run the HTML report generation command
+     */
+    public List<String> run() {
+        List<String> errorMessageList = new ArrayList<>();
+        errorMessageList.addAll(checkArguments());
+        if (!errorMessageList.isEmpty()) {
+            return errorMessageList;
+        }
+        
+        ByteArrayOutputStream commandExecutionOutput = new ByteArrayOutputStream();
+        int resultCode = -1;
+        List<String> generationCommand = createGenerationCommand();
+        try {
+            SystemCommand sc = new SystemCommand(new File(JMeterUtils.getJMeterBinDir()), COMMAND_TIMEOUT, 100, null, null,
+                    commandExecutionOutput, null);
+            LOGGER.debug("Running report generation");
+            resultCode = sc.run(generationCommand);
+            if (resultCode != 0) {
+                errorMessageList.add(commandExecutionOutput.toString());
+                LOGGER.info("The HTML report generation failed and returned: {}", commandExecutionOutput);
+                return errorMessageList;
+            }
+        } catch (InterruptedException | IOException e) {
+            errorMessageList.add(commandExecutionOutput.toString());
+            if (LOGGER.isErrorEnabled()) {
+                LOGGER.error("Error during HTML report generation: {}", e.getMessage(), e);
+            }
+        }
+        LOGGER.debug("SystemCommand ran: {}  returned: {}", generationCommand, resultCode);
+        return errorMessageList;
+    }
+
+    /**
+     * create the command for html report generation with all the directories /
+     * file
+     * 
+     * @return the list of arguments for SystemCommand execution
+     */
+    private List<String> createGenerationCommand() {
+        String jmeterBinDir = JMeterUtils.getJMeterBinDir();
+        List<String> arguments = new ArrayList<>();
+        String java = System.getProperty("java.home") + "/bin/java";
+        arguments.add(java);
+        arguments.add("-jar");
+        arguments.add(jmeterBinDir + "/ApacheJMeter.jar");
+        arguments.add("-p");
+        arguments.add(jmeterBinDir + "/jmeter.properties");
+        arguments.add("-q");
+        arguments.add(userPropertiesFilePath);
+        arguments.add("-g");
+        arguments.add(csvFilePath);
+        arguments.add("-j");
+        arguments.add(jmeterBinDir + "/jmeter_html_report.log");
+        arguments.add("-o");
+        arguments.add(outputDirectoryPath);
+        return arguments;
+    }
+
+    /**
+     * test that all arguments are correct and send a message to the user if not
+     * 
+     * @return whether or not the files are correct
+     */
+    private List<String> checkArguments() {
+        List<String> errors = new ArrayList<>();
+
+        String csvError = checkFile(new File(csvFilePath));
+        if (csvError != null) {
+            errors.add(JMeterUtils.getResString("generate_report_ui.csv_file") + csvError);
+        }
+
+        String userPropertiesError = checkFile(new File(userPropertiesFilePath));
+        if (userPropertiesError != null) {
+            errors.add(JMeterUtils.getResString("generate_report_ui.user_properties_file") + userPropertiesError);
+        }
+
+        String outputError = checkDirectory(new File(outputDirectoryPath));
+        if (outputError != null) {
+            errors.add(JMeterUtils.getResString("generate_report_ui.output_directory") + outputError);
+        }
+        return errors;
+    }
+
+    /**
+     * Check if a file is correct for report generation
+     * 
+     * @param fileToCheck
+     *            the directory to check
+     * @return the error message or null if the file is ok
+     */
+    private String checkFile(File fileToCheck) {
+        if (fileToCheck.exists() && fileToCheck.canRead() && fileToCheck.isFile()) {
+            return null;
+        } else {
+            return MessageFormat.format(JMeterUtils.getResString(NO_FILE), fileToCheck);
+        }
+    }
+
+    /**
+     * Check if a directory is fine for report generation
+     * 
+     * @param directoryToCheck
+     *            the directory to check
+     * @return the error message or an empty string if the directory is fine
+     */
+    private String checkDirectory(File directoryToCheck) {
+        if (directoryToCheck.exists()) {
+            String[] files = directoryToCheck.list();
+            if (files != null && files.length > 0) {
+                return MessageFormat.format(JMeterUtils.getResString(NOT_EMPTY_DIRECTORY), directoryToCheck);
+            } else {
+                return null;
+            }
+        } else {
+            File parentDirectory = directoryToCheck.getParentFile();
+            if(parentDirectory != null && parentDirectory.exists() && parentDirectory.canWrite()) {
+                if(directoryToCheck.mkdir()) {
+                    return null;
+                } else {
+                    return MessageFormat.format(JMeterUtils.getResString(CANNOT_CREATE_DIRECTORY), directoryToCheck);
+                }
+            } else {
+                return MessageFormat.format(JMeterUtils.getResString(CANNOT_CREATE_DIRECTORY), directoryToCheck);
+            }
+        }
+    }
+}

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jmeter/trunk/src/core/org/apache/jmeter/gui/action/HtmlReportGenerator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/util/FileDialoger.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/util/FileDialoger.java?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/util/FileDialoger.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/util/FileDialoger.java Wed Mar  6 19:59:29 2019
@@ -18,6 +18,7 @@
 
 package org.apache.jmeter.gui.util;
 
+import java.awt.Component;
 import java.io.File;
 
 import javax.swing.JFileChooser;
@@ -151,7 +152,29 @@ public final class FileDialoger {
     * @return the JFileChooser that interacted with the user, after they are
     *         finished using it - null if no file was chosen
     */
-   public static JFileChooser promptToOpenFile(String[] exts, String existingFileName, boolean onlyDirectories) {
+    public static JFileChooser promptToOpenFile(String[] exts, String existingFileName, boolean onlyDirectories) {
+        return promptToOpenFile(GuiPackage.getInstance().getMainFrame(), exts, existingFileName, onlyDirectories);
+    }
+    
+    /**
+    * Prompts the user to choose a file or a directory from their filesystems for our own
+    * devious uses. This method maintains the last directory the user visited
+    * before dismissing the dialog. This does NOT imply they actually chose a
+    * file from that directory, only that they closed the dialog there. It is
+    * the caller's responsibility to check to see if the selected file is
+    * non-null.
+    * @param parentComponent Component parent of current element
+    * @param exts The list of allowed file extensions. If empty, any
+    *             file extension is allowed
+    * @param existingFileName The name of a file with path. If the filename points
+    *             to an existing file, the directory in which it lies, will be used
+    *             as the starting point for the returned JFileChooser.
+    * @param onlyDirectories If true, only directories are displayed in the FileChooser
+    *
+    * @return the JFileChooser that interacted with the user, after they are
+    *         finished using it - null if no file was chosen
+    */
+    public static JFileChooser promptToOpenFile(Component parentComponent, String[] exts, String existingFileName, boolean onlyDirectories) {
        if (onlyDirectories) {
            jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        } else {
@@ -181,7 +204,7 @@ public final class FileDialoger {
            lastJFCDirectory = System.getProperty("user.dir", ""); //$NON-NLS-1$//$NON-NLS-2$
        }
        jfc.setCurrentDirectory(new File(lastJFCDirectory));
-       int retVal = jfc.showOpenDialog(GuiPackage.getInstance().getMainFrame());
+       int retVal = jfc.showOpenDialog(parentComponent);
        lastJFCDirectory = jfc.getCurrentDirectory().getAbsolutePath();
 
        if (retVal == JFileChooser.APPROVE_OPTION) {

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=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Wed Mar  6 19:59:29 2019
@@ -395,6 +395,21 @@ gaussian_timer_range=Deviation (in milli
 gaussian_timer_title=Gaussian Random Timer
 generate=Generate & Copy to clipboard
 generator=Name of Generator class
+generate_report_ui.directory_not_empty=The directory {0} isn't empty
+generate_report_ui.no_such_directory=The specified directory {0} doesn't exist
+generate_report_ui.cannot_create_directory=Cannot create output folder {0}
+generate_report_ui.user_properties_file=user.properties file \: 
+generate_report_ui.csv_file=Results file (csv or jtl) \:
+generate_report_ui.html_report=HTML report
+generate_report_ui.html_report_error=Error generating report
+generate_report_ui.html_report_file_not_found=File not found at \: {0}
+generate_report_ui.html_report_menu=Generate HTML report
+generate_report_ui.html_report_processing=Generating report
+generate_report_ui.html_report_request=Generate report
+generate_report_ui.html_report_success=Report created !
+generate_report_ui.html_report_unknown_error=Error \: {0}
+generate_report_ui.no_such_file=The specified file {0} doesn't exist
+generate_report_ui.output_directory=Output directory \:
 generator_cnf_msg=Could not find the generator class. Please make sure you place your jar file in the /lib directory.
 generator_illegal_msg=Could not access the generator class due to IllegalAccessException.
 generator_instantiate_msg=Could not create an instance of the generator parser. Please make sure the generator implements Generator interface.

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=1854942&r1=1854941&r2=1854942&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 Wed Mar  6 19:59:29 2019
@@ -389,6 +389,21 @@ gaussian_timer_range=Déviation (en mi
 gaussian_timer_title=Compteur de temps aléatoire gaussien
 generate=Générer et copier dans le presse-papiers
 generator=Nom de la classe génératrice
+generate_report_ui.directory_not_empty=Le répertoire {0} n'est pas vide
+generate_report_ui.no_such_directory=Le répertoire spécifié {0} n'existe pas
+generate_report_ui.cannot_create_directory=Création du répertoire {0} impossible
+generate_report_ui.user_properties_file=Fichier user.properties \: 
+generate_report_ui.csv_file=Fichier de résultats (csv ou jtl) \:
+generate_report_ui.html_report=Rapport HTML
+generate_report_ui.html_report_error=Erreur lors de la génération du rapport
+generate_report_ui.html_report_file_not_found=Le fichier \: {0} n'' a pas été trouvé
+generate_report_ui.html_report_menu=Générer le rapport HTML
+generate_report_ui.html_report_processing=Génération du rapport en cours
+generate_report_ui.html_report_request=Générer le rapport
+generate_report_ui.html_report_success=Rapport créé !
+generate_report_ui.html_report_unknown_error=Erreur \: {0}
+generate_report_ui.no_such_file=Le fichier spécifié {0} n'existe pas
+generate_report_ui.output_directory=Répertoire de sortie \ :
 generator_cnf_msg=N'a pas pû trouver la classe génératrice. Assurez-vous que vous avez placé votre fichier jar dans le répertoire /lib
 generator_illegal_msg=N'a pas pû accéder à la classes génératrice à cause d'une IllegalAccessException.
 generator_instantiate_msg=N'a pas pû créer une instance du parseur générateur. Assurez-vous que le générateur implémente l'interface Generator.

Added: jmeter/trunk/test/src/org/apache/jmeter/gui/HtmlReportGUISpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/gui/HtmlReportGUISpec.groovy?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/gui/HtmlReportGUISpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/gui/HtmlReportGUISpec.groovy Wed Mar  6 19:59:29 2019
@@ -0,0 +1,50 @@
+/*
+ * 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.gui;
+
+import java.awt.event.ActionEvent;
+
+import org.apache.jmeter.gui.tree.JMeterCellRenderer
+import org.apache.jmeter.gui.tree.JMeterTreeListener
+import org.apache.jmeter.gui.tree.JMeterTreeModel
+import org.apache.jmeter.junit.spock.JMeterSpec
+
+import spock.lang.IgnoreIf
+
+@IgnoreIf({ JMeterSpec.isHeadless() })
+class HtmlReportGUISpec extends JMeterSpec{
+
+    def "test HtmlReportUI initialization"(){
+        given:
+            def HtmlReportUI htmlReportPanel = new HtmlReportUI();
+            def JMeterTreeModel treeModel = new JMeterTreeModel();
+            def JMeterTreeListener treeListener = new JMeterTreeListener(treeModel);
+            GuiPackage.initInstance(treeListener, treeModel);
+            GuiPackage.getInstance().setMainFrame(new MainFrame(treeModel, treeListener));
+        when:
+            htmlReportPanel.showInputDialog(GuiPackage.getInstance().getMainFrame())
+            htmlReportPanel.messageDialog.setVisible(false)
+        then:
+            "" == htmlReportPanel.csvFilePathTextField.getText()
+            "" == htmlReportPanel.userPropertiesFilePathTextField.getText()
+            "" == htmlReportPanel.outputDirectoryPathTextField.getText()
+            "" == htmlReportPanel.reportArea.getText()
+            1 == htmlReportPanel.messageDialog.getComponents().length;
+    }
+}

Added: jmeter/trunk/test/src/org/apache/jmeter/gui/action/HtmlReportGeneratorSpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/gui/action/HtmlReportGeneratorSpec.groovy?rev=1854942&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/gui/action/HtmlReportGeneratorSpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/gui/action/HtmlReportGeneratorSpec.groovy Wed Mar  6 19:59:29 2019
@@ -0,0 +1,128 @@
+/*
+ * 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.gui.action
+
+import spock.lang.IgnoreIf
+import spock.lang.Unroll
+
+import java.text.MessageFormat
+
+import org.apache.commons.io.FileUtils
+import org.apache.jmeter.junit.spock.JMeterSpec
+import org.apache.jmeter.util.JMeterUtils
+
+import com.fasterxml.jackson.annotation.JsonMerge
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.ObjectMapper
+
+class HtmlReportGeneratorSpec extends JMeterSpec{
+
+    def "check if generation from csv: '#csvPath' with properties: '#userPropertiesPath' in folder: '#outputDirectoryPath' contains the expected error"(){
+        when:
+            HtmlReportGenerator htmlReportGenerator = new HtmlReportGenerator(csvPath, userPropertiesPath, outputDirectoryPath)
+            List<String> resultList = htmlReportGenerator.checkArguments()
+        then:
+            resultList.equals(expected)
+        where:
+            csvPath                                                           | userPropertiesPath                                        | outputDirectoryPath                                   | expected
+            JMeterUtils.getJMeterBinDir()+"/testfiles/HTMLReportTestFile.csv" | JMeterUtils.getJMeterBinDir()+"/user.properties"          | JMeterUtils.getJMeterBinDir()+"/testfiles/testReport" | []
+            JMeterUtils.getJMeterBinDir()+"/testfiles/HTMLReportTestFile.csv" | JMeterUtils.getJMeterBinDir()+"/user.properties"          | JMeterUtils.getJMeterBinDir()+"/testfiles" | [
+                JMeterUtils.getResString("generate_report_ui.output_directory") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.NOT_EMPTY_DIRECTORY), outputDirectoryPath)
+            ]
+            JMeterUtils.getJMeterBinDir()+"/testfiles/HTMLReportTestFileMissing.csv" | JMeterUtils.getJMeterBinDir()+"/user.properties"          | JMeterUtils.getJMeterBinDir()+"/testfiles/testReport" | [
+                JMeterUtils.getResString("generate_report_ui.csv_file") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.NO_FILE), csvPath)
+            ]
+            ""                                                                | ""                                                        | ""                                                    | [
+                JMeterUtils.getResString("generate_report_ui.csv_file") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.NO_FILE), csvPath),
+                JMeterUtils.getResString("generate_report_ui.user_properties_file") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.NO_FILE), userPropertiesPath),
+                JMeterUtils.getResString("generate_report_ui.output_directory") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.CANNOT_CREATE_DIRECTORY), outputDirectoryPath)
+            ]
+            JMeterUtils.getJMeterBinDir()+"/testfiles/HTMLReportTestFile.csv" | JMeterUtils.getJMeterBinDir()+"/user.properties" | JMeterUtils.getJMeterBinDir()+"/testfiles/testReport/oneLevel/twolevel"            | [
+                JMeterUtils.getResString("generate_report_ui.output_directory") + MessageFormat.format(JMeterUtils.getResString(HtmlReportGenerator.CANNOT_CREATE_DIRECTORY), outputDirectoryPath)
+            ]
+    }
+    
+    def "check that report generation succeeds and statistic are generated"(){
+        setup:
+            File testDirectory = new File(JMeterUtils.getJMeterBinDir(), "/testfiles/testReport")
+            if(testDirectory.exists()) {
+                if (testDirectory.list().length>0) {
+                    FileUtils.cleanDirectory(testDirectory)
+                }
+            } else {
+                testDirectory.mkdir()
+            }
+            ObjectMapper mapper = new ObjectMapper()
+            File expected = new File(JMeterUtils.getJMeterBinDir(),"/testfiles/HTMLReportExpect.json")
+            JsonNode expectedRoot = null;
+            expected.withReader { jsonFileReader ->
+                expectedRoot = mapper.readTree(jsonFileReader)
+            }
+        when:
+            HtmlReportGenerator htmlReportGenerator = new HtmlReportGenerator(
+                    JMeterUtils.getJMeterBinDir() + "/testfiles/HTMLReportTestFile.csv",
+                    JMeterUtils.getJMeterBinDir() + "/user.properties", 
+                    JMeterUtils.getJMeterBinDir() + "/testfiles/testReport")
+            List<String> resultList = htmlReportGenerator.run()
+            File statistics = new File(JMeterUtils.getJMeterBinDir(), "/testfiles/testReport/statistics.json")
+            JsonNode actualRoot = null;
+            if (statistics.exists()) {
+                statistics.withReader { jsonFileReader -> 
+                    actualRoot = mapper.readTree(jsonFileReader)
+                }
+            }
+        then:
+            resultList.isEmpty()
+            statistics.exists()
+            expectedRoot == actualRoot
+        cleanup:
+            if(testDirectory.exists()) {
+                if (testDirectory.list().length>0) {
+                    FileUtils.cleanDirectory(testDirectory)
+                }
+            }
+    }
+    
+    def "check that report generation fails when format does not match and error is reported"(){
+        setup:
+            File testDirectory = new File(JMeterUtils.getJMeterBinDir(),"/testfiles/testReportThatShouldBeEmpty")
+            if(testDirectory.exists()) {
+                if (testDirectory.list().length>0) {
+                    FileUtils.cleanDirectory(testDirectory)
+                }
+            } else {
+                testDirectory.mkdir()
+            }
+        when:
+            HtmlReportGenerator htmlReportGenerator = new HtmlReportGenerator(
+                JMeterUtils.getJMeterBinDir() + "/testfiles/HTMLReportFalseTestFile.csv",
+                JMeterUtils.getJMeterBinDir() + "/user.properties", 
+                JMeterUtils.getJMeterBinDir() + "/testfiles/testReport")
+            List<String> resultList = htmlReportGenerator.run()
+        then:
+            testDirectory.list().length == 0
+            resultList.get(0).contains("An error occurred: Error while processing samples:Consumer failed with message")
+        cleanup:
+            if(testDirectory.exists()) {
+                if (testDirectory.list().length>0) {
+                    FileUtils.cleanDirectory(testDirectory)
+                }
+            }
+    }
+}

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Wed Mar  6 19:59:29 2019
@@ -107,6 +107,7 @@ Summary
 
 <h3>Report / Dashboard</h3>
 <ul>
+    <li><bug>59896</bug> Report / Dashboard : Add a menu entry to generate a report on demand from a CSV file. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
 </ul>
 
 <h3>General</h3>

Added: jmeter/trunk/xdocs/images/screenshots/html_report_menu.png
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/images/screenshots/html_report_menu.png?rev=1854942&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jmeter/trunk/xdocs/images/screenshots/html_report_menu.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Modified: jmeter/trunk/xdocs/usermanual/generating-dashboard.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/generating-dashboard.xml?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/generating-dashboard.xml (original)
+++ jmeter/trunk/xdocs/usermanual/generating-dashboard.xml Wed Mar  6 19:59:29 2019
@@ -7,6 +7,7 @@
 <!DOCTYPE document[
 <!ENTITY sect-num '14'>
 <!ENTITY hellip   "&#x02026;" >
+<!ENTITY rarr     "&#x02192;" >
 ]>
 
 <document prev="remote-test.html" next="realtime-results.html" id="$Id$">
@@ -586,6 +587,22 @@ jmeter.reportgenerator.exporter.html.fil
                 </subsection>
             </subsection>
 
+            <subsection name="&sect-num;.3.3 Generation using GUI Tools menu" anchor="report_gui">
+                <p>
+                You can generate the HTML report using menu item <code>Tools &rarr; Generate HTML report</code>:
+                <figure image="html_report_menu.png">Figure &sect-num;.1. HTML Report Dialog Menu</figure>
+                </p>
+                <p>For each parameters see the following table :</p>
+                <properties>
+	                <property name="Results file (csv or jtl)" required="Yes">The CSV output of a tes run</property>
+	                <property name="user.properties file" required="Yes">The user.properties file used to run the load test</property>
+	                <property name="Output directory" required="No">The directory where you want the report to be created(must be empty)</property>
+                </properties>
+                <p>If no output directory is defined, the controller will use <code>${JMETER_HOME}/bin/report-output</code>.</p>
+                <p>You then only have to click on the <code>Generate report</code> button and wait for an information dialog to appear
+                <note>If report generation takes more than two minutes, adjust the property <code>generate_report_ui.generation_timeout</code></note></p>
+             </subsection>
+
             <subsection name="&sect-num;.4 Default graphs" anchor="default_graphs">
                 <note>Due to limitations of this early version, each default graph
                     must be declared in JMeter properties. Otherwise, the graph

Modified: jmeter/trunk/xdocs/usermanual/properties_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/properties_reference.xml?rev=1854942&r1=1854941&r2=1854942&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/properties_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/properties_reference.xml Wed Mar  6 19:59:29 2019
@@ -1771,6 +1771,10 @@ JMETER-SERVER</source>
     End date of report using date_format property.<br/>
     Defaults to: nothing
 </property>
+<property name="generate_report_ui.generation_timeout">
+    Timeout in milliseconds for Report generation when using Tools &gt; Generate HTML report.<br/>
+    Defaults to: 120000
+</property>
 </properties>
 </section>
 <section name="&sect-num;.38 Additional property files to load" anchor="properties">



Mime
View raw message