/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.test.client;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.teiid.test.framework.ConfigPropertyLoader;
import org.teiid.test.framework.TestLogger;
import org.teiid.test.util.StringUtil;
public class TestResultsSummary {
private static final String OVERALL_SUMMARY_FILE = "Summary_totals.txt";
private static final String OVERALL_SUMMARY_ERROR_FILE = "Summary_errors.txt";
private static final String PROP_SUMMARY_PRT_DIR = "summarydir";
private static final SimpleDateFormat FILE_NAME_DATE_FORMATER = new SimpleDateFormat(
"yyyyMMdd_HHmmss"); //$NON-NLS-1$
private static final String NL = System.getProperty("line.separator"); //$NON-NLS-1$
// totals for scenario
private String resultMode = "NotSet";
private int total_queries = 0;
private int total_pass = 0;
private int total_fail = 0;
private int total_querysets = 0;
private long total_seconds = 0;
private List<String> failed_queries = new ArrayList<String>();
private List<String> query_sets = new ArrayList<String>(10);
private Map<String, Collection<TestResult>> testResults = Collections
.synchronizedMap(new HashMap<String, Collection<TestResult>>());
public TestResultsSummary(String resultMode) {
this.resultMode = resultMode;
}
public void cleanup() {
failed_queries.clear();
query_sets.clear();
testResults.clear();
}
public synchronized void addTestResult(String querySetID, TestResult result) {
if (result == null) {
System.err
.println("Error - trying to add a null result set for querysetID: " + querySetID); //$NON-NLS-1$
throw new RuntimeException(
"Error - trying to add a null result set for querysetID: " + querySetID); //$NON-NLS-1$
}
Collection<TestResult> results = null;
if (this.testResults.containsKey(querySetID)) {
results = this.testResults.get(querySetID);
} else {
results = new ArrayList<TestResult>();
this.testResults.put(querySetID, results);
}
results.add(result);
}
public Collection<TestResult> getTestResults(String querySetID) {
return this.testResults.get(querySetID);
}
private static PrintStream getSummaryStream(String outputDir,
String summaryName) throws IOException {
File summaryFile = createSummaryFile(outputDir, summaryName);
OutputStream os = new FileOutputStream(summaryFile);
os = new BufferedOutputStream(os);
return new PrintStream(os);
}
// private static Writer getOverallSummaryStream(String outputDir) throws IOException {
// return createOverallSummaryFile(outputDir);
//
// }
/**
* Overloaded to overwrite the already existing files
*/
private static PrintStream getSummaryStream(String outputDir,
String summaryName, boolean overwrite) throws IOException {
// Check Extension is already specified for the file, if not add the
// .txt
if (summaryName.indexOf(".") == -1) { //$NON-NLS-1$
summaryName = summaryName + ".txt"; //$NON-NLS-1$
}
File summaryFile = new File(outputDir, summaryName);
if (summaryFile.exists() && !overwrite) {
throw new IOException(
"Summary file already exists: " + summaryFile.getName()); //$NON-NLS-1$
}
try {
summaryFile.createNewFile();
} catch (IOException ioe) {
TestLogger.log("Error creating new summary file: "
+ summaryFile.getAbsolutePath());
throw ioe;
}
OutputStream os = new FileOutputStream(summaryFile);
os = new BufferedOutputStream(os);
return new PrintStream(os);
}
private static File createSummaryFile(String outputDir, String summaryName)
throws IOException {
File summaryFile = new File(outputDir, summaryName + ".txt"); //$NON-NLS-1$
if (summaryFile.exists()) {
System.err
.println("Summary file already exists: " + summaryFile.getName()); //$NON-NLS-1$
throw new IOException(
"Summary file already exists: " + summaryFile.getName()); //$NON-NLS-1$
}
try {
summaryFile.createNewFile();
} catch (IOException e) {
System.err
.println("Failed to create summary file at: " + summaryFile.getAbsolutePath()); //$NON-NLS-1$
throw new IOException(
"Failed to create summary file at: " + summaryFile.getAbsolutePath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
}
return summaryFile;
}
private static Writer getOverallSummaryStream(String outputDir)
throws IOException {
boolean exists = false;
File summaryFile = new File(outputDir, OVERALL_SUMMARY_FILE); //$NON-NLS-1$
exists = summaryFile.exists();
FileWriter fstream = new FileWriter(summaryFile,true);
BufferedWriter out = new BufferedWriter(fstream);
if (!exists) {
try {
summaryFile.createNewFile();
} catch (IOException e) {
System.err
.println("Failed to create overall summary file at: " + summaryFile.getAbsolutePath()); //$NON-NLS-1$
throw new IOException(
"Failed to create overall summary file at: " + summaryFile.getAbsolutePath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
}
printOverallSummaryHeadings(out);
}
return out;
}
private static void printOverallSummaryHeadings(Writer overallsummary) {
try {
overallsummary.write("================== \n"); //$NON-NLS-1$
overallsummary.write("Test Summary \n"); //$NON-NLS-1$
overallsummary.write("================== \n"); //$NON-NLS-1$
overallsummary
.write("Scenario \t\t\t" + "Pass" + "\t" + "Fail" + "\t" + "Total \n"); //$NON-NLS-1$
overallsummary.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private static Writer getOverallSummaryErrorsStream(String outputDir)
throws IOException {
boolean exists = false;
File summaryFile = new File(outputDir, OVERALL_SUMMARY_ERROR_FILE); //$NON-NLS-1$
exists = summaryFile.exists();
FileWriter fstream = new FileWriter(summaryFile,true);
BufferedWriter out = new BufferedWriter(fstream);
if (!exists) {
try {
summaryFile.createNewFile();
} catch (IOException e) {
System.err
.println("Failed to create overall summary error file at: " + summaryFile.getAbsolutePath()); //$NON-NLS-1$
throw new IOException(
"Failed to create overall summary error file at: " + summaryFile.getAbsolutePath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
}
printOverallSummaryErrorHeadings(out);
}
return out;
}
private static void printOverallSummaryErrorHeadings(Writer overallsummary) {
try {
overallsummary.write("================== \n"); //$NON-NLS-1$
overallsummary.write("Test Summary Errors \n"); //$NON-NLS-1$
overallsummary.write("================== \n"); //$NON-NLS-1$
overallsummary
.write("Scenario \t" + "Error \n"); //$NON-NLS-1$
overallsummary.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void printQueryTestResults(PrintStream outputStream,
Date testStartTS, Date endTS, Date length, int numberOfClients,
SimpleDateFormat formatter, Collection results) {
outputStream.println("Query Test Results [" + this.resultMode + "]"); //$NON-NLS-1$
outputStream.println("=================="); //$NON-NLS-1$
outputStream.println("Start Time: " + testStartTS); //$NON-NLS-1$
outputStream.println("End Time: " + endTS); //$NON-NLS-1$
outputStream
.println("Elapsed Time: " + (length.getTime() / 1000) + " seconds"); //$NON-NLS-1$ //$NON-NLS-2$
// outputStream.println("Start Time: " + new Date(testStartTS)); //$NON-NLS-1$
// outputStream.println("End Time: " + new Date(endTS)); //$NON-NLS-1$
// outputStream
// .println("Elapsed Time: " + ((endTS - testStartTS) / 1000) + " seconds"); //$NON-NLS-1$ //$NON-NLS-2$
//
outputStream.println("Number of Clients: " + numberOfClients); //$NON-NLS-1$
Map passFailGenMap = getPassFailGen(results);
outputStream
.println("Number of Queries: " + passFailGenMap.get("queries")); //$NON-NLS-1$ //$NON-NLS-2$
outputStream
.println("Number Passed : " + passFailGenMap.get("pass")); //$NON-NLS-1$ //$NON-NLS-2$
outputStream
.println("Number Failed : " + passFailGenMap.get("fail")); //$NON-NLS-1$ //$NON-NLS-2$
// outputStream.println("Number Generated : " + passFailGenMap.get("gen")); //$NON-NLS-1$ //$NON-NLS-2$
ResponseTimes responseTimes = calcQueryResponseTimes(results);
outputStream.println("QPS : " + responseTimes.qps); //$NON-NLS-1$
outputStream.println("Ave First Resp : " + responseTimes.first); //$NON-NLS-1$
outputStream.println("Ave Full Resp : " + responseTimes.full); //$NON-NLS-1$
Iterator resultItr = results.iterator();
while (resultItr.hasNext()) {
TestResult stat = (TestResult) resultItr.next();
writeQueryResult(outputStream, formatter, stat);
}
}
private static Map getPassFailGen(Collection results) {
Map passFailGenMap = new HashMap();
int queries = 0;
int pass = 0;
int fail = 0;
int gen = 0;
for (Iterator resultsItr = results.iterator(); resultsItr.hasNext();) {
TestResult stat = (TestResult) resultsItr.next();
++queries;
switch (stat.getStatus()) {
case TestResult.RESULT_STATE.TEST_EXCEPTION:
++fail;
break;
case TestResult.RESULT_STATE.TEST_SUCCESS:
++pass;
break;
case TestResult.RESULT_STATE.TEST_EXPECTED_EXCEPTION:
++pass;
break;
}
}
passFailGenMap.put("queries", Integer.toString(queries)); //$NON-NLS-1$
passFailGenMap.put("pass", Integer.toString(pass)); //$NON-NLS-1$
passFailGenMap.put("fail", Integer.toString(fail)); //$NON-NLS-1$
// passFailGenMap.put("gen", Integer.toString(gen)); //$NON-NLS-1$
return passFailGenMap;
}
private void addTotalPassFailGen(String scenario_name, Collection results,
Date testStartTS, Date endTS, Date lengthTime) {
int queries = 0;
int pass = 0;
int fail = 0;
String queryset = null;
total_querysets++;
for (Iterator resultsItr = results.iterator(); resultsItr.hasNext();) {
TestResult stat = (TestResult) resultsItr.next();
if (queryset == null) {
queryset = stat.getQuerySetID();
}
++queries;
switch (stat.getStatus()) {
case TestResult.RESULT_STATE.TEST_EXCEPTION:
++fail;
String msg = StringUtil.removeChars(stat.getExceptionMsg(),
new char[] { '\r', '\n' });
this.failed_queries.add(stat.getQueryID() + "~" + msg);
break;
case TestResult.RESULT_STATE.TEST_SUCCESS:
++pass;
break;
case TestResult.RESULT_STATE.TEST_EXPECTED_EXCEPTION:
++pass;
break;
}
}
this.query_sets.add("\t" + queryset + "\t\t" + pass + "\t" + fail
+ "\t" + queries + "\t" + (lengthTime.getTime() / 1000));
total_fail = total_fail + fail;
total_pass = total_pass + pass;
total_queries = total_queries + queries;
}
public void printResults(QueryScenario scenario, String querySetID,
long beginTS, long endTS) throws Exception {
TestLogger.logDebug("Print results for Query Set [" + querySetID + "]");
try {
printResults(scenario, querySetID, beginTS, endTS, 1, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Print test results.
*
* @param testStartTS
* The test start time.
* @param endTS
* The test end time.
* @throws Exception
*/
public void printResults(QueryScenario scenario, String querySetID,
long testStartTS, long endTS, int numberOfClients, int runNumber)
throws Exception {
String testname = scenario.getQueryScenarioIdentifier();
Collection<TestResult> testResults = getTestResults(querySetID);
// Properties props = scenario.getProperties();
String outputDir = scenario.getResultsGenerator().getOutputDir();
// CombinedTestClient.log("Calculating and printing result statistics"); //$NON-NLS-1$
if (testResults == null) {
// do nothing
} else if (testResults.size() > 0) {
// Create output file
String outputFileName = generateFileName(querySetID, System
.currentTimeMillis(), runNumber);
// CombinedTestClient.log("Creating output file: " + outputFileName); //$NON-NLS-1$
PrintStream outputStream = null;
PrintStream overwriteStream = null;
try {
outputStream = getSummaryStream(outputDir, outputFileName);
overwriteStream = getSummaryStream(outputDir, querySetID, true); //$NON-NLS-1$
} catch (IOException e) {
// logError("Unable to get output stream for file: " + outputFileName); //$NON-NLS-1$
throw e;
}
Date starttest = new Date(testStartTS);
Date endtest = new Date(endTS);
long diff = endtest.getTime() - starttest.getTime();
total_seconds = total_seconds + diff;
Date diffdate = new Date(diff);
// endtest - starttest;
//
// outputStream.println("Start Time: " + new Date(testStartTS)); //$NON-NLS-1$
// outputStream.println("End Time: " + new Date(endTS)); //$NON-NLS-1$
// outputStream
// .println("Elapsed Time: " + ((endTS - testStartTS) / 1000) + " seconds"); //$NON-NLS-1$ //$NON-NLS-2$
addTotalPassFailGen(testname, testResults, starttest, endtest,
diffdate);
// Text File output
printQueryTestResults(outputStream, starttest, endtest, diffdate,
numberOfClients, TestClient.TSFORMAT, testResults);
printQueryTestResults(overwriteStream, starttest, endtest,
diffdate, numberOfClients, TestClient.TSFORMAT, testResults);
// HTML Vesion of output
PrintStream htmlStream = getSummaryStream(outputDir, querySetID
+ ".html", true); //$NON-NLS-1$
printHtmlQueryTestResults(htmlStream, testStartTS, endTS,
numberOfClients, TestClient.TSFORMAT, testResults);
htmlStream.close();
// Wiki Update
// CombinedTestUtil.publishResultsToWiki(props, outputDir+File.separator+querySetID+".html", testStartTS, endTS, numberOfClients, testResults); //$NON-NLS-1$ //$NON-NLS-2$
// Print results according to test type
// switch (CombinedTestClient.TEST_TYPE) {
// case CombinedTestClient.TEST_TYPE_QUERY:
// // Text File output
// printQueryTestResults(outputStream, testStartTS, endTS,
// numberOfClients, TestClientTransaction.TSFORMAT, testResults);
// printQueryTestResults(overwriteStream, testStartTS, endTS,
// numberOfClients, TestClientTransaction.TSFORMAT, testResults);
//
// // HTML Vesion of output
// PrintStream htmlStream = getSummaryStream(outputDir, CONFIG_ID+".html", true); //$NON-NLS-1$
// CombinedTestUtil.printHtmlQueryTestResults(htmlStream,
// testStartTS, endTS, numberOfClients,
// TestClientTransaction.TSFORMAT, testResults);
// htmlStream.close();
//
// // Wiki Update
// CombinedTestUtil.publishResultsToWiki(props, outputDir+File.separator+CONFIG_ID+".html", testStartTS, endTS, numberOfClients, testResults); //$NON-NLS-1$ //$NON-NLS-2$
// break;
// case CombinedTestClient.TEST_TYPE_LOAD:
// CombinedTestUtil.printLoadTestResults(outputStream, testStartTS,
// endTS, numberOfClients, TestClientTransaction.TSFORMAT,
// testResults);
// CombinedTestUtil.printLoadTestResults(overwriteStream,
// testStartTS, endTS, numberOfClients,
// TestClientTransaction.TSFORMAT, testResults);
// break;
// case CombinedTestClient.TEST_TYPE_PERF:
// CombinedTestUtil.printPerfTestResults(outputStream, testStartTS,
// endTS, numberOfClients, CONF_LVL, TestClientTransaction.TSFORMAT,
// testResults);
// CombinedTestUtil.printPerfTestResults(overwriteStream,
// testStartTS, endTS, numberOfClients, CONF_LVL,
// TestClientTransaction.TSFORMAT, testResults);
// break;
// case CombinedTestClient.TEST_TYPE_PROF:
// CombinedTestUtil.printProfTestResults();
// break;
// default:
// break;
// }
// CombinedTestClient.log("Closing output stream"); //$NON-NLS-1$
outputStream.close();
overwriteStream.close();
} else {
// logError("No results to print."); //$NON-NLS-1$
}
}
public void printTotals(QueryScenario scenario) throws Exception {
// String outputDir = scenario.getResultsGenerator().getOutputDir();
String scenario_name = scenario.getQueryScenarioIdentifier();
String querysetname = scenario.getQuerySetName();
String summarydir = ConfigPropertyLoader.getInstance().getProperty(
PROP_SUMMARY_PRT_DIR);
// if (summarydir != null) {
// outputDir = summarydir;
// }
PrintStream outputStream = null;
Writer overallsummary = null;
Writer overallsummaryerrors = null;
try {
outputStream = getSummaryStream(summarydir,
"Summary_" + querysetname + "_" + scenario_name, true); //$NON-NLS-1$
overallsummary = getOverallSummaryStream(summarydir);
overallsummaryerrors = getOverallSummaryErrorsStream(summarydir);
} catch (IOException e) {
e.printStackTrace();
// logError("Unable to get output stream for file: " + outputFileName); //$NON-NLS-1$
throw e;
}
outputStream
.println("Scenario " + scenario_name + " Summary [" + this.resultMode + "]"); //$NON-NLS-1$
outputStream.println("Query Set Name " + querysetname); //$NON-NLS-1$
outputStream.println("=================="); //$NON-NLS-1$
outputStream.println("Number of Test Query Sets: " + total_querysets); //$NON-NLS-1$ //$NON-NLS-2$
outputStream.println("=================="); //$NON-NLS-1$
outputStream.println("Test Query Set"); //$NON-NLS-1$
outputStream
.println("\t" + "Name" + "\t\t\t\t" + "Pass" + "\t" + "Fail" + "\t" + "Total" + "\t" + "Time(sec)"); //$NON-NLS-1$
if (!this.query_sets.isEmpty()) {
// sort so that like failed queries are show together
Collections.sort(this.query_sets);
for (Iterator<String> it = this.query_sets.iterator(); it.hasNext();) {
outputStream.println(it.next()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
outputStream.println("=================="); //$NON-NLS-1$
outputStream.println("\t" + "Totals" + "\t\t\t\t" + total_pass + "\t"
+ total_fail + "\t" + total_queries + "\t" + total_seconds
/ 1000);
try {
overallsummary.write( pad(scenario_name, 30, ' ') + " \t" + total_pass + "\t" + total_fail + "\t" + total_queries + "\n");
overallsummary.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally { // always close the file
try {
overallsummary.close();
} catch (IOException ioe2) {
// just ignore it
}
} //
// outputStream
// .println("Number of Queries: " + total_queries); //$NON-NLS-1$ //$NON-NLS-2$
// outputStream
// .println("Number Passed : " + total_pass); //$NON-NLS-1$ //$NON-NLS-2$
// outputStream
// .println("Number Failed : " + total_fail); //$NON-NLS-1$ //$NON-NLS-2$
if (!this.failed_queries.isEmpty()) {
// sort so that like failed queries are show together
Collections.sort(this.failed_queries);
outputStream.println("\n\n=================="); //$NON-NLS-1$
outputStream.println("Failed Queries"); //$NON-NLS-1$
overallsummaryerrors.write("\n" + scenario_name + "\n");
for (Iterator<String> it = this.failed_queries.iterator(); it
.hasNext();) {
String error = it.next();
outputStream.println("\t - " + error); //$NON-NLS-1$ //$NON-NLS-2$
// write all errors to the summary file
overallsummaryerrors.write("\t\t" + error + "\n");
}
try {
overallsummaryerrors.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally { // always close the file
try {
overallsummaryerrors.close();
} catch (IOException ioe2) {
// just ignore it
}
} //
outputStream.println("=================="); //$NON-NLS-1$
}
outputStream.close();
}
private static String pad(String src, int padTo, char padChar) {
int numPad = padTo - src.length();
if (numPad > 0) {
StringBuffer sb = new StringBuffer();
char[] pad = new char[numPad] ;
Arrays.fill(pad, padChar);
sb.append(src);
sb.append(pad);
return sb.toString();
}
return src;
}
private static String generateFileName(String configName, long timestamp,
int runNumber) {
return configName
+ "_" + FILE_NAME_DATE_FORMATER.format(new Date(timestamp)) + "_Run-" + runNumber; //$NON-NLS-1$ //$NON-NLS-2$
}
private static void printHtmlQueryTestResults(PrintStream outputStream,
long testStartTS, long endTS, int numberOfClients,
SimpleDateFormat formatter, Collection results) {
StringBuffer htmlCode = new StringBuffer("<html>").append(NL); //$NON-NLS-1$
htmlCode.append("<HEAD>").append(NL); //$NON-NLS-1$
htmlCode.append("<TITLE>Query Test Results</TITLE>").append(NL); //$NON-NLS-1$
htmlCode.append("<STYLE TYPE=\"text/css\">").append(NL); //$NON-NLS-1$
htmlCode
.append(
"td { font-family: \"New Century Schoolbook\", Times, serif }").append(NL); //$NON-NLS-1$
htmlCode.append("td { font-size: 8pt }").append(NL); //$NON-NLS-1$
htmlCode.append("</STYLE>").append(NL); //$NON-NLS-1$
htmlCode.append("<SCRIPT type=\"text/javascript\">").append(NL); //$NON-NLS-1$
htmlCode.append("var scriptWin = null;").append(NL); //$NON-NLS-1$
htmlCode.append("function show(msg){").append(NL); //$NON-NLS-1$
//htmlCode.append("alert(msg);").append(nl); //$NON-NLS-1$
htmlCode
.append("if (scriptWin == null || scriptWin.closed){").append(NL); //$NON-NLS-1$
htmlCode
.append(
"scriptWin = window.open(\"\", \"script\", \"width=800,height=50,resizable\");").append(NL); //$NON-NLS-1$
htmlCode.append("scriptWin.document.open(\"text/plain\");").append(NL); //$NON-NLS-1$
htmlCode.append("}").append(NL); //$NON-NLS-1$
htmlCode.append("scriptWin.focus();").append(NL); //$NON-NLS-1$
htmlCode.append("msg = msg.replace(/#/g, '\"');").append(NL); //$NON-NLS-1$
htmlCode.append("scriptWin.document.writeln(msg);").append(NL); //$NON-NLS-1$
htmlCode.append("}").append(NL); //$NON-NLS-1$
htmlCode.append("</SCRIPT>").append(NL); //$NON-NLS-1$
htmlCode.append("</HEAD>").append(NL); //$NON-NLS-1$
htmlCode.append("<body>").append(NL); //$NON-NLS-1$
htmlCode.append("<h1>Query Test Results</h1>").append(NL); //$NON-NLS-1$
htmlCode.append("<table border=\"1\">").append(NL); //$NON-NLS-1$
addTableRow(htmlCode, "StartTime", new Date(testStartTS).toString()); //$NON-NLS-1$
addTableRow(htmlCode, "EndTime", new Date(endTS).toString()); //$NON-NLS-1$
addTableRow(htmlCode,
"Elapsed Time", ((endTS - testStartTS) / 1000) + " seconds"); //$NON-NLS-1$ //$NON-NLS-2$
addTableRow(htmlCode,
"Number Of Clients", String.valueOf(numberOfClients)); //$NON-NLS-1$
Map passFailGenMap = getPassFailGen(results);
addTableRow(htmlCode,
"Number of Queries:", passFailGenMap.get("queries")); //$NON-NLS-1$ //$NON-NLS-2$
addTableRow(htmlCode, "Number Passed :", passFailGenMap.get("pass")); //$NON-NLS-1$ //$NON-NLS-2$
addTableRow(htmlCode, "Number Failed :", passFailGenMap.get("fail")); //$NON-NLS-1$ //$NON-NLS-2$
// addTableRow(htmlCode, "Number Generated :", passFailGenMap.get("gen")); //$NON-NLS-1$ //$NON-NLS-2$
ResponseTimes responseTimes = calcQueryResponseTimes(results);
addTableRow(htmlCode, "QPS :", Double.toString(responseTimes.qps)); //$NON-NLS-1$
// addTableRow(htmlCode, "Ave First Resp :", Double.toString(responseTimes.first)); //$NON-NLS-1$
// addTableRow(htmlCode, "Ave Full Resp :", Double.toString(responseTimes.full)); //$NON-NLS-1$
htmlCode.append("</table> <p>").append(NL); //$NON-NLS-1$
htmlCode.append("<table border=\"1\">").append(NL); //$NON-NLS-1$
// Add table headers
htmlCode.append("<tr style=\"background: #C0C0C0 \">"); //$NON-NLS-1$
addTableData(htmlCode, "QueryId"); //$NON-NLS-1$
addTableData(htmlCode, "Result"); //$NON-NLS-1$
addTableData(htmlCode, "First Response"); //$NON-NLS-1$
addTableData(htmlCode, "Total Seconds"); //$NON-NLS-1$
addTableData(htmlCode, "Exception"); //$NON-NLS-1$
addTableData(htmlCode, "Error File (if any)"); //$NON-NLS-1$
htmlCode.append("</tr>").append(NL); //$NON-NLS-1$
Iterator resultItr = results.iterator();
while (resultItr.hasNext()) {
TestResult stat = (TestResult) resultItr.next();
htmlCode.append("<tr>").append(NL); //$NON-NLS-1$
addTableDataLink(htmlCode, stat.getQueryID(),
"show('" + scrub(stat.getQuery()) + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
addTableData(htmlCode, stat.getResultStatusString(),
"fail".equalsIgnoreCase(stat.getResultStatusString())); //$NON-NLS-1$
addTableData(htmlCode, new Date(stat.getBeginTS()).toString());
// Long.toString(stat.getBeginTS()));
addTableData(htmlCode, Long.toString((stat.getEndTS() - stat
.getBeginTS() / 1000)));
// Long.toString(stat.getEndTS()));
if (stat.getStatus() == TestResult.RESULT_STATE.TEST_EXCEPTION) {
addTableData(htmlCode, stat.getExceptionMsg());
if (stat.getErrorfile() != null
&& !stat.getErrorfile().equals("null")) { //$NON-NLS-1$
addTableDataLink(htmlCode, stat.getErrorfile(), ""); //$NON-NLS-1$
} else {
addTableData(htmlCode, ""); //$NON-NLS-1$
}
} else {
addTableData(htmlCode, ""); //$NON-NLS-1$
addTableData(htmlCode, ""); //$NON-NLS-1$
}
htmlCode.append("</tr>").append(NL); //$NON-NLS-1$
}
htmlCode.append("</table>").append(NL); //$NON-NLS-1$
outputStream.print(htmlCode.toString());
}
private static void addTableRow(StringBuffer table, String column,
Object msg) {
table.append("<tr>").append(NL); //$NON-NLS-1$
addTableData(table, column); //$NON-NLS-1$
addTableData(table, msg.toString());
table.append("</tr>").append(NL); //$NON-NLS-1$
}
private static void addTableData(StringBuffer table, String msg) {
addTableData(table, msg, false);
}
private static void addTableDataLink(StringBuffer table, String link,
String jsEvent) {
if (link.indexOf(".") == -1) //$NON-NLS-1$
table
.append("<td>").append("<a href=\"#" + link + "\" onclick=\"" + jsEvent + "\">" + link + "</a>").append("</td>").append(NL); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
else
table
.append("<td>").append("<a href=\"" + link + "\" onclick=\"" + jsEvent + "\">" + link + "</a>").append("</td>").append(NL); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
}
private static void addTableData(StringBuffer table, String msg,
boolean error) {
if (error)
table
.append("<td style=\"background: #ffccff \">").append(msg).append("</td>").append(NL); //$NON-NLS-1$ //$NON-NLS-2$
else
table.append("<td>").append(msg).append("</td>").append(NL); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @param results
* @return
* @since 4.2
*/
private static ResponseTimes calcQueryResponseTimes(Collection queryResults) {
ResponseTimes responseTimes = new ResponseTimes();
int nQueries = 0;
double startTS;
// double firstResponseTimeStamp;
double fullResponseTimeStamp;
double totalSecs = 0.0;
double totalFullMilliSecs = 0.0;
// double totalFirstMilliSecs = 0.0;
for (Iterator resultItr = queryResults.iterator(); resultItr.hasNext();) {
TestResult result = (TestResult) resultItr.next();
++nQueries;
startTS = result.getBeginTS();
// firstResponseTimeStamp = result.getBeginTS();
fullResponseTimeStamp = result.getEndTS();
totalSecs += ((fullResponseTimeStamp - startTS) / 1000);
// totalFirstMilliSecs += (firstResponseTimeStamp - startTS);
totalFullMilliSecs += (fullResponseTimeStamp - startTS);
}
responseTimes.qps = (totalSecs > 0 ? nQueries / totalSecs : -1.0);
// responseTimes.first = (nQueries > 0 ? totalFirstMilliSecs / nQueries
// : -1.0);
responseTimes.full = (nQueries > 0 ? totalFullMilliSecs / nQueries
: -1.0);
return responseTimes;
}
private static String scrub(String str) {
// Scrub the query
if (str != null) {
str = str.replace('"', '#');
str = str.replace('\'', '#');
}
return str;
}
/**
* @param outputStream
* @param formatter
* @param stat
*/
private static void writeQueryResult(PrintStream outputStream,
SimpleDateFormat formatter, TestResult stat) {
outputStream.print(stat.getQueryID());
outputStream.print(","); //$NON-NLS-1$
outputStream.print(stat.getResultStatusString());
outputStream.print(","); //$NON-NLS-1$
outputStream.print(stat.getBeginTS());
outputStream.print(","); //$NON-NLS-1$
outputStream.print(stat.getEndTS());
outputStream.print(","); //$NON-NLS-1$
outputStream.print(getFormattedTimestamp(formatter, stat.getBeginTS()));
// outputStream.print(","); //$NON-NLS-1$
// outputStream.print(getFormattedTimestamp(formatter,
// stat.getFirstRepsonseTimeStamp()));
outputStream.print(","); //$NON-NLS-1$
outputStream.print(getFormattedTimestamp(formatter, stat.getEndTS()));
outputStream.print(","); //$NON-NLS-1$
outputStream
.println((stat.getStatus() != TestResult.RESULT_STATE.TEST_SUCCESS ? stat
.getExceptionMsg()
: "")); //$NON-NLS-1$
}
private static String getFormattedTimestamp(SimpleDateFormat format,
long millis) {
return format.format(new Date(millis));
}
private static class ResponseTimes {
double first; // millis
double full; // millis
double qps; // secs
}
}