NIHVIVO-1129 create a utility that will merge and compare the results of tests on different systems.
This commit is contained in:
parent
43135eccfe
commit
493da8b667
9 changed files with 638 additions and 0 deletions
|
@ -48,6 +48,8 @@ report - Just summarize output from previously run tests.
|
||||||
target: properties
|
target: properties
|
||||||
- - - - - - - - - - - - - - - - - -->
|
- - - - - - - - - - - - - - - - - -->
|
||||||
<target name="properties">
|
<target name="properties">
|
||||||
|
<property name="source.dir" value="src" />
|
||||||
|
<property name="build.dir" value=".build" />
|
||||||
<property name="tests.dir" value="tests" />
|
<property name="tests.dir" value="tests" />
|
||||||
<property name="results.dir" value=".results" />
|
<property name="results.dir" value=".results" />
|
||||||
|
|
||||||
|
@ -96,6 +98,7 @@ report - Just summarize output from previously run tests.
|
||||||
target: prepare
|
target: prepare
|
||||||
- - - - - - - - - - - - - - - - - -->
|
- - - - - - - - - - - - - - - - - -->
|
||||||
<target name="prepare" depends="properties">
|
<target name="prepare" depends="properties">
|
||||||
|
<mkdir dir="${build.dir}" />
|
||||||
<mkdir dir="${results.dir}" />
|
<mkdir dir="${results.dir}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -189,7 +192,32 @@ report - Just summarize output from previously run tests.
|
||||||
target: merge
|
target: merge
|
||||||
================================= -->
|
================================= -->
|
||||||
<target name="merge" depends="prepare" description="--> Merge summaries together">
|
<target name="merge" depends="prepare" description="--> Merge summaries together">
|
||||||
|
<javac srcdir="${source.dir}"
|
||||||
|
destdir="${build.dir}"
|
||||||
|
debug="true"
|
||||||
|
deprecation="true"
|
||||||
|
optimize="true"
|
||||||
|
source="1.6">
|
||||||
|
</javac>
|
||||||
|
|
||||||
|
<property name="merge.output.dir"
|
||||||
|
location="/Development/JIRA issues/NIHVIVO-1129_Load_testing/mergerFiles/" />
|
||||||
|
<property name="merge.input.dir"
|
||||||
|
location="/Development/JIRA issues/NIHVIVO-1129_Load_testing/mergerFiles/results" />
|
||||||
|
<property name="merge.input.filenames"
|
||||||
|
value="ver_release1.1.1/SecondTests-rel-1-1-1.html, ver_trunkRdb/SecondTests-rel-1-2.html, ver_trunkSdb/SecondTests-rel-1-2.html" />
|
||||||
|
|
||||||
|
<java classname="edu.cornell.mannlib.vitro.utilities.loadtesting.ReportsMerger"
|
||||||
|
fork="yes"
|
||||||
|
failonerror="true">
|
||||||
|
<classpath location="${build.dir}" />
|
||||||
|
<arg value="${merge.output.dir}" />
|
||||||
|
<arg value="${merge.input.dir}" />
|
||||||
|
<arg value="${merge.input.filenames}" />
|
||||||
|
</java>
|
||||||
|
|
||||||
|
<copy file="mergedResults.css"
|
||||||
|
todir="${merge.output.dir}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
40
utilities/load-testing/mergedResults.css
Normal file
40
utilities/load-testing/mergedResults.css
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
table.testData {
|
||||||
|
}
|
||||||
|
|
||||||
|
table.testData td,th {
|
||||||
|
border: thin solid black;
|
||||||
|
font-family: sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.testData td.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.testData td.open {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.testData td.middle {
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.testData td.close {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.oneResult td {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.oneResult {
|
||||||
|
border: thin solid black;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.oneResult td.minmax {
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the merged data to an HTML page.
|
||||||
|
*/
|
||||||
|
public class OutputMarshaller {
|
||||||
|
private final List<TestResultsFileData> reportData;
|
||||||
|
private final PrintWriter w;
|
||||||
|
private final List<String> testNames;
|
||||||
|
|
||||||
|
public OutputMarshaller(List<TestResultsFileData> reportData, PrintWriter w) {
|
||||||
|
this.reportData = reportData;
|
||||||
|
this.w = w;
|
||||||
|
this.testNames = assembleListOfTestNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void marshall() {
|
||||||
|
writePageHeader();
|
||||||
|
writeTestDataTable();
|
||||||
|
writePageFooter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> assembleListOfTestNames() {
|
||||||
|
Set<String> names = new TreeSet<String>();
|
||||||
|
for (TestResultsFileData filedata : reportData) {
|
||||||
|
names.addAll(filedata.getTestMap().keySet());
|
||||||
|
}
|
||||||
|
return new ArrayList<String>(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writePageHeader() {
|
||||||
|
w.println("<html>");
|
||||||
|
w.println("<head>");
|
||||||
|
w.println(" <link REL='STYLESHEET' TYPE='text/css' HREF='./mergedResults.css'>");
|
||||||
|
w.println("</head>");
|
||||||
|
w.println("<body>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTestDataTable() {
|
||||||
|
w.println("<table class='testData' cellspacing='0'>");
|
||||||
|
writeTestDataHeader();
|
||||||
|
for (String testName : testNames) {
|
||||||
|
writeTestDataRow(testName);
|
||||||
|
}
|
||||||
|
w.println("</table>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTestDataHeader() {
|
||||||
|
w.println(" <tr>");
|
||||||
|
w.println(" <th> </th>");
|
||||||
|
for (TestResultsFileData fileData : reportData) {
|
||||||
|
w.println(" <th colspan='3'>" + fileData.getVivoVersion()
|
||||||
|
+ "<br/>" + fileData.getResultsFilename() + "<br/>"
|
||||||
|
+ formatDate(fileData.getCreated()) + "</th>");
|
||||||
|
}
|
||||||
|
w.println(" </tr>");
|
||||||
|
|
||||||
|
w.println(" <tr>");
|
||||||
|
w.println(" <th>Test Name</th>");
|
||||||
|
for (TestResultsFileData fileData : reportData) {
|
||||||
|
w.println(" <th>iterations</th>");
|
||||||
|
w.println(" <th>time (min/max)</th>");
|
||||||
|
w.println(" <th>ratio</th>");
|
||||||
|
}
|
||||||
|
w.println(" </tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTestDataRow(String testName) {
|
||||||
|
w.println(" <tr>");
|
||||||
|
w.println(" <td class='left'>" + testName + "</td>");
|
||||||
|
for (TestResultsFileData fileData : reportData) {
|
||||||
|
writeTestDataCellForFile(fileData, testName);
|
||||||
|
}
|
||||||
|
w.println(" </tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTestDataCellForFile(TestResultsFileData fileData,
|
||||||
|
String testName) {
|
||||||
|
TestResultInfo testData = fileData.getTestMap().get(testName);
|
||||||
|
TestResultInfo baselineTestData = reportData.get(0).getTestMap()
|
||||||
|
.get(testName);
|
||||||
|
|
||||||
|
String count = (testData == null) ? " " : ("" + testData
|
||||||
|
.getCount());
|
||||||
|
String averageTime = (testData == null) ? " "
|
||||||
|
: ("" + formatTime(testData.getAverageTime()));
|
||||||
|
String minTime = (testData == null) ? " "
|
||||||
|
: ("" + formatTime(testData.getMinTime()));
|
||||||
|
String maxTime = (testData == null) ? " "
|
||||||
|
: ("" + formatTime(testData.getMaxTime()));
|
||||||
|
|
||||||
|
String ratioWithBaseline = " ";
|
||||||
|
if ((testData != null) && (baselineTestData != null)) {
|
||||||
|
ratioWithBaseline = percentage(testData.getAverageTime(),
|
||||||
|
baselineTestData.getAverageTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
w.println(" <td class='open'>" + count + "</td>");
|
||||||
|
w.println(" <td>");
|
||||||
|
w.println(" <table class='oneResult middle' cellspacing=0>");
|
||||||
|
w.println(" <tr>");
|
||||||
|
w.println(" <td rowspan='2'>" + averageTime + "</td>");
|
||||||
|
w.println(" <td class='minmax'>" + minTime + "</td>");
|
||||||
|
w.println(" </tr>");
|
||||||
|
w.println(" <tr>");
|
||||||
|
w.println(" <td class='minmax'>" + maxTime + "</td>");
|
||||||
|
w.println(" </tr>");
|
||||||
|
w.println(" </table>");
|
||||||
|
w.println(" <td class='close'>" + ratioWithBaseline + "</td>");
|
||||||
|
w.println(" </td>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String percentage(float value, float baseline) {
|
||||||
|
float ratio = value / baseline;
|
||||||
|
return String.format("%1$8.2f%%", ratio * 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatTime(float time) {
|
||||||
|
return String.format("%1$8.3f", time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatDate(long date) {
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||||
|
.format(new Date(date));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writePageFooter() {
|
||||||
|
w.println("</body>");
|
||||||
|
w.println("</html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take two or more reports from JMeter's test results, and merge them into a
|
||||||
|
* unified HTML report.
|
||||||
|
*/
|
||||||
|
public class ReportsMerger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start with list of filenames in command line For each contributing file,
|
||||||
|
* heading is from parsing the filename. Get the one after LoadTesting, and
|
||||||
|
* the last one, minus the extension.
|
||||||
|
*
|
||||||
|
* For each file, build a structure with header info and a LinkedMap of the
|
||||||
|
* desired info, testname -> info structure Build a list of these. Build a
|
||||||
|
* unified list of testnames.
|
||||||
|
*
|
||||||
|
* List<TestResultsFile>
|
||||||
|
*
|
||||||
|
* TestResultsFile: String version; String filename; Date timestamp;
|
||||||
|
* LinkedMap<String, TestResultInfo> testMap;
|
||||||
|
*
|
||||||
|
* TestResultInfo: boolean success; int count; float averageTime; float
|
||||||
|
* maxTime; float minTime;
|
||||||
|
*/
|
||||||
|
|
||||||
|
private final ReportsMergerParameters parms;
|
||||||
|
private List<TestResultsFileData> reportData;
|
||||||
|
|
||||||
|
public ReportsMerger(ReportsMergerParameters parms) {
|
||||||
|
this.parms = parms;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseReports() {
|
||||||
|
List<TestResultsFileData> reportData = new ArrayList<TestResultsFileData>();
|
||||||
|
for (File reportFile : parms.getReportFiles()) {
|
||||||
|
TestResultsFileData fileData = new TestResultsParser(reportFile)
|
||||||
|
.parse();
|
||||||
|
System.out.println("File data: " + fileData);
|
||||||
|
reportData.add(fileData);
|
||||||
|
}
|
||||||
|
this.reportData = reportData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void produceOutput() {
|
||||||
|
PrintWriter writer = parms.getOutputWriter();
|
||||||
|
new OutputMarshaller(reportData, writer).marshall();
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ReportsMergerParameters parms = ReportsMergerParameters
|
||||||
|
.getInstance(args);
|
||||||
|
ReportsMerger rm = new ReportsMerger(parms);
|
||||||
|
rm.parseReports();
|
||||||
|
rm.produceOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the command-line parameters for the ReportManager
|
||||||
|
*/
|
||||||
|
public abstract class ReportsMergerParameters {
|
||||||
|
|
||||||
|
public static ReportsMergerParameters getInstance(String[] args) {
|
||||||
|
return new ReportsMergerParametersImpl(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract List<File> getReportFiles();
|
||||||
|
|
||||||
|
public abstract PrintWriter getOutputWriter();
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base implementation of ReportsMergerParameters
|
||||||
|
*/
|
||||||
|
public class ReportsMergerParametersImpl extends ReportsMergerParameters {
|
||||||
|
|
||||||
|
private final String outputDirectoryPath;
|
||||||
|
private final String inputDirectoryPath;
|
||||||
|
private final List<String> inputFilenames;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first arg is the output directory. The second arg is an input
|
||||||
|
* directory. The third arg is a comma-separated list of input filenames.
|
||||||
|
*/
|
||||||
|
public ReportsMergerParametersImpl(String[] args) {
|
||||||
|
this.outputDirectoryPath = args[0];
|
||||||
|
this.inputDirectoryPath = args[1];
|
||||||
|
this.inputFilenames = Arrays.asList(args[2].split("[, ]+"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<File> getReportFiles() {
|
||||||
|
List<File> files = new ArrayList<File>();
|
||||||
|
for (String filename : inputFilenames) {
|
||||||
|
files.add(new File(inputDirectoryPath, filename));
|
||||||
|
}
|
||||||
|
// files.add(new File(
|
||||||
|
// "/Development/JIRA issues/NIHVIVO-1129_Load_testing/mergerFiles/LoadTesting/release1.1.1/SecondTests-rel-1-1-1.html"));
|
||||||
|
// files.add(new File(
|
||||||
|
// "/Development/JIRA issues/NIHVIVO-1129_Load_testing/mergerFiles/LoadTesting/trunkNoSdb/SecondTests-rel-1-2.html"));
|
||||||
|
// files.add(new File(
|
||||||
|
// "/Development/JIRA issues/NIHVIVO-1129_Load_testing/mergerFiles/LoadTesting/trunkSdb/SecondTests-rel-1-2.html"));
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrintWriter getOutputWriter() {
|
||||||
|
try {
|
||||||
|
File outputFile = new File(outputDirectoryPath,
|
||||||
|
"mergedResults.html");
|
||||||
|
return new PrintWriter(new FileWriter(outputFile));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Can't open the output writer.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Info about the executions of a single test in a single file.
|
||||||
|
*/
|
||||||
|
public class TestResultInfo {
|
||||||
|
private final String testName;
|
||||||
|
private final boolean success;
|
||||||
|
private final int count;
|
||||||
|
private final float averageTime;
|
||||||
|
private final float maxTime;
|
||||||
|
private final float minTime;
|
||||||
|
|
||||||
|
public TestResultInfo(String testName, boolean success, int count,
|
||||||
|
float averageTime, float maxTime, float minTime) {
|
||||||
|
this.testName = testName;
|
||||||
|
this.success = success;
|
||||||
|
this.count = count;
|
||||||
|
this.averageTime = averageTime;
|
||||||
|
this.maxTime = maxTime;
|
||||||
|
this.minTime = minTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTestName() {
|
||||||
|
return testName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAverageTime() {
|
||||||
|
return averageTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxTime() {
|
||||||
|
return maxTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinTime() {
|
||||||
|
return minTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TestResultInfo[testName=" + testName + ", success=" + success
|
||||||
|
+ ", count=" + count + ", averageTime=" + averageTime
|
||||||
|
+ ", maxTime=" + maxTime + ", minTime=" + minTime + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the data that was parsed from a single results file.
|
||||||
|
*/
|
||||||
|
public class TestResultsFileData {
|
||||||
|
private final String vivoVersion;
|
||||||
|
private final String resultsFilename;
|
||||||
|
private final long created;
|
||||||
|
private final LinkedHashMap<String, TestResultInfo> testMap;
|
||||||
|
|
||||||
|
public TestResultsFileData(String vivoVersion, String resultsFilename,
|
||||||
|
long created, Map<String, TestResultInfo> testMap) {
|
||||||
|
this.vivoVersion = vivoVersion;
|
||||||
|
this.resultsFilename = resultsFilename;
|
||||||
|
this.created = created;
|
||||||
|
this.testMap = new LinkedHashMap<String, TestResultInfo>(testMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimeStamp() {
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(
|
||||||
|
created));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVivoVersion() {
|
||||||
|
return vivoVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResultsFilename() {
|
||||||
|
return resultsFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<String, TestResultInfo> getTestMap() {
|
||||||
|
return testMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TestResultsFileData[vivoVersion=" + vivoVersion
|
||||||
|
+ ", resultsFilename=" + resultsFilename + ", created="
|
||||||
|
+ getTimeStamp() + ", testMap=" + testMap + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.loadtesting;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a single test results file.
|
||||||
|
*/
|
||||||
|
public class TestResultsParser {
|
||||||
|
/** Find the "Pages" table in the file. */
|
||||||
|
private static final String PATTERN_PAGES_TABLE = "<h2>Pages</h2><table[^>]*>(.*?)</table>";
|
||||||
|
|
||||||
|
/** Find a row in the table. */
|
||||||
|
private static final String PATTERN_TABLE_ROW = "<tr[^>]*>(.*?)</tr>";
|
||||||
|
|
||||||
|
private final File reportFile;
|
||||||
|
private final String filePath;
|
||||||
|
|
||||||
|
public TestResultsParser(File reportFile) {
|
||||||
|
this.reportFile = reportFile;
|
||||||
|
this.filePath = reportFile.getAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info from the file path, the create date, and the contents of the
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
public TestResultsFileData parse() {
|
||||||
|
String[] pathInfo = parseInfoFromFilePath();
|
||||||
|
Map<String, TestResultInfo> testMap = extractTestMap();
|
||||||
|
return new TestResultsFileData(pathInfo[0], pathInfo[1],
|
||||||
|
reportFile.lastModified(), testMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] parseInfoFromFilePath() {
|
||||||
|
String vivoVersion = "--";
|
||||||
|
String[] pathParts = filePath.split(Pattern.quote(File.separator));
|
||||||
|
for (int i = 0; i < pathParts.length; i++) {
|
||||||
|
if (pathParts[i].startsWith("ver_")) {
|
||||||
|
vivoVersion = pathParts[i].substring(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String trimmedFilename = reportFile.getName().substring(0,
|
||||||
|
reportFile.getName().lastIndexOf('.'));
|
||||||
|
|
||||||
|
return new String[] { vivoVersion, trimmedFilename };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan through the contents of the file for info
|
||||||
|
*/
|
||||||
|
private Map<String, TestResultInfo> extractTestMap() {
|
||||||
|
String contents = readEntireFileWithoutLineFeeds();
|
||||||
|
|
||||||
|
String pagesTable = findPagesTableInFile(contents);
|
||||||
|
// System.out.println("PagesTable: " + pagesTable);
|
||||||
|
|
||||||
|
return parsePagesTable(pagesTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readEntireFileWithoutLineFeeds() {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
BufferedReader reader = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new FileReader(reportFile));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while (null != (line = reader.readLine())) {
|
||||||
|
result.append(line);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"File doesn't exist: '" + filePath + "'", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to read the file: '" + filePath
|
||||||
|
+ "'", e);
|
||||||
|
} finally {
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findPagesTableInFile(String contents) {
|
||||||
|
Pattern p = Pattern.compile(PATTERN_PAGES_TABLE);
|
||||||
|
Matcher m = p.matcher(contents);
|
||||||
|
if (m.find()) {
|
||||||
|
return m.group(1);
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Failed to find the 'Pages' "
|
||||||
|
+ "table in file: '" + filePath + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, TestResultInfo> parsePagesTable(String pagesTable) {
|
||||||
|
Map<String, TestResultInfo> map = new LinkedHashMap<String, TestResultInfo>();
|
||||||
|
|
||||||
|
Pattern p = Pattern.compile(PATTERN_TABLE_ROW);
|
||||||
|
Matcher m = p.matcher(pagesTable);
|
||||||
|
|
||||||
|
discardHeaderRowFromPagesTable(m);
|
||||||
|
|
||||||
|
while (m.find()) {
|
||||||
|
TestResultInfo info = parseTestRowFromPagesTable(m.group(1));
|
||||||
|
map.put(info.getTestName(), info);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void discardHeaderRowFromPagesTable(Matcher m) {
|
||||||
|
if (!m.find()) {
|
||||||
|
throw new RuntimeException("Failed to find a header row "
|
||||||
|
+ "in the 'Pages' table, in file: '" + filePath + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestResultInfo parseTestRowFromPagesTable(String tableRow) {
|
||||||
|
// System.out.println("Table Row: " + tableRow);
|
||||||
|
|
||||||
|
List<String> cells = new ArrayList<String>();
|
||||||
|
|
||||||
|
Pattern p = Pattern.compile("<td.*?>(.*?)</td>");
|
||||||
|
Matcher m = p.matcher(tableRow);
|
||||||
|
while (m.find()) {
|
||||||
|
cells.add(m.group(1));
|
||||||
|
}
|
||||||
|
// System.out.println("Cells: " + cells);
|
||||||
|
|
||||||
|
if (cells.size() < 7) {
|
||||||
|
throw new RuntimeException("Only " + cells.size()
|
||||||
|
+ " cells in this table row: '" + tableRow
|
||||||
|
+ "', in file: '" + filePath + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
String testName = cells.get(0);
|
||||||
|
int count = Integer.parseInt(cells.get(1));
|
||||||
|
boolean success = cells.get(2).equals("0");
|
||||||
|
float averageTime = parseTimeFromCell(cells.get(4));
|
||||||
|
float minTime = parseTimeFromCell(cells.get(5));
|
||||||
|
float maxTime = parseTimeFromCell(cells.get(6));
|
||||||
|
|
||||||
|
return new TestResultInfo(testName, success, count, averageTime,
|
||||||
|
maxTime, minTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float parseTimeFromCell(String cell) {
|
||||||
|
String[] parts = cell.split(" ");
|
||||||
|
return Integer.parseInt(parts[0]) / 1000.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue