package jetbrains.mps.tool.builder.unittest; /*Generated by MPS */ import org.jdom.JDOMFactory; import org.jdom.DefaultJDOMFactory; import java.text.SimpleDateFormat; import org.jdom.Document; import org.jdom.Element; import java.util.Map; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import java.util.Set; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.HashSet; import java.util.Date; import java.io.OutputStream; import java.io.IOException; import org.jdom.output.XMLOutputter; import org.jdom.output.Format; import java.util.regex.Matcher; import java.util.TimeZone; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Pattern; public class XmlTestReporter implements ITestReporter { private static final String ISO8601_DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; private static final String TESTSUITES = "testsuites"; private static final String TESTSUITE = "testsuite"; private static final String TESTCASE = "testcase"; private static final String ERROR = "error"; private static final String FAILURE = "failure"; private static final String SYSTEM_ERR = "system-err"; private static final String SYSTEM_OUT = "system-out"; private static final String ATTR_PACKAGE = "package"; private static final String ATTR_NAME = "name"; private static final String ATTR_TIME = "time"; private static final String ATTR_ERRORS = "errors"; private static final String ATTR_FAILURES = "failures"; private static final String ATTR_TESTS = "tests"; private static final String ATTR_TYPE = "type"; private static final String ATTR_MESSAGE = "message"; private static final String PROPERTIES = "properties"; private static final String PROPERTY = "property"; private static final String ATTR_VALUE = "value"; private static final String ATTR_CLASSNAME = "classname"; private static final String ATTR_ID = "id"; private static final String TIMESTAMP = "timestamp"; private static final String HOSTNAME = "hostname"; private JDOMFactory jdom = new DefaultJDOMFactory(); private SimpleDateFormat simpleDateFormat; private Document document; private Element root; private String hostname; private long suiteStarted; private Map<String, Long> testStarted = MapSequence.fromMap(new HashMap<String, Long>()); private Set<String> testFailed = SetSequence.fromSet(new HashSet<String>()); private Map<String, Element> testElement = MapSequence.fromMap(new HashMap<String, Element>()); private Map<String, StringBuilder> testStdout = MapSequence.fromMap(new HashMap<String, StringBuilder>()); private Map<String, StringBuilder> testStderr = MapSequence.fromMap(new HashMap<String, StringBuilder>()); private StringBuilder suiteStdout = new StringBuilder(); private StringBuilder suiteStderr = new StringBuilder(); public XmlTestReporter(String name) { this.suiteStarted = System.currentTimeMillis(); this.root = jdom.element(TESTSUITE).setAttribute(jdom.attribute(ATTR_NAME, name)).setAttribute(jdom.attribute(TIMESTAMP, timeStamp(new Date(suiteStarted)))).setAttribute(jdom.attribute(HOSTNAME, hostname())); this.document = jdom.document(this.root); } public void dump(OutputStream os) throws IOException { new XMLOutputter(Format.getPrettyFormat()).output(document, os); } @Override public void runFinished() { long suiteFinished = System.currentTimeMillis(); root.setAttribute(jdom.attribute(ATTR_TESTS, String.valueOf(MapSequence.fromMap(testStarted).count()))).setAttribute(jdom.attribute(ATTR_FAILURES, String.valueOf(SetSequence.fromSet(testFailed).count()))).setAttribute(jdom.attribute(ATTR_ERRORS, String.valueOf(0))).setAttribute(jdom.attribute(ATTR_TIME, seconds(suiteFinished - suiteStarted))); if (suiteStdout.length() > 0) { root.addContent(jdom.element(SYSTEM_OUT).addContent(jdom.cdata(fixDoubleClosingBrackets(suiteStdout).toString()))); } if (suiteStderr.length() > 0) { root.addContent(jdom.element(SYSTEM_ERR).addContent(jdom.cdata(fixDoubleClosingBrackets(suiteStderr).toString()))); } } @Override public void testStarted(String testFQname) { MapSequence.fromMap(testStarted).put(testFQname, System.currentTimeMillis()); MapSequence.fromMap(testElement).put(testFQname, jdom.element(TESTCASE).setAttribute(jdom.attribute(ATTR_NAME, shortName(testFQname))).setAttribute(jdom.attribute(ATTR_CLASSNAME, prefix(testFQname)))); root.addContent(MapSequence.fromMap(testElement).get(testFQname)); } @Override public void testFinished(String testFQname) { if (!(MapSequence.fromMap(testElement).containsKey(testFQname))) { testStarted(testFQname); } long testFinished = System.currentTimeMillis(); MapSequence.fromMap(testElement).get(testFQname).setAttribute(jdom.attribute(ATTR_TIME, seconds(testFinished - MapSequence.fromMap(testStarted).get(testFQname)))); if (MapSequence.fromMap(testStdout).containsKey(testFQname)) { MapSequence.fromMap(testElement).get(testFQname).addContent(jdom.element(SYSTEM_OUT).addContent(jdom.cdata(fixDoubleClosingBrackets(MapSequence.fromMap(testStdout).get(testFQname)).toString()))); } if (MapSequence.fromMap(testStderr).containsKey(testFQname)) { MapSequence.fromMap(testElement).get(testFQname).addContent(jdom.element(SYSTEM_ERR).addContent(jdom.cdata(fixDoubleClosingBrackets(MapSequence.fromMap(testStderr).get(testFQname)).toString()))); } } @Override public void testFailed(String testFQname, String msg, String longMsg) { if (!(MapSequence.fromMap(testElement).containsKey(testFQname))) { testStarted(testFQname); } SetSequence.fromSet(testFailed).addElement(testFQname); Element fail = jdom.element(FAILURE).setAttribute(jdom.attribute(ATTR_MESSAGE, msg)); MapSequence.fromMap(testElement).get(testFQname).addContent(fail); if (longMsg != null) { fail.addContent(jdom.text(longMsg)); } } @Override public void testOutputLine(String testFQname, String msg) { if (!(MapSequence.fromMap(testElement).containsKey(testFQname))) { testStarted(testFQname); } StringBuilder sb = MapSequence.fromMap(testStdout).get(testFQname); if (sb == null) { MapSequence.fromMap(testStdout).put(testFQname, new StringBuilder()); sb = MapSequence.fromMap(testStdout).get(testFQname); } sb.append(msg).append("\n"); } @Override public void testErrorLine(String testFQname, String msg) { if (!(MapSequence.fromMap(testElement).containsKey(testFQname))) { testStarted(testFQname); } StringBuilder sb = MapSequence.fromMap(testStderr).get(testFQname); if (sb == null) { MapSequence.fromMap(testStderr).put(testFQname, new StringBuilder()); sb = MapSequence.fromMap(testStderr).get(testFQname); } sb.append(msg).append("\n"); } @Override public void outputLine(String msg) { suiteStdout.append(msg).append("\n"); } @Override public void errorLine(String msg) { suiteStderr.append(msg).append("\n"); } private StringBuilder fixDoubleClosingBrackets(StringBuilder sb) { int dcb = 0; while ((dcb = sb.indexOf("]]", dcb)) >= 0) { sb.replace(dcb, dcb + 2, "].]"); } return sb; } private String shortName(String testFQname) { Matcher matcher = REGEXP_rw4j9x_a0a0a74.matcher(testFQname); return (matcher.matches() ? matcher.group(1) : testFQname); } private String prefix(String testFQname) { Matcher matcher = REGEXP_rw4j9x_a0a0a84.matcher(testFQname); return (matcher.matches() ? matcher.group(1) : testFQname); } public String seconds(long millis) { return String.valueOf(((double) millis) / 1000.0); } private String timeStamp(Date date) { if (simpleDateFormat == null) { simpleDateFormat = new SimpleDateFormat(ISO8601_DATETIME_PATTERN); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); simpleDateFormat.setLenient(true); } return simpleDateFormat.format(date); } private String hostname() { if (hostname == null) { try { this.hostname = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException ignore) { } } return this.hostname; } private static Pattern REGEXP_rw4j9x_a0a0a74 = Pattern.compile(".+\\.([^\\.]+)$", 0); private static Pattern REGEXP_rw4j9x_a0a0a84 = Pattern.compile("(.*)\\.[^\\.]+$", 0); }