Fixed: Issue24 OOM errors in SuiteHTMLReporter
Added Utils.appendToFile() method to avoid creating a huge stringbuffer before writing out to file.
Ran a Factory test with 2000 instances before and after the changes to ensure that OOM error doesn't occur anymore.
diff --git a/CHANGES.txt b/CHANGES.txt
index e78b5f6..e3eaaee 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,6 +3,7 @@
Added: New ant task tag: propertyset (Todd Wells)
Added: ITestNGListenerFactory
Added: Passing command line properties via the ant task and doc update (Todd Wells)
+Fixed: Issue24 OOM errors in SuiteHTMLReporter
Fixed: Time outs specified in XML were not honored for <suite parallel="tests">
Fixed: <suite> and <test> time outs were hardcoded, they now honor their time-out attribute
Fixed: TestNG was hanging if no test methods were found
diff --git a/src/org/testng/internal/Utils.java b/src/org/testng/internal/Utils.java
index f71ec8e..5e34d9a 100755
--- a/src/org/testng/internal/Utils.java
+++ b/src/org/testng/internal/Utils.java
@@ -1,6 +1,5 @@
package org.testng.internal;
-
import org.testng.ITestNGMethod;
import org.testng.TestNGCommandLineArgs;
import org.testng.TestRunner;
@@ -24,7 +23,6 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -142,7 +140,7 @@
public static void writeUtf8File(String outputDir, String fileName, String sb) {
final String outDirPath= outputDir != null ? outputDir : "";
final File outDir= new File(outDirPath);
- writeFile(outDir, fileName, sb, "UTF-8");
+ writeFile(outDir, fileName, sb, "UTF-8", false);
}
/**
@@ -156,7 +154,20 @@
public static void writeFile(String outputDir, String fileName, String sb) {
final String outDirPath= outputDir != null ? outputDir : "";
final File outDir= new File(outDirPath);
- writeFile(outDir, fileName, sb, null);
+ writeFile(outDir, fileName, sb, null, false);
+ }
+
+ /**
+ * Appends contents of the string to the specified file. If output directory/file don't
+ * exist, they are created.
+ * @param outputDir output directory. If <tt>null</tt>, then current directory is used
+ * @param fileName file name
+ * @param sb string to be appended to file
+ */
+ public static void appendToFile(String outputDir, String fileName, String sb) {
+ final String outDirPath= outputDir != null ? outputDir : "";
+ final File outDir= new File(outDirPath);
+ writeFile(outDir, fileName, sb, null, true);
}
/**
@@ -167,7 +178,7 @@
* @param fileName the filename
* @param sb the file content
*/
- private static void writeFile(File outDir, String fileName, String sb, String encoding) {
+ private static void writeFile(File outDir, String fileName, String sb, String encoding, boolean append) {
try {
if (!outDir.exists()) {
outDir.mkdirs();
@@ -175,10 +186,11 @@
fileName = replaceSpecialCharacters(fileName);
File outputFile = new File(outDir, fileName);
- outputFile.delete();
- outputFile.createNewFile();
-
- writeFile(outputFile, sb, encoding);
+ if (!append) {
+ outputFile.delete();
+ outputFile.createNewFile();
+ }
+ writeFile(outputFile, sb, encoding, append);
}
catch (IOException e) {
if (TestRunner.getVerbose() > 1) {
@@ -190,16 +202,16 @@
}
}
- private static void writeFile(File outputFile, String sb, String encoding) {
+ private static void writeFile(File outputFile, String sb, String encoding, boolean append) {
BufferedWriter fw = null;
try {
- if (! outputFile.exists()) outputFile.createNewFile();
+ if (!outputFile.exists()) outputFile.createNewFile();
OutputStreamWriter osw= null;
- if(null != encoding) {
- osw= new OutputStreamWriter(new FileOutputStream(outputFile, false), encoding);
+ if (null != encoding) {
+ osw = new OutputStreamWriter(new FileOutputStream(outputFile, append), encoding);
}
else {
- osw= new OutputStreamWriter(new FileOutputStream(outputFile, false));
+ osw = new OutputStreamWriter(new FileOutputStream(outputFile, append));
}
fw = new BufferedWriter(osw);
fw.write(sb);
diff --git a/src/org/testng/reporters/SuiteHTMLReporter.java b/src/org/testng/reporters/SuiteHTMLReporter.java
index 36fe0fe..b9e2731 100755
--- a/src/org/testng/reporters/SuiteHTMLReporter.java
+++ b/src/org/testng/reporters/SuiteHTMLReporter.java
@@ -340,11 +340,12 @@
sb.append("<h3>" + BEFORE + " means before, " + AFTER + " means after</h3><p/>");
long startDate = -1;
- Map<Long, StringBuffer> tables = Maps.newHashMap();
sb.append("<br/><em>").append(suite.getName()).append("</em><p/>");
sb.append("<small><i>(Hover the method name to see the test class name)</i></small><p/>\n");
+ Utils.writeFile(getOutputDirectory(xmlSuite), outputFileName, sb.toString());
+ sb = null; //not needed anymore
+
Collection<ITestNGMethod> invokedMethods = suite.getInvokedMethods();
-
if (alphabetical) {
@SuppressWarnings({"unchecked"})
Comparator<? super ITestNGMethod> alphabeticalComparator = new Comparator(){
@@ -357,12 +358,12 @@
Collections.sort((List) invokedMethods, alphabeticalComparator);
}
+ SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
+ StringBuffer table = new StringBuffer();
+ boolean addedHeader = false;
for (ITestNGMethod tm : invokedMethods) {
- Long id = new Long(0);
- StringBuffer table = tables.get(id);
- if (null == table) {
- table = new StringBuffer();
- tables.put(id, table);
+ table.setLength(0);
+ if (!addedHeader) {
table.append("<table border=\"1\">\n")
.append("<tr>")
.append("<th>Time</th>")
@@ -376,6 +377,7 @@
.append("<th>Thread</th>")
.append("<th>Instances</th>")
.append("</tr>\n");
+ addedHeader = true;
}
String methodName = tm.toString();
boolean bc = tm.isBeforeClassConfiguration();
@@ -406,7 +408,6 @@
}
if (startDate == -1) startDate = tm.getDate();
- SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
String date = format.format(tm.getDate());
table.append("<tr bgcolor=\"" + createColor(tm) + "\">")
.append(" <td>").append(date).append("</td> ")
@@ -421,19 +422,9 @@
.append(" <td>").append(instances).append("</td> ")
.append("</tr>\n")
;
+ Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, table.toString());
}
-
- /// Close all the tables
- for (StringBuffer table : tables.values()) {
- table.append("</table>\n");
- sb.append(table.toString());
- }
- Utils.writeFile(getOutputDirectory(xmlSuite), outputFileName, sb.toString());
-
- }
-
- private static String toHex(int n) {
- return Integer.toHexString(0x10 | n).substring(1).toUpperCase();
+ Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, "</table>\n");
}
/**