diff --git a/src/main/java/hudson/plugins/performance/parsers/LocustParser.java b/src/main/java/hudson/plugins/performance/parsers/LocustParser.java index 4def8868..d1d881b5 100644 --- a/src/main/java/hudson/plugins/performance/parsers/LocustParser.java +++ b/src/main/java/hudson/plugins/performance/parsers/LocustParser.java @@ -1,6 +1,8 @@ package hudson.plugins.performance.parsers; +import hudson.Extension; import hudson.plugins.performance.data.HttpSample; +import hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor; import hudson.plugins.performance.reports.PerformanceReport; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; @@ -13,10 +15,11 @@ import java.io.Reader; import java.util.Date; import java.util.List; +import org.kohsuke.stapler.DataBoundConstructor; public class LocustParser extends AbstractParser { enum ReportColumns { - Method(0), Name(1), Requests(2), Failures(3), Median(4), + Type(0), Name(1), Requests(2), Failures(3), Median(4), Average(5), Min(6), Max(7), AvgContentSize(8), Rps(9); int column; @@ -30,10 +33,23 @@ int getColumn() { } } - public LocustParser(final String glob, final String percentiles, final String filterRegex) { + public LocustParser(String glob, String percentiles) { + super(glob, percentiles, PerformanceReport.INCLUDE_ALL); + } + + @DataBoundConstructor + public LocustParser(String glob, String percentiles, String filterRegex) { super(glob, percentiles, filterRegex); } + @Extension + public static class DescriptorImpl extends PerformanceReportParserDescriptor { + @Override + public String getDisplayName() { + return "Locust"; + } + } + @Override PerformanceReport parse(final File reportFile) throws Exception { PerformanceReport report = createPerformanceReport(); @@ -45,15 +61,15 @@ PerformanceReport parse(final File reportFile) throws Exception { for (CSVRecord record : reportData) { String name = record.get(ReportColumns.Name.getColumn()); - long average = Long.parseLong(record.get(ReportColumns.Average.getColumn())); - long min = Long.parseLong(record.get(ReportColumns.Min.getColumn())); - long max = Long.parseLong(record.get(ReportColumns.Max.getColumn())); - long failures = Long.parseLong(record.get(ReportColumns.Failures.getColumn())); - long success = Long.parseLong(record.get(ReportColumns.Requests.getColumn())); - float errors = Float.valueOf(failures / success); - long avgContentSize = Long.parseLong(record.get(ReportColumns.AvgContentSize.getColumn())); - - if (name.equals("Total")) { + long average = Double.valueOf(record.get(ReportColumns.Average.getColumn())).longValue(); + long min = Double.valueOf(record.get(ReportColumns.Min.getColumn())).longValue(); + long max = Double.valueOf(record.get(ReportColumns.Max.getColumn())).longValue(); + long failures = Double.valueOf(record.get(ReportColumns.Failures.getColumn())).longValue(); + long success = Double.valueOf(record.get(ReportColumns.Requests.getColumn())).longValue(); + long errors = Double.valueOf(failures / success).longValue(); + long avgContentSize = Double.valueOf(record.get(ReportColumns.AvgContentSize.getColumn())).longValue(); + + if (name.equals("Aggregated")) { report.setSummarizerSize(reportData.size() - 1); report.setSummarizerAvg(average); report.setSummarizerMin(min); @@ -93,6 +109,6 @@ List getCsvData(final File reportFile) { @Override public String getDefaultGlobPattern() { - return "**/*.csv"; + return "**/*_stats.csv"; } } diff --git a/src/main/java/hudson/plugins/performance/parsers/ParserDetector.java b/src/main/java/hudson/plugins/performance/parsers/ParserDetector.java index 6fc53372..7846b625 100644 --- a/src/main/java/hudson/plugins/performance/parsers/ParserDetector.java +++ b/src/main/java/hudson/plugins/performance/parsers/ParserDetector.java @@ -176,10 +176,9 @@ protected static String detectXMLFileType(final InputStream in) throws XMLStream */ private static boolean isLocustFileType(String line) { String[] fileLineHeader = line.replaceAll("\"", "").split(","); - String[] expectedHeaderFields = new String[]{"Method", "Name", "# requests", "# failures", - "Median response time", "Average response time", "Min response time", "Max response time", + String[] expectedHeaderFields = new String[]{"Type", "Name", "Request Count", "Failure Count", + "Median Response Time", "Average Response Time", "Min Response Time", "Max Response Time", "Average Content Size", "Requests/s"}; - return (Arrays.equals(fileLineHeader, expectedHeaderFields)); + return (Arrays.asList(fileLineHeader).containsAll(Arrays.asList(expectedHeaderFields))); } - } diff --git a/src/main/java/hudson/plugins/performance/parsers/ParserFactory.java b/src/main/java/hudson/plugins/performance/parsers/ParserFactory.java index d2445f2e..bc456217 100644 --- a/src/main/java/hudson/plugins/performance/parsers/ParserFactory.java +++ b/src/main/java/hudson/plugins/performance/parsers/ParserFactory.java @@ -29,6 +29,7 @@ public class ParserFactory { defaultGlobPatterns.put("**/*.xml", TaurusParser.class.getSimpleName()); defaultGlobPatterns.put("**/*.wrk", WrkSummarizerParser.class.getSimpleName()); defaultGlobPatterns.put("**/*.mdb", LoadRunnerParser.class.getSimpleName()); + defaultGlobPatterns.put("**/*_stats.csv", LocustParser.class.getSimpleName()); } public static List getParser(Run build, FilePath workspace, PrintStream logger, String glob, @@ -152,6 +153,8 @@ private static PerformanceReportParser getParser(String parserName, String glob, return new IagoParser(glob, percentiles, filterRegex); } else if (parserName.equals(LoadRunnerParser.class.getSimpleName())) { return new LoadRunnerParser(glob, percentiles, filterRegex); + } else if (parserName.equals(LocustParser.class.getSimpleName())) { + return new LocustParser(glob, percentiles, filterRegex); } else { throw new IllegalArgumentException("Unknown parser type: " + parserName); } diff --git a/src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html b/src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html index 4cbb3132..7da4fe55 100644 --- a/src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html +++ b/src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html @@ -18,6 +18,7 @@
  • Taurus reports: "**/*.xml"
  • JUnit report: "**/TEST-*.xml"
  • wrk report: "**/*.wrk"
  • +
  • Locust report: "**/*_stats.csv"
  • diff --git a/src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java b/src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java index 6444b200..ee33786f 100644 --- a/src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java +++ b/src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java @@ -10,7 +10,7 @@ import static org.junit.Assert.*; public class LocustParserTest { - final static String FILE_NAME = "test_results_requests.csv"; + final static String FILE_NAME = "test_results_stats.csv"; File requestReportFile; LocustParser locustParser; PerformanceReport report; @@ -18,7 +18,7 @@ public class LocustParserTest { @Before public void setUp() throws Exception { requestReportFile = new File(getClass().getResource(String.format("/%s", FILE_NAME)).toURI()); - locustParser = new LocustParser(null, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL); + locustParser = new LocustParser(null, PerformanceReportTest.DEFAULT_PERCENTILES); report = locustParser.parse(requestReportFile); } @@ -29,7 +29,7 @@ public void shouldCreateParser() throws Exception { @Test public void parserShouldReturnGlobPattern() throws Exception { - assertEquals("**/*.csv", locustParser.getDefaultGlobPattern()); + assertEquals("**/*_stats.csv", locustParser.getDefaultGlobPattern()); } @Test diff --git a/src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java b/src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java index 7928ab2f..501c657d 100644 --- a/src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java +++ b/src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java @@ -42,6 +42,9 @@ public void testFlow() throws Exception { filePath = getClass().getResource("/lr-session.mdb").toURI().getPath(); assertEquals(LoadRunnerParser.class.getSimpleName(), ParserDetector.detect(filePath)); + + filePath = getClass().getResource("/test_results_stats.csv").toURI().getPath(); + assertEquals(LocustParser.class.getSimpleName(), ParserDetector.detect(filePath)); } @Issue("JENKINS-44317") @@ -64,12 +67,6 @@ public void testIssue() throws Exception { assertEquals(JMeterParser.class.getSimpleName(), ParserDetector.detectXMLFileType(getHugeJMeterInputStream())); } - @Test - public void testLocustReport() throws Exception { - String filePath = getClass().getResource("/test_results_requests.csv").toURI().getPath(); - assertEquals(LocustParser.class.getSimpleName(), ParserDetector.detect(filePath)); - } - public static InputStream getHugeJMeterInputStream() { return new SequenceInputStream(getPrefixInputStream(), getInfiniteSampleInputStream()); } diff --git a/src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java b/src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java index c018b3cb..03d74808 100644 --- a/src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java +++ b/src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java @@ -56,6 +56,9 @@ public void testFlow() throws Exception { filePath = getClass().getResource("/summary.log").toURI().getPath(); assertTrue(ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof JmeterSummarizerParser); + + filePath = getClass().getResource("/test_results_stats.csv").toURI().getPath(); + assertTrue(ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof LocustParser); } @Test @@ -68,6 +71,7 @@ public void testFlowWithGlob() throws Exception { assertTrue(ParserFactory.getParser(null, null, null, "**/*.wrk", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof WrkSummarizerParser); assertTrue(ParserFactory.getParser(null, null, null, "**/*.csv", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof JMeterCsvParser); assertTrue(ParserFactory.getParser(null, null, null, "**/*.log", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof JmeterSummarizerParser); + assertTrue(ParserFactory.getParser(null, null, null, "**/*_stats.csv", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0) instanceof LocustParser); } @Test diff --git a/src/test/resources/test_results_requests.csv b/src/test/resources/test_results_requests.csv deleted file mode 100644 index 67e88731..00000000 --- a/src/test/resources/test_results_requests.csv +++ /dev/null @@ -1,6 +0,0 @@ -"Method","Name","# requests","# failures","Median response time","Average response time","Min response time","Max response time","Average Content Size","Requests/s" -"POST","big",638,10,400,370,198,906,1,1.07 -"POST","huge",72,0,800,865,411,1993,1,0.12 -"POST","medium",6535,0,200,221,197,469,1,10.91 -"POST","small",64219,0,200,221,196,1009,1,107.22 -"None","Total",71464,10000,200,223,196,1993,1,119.31 \ No newline at end of file diff --git a/src/test/resources/test_results_stats.csv b/src/test/resources/test_results_stats.csv new file mode 100644 index 00000000..4133d0ea --- /dev/null +++ b/src/test/resources/test_results_stats.csv @@ -0,0 +1,12 @@ +Type,Name,Request Count,Failure Count,Median Response Time,Average Response Time,Min Response Time,Max Response Time,Average Content Size,Requests/s,Failures/s,50%,66%,75%,80%,90%,95%,98%,99%,99.9%,99.99%,100% + +POST,big,638,10,400.0,370.51828915662696,198.03439999999955,906.8718,1.0,1.07917812740814,1.07917812740814,480,510,530,540,570,580,620,630,630,630,630 + +POST,huge,72,0,800.0,865.0785481927712,411.80529999999993,1993.6761999999989,1.0,0.12917812740814,4.37917812740814,420,470,510,530,550,570,610,700,700,700,700 + +POST,medium,6535,0,200.0,221.6907592592591,197.3858000000009,469.2998,1.0,10.913655762892281,4.273655762892281,440,480,500,510,530,560,580,630,630,630,630 + +POST,small,64219,0,200.0,221.009044155844,196.10569999999944,1009.6347999999989,1.0,107.062611033860563,4.062611033860563,450,490,520,530,540,570,580,590,590,590,590 + +,Aggregated,71464,10000,200.0,223.833905555556,196.10569999999944,1993.6761999999989,1.4444444444443,119.314623051569123,17.094623051569123,450,500,520,530,550,570,600,620,700,700,700 +