At my company, we have JUnit runs with over 8000 tests per run and dozens of runs per week. I found that eventually, UnitTH will run out of heap space and crash when the StringBuffer used to generate the run pages needs to hold 100s of MBs of HTML markup.
Here is a sample of the stack trace that I normally see:
[java] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
[java] at java.util.Arrays.copyOf(Arrays.java:2882)
[java] at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
[java] at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
[java] at java.lang.StringBuffer.append(StringBuffer.java:224)
[java] at unitth.html.junit.HtmlGen.generateSpreadBar(HtmlGen.java:606)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadItem(HtmlPackageGen.java:983)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadItems(HtmlPackageGen.java:923)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadList(HtmlPackageGen.java:904)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageRunPage(HtmlPackageGen.java:95)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageRunPages(HtmlPackageGen.java:62)
[java] at unitth.html.junit.HtmlPackageGen.generateHtmlHistory(HtmlPackageGen.java:52)
[java] at unitth.core.UnitTH.unpackAndGenerate(UnitTH.java:414)
[java] at unitth.core.UnitTH.doTheStuff(UnitTH.java:386)
[java] at unitth.core.UnitTH.<init>(UnitTH.java:316)
[java] at unitth.core.UnitTH.main(UnitTH.java:295)
Proposed Fix:
I fixed bug in our in-house repository of UnitTH (we had extended it to add support for NUnit). My solution was to use a BufferedWriter in the methods that are used to create the different HTML files (e.g., generateMainPage(), generatePackageRunPage(), etc.) and pass the bufferedwriter to the different methods used to generate the markup.
With this approach, writing to the BufferedWriter is efficient like appending to StringBuffer. The difference is that the buffer will be flushed to disk periodically, allowing the application to scale up to very large report sizes like in our case.
I am attaching the patch file with my changes, against revision 193 of the main repository.
Patch file containing my proposed fix
Thanks, probably should have expected bugs like this to surface after a while. I'll review the patch and it does not sound all too complext to fix though if I recall correctly StringBuffer has been used in quite a number of places.
Thanks again,
Andreas
Part of 2.0 release. Build snapshot if needed.