package hudson.plugins.performance.parsers;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Auto-detect parser for file
*/
public class ParserDetector {
/**
* Detect report file type using file content.
* @return report file type.
*/
public static String detect(String reportPath) throws IOException {
final BufferedReader reader = new BufferedReader(new FileReader(new File(reportPath)));
String line = reader.readLine();
if (line == null) {
throw new IllegalArgumentException("File " + reportPath + " is empty");
}
if (line.startsWith("<?xml")) {
return detectXMLFileType(reader, null);
} else if (isIagoFileType(line)) {
return IagoParser.class.getSimpleName();
} else if (isWRKFileType(line)) {
return WrkSummarizerParser.class.getSimpleName();
} else if (isJMeterCSVFileType(line)) {
return JMeterCsvParser.class.getSimpleName();
} else if (isJMeterSummarizerFileType(line, reader)) {
return JmeterSummarizerParser.class.getSimpleName();
} else {
try {
return detectXMLFileType(reader, line);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Can not detect file type: " + reportPath, ex);
}
}
}
/**
* Detect Iago report type using pattern "INF \[.*\] stats:.*
*/
private static boolean isIagoFileType(String line) {
String patternString = "INF \\[.*\\] stats:.*";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
/**
* Detect WRK report type using pattern "Running .*s test @.*"
*/
private static boolean isWRKFileType(String line) {
String patternString = "Running .*s test @.*";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
/**
* Detect JMeterCSV report type using the search of main columns in CSV header,
* such as timestamp, elapsed and url/label
*/
private static boolean isJMeterCSVFileType(String header) {
String line = header.toLowerCase();
return (line.contains("timestamp") && line.contains("elapsed") &&
(line.contains("url") || line.contains("label")));
}
/**
* Detect JMeterSummarizer report type.
* Read file, until It find a string "jmeter.reporters.Summariser: Generate Summary Results"
*/
private static boolean isJMeterSummarizerFileType(String firstLine, final BufferedReader reader) throws IOException {
String pattern = "jmeter.reporters.Summariser: Generate Summary Results";
String line = firstLine;
if (line.contains(pattern)) {
return true;
}
line = reader.readLine();
while (line != null) {
if (line.contains(pattern)) {
return true;
}
line = reader.readLine();
}
return false;
}
/**
* Detect XML report type using the search of the first opening xml-tag.
* <testResults> - JMETER;
* <testsuite> - JUNIT;
* <FinalStatus> - TAURUS.
*/
private static String detectXMLFileType(final BufferedReader reader, String lineToAnalyze) throws IOException {
String line = (lineToAnalyze != null) ? lineToAnalyze : reader.readLine();
if (line == null) {
throw new IllegalArgumentException("File contains only xml header");
}
if (line.contains("<testResults")) {
return JMeterParser.class.getSimpleName();
} else if (line.contains("<testsuite")) {
return JUnitParser.class.getSimpleName();
} else if (line.contains("<FinalStatus>")) {
return TaurusParser.class.getSimpleName();
} else {
throw new IllegalArgumentException("Unknown xml file format");
}
}
}