blob: 817be18247d3919ad82e413fa7e70d34cc15f312 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed 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 vogar;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.kxml2.io.KXmlSerializer;
/**
* Writes JUnit results to a series of XML files in a format consistent with
* Ant's XMLJUnitResultFormatter.
*
* <p>Unlike Ant's formatter, this class does not report the execution time of
* tests.
*
* TODO: unify this and com.google.coretests.XmlReportPrinter
*/
public class XmlReportPrinter {
/** the XML namespace */
private static final String ns = null;
private final File directory;
private final ExpectationStore expectationStore;
private final Date date;
public XmlReportPrinter(File directory, ExpectationStore expectationStore, Date date) {
this.directory = directory;
this.expectationStore = expectationStore;
this.date = date;
}
/**
* Returns true if this XML Report printer can be used to emit XML.
*/
public boolean isReady() {
return directory != null;
}
private String getGMTTimestamp() {
SimpleDateFormat dateFormat = new SimpleDateFormat(XmlReportConstants.DATEFORMAT);
TimeZone gmt = TimeZone.getTimeZone("GMT");
dateFormat.setTimeZone(gmt);
dateFormat.setLenient(true);
return dateFormat.format(date);
}
/**
* Populates the directory with the report data from the completed tests.
*/
public int generateReports(Collection<Outcome> results) {
Map<String, Suite> suites = testsToSuites(results);
String timestamp = getGMTTimestamp();
for (Suite suite : suites.values()) {
String fileName = "TEST-" + suite.name + ".xml";
suite.printReport(timestamp, fileName);
}
return suites.size();
}
private Map<String, Suite> testsToSuites(Collection<Outcome> outcomes) {
Map<String, Suite> result = new LinkedHashMap<String, Suite>();
for (Outcome outcome : outcomes) {
if (outcome.getResult() == Result.UNSUPPORTED) {
continue;
}
String suiteName = outcome.getSuiteName();
Suite suite = result.get(suiteName);
if (suite == null) {
suite = new Suite(suiteName);
result.put(suiteName, suite);
}
suite.outcomes.add(outcome);
Expectation expectation = expectationStore.get(outcome);
if (!expectation.matches(outcome)) {
if (outcome.getResult() == Result.EXEC_FAILED) {
suite.failuresCount++;
} else {
suite.errorsCount++;
}
}
}
return result;
}
class Suite {
private final String name;
private final List<Outcome> outcomes = new ArrayList<Outcome>();
private int failuresCount;
private int errorsCount;
Suite(String name) {
this.name = name;
}
private void print(KXmlSerializer serializer, String timestamp) throws IOException {
serializer.startTag(ns, XmlReportConstants.TESTSUITE);
serializer.attribute(ns, XmlReportConstants.ATTR_NAME, name);
serializer.attribute(ns, XmlReportConstants.ATTR_TESTS, Integer.toString(outcomes.size()));
serializer.attribute(ns, XmlReportConstants.ATTR_FAILURES, Integer.toString(failuresCount));
serializer.attribute(ns, XmlReportConstants.ATTR_ERRORS, Integer.toString(errorsCount));
serializer.attribute(ns, XmlReportConstants.ATTR_TIME, "0");
serializer.attribute(ns, XmlReportConstants.TIMESTAMP, timestamp);
serializer.attribute(ns, XmlReportConstants.HOSTNAME, "localhost");
serializer.startTag(ns, XmlReportConstants.PROPERTIES);
serializer.endTag(ns, XmlReportConstants.PROPERTIES);
for (Outcome outcome : outcomes) {
print(serializer, outcome);
}
serializer.endTag(ns, XmlReportConstants.TESTSUITE);
}
private void print(KXmlSerializer serializer, Outcome outcome) throws IOException {
serializer.startTag(ns, XmlReportConstants.TESTCASE);
serializer.attribute(ns, XmlReportConstants.ATTR_NAME, outcome.getTestName());
serializer.attribute(ns, XmlReportConstants.ATTR_CLASSNAME, outcome.getSuiteName());
serializer.attribute(ns, XmlReportConstants.ATTR_TIME, "0");
Expectation expectation = expectationStore.get(outcome);
if (!expectation.matches(outcome)) {
String result;
switch (outcome.getResult()) {
case EXEC_FAILED:
result = XmlReportConstants.FAILURE;
break;
case SUCCESS:
result = XmlReportConstants.SUCCESS;
break;
default:
result = XmlReportConstants.ERROR;
break;
}
serializer.startTag(ns, result);
serializer.attribute(ns, XmlReportConstants.ATTR_TYPE, outcome.getResult().toString());
String text = outcome.getOutput();
serializer.text(text);
serializer.endTag(ns, result);
}
serializer.endTag(ns, XmlReportConstants.TESTCASE);
}
void printReport(String timestamp, String fileName) {
FileOutputStream stream = null;
try {
stream = new FileOutputStream(new File(directory, fileName));
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(stream, "UTF-8");
serializer.startDocument("UTF-8", null);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
print(serializer, timestamp);
serializer.endDocument();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ignored) {
}
}
}
}
}
}