diff --git a/README.md b/README.md
index cf6b973..1052199 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Generating JUnit Report based on custom Key Performance Indicators (KPIs) applied to the JMeter Report CSV file
-This tool read KPI declarations in a file and apply the KPI assertion on a JMeter Report CSV file and generates a result file in JUnit XML format.
+This tool read KPI declarations in a file and apply the KPI assertion on a JMeter Report CSV file and generates a result file in JUnit XML format and others formats Html, Json and Csv.
JMeter Report CSV file is created with Listener :
- Summary Report, documentation at [Summary Report](https://jmeter.apache.org/usermanual/component_reference.html#Summary_Report)
@@ -50,19 +50,27 @@ Save in UTF-8 comma separator **no BOM** or csv with comma separator if you have
## Parameters
The tool have parameters :
-usage: io.github.vdaburon.jmeter.utils.reportkpi.JUnitReportFromJMReportCsv -csvJMReport <csvJMReport> [-csvLabelColumnName <csvLabelColumnName>]
- [-exitReturnOnFail <exitReturnOnFail>] [-help] [-junitFile <junitFile>] -kpiFile <kpiFile>
+usage: io.github.vdaburon.jmeter.utils.reportkpi.JUnitReportFromJMReportCsv -csvJMReport <csvJMReport> [-csvLabelColumnName
+ <csvLabelColumnName>] [-csvOutFile <csvOutFile>] [-divHtmlOutFile <divHtmlOutFile>] [-exitReturnOnFail <exitReturnOnFail>] [-help]
+ [-htmlOutFile <htmlOutFile>] [-jsonOutFile <jsonOutFile>] [-junitFile <junitFile>] -kpiFile <kpiFile>
io.github.vdaburon.jmeter.utils.reportkpi.JUnitReportFromJMReportCsv
- -csvJMReport <csvJMReport> JMeter report csv file (E.g : summary.csv or aggregate.csv or synthesis.csv)
- -csvLabelColumnName <csvLabelColumnName> Label Column Name in CSV JMeter Report (Default : Label)
- -exitReturnOnFail <exitReturnOnFail> if true then when kpi fail then create JUnit XML file and program return exit 1 (KO); if false
+ -csvJMReport <csvJMReport> JMeter report csv file (E.g: summary.csv or aggregate.csv or synthesis.csv)
+ -csvLabelColumnName <csvLabelColumnName> Label Column Name in CSV JMeter Report (Default: Label)
+ -csvOutFile <csvOutFile> Csv out file result optional (E.g: result.csv)
+ -divHtmlOutFile <divHtmlOutFile> Div Partial Html Page out file result optional (E.g: div_result.html), to include in an another
+ HTML Page
+ -exitReturnOnFail <exitReturnOnFail> If true then when kpi fail then create JUnit XML file and program return exit 1 (KO); If false
(Default) then create JUnit XML File and exit 0 (OK)
-help Help and show parameters
- -junitFile <junitFile> junit file name out (Default : jmeter-junit-plugin-jmreport.xml)
- -kpiFile <kpiFile> KPI file contains rule to check (E.g : kpi.csv)
-E.g : java -jar junit-reporter-kpi-from-jmeter-report-csv-<version>-jar-with-dependencies.jar -csvJMReport summary.csv -kpiFile kpi.csv -exitReturnOnFail true
-or more parameters : java -jar junit-reporter-kpi-from-jmeter-report-csv-<version>-jar-with-dependencies.jar -csvJMReport AggregateReport.csv -csvLabelColumnName Label
--kpiFile kpi_check.csv -junitFile junit.xml -exitReturnOnFail true
+ -htmlOutFile <htmlOutFile> Html out file result optional (E.g: result.html)
+ -jsonOutFile <jsonOutFile> Json out file result optional (E.g: result.json)
+ -junitFile <junitFile> JUnit XML file name out (Always created, default: TEST-jmeter-junit-plugin-jmreport.xml)
+ -kpiFile <kpiFile> KPI file contains rule to check (E.g: kpi.csv)
+E.g : java -jar junit-reporter-kpi-from-jmeter-report-csv-<version>-jar-with-dependencies.jar -csvJMReport summary.csv -kpiFile kpi.csv
+-exitReturnOnFail true
+or more parameters : java -jar junit-reporter-kpi-from-jmeter-report-csv-<version>-jar-with-dependencies.jar -csvJMReport
+AggregateReport.csv -csvLabelColumnName Label -kpiFile kpi_check.csv -junitFile junit.xml -htmlOutFile result.html -divHtmlOutFile
+div_result.html -csvOutFile result.csv -jsonOutFile result.json -exitReturnOnFail false
## JUnit Report XML file generated
@@ -95,6 +103,18 @@ A JUnit Report with KPIs display in Jenkins Build
If you click on link "Name Test" fail , you will show the fail message
![junit jenkins build detail fail](doc/images/junit_report_jenkins_detail_fail.png)
+## Html out format
+The result could be a html page ou partial html page (div)
+![html out format](doc/images/html_out_result.png)
+
+## Csv out format
+The result in a csv file
+![csv out format](doc/images/csv_out_result.png)
+
+## Json out format
+The result in a Json file
+![csv out format](doc/images/json_out_result.png)
+
## License
See the LICENSE file Apache 2 [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
@@ -104,7 +124,7 @@ The maven groupId, artifactId and version, this plugin is in the **Maven Central
```xml
io.github.vdaburon
junit-reporter-kpi-from-jmeter-report-csv
-1.3
+1.4
```
Just include the plugin in your `pom.xml` and execute `mvn verify`
or individual launch `mvn -DjmeterReportFile=synthesis.csv -DkpiFile=kpi.csv -DjunitFile=jmeter-junit-plugin-jmreport.xml exec:java@create_junit-report-kpi-from-jmeter-report`
@@ -122,7 +142,7 @@ or individual launch `mvn -DjmeterReportFile=synthesis.csv -DkpiFile=kpi.csv -Dj
io.github.vdaburon
junit-reporter-kpi-from-jmeter-report-csv
- 1.3
+ 1.4
@@ -170,6 +190,8 @@ java -jar junit-reporter-kpi-from-jmeter-report-csv-<version>-jar-with-dep
Usually this plugin is use with [jmeter-graph-tool-maven-plugin](https://github.com/vdaburon/jmeter-graph-tool-maven-plugin)
## Versions
+version 1.4 export result in html, json or csv format
+
Version 1.3 change Fail Message when Equality
Version 1.2 change package name (add reportkpi)
diff --git a/doc/images/csv_out_result.png b/doc/images/csv_out_result.png
new file mode 100644
index 0000000..e8d7311
Binary files /dev/null and b/doc/images/csv_out_result.png differ
diff --git a/doc/images/html_out_result.png b/doc/images/html_out_result.png
new file mode 100644
index 0000000..39f642f
Binary files /dev/null and b/doc/images/html_out_result.png differ
diff --git a/doc/images/json_out_result.png b/doc/images/json_out_result.png
new file mode 100644
index 0000000..fab308b
Binary files /dev/null and b/doc/images/json_out_result.png differ
diff --git a/pom.xml b/pom.xml
index 4917cad..ccec51b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,10 +6,10 @@
io.github.vdaburon
junit-reporter-kpi-from-jmeter-report-csv
- 1.3
+ 1.4
jar
Create a JUnit XML file with KPI rules from JMeter CSV Report
- A tool that creates a JUnit XML file with KPI rules from JMeter CSV Report
+ A tool that creates a JUnit XML file with KPI rules from JMeter CSV Report, export result in html, csv or json format
https://github.com/vdaburon/JUnitReportKpiJMeterReportCsv
2023
@@ -64,16 +64,34 @@
+
+
+ commons-cli
+ commons-cli
+ 1.5.0
+
+
+
org.apache.commons
commons-csv
1.10.0
+
+
+
+ org.freemarker
+ freemarker
+ 2.3.32
+
+
+
- commons-cli
- commons-cli
- 1.5.0
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.15.2
+
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/CheckKpiResult.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/CheckKpiResult.java
index ecc03cb..1c2d8d7 100644
--- a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/CheckKpiResult.java
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/CheckKpiResult.java
@@ -53,6 +53,10 @@ public boolean isKpiFail() {
return isKpiFail;
}
+ public boolean getKpiFail() {
+ return isKpiFail;
+ }
+
public void setKpiFail(boolean kpiFail) {
isKpiFail = kpiFail;
}
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/GlobalResult.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/GlobalResult.java
new file mode 100644
index 0000000..0fa4253
--- /dev/null
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/GlobalResult.java
@@ -0,0 +1,63 @@
+package io.github.vdaburon.jmeter.utils.reportkpi;
+
+import java.util.List;
+
+public class GlobalResult {
+ private String csvJmeterReport;
+ private String kpiFile;
+ private int numberOfKpis;
+ private int numberFailed;
+ List checkKpiResults;
+
+ public String getCsvJmeterReport() {
+ return csvJmeterReport;
+ }
+
+ public void setCsvJmeterReport(String csvJmeterReport) {
+ this.csvJmeterReport = csvJmeterReport;
+ }
+
+ public String getKpiFile() {
+ return kpiFile;
+ }
+
+ public void setKpiFile(String kpiFile) {
+ this.kpiFile = kpiFile;
+ }
+
+ public int getNumberOfKpis() {
+ return numberOfKpis;
+ }
+
+ public void setNumberOfKpis(int numberOfKpis) {
+ this.numberOfKpis = numberOfKpis;
+ }
+
+ public int getNumberFailed() {
+ return numberFailed;
+ }
+
+ public void setNumberFailed(int numberFailed) {
+ this.numberFailed = numberFailed;
+ }
+
+ public List getCheckKpiResults() {
+ return checkKpiResults;
+ }
+
+ public void setCheckKpiResults(List checkKpiResults) {
+ this.checkKpiResults = checkKpiResults;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("GlobalResult{");
+ sb.append("csvJmeterReport='").append(csvJmeterReport).append('\'');
+ sb.append(", kpiFile='").append(kpiFile).append('\'');
+ sb.append(", numberOfKpis=").append(numberOfKpis);
+ sb.append(", numberFailed=").append(numberFailed);
+ sb.append(", checkKpiResults=").append(checkKpiResults);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/JUnitReportFromJMReportCsv.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/JUnitReportFromJMReportCsv.java
index d6a6440..d1772ef 100644
--- a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/JUnitReportFromJMReportCsv.java
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/JUnitReportFromJMReportCsv.java
@@ -1,11 +1,14 @@
package io.github.vdaburon.jmeter.utils.reportkpi;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import freemarker.template.TemplateException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
@@ -24,13 +27,23 @@
public class JUnitReportFromJMReportCsv {
private static final Logger LOGGER = Logger.getLogger(JUnitReportFromJMReportCsv.class.getName());
+
+ // System.exit return
public static final int K_RETURN_OK = 0;
public static final int K_RETURN_KO = 1;
- public static final String K_JUNIT_XML_FILE_DEFAULT = "jmeter-junit-plugin-jmreport.xml";
+
+ // Defaut JUnit XML Report file
+ public static final String K_JUNIT_XML_FILE_DEFAULT = "TEST-jmeter-junit-plugin-jmreport.xml";
+
+ // OPTions for Command Line Parameters
public static final String K_CVS_JM_REPORT_OPT = "csvJMReport";
public static final String K_CSV_LABEL_COLUMN_NAME_OPT = "csvLabelColumnName";
public static final String K_KPI_FILE_OPT = "kpiFile";
public static final String K_JUNIT_XML_FILE_OPT = "junitFile";
+ public static final String K_OUT_HTML_FILE_OPT = "htmlOutFile";
+ public static final String K_OUT_DIV_HTML_FILE_OPT = "divHtmlOutFile";
+ public static final String K_OUT_CSV_FILE_OPT = "csvOutFile";
+ public static final String K_OUT_JSON_FILE_OPT = "jsonOutFile";
public static final String K_EXIT_RETURN_ON_FAIL_OPT = "exitReturnOnFail";
@@ -41,10 +54,22 @@ public class JUnitReportFromJMReportCsv {
public static final String K_CSV_COL_COMPARATOR = "comparator";
public static final String K_CSV_COL_THREASHOLD = "threshold";
+ // Column name for Html or CSV out file
+ public static final String K_CSV_COL_OUT_RESULT = "result";
+ public static final String K_CSV_COL_OUT_FAIL_MSG = "fail_msg";
+
+ private static final String K_NOT_SET = "NOT SET";
- // column name Label in jmeter csv report
+ // Column name Label in jmeter csv report
public static final String K_CSV_JMREPORT_COL_LABEL_DEFAULT = "Label";
+ // Freemarker Html Template
+ public static final String K_FREEMARKER_HTML_TEMPLATE_DIRECTORY = "/templates_freemarker";
+ public static final String K_FREEMARKER_HTML_TEMPLATE = "template_html_result.ftl";
+ public static final String K_FREEMARKER_DIV_HTML_TEMPLATE = "template_div_result.ftl";
+
+ public static final int K_TYPE_HTML_TEMPLATE = 1;
+ public static final int K_TYPE_DIV_HTML_TEMPLATE = 2;
public static final int K_FAIL_MESSAGE_SIZE_MAX = 1024;
public static void main(String[] args) {
@@ -61,10 +86,15 @@ public static void main(String[] args) {
}
int exitReturn = K_RETURN_KO;
- String csvJmeterReport = "NOT SET";
+ String csvJmeterReport = K_NOT_SET;
String csvLabelColumnName = K_CSV_JMREPORT_COL_LABEL_DEFAULT;
- String kpiFile = "NOT SET";
+ String kpiFile = K_NOT_SET;
String junitFile = K_JUNIT_XML_FILE_DEFAULT;
+ String htmlFile = K_NOT_SET;
+ String divHtmlFile = K_NOT_SET;
+ String csvFile = K_NOT_SET;
+ String jsonFile = K_NOT_SET;
+
boolean exitOnFailKpi = false;
String sTmp;
@@ -88,6 +118,26 @@ public static void main(String[] args) {
junitFile = sTmp;
}
+ sTmp = (String) parseProperties.get(K_OUT_HTML_FILE_OPT);
+ if (sTmp != null && sTmp.length() > 1) {
+ htmlFile = sTmp;
+ }
+
+ sTmp = (String) parseProperties.get(K_OUT_DIV_HTML_FILE_OPT);
+ if (sTmp != null && sTmp.length() > 1) {
+ divHtmlFile = sTmp;
+ }
+
+ sTmp = (String) parseProperties.get(K_OUT_CSV_FILE_OPT);
+ if (sTmp != null && sTmp.length() > 1) {
+ csvFile = sTmp;
+ }
+
+ sTmp = (String) parseProperties.get(K_OUT_JSON_FILE_OPT);
+ if (sTmp != null && sTmp.length() > 1) {
+ jsonFile = sTmp;
+ }
+
sTmp = (String) parseProperties.get(K_EXIT_RETURN_ON_FAIL_OPT);
if (sTmp != null) {
exitOnFailKpi = Boolean.parseBoolean(sTmp);
@@ -95,13 +145,16 @@ public static void main(String[] args) {
}
boolean isKpiFail = false;
LOGGER.info("Parameters CLI:" + parseProperties);
+
try {
- isKpiFail = analyseCsvJMReportWithKpiRules(csvJmeterReport,csvLabelColumnName, kpiFile, junitFile);
+ isKpiFail = analyseCsvJMReportWithKpiRules(csvJmeterReport, csvLabelColumnName, kpiFile, junitFile, htmlFile, divHtmlFile, csvFile, jsonFile);
LOGGER.info("isKpiFail=" + isKpiFail);
} catch (Exception ex) {
- LOGGER.warning(ex.toString());
+ LOGGER.warning(stackTraceInString(ex));
+ isKpiFail = true;
exitReturn = K_RETURN_KO;
}
+
if (exitOnFailKpi && isKpiFail) {
// at least one kpi rule failure => exit 1
exitReturn = K_RETURN_KO;
@@ -109,6 +162,7 @@ public static void main(String[] args) {
} else {
exitReturn = K_RETURN_OK;
}
+
long endTimeMs = System.currentTimeMillis();
LOGGER.info("Duration ms=" + (endTimeMs - startTimeMs));
LOGGER.info("End main (exit " + exitReturn + ")");
@@ -118,20 +172,31 @@ public static void main(String[] args) {
/**
* Analyse the kpi verifications on JMeter report values
- * @param csvJmeterReport the JMeter Report CSV format
+ *
+ * @param csvJmeterReport the JMeter Report CSV format
* @param csvLabelColumnName the Label Column Name (default : Label)
- * @param kpiFile the kpi contains kpi declaration
- * @param junitFile the JUnit XML out file to create
+ * @param kpiFile the kpi contains kpi declaration
+ * @param junitFile the JUnit XML out file to create
+ * @param htmlFile the Html out file result optional
+ * @param divHtmlFile partial Div Html out file result optional
+ * @param csvFile the Cvs out file result optional
+ * @param jsonFile the Json out file result optional
* @return is Fail true or false, a kpi is fail or not
- * @throws IOException file exception
+ * @throws IOException file exception
* @throws ParserConfigurationException error reading csv file
- * @throws TransformerException error writing JUnit XML file
+ * @throws TransformerException error writing JUnit XML file
*/
- private static boolean analyseCsvJMReportWithKpiRules(String csvJmeterReport, String csvLabelColumnName, String kpiFile, String junitFile) throws IOException, ParserConfigurationException, TransformerException {
+ private static boolean analyseCsvJMReportWithKpiRules(String csvJmeterReport, String csvLabelColumnName, String kpiFile, String junitFile, String htmlFile, String divHtmlFile, String csvFile, String jsonFile) throws IOException, ParserConfigurationException, TransformerException, TemplateException {
boolean isFail = false;
List csvJMReportLines = UtilsCsvFile.readCsvFile(csvJmeterReport);
List csvKpiLines = UtilsCsvFile.readCsvFile(kpiFile);
+ GlobalResult globalResult = new GlobalResult();
+ List checkKpiResults = new ArrayList<>();
+ globalResult.setCheckKpiResults(checkKpiResults);
+ globalResult.setCsvJmeterReport(csvJmeterReport);
+ globalResult.setKpiFile(kpiFile);
+ int nbFailed = 0;
Document document = UtilsJUnitXml.createJUnitRootDocument();
for (int i = 0; i < csvKpiLines.size(); i++) {
CSVRecord recordKpiLine = csvKpiLines.get(i);
@@ -141,22 +206,47 @@ private static boolean analyseCsvJMReportWithKpiRules(String csvJmeterReport, St
CheckKpiResult checkKpiResult = verifyKpi(recordKpiLine, csvJMReportLines, csvLabelColumnName);
if (checkKpiResult.isKpiFail()) {
isFail = true;
- String className = checkKpiResult.getMetricCsvColumnName() + " (" + checkKpiResult.getLabelRegex() + ") " + checkKpiResult.getComparator() + " " + checkKpiResult.getThreshold();
- UtilsJUnitXml.addTestCaseFailure(document,checkKpiResult.getNameKpi(), className, checkKpiResult.getFailMessage());
+ nbFailed++;
+ String className = checkKpiResult.getMetricCsvColumnName() + " (" + checkKpiResult.getLabelRegex() + ") " + checkKpiResult.getComparator() + " " + checkKpiResult.getThreshold();
+ UtilsJUnitXml.addTestCaseFailure(document, checkKpiResult.getNameKpi(), className, checkKpiResult.getFailMessage());
} else {
- String className = checkKpiResult.getMetricCsvColumnName() + " (" + checkKpiResult.getLabelRegex() + ") " + checkKpiResult.getComparator() + " " + checkKpiResult.getThreshold();
- UtilsJUnitXml.addTestCaseOk(document,checkKpiResult.getNameKpi(), className);
+ String className = checkKpiResult.getMetricCsvColumnName() + " (" + checkKpiResult.getLabelRegex() + ") " + checkKpiResult.getComparator() + " " + checkKpiResult.getThreshold();
+ UtilsJUnitXml.addTestCaseOk(document, checkKpiResult.getNameKpi(), className);
}
+ globalResult.getCheckKpiResults().add(checkKpiResult);
}
+ globalResult.setNumberOfKpis(csvKpiLines.size());
+ globalResult.setNumberFailed(nbFailed);
+
LOGGER.info("Write junitFile=" + junitFile);
- UtilsJUnitXml.saveXmlInFile(document, junitFile);
+ UtilsJUnitXml.saveXmFile(document, junitFile);
+ if (!K_NOT_SET.equals(htmlFile)) {
+ LOGGER.info("Write html file=" + htmlFile);
+ UtilsHtml.saveHtmlFile(globalResult, htmlFile, K_TYPE_HTML_TEMPLATE);
+ }
+
+ if (!K_NOT_SET.equals(divHtmlFile)) {
+ LOGGER.info("Write Div Html file=" + divHtmlFile);
+ UtilsHtml.saveHtmlFile(globalResult, divHtmlFile, K_TYPE_DIV_HTML_TEMPLATE);
+ }
+
+ if (!K_NOT_SET.equals(csvFile)) {
+ LOGGER.info("Write csv file=" + csvFile);
+ UtilsCsvFile.saveCsvFile(globalResult, csvFile);
+ }
+
+ if (!K_NOT_SET.equals(jsonFile)) {
+ LOGGER.info("Write json file=" + jsonFile);
+ UtilsJsonFile.saveJsonFile(globalResult, jsonFile);
+ }
return isFail;
}
/**
* verify one kpi for lines in csv JMeter Report
- * @param recordKpiLine a kpi line to verify
- * @param csvJMReportLines all lines in JMeter Report
+ *
+ * @param recordKpiLine a kpi line to verify
+ * @param csvJMReportLines all lines in JMeter Report
* @param csvLabelColumnName the Label Column name in the JMeter Report (usually : Label)
* @return the result of the kpi verification and the failure message if kpi fail
*/
@@ -178,16 +268,16 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
checkKpiResult.setThreshold(threshold.trim());
checkKpiResult.setKpiFail(false);
- checkKpiResult.setFailMessage("NOT SET");
+ checkKpiResult.setFailMessage("");
- Pattern patternRegex = Pattern.compile(labelRegex) ;
+ Pattern patternRegex = Pattern.compile(labelRegex);
boolean isFailKpi = false;
boolean isFirstFail = true;
for (int i = 0; i < csvJMReportLines.size(); i++) {
CSVRecord recordJMReportLine = csvJMReportLines.get(i);
String label = recordJMReportLine.get(csvLabelColumnName);
- Matcher matcherRegex = patternRegex.matcher(label) ;
+ Matcher matcherRegex = patternRegex.matcher(label);
if (matcherRegex.matches()) {
String sMetric = recordJMReportLine.get(metricCsvColumnName);
LOGGER.fine("sMetric=<" + sMetric + ">");
@@ -214,18 +304,12 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
isFailKpi = true;
if (isFirstFail) {
isFirstFail = false;
- String failMessage = "Actual value " + dMetric + " exceeds or equals threshold " + dThreshold + " for samples matching \"" + labelRegex + "\"; fail label(s) \"" + label + "\""; // Actual value 2908,480000 exceeds threshold 2500,000000 for samples matching "@SC01_P03_DUMMY"
+ String failMessage = "Actual value " + dMetric + " exceeds or equals threshold " + dThreshold + " for samples matching \"" + labelRegex + "\"; fail label(s) \"" + label + "\""; // Actual value 2908,480000 exceeds threshold 2500,000000 for samples matching "@SC01_P03_DUMMY"
checkKpiResult.setKpiFail(true);
checkKpiResult.setFailMessage(failMessage);
} else {
String failMessage = checkKpiResult.getFailMessage();
- if ((failMessage.length() + label.length()) < K_FAIL_MESSAGE_SIZE_MAX) {
- failMessage += ", \"" + label + "\"";
- } else {
- if (!failMessage.endsWith(" ...")) {
- failMessage += " ...";
- }
- }
+ failMessage = concatFailMessage(label, failMessage);
checkKpiResult.setFailMessage(failMessage);
}
}
@@ -242,13 +326,7 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
checkKpiResult.setFailMessage(failMessage);
} else {
String failMessage = checkKpiResult.getFailMessage();
- if ((failMessage.length() + label.length()) < K_FAIL_MESSAGE_SIZE_MAX) {
- failMessage += ", \"" + label + "\"";
- } else {
- if (!failMessage.endsWith(" ...")) {
- failMessage += " ...";
- }
- }
+ failMessage = concatFailMessage(label, failMessage);
checkKpiResult.setFailMessage(failMessage);
}
}
@@ -265,13 +343,7 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
checkKpiResult.setFailMessage(failMessage);
} else {
String failMessage = checkKpiResult.getFailMessage();
- if ((failMessage.length() + label.length()) < K_FAIL_MESSAGE_SIZE_MAX) {
- failMessage += ", \"" + label + "\"";
- } else {
- if (!failMessage.endsWith(" ...")) {
- failMessage += " ...";
- }
- }
+ failMessage = concatFailMessage(label, failMessage);
checkKpiResult.setFailMessage(failMessage);
}
}
@@ -288,13 +360,7 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
checkKpiResult.setFailMessage(failMessage);
} else {
String failMessage = checkKpiResult.getFailMessage();
- if ((failMessage.length() + label.length()) < K_FAIL_MESSAGE_SIZE_MAX) {
- failMessage += ", \"" + label + "\"";
- } else {
- if (!failMessage.endsWith(" ...")) {
- failMessage += " ...";
- }
- }
+ failMessage = concatFailMessage(label, failMessage);
checkKpiResult.setFailMessage(failMessage);
}
}
@@ -307,6 +373,23 @@ private static CheckKpiResult verifyKpi(CSVRecord recordKpiLine, List
return checkKpiResult;
}
+ private static String concatFailMessage(String label, String failMessage) {
+ if ((failMessage.length() + label.length()) < K_FAIL_MESSAGE_SIZE_MAX) {
+ failMessage += ", \"" + label + "\"";
+ } else {
+ if (!failMessage.endsWith(" ...")) {
+ failMessage += " ...";
+ }
+ }
+ return failMessage;
+ }
+
+ private static String stackTraceInString(Exception ex) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ ex.printStackTrace(pw);
+ return sw.toString();
+ }
/**
* If incorrect parameter or help, display usage
* @param options options and cli parameters
@@ -316,7 +399,8 @@ private static void helpUsage(Options options) {
String footer = "E.g : java -jar junit-reporter-kpi-from-jmeter-report-csv--jar-with-dependencies.jar -" + K_CVS_JM_REPORT_OPT + " summary.csv -" +
K_KPI_FILE_OPT + " kpi.csv -" + K_EXIT_RETURN_ON_FAIL_OPT + " true\n";
footer += "or more parameters : java -jar junit-reporter-kpi-from-jmeter-report-csv--jar-with-dependencies.jar -" + K_CVS_JM_REPORT_OPT + " AggregateReport.csv -"
- + K_CSV_LABEL_COLUMN_NAME_OPT + " Label -" + K_KPI_FILE_OPT + " kpi_check.csv -" + K_JUNIT_XML_FILE_OPT + " junit.xml -" + K_EXIT_RETURN_ON_FAIL_OPT + " true\n";
+ + K_CSV_LABEL_COLUMN_NAME_OPT + " Label -" + K_KPI_FILE_OPT + " kpi_check.csv -" + K_JUNIT_XML_FILE_OPT + " junit.xml -" +
+ K_OUT_HTML_FILE_OPT + " result.html -" + K_OUT_DIV_HTML_FILE_OPT + " div_result.html -" + K_OUT_CSV_FILE_OPT + " result.csv -" + K_OUT_JSON_FILE_OPT + " result.json -" + K_EXIT_RETURN_ON_FAIL_OPT + " false\n";
formatter.printHelp(140, JUnitReportFromJMReportCsv.class.getName(),
JUnitReportFromJMReportCsv.class.getName(), options, footer, true);
}
@@ -360,6 +444,22 @@ private static Properties parseOption(Options optionsP, String[] args) throws Pa
properties.setProperty(K_JUNIT_XML_FILE_OPT, line.getOptionValue(K_JUNIT_XML_FILE_OPT));
}
+ if (line.hasOption(K_OUT_HTML_FILE_OPT)) {
+ properties.setProperty(K_OUT_HTML_FILE_OPT, line.getOptionValue(K_OUT_HTML_FILE_OPT));
+ }
+
+ if (line.hasOption(K_OUT_DIV_HTML_FILE_OPT)) {
+ properties.setProperty(K_OUT_DIV_HTML_FILE_OPT, line.getOptionValue(K_OUT_DIV_HTML_FILE_OPT));
+ }
+
+ if (line.hasOption(K_OUT_CSV_FILE_OPT)) {
+ properties.setProperty(K_OUT_CSV_FILE_OPT, line.getOptionValue(K_OUT_CSV_FILE_OPT));
+ }
+
+ if (line.hasOption(K_OUT_JSON_FILE_OPT)) {
+ properties.setProperty(K_OUT_JSON_FILE_OPT, line.getOptionValue(K_OUT_JSON_FILE_OPT));
+ }
+
if (line.hasOption(K_EXIT_RETURN_ON_FAIL_OPT)) {
properties.setProperty(K_EXIT_RETURN_ON_FAIL_OPT, line.getOptionValue(K_EXIT_RETURN_ON_FAIL_OPT));
}
@@ -380,35 +480,63 @@ private static Options createOptions() {
Option csvJmeterReportFileOpt = Option.builder(K_CVS_JM_REPORT_OPT).argName(K_CVS_JM_REPORT_OPT)
.hasArg(true)
.required(true)
- .desc("JMeter report csv file (E.g : summary.csv or aggregate.csv or synthesis.csv)")
+ .desc("JMeter report csv file (E.g: summary.csv or aggregate.csv or synthesis.csv)")
.build();
options.addOption(csvJmeterReportFileOpt);
Option csvLabelColumnNameOpt = Option.builder(K_CSV_LABEL_COLUMN_NAME_OPT).argName(K_CSV_LABEL_COLUMN_NAME_OPT)
.hasArg(true)
.required(false)
- .desc("Label Column Name in CSV JMeter Report (Default : " + K_CSV_JMREPORT_COL_LABEL_DEFAULT + ")")
+ .desc("Label Column Name in CSV JMeter Report (Default: " + K_CSV_JMREPORT_COL_LABEL_DEFAULT + ")")
.build();
options.addOption(csvLabelColumnNameOpt);
Option kpiFileOpt = Option.builder(K_KPI_FILE_OPT).argName(K_KPI_FILE_OPT)
.hasArg(true)
.required(true)
- .desc("KPI file contains rule to check (E.g : kpi.csv)")
+ .desc("KPI file contains rule to check (E.g: kpi.csv)")
.build();
options.addOption(kpiFileOpt);
Option junitXmlOutOpt = Option.builder(K_JUNIT_XML_FILE_OPT).argName(K_JUNIT_XML_FILE_OPT)
.hasArg(true)
.required(false)
- .desc("junit file name out (Default : " + K_JUNIT_XML_FILE_DEFAULT + ")")
+ .desc("JUnit XML file name out (Always created, default: " + K_JUNIT_XML_FILE_DEFAULT + ")")
.build();
options.addOption(junitXmlOutOpt);
+ Option htmlOutOpt = Option.builder(K_OUT_HTML_FILE_OPT).argName(K_OUT_HTML_FILE_OPT)
+ .hasArg(true)
+ .required(false)
+ .desc("Html out file result optional (E.g: result.html)")
+ .build();
+ options.addOption(htmlOutOpt);
+
+ Option divHtmlOutOpt = Option.builder(K_OUT_DIV_HTML_FILE_OPT).argName(K_OUT_DIV_HTML_FILE_OPT)
+ .hasArg(true)
+ .required(false)
+ .desc("Div Partial Html Page out file result optional (E.g: div_result.html), to include in an another HTML Page")
+ .build();
+ options.addOption(divHtmlOutOpt);
+
+ Option csvOutOpt = Option.builder(K_OUT_CSV_FILE_OPT).argName(K_OUT_CSV_FILE_OPT)
+ .hasArg(true)
+ .required(false)
+ .desc("Csv out file result optional (E.g: result.csv)")
+ .build();
+ options.addOption(csvOutOpt);
+
+ Option jsonOutOpt = Option.builder(K_OUT_JSON_FILE_OPT).argName(K_OUT_JSON_FILE_OPT)
+ .hasArg(true)
+ .required(false)
+ .desc("Json out file result optional (E.g: result.json)")
+ .build();
+ options.addOption(jsonOutOpt);
+
Option exitReturnOnFailOpt = Option.builder(K_EXIT_RETURN_ON_FAIL_OPT).argName(K_EXIT_RETURN_ON_FAIL_OPT)
.hasArg(true)
.required(false)
- .desc("if true then when kpi fail then create JUnit XML file and program return exit 1 (KO); if false (Default) then create JUnit XML File and exit 0 (OK)")
+ .desc("If true then when kpi fail then create JUnit XML file and program return exit 1 (KO); If false (Default) then create JUnit XML File and exit 0 (OK)")
.build();
options.addOption(exitReturnOnFailOpt);
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsCsvFile.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsCsvFile.java
index 14a139c..6344aac 100644
--- a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsCsvFile.java
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsCsvFile.java
@@ -1,9 +1,13 @@
package io.github.vdaburon.jmeter.utils.reportkpi;
import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;
-import java.io.*;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
@@ -26,4 +30,39 @@ public static List readCsvFile(String fileIn) throws IOException {
in.close();
return listRecordsBetweenFirstAndLast;
}
+
+ /**
+ * Write the KPIs Lines Result in a CSV file (
+ * @param globalResult Global KPIs result
+ * @param csvFile Csv out file result
+ * @throws IOException
+ */
+ public static void saveCsvFile(GlobalResult globalResult, String csvFile) throws IOException {
+ String[] headers = {
+ JUnitReportFromJMReportCsv.K_CSV_COL_NAME_KPI,
+ JUnitReportFromJMReportCsv.K_CSV_LABEL_COLUMN_NAME_OPT,
+ JUnitReportFromJMReportCsv.K_CSV_COL_LABEL_REGEX,
+ JUnitReportFromJMReportCsv.K_CSV_COL_COMPARATOR,
+ JUnitReportFromJMReportCsv.K_CSV_COL_THREASHOLD,
+ JUnitReportFromJMReportCsv.K_CSV_COL_OUT_RESULT,
+ JUnitReportFromJMReportCsv.K_CSV_COL_OUT_FAIL_MSG
+ };
+
+ FileWriter fileWrite = new FileWriter(csvFile);
+
+ CSVFormat csvFormat = CSVFormat.RFC4180.builder()
+ .setHeader(headers)
+ .build();
+ List checkKpiResults = globalResult.getCheckKpiResults();
+ CSVPrinter printer = new CSVPrinter(fileWrite, csvFormat);
+ for (int i = 0; i < checkKpiResults.size(); i++) {
+ CheckKpiResult checkKpiResult = (CheckKpiResult) checkKpiResults.get(i);
+ String sResult = checkKpiResult.isKpiFail()?"fail":"sucess";
+ String sFailMessage = checkKpiResult.getFailMessage() != null?checkKpiResult.getFailMessage():"";
+
+ printer.printRecord(checkKpiResult.getNameKpi(), checkKpiResult.getMetricCsvColumnName(), checkKpiResult.getLabelRegex(), checkKpiResult.getComparator(),
+ checkKpiResult.getThreshold(), sResult, sFailMessage);
+ }
+ printer.close();
+ }
}
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsFile.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsFile.java
new file mode 100644
index 0000000..5317b96
--- /dev/null
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsFile.java
@@ -0,0 +1,19 @@
+package io.github.vdaburon.jmeter.utils.reportkpi;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class UtilsFile {
+
+ public static void writeFileUtf8(String fileName, String toWrite) throws java.io.IOException {
+ Path path = Paths.get(fileName);
+ BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
+ writer.append(toWrite);
+ writer.newLine();
+ writer.close();
+ }
+}
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsHtml.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsHtml.java
new file mode 100644
index 0000000..8019b50
--- /dev/null
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsHtml.java
@@ -0,0 +1,70 @@
+package io.github.vdaburon.jmeter.utils.reportkpi;
+
+import freemarker.core.HTMLOutputFormat;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateExceptionHandler;
+import freemarker.template.Version;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public class UtilsHtml {
+
+ private static Configuration cfg = null;
+
+ /**
+ * Initialise the Freemarker Template Engine for Html result
+ * @throws IOException
+ */
+ public static void init() throws IOException {
+ cfg = new Configuration();
+ cfg.setClassForTemplateLoading(UtilsHtml.class, JUnitReportFromJMReportCsv.K_FREEMARKER_HTML_TEMPLATE_DIRECTORY);
+
+ cfg.setIncompatibleImprovements(new Version(2, 3, 22));
+ cfg.setDefaultEncoding("UTF-8");
+ cfg.setLocale(Locale.US);
+ cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
+ cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+
+ }
+
+ /**
+ * Write the Global KPIs Result in a Html format
+ * @param globalResult contains the KPIs results
+ * @param htmlFileOut Html out file result
+ * @throws IOException can write the file
+ * @throws TemplateException can read the template freemaker file
+ */
+ public static void saveHtmlFile(GlobalResult globalResult, String htmlFileOut, int typeTemplate) throws IOException, TemplateException {
+ if (cfg == null) {
+ init();
+ }
+ Template template = null;
+ if (typeTemplate == JUnitReportFromJMReportCsv.K_TYPE_HTML_TEMPLATE) {
+ template = cfg.getTemplate(JUnitReportFromJMReportCsv.K_FREEMARKER_HTML_TEMPLATE);
+ }
+
+ if (typeTemplate == JUnitReportFromJMReportCsv.K_TYPE_DIV_HTML_TEMPLATE) {
+ template = cfg.getTemplate(JUnitReportFromJMReportCsv.K_FREEMARKER_DIV_HTML_TEMPLATE);
+ }
+
+ Map root = new HashMap<>();
+ root.put("globalResult", globalResult);
+ Writer fileWriter = new FileWriter(new File(htmlFileOut));
+ try {
+ template.process(root, fileWriter);
+ } finally {
+ fileWriter.close();
+ }
+
+ }
+
+}
+
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJUnitXml.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJUnitXml.java
index 272e6aa..ef9bd7f 100644
--- a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJUnitXml.java
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJUnitXml.java
@@ -15,11 +15,14 @@
import javax.xml.transform.stream.StreamResult;
import java.io.File;
+import java.util.logging.Logger;
+
/**
* Utility Class to create a JUnit DOM, add testcase and write JUnit XML file
*/
public class UtilsJUnitXml {
+ private static final Logger LOGGER = Logger.getLogger(UtilsJUnitXml.class.getName());
/**
* Create the DOM for a JUnit XML file
* @return the DOM with testsuite root element
@@ -149,7 +152,7 @@ public static void addTestCaseFailure(Document document, String classname, Stri
* @param junitXmlFileOut XML file to write
* @throws TransformerException error when write XML file
*/
- public static void saveXmlInFile(Document document, String junitXmlFileOut) throws TransformerException {
+ public static void saveXmFile(Document document, String junitXmlFileOut) throws TransformerException {
// create the xml file
//transform the DOM Object to an XML File
TransformerFactory transformerFactory = TransformerFactory.newInstance();
@@ -160,4 +163,5 @@ public static void saveXmlInFile(Document document, String junitXmlFileOut) thro
StreamResult streamResult = new StreamResult(new File(junitXmlFileOut));
transformer.transform(domSource, streamResult);
}
+
}
diff --git a/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJsonFile.java b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJsonFile.java
new file mode 100644
index 0000000..241ddf2
--- /dev/null
+++ b/src/main/java/io/github/vdaburon/jmeter/utils/reportkpi/UtilsJsonFile.java
@@ -0,0 +1,16 @@
+package io.github.vdaburon.jmeter.utils.reportkpi;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import freemarker.template.TemplateException;
+
+import java.io.File;
+import java.io.IOException;
+
+public class UtilsJsonFile {
+ public static void saveJsonFile(GlobalResult globalResult, String jsonFileOut) throws IOException, TemplateException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+ objectMapper.writeValue(new File(jsonFileOut), globalResult);
+ }
+}
diff --git a/src/main/resources/templates_freemarker/template_div_result.ftl b/src/main/resources/templates_freemarker/template_div_result.ftl
new file mode 100644
index 0000000..6d95389
--- /dev/null
+++ b/src/main/resources/templates_freemarker/template_div_result.ftl
@@ -0,0 +1,41 @@
+
+
+
HTML KPIs Result From JMeter Report Csv
+
Files In
+
+ File with KPIs | ${globalResult.kpiFile} |
+ File CSV Report | ${globalResult.csvJmeterReport} |
+
+
+
Test Summary
+
+ Number of failed tests | style="color:Red;bold"#if>>${globalResult.numberFailed} |
+ Number of tests | ${globalResult.numberOfKpis} |
+
+
+
Table KPIs Results
+
+ name_kpi | metric_csv_column_name | label_regex | comparator | threshold | result | fail_msg |
+ <#list globalResult.checkKpiResults as checkKpiResult>
+
+ ${checkKpiResult.nameKpi} |
+ ${checkKpiResult.metricCsvColumnName} |
+ ${checkKpiResult.labelRegex} |
+ ${checkKpiResult.comparator} |
+ ${checkKpiResult.threshold} |
+ <#if checkKpiResult.kpiFail>fail<#else>sucess#if> |
+ <#if checkKpiResult.kpiFail>${checkKpiResult.failMessage}#if> |
+
+ #list>
+
+