diff --git a/core/src/main/java/hudson/tasks/junit/TestResultAction.java b/core/src/main/java/hudson/tasks/junit/TestResultAction.java index 22e9b0b068..bcaa374ce0 100644 --- a/core/src/main/java/hudson/tasks/junit/TestResultAction.java +++ b/core/src/main/java/hudson/tasks/junit/TestResultAction.java @@ -171,15 +171,18 @@ public class TestResultAction extends AbstractTestResultAction public List getActions(TestObject object) { List result = new ArrayList(); - for (Data data: testData) { - result.addAll(data.getTestAction(object)); - } - return Collections.unmodifiableList(result); - } - - public void setData(List testData) { - this.testData = testData; + // Added check for null testData to avoid NPE from issue 4257. + if (testData!=null) { + for (Data data: testData) { + result.addAll(data.getTestAction(object)); + } } + return Collections.unmodifiableList(result); + + } + public void setData(List testData) { + this.testData = testData; + } /** * Resolves {@link TestAction}s for the given {@link TestObject}. diff --git a/core/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly b/core/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly index e3acbb9dd3..e4aa0493ec 100644 --- a/core/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly +++ b/core/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly @@ -68,7 +68,7 @@ THE SOFTWARE.

${%Error Message}

-
"${it.annotate(it.errorDetails)}
+
"${it.annotate(it.errorDetails)}"

${%Stacktrace}

${it.annotate(it.errorStackTrace)}
diff --git a/test/pom.xml b/test/pom.xml index f6a81325bd..a4848cf63c 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -60,6 +60,7 @@ THE SOFTWARE. org.codehaus.groovy.maven gmaven-plugin + 1.0-rc-5 process-resources diff --git a/test/src/test/java/hudson/tasks/junit/CaseResultTest.java b/test/src/test/java/hudson/tasks/junit/CaseResultTest.java index eba7427e5e..75102b6ffb 100644 --- a/test/src/test/java/hudson/tasks/junit/CaseResultTest.java +++ b/test/src/test/java/hudson/tasks/junit/CaseResultTest.java @@ -31,7 +31,11 @@ import hudson.model.FreeStyleBuild; import hudson.Launcher; import org.jvnet.hudson.test.HudsonTestCase; import org.jvnet.hudson.test.Email; +import org.jvnet.hudson.test.Bug; import org.jvnet.hudson.test.TestBuilder; +import com.gargoylesoftware.htmlunit.WebAssert; +import com.gargoylesoftware.htmlunit.html.HtmlPage; +import com.gargoylesoftware.htmlunit.html.HtmlElement; import java.io.IOException; @@ -98,7 +102,44 @@ public class CaseResultTest extends HudsonTestCase { "http://localhost:8080/stuff/"); } + + /** + * Verifies that the error message and stacktrace from a failed junit test actually render properly. + */ + @Bug(4257) + public void testErrorMsgAndStacktraceRender() throws Exception { + FreeStyleProject p = createFreeStyleProject("render-test"); + p.getBuildersList().add(new TestBuilder() { + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + build.getWorkspace().child("junit.xml").copyFrom( + getClass().getResource("junit-report-20090516.xml")); + return true; + } + }); + p.getPublishersList().add(new JUnitResultArchiver("*.xml")); + FreeStyleBuild b = assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get()); + TestResult tr = b.getAction(TestResultAction.class).getResult(); + assertEquals(3,tr.getFailedTests().size()); + CaseResult cr = tr.getFailedTests().get(1); + assertEquals("org.twia.vendor.VendorManagerTest",cr.getClassName()); + assertEquals("testGetRevokedClaimsForAdjustingFirm",cr.getName()); + + String testUrl = cr.getRelativePathFrom(tr); + + HtmlPage page = new WebClient().goTo("job/render-test/1/testReport/" + testUrl); + + HtmlElement errorMsg = (HtmlElement) page.getByXPath("//h3[text()='Error Message']/following-sibling::*").get(0); + assertEquals("\"" + cr.annotate(cr.getErrorDetails()) + "\"", errorMsg.getTextContent()); + HtmlElement errorStackTrace = (HtmlElement) page.getByXPath("//h3[text()='Stacktrace']/following-sibling::*").get(0); + + // Have to do some annoying replacing here to get the same text Jelly produces in the end. + assertEquals(cr.annotate(cr.getErrorStackTrace()).replaceAll("<", "<").replace("\r\n", "\n"), + errorStackTrace.getTextContent()); + } + + private void assertOutput(CaseResult cr, String in, String out) throws Exception { assertEquals(out, cr.annotate(in)); } + }