blob: 2aba35a8d1bee1871336aa08e624fed399240d09 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.nbbuild;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Utility permitting Ant tasks to write out JUnit-format reports rather than aborting the build.
*/
public class JUnitReportWriter {
private JUnitReportWriter() {}
/**
* Possibly write out a report.
* @param task the Ant task doing the work
* @param suiteName name for the reported test (defaults to class name of {@code task}
* @param reportFile an XML file to create with the report; if null, and there were some failures,
* throw a {@link BuildException} instead
* @param pseudoTests the results of the "tests", as a map from test name (e.g. <samp>testSomething</samp>)
* to either null (success) or a (possibly multiline) failure message;
* use of a {@link java.util.LinkedHashMap} to preserve order is recommended
* @throws BuildException in case <code>reportFile</code> was null
* and <code>pseudoTests</code> contained some non-null values
*/
public static void writeReport(Task task, String suiteName, File reportFile, Map<String,String> pseudoTests) throws BuildException {
if (reportFile == null) {
StringBuilder errors = new StringBuilder();
for (Map.Entry<String,String> entry : pseudoTests.entrySet()) {
String msg = entry.getValue();
if (msg != null) {
errors.append("\n" + entry.getKey() + ": " + msg);
}
}
if (errors.length() > 0) {
throw new BuildException("Some tests failed:" + errors, task.getLocation());
} else {
task.log("All tests passed");
}
} else {
Document reportDoc = XMLUtil.createDocument("testsuite");
Element testsuite = reportDoc.getDocumentElement();
int failures = 0;
testsuite.setAttribute("errors", "0");
testsuite.setAttribute("time", "0.0");
String name = suiteName != null ? suiteName : task.getClass().getName();
testsuite.setAttribute("name", name); // http://www.nabble.com/difference-in-junit-publisher-and-ant-junitreport-tf4308604.html#a12265700
for (Map.Entry<String,String> entry : pseudoTests.entrySet()) {
Element testcase = reportDoc.createElement("testcase");
testsuite.appendChild(testcase);
testcase.setAttribute("classname", name);
testcase.setAttribute("name", entry.getKey());
testcase.setAttribute("time", "0.0");
String msg = entry.getValue();
if (msg != null) {
failures++;
Element failure = reportDoc.createElement("failure");
testcase.appendChild(failure);
failure.setAttribute("type", "junit.framework.AssertionFailedError");
failure.setAttribute("message", msg.replaceFirst("(?s)\n.*", ""));
failure.appendChild(reportDoc.createTextNode(msg));
}
}
testsuite.setAttribute("failures", Integer.toString(failures));
testsuite.setAttribute("tests", Integer.toString(pseudoTests.size()));
try {
try (OutputStream os = new FileOutputStream(reportFile)) {
XMLUtil.write(reportDoc, os);
}
} catch (IOException x) {
throw new BuildException("Could not write " + reportFile + ": " + x, x, task.getLocation());
}
task.log(reportFile + ": " + failures + " failures out of " + pseudoTests.size() + " tests");
}
}
}