1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 package org.openoffice.test.common; 22 23 import java.io.File; 24 import java.io.InputStream; 25 import java.text.SimpleDateFormat; 26 import java.util.Date; 27 import java.util.Map.Entry; 28 import java.util.Set; 29 30 import org.junit.Ignore; 31 import org.junit.runner.Description; 32 import org.junit.runner.Result; 33 import org.junit.runner.notification.Failure; 34 import org.junit.runner.notification.RunListener; 35 import org.w3c.dom.Document; 36 import org.w3c.dom.Element; 37 import org.w3c.dom.NodeList; 38 39 /** 40 * Generate XML test report 41 * 42 */ 43 public class XMLReporter extends RunListener { 44 45 private File outputDir = Testspace.getFile("output"); 46 47 private File file = null; 48 49 private Document doc = null; 50 51 private Element testsuiteEl = null; 52 53 private Element testcaseEl = null; 54 55 private String suiteName = null; 56 57 private long suiteStart = 0; 58 59 private long failures = 0; 60 61 private long errors = 0; 62 63 private long tests = 0; 64 65 private long ignored = 0; 66 67 private long runStart = 0; 68 private long testStart = 0; 69 70 @Override testStarted(Description description)71 public void testStarted(Description description) throws Exception { 72 // if (!description.getClassName().equals(testClassName)) { 73 // finishSuite(); 74 // startSuite(description); 75 // testClassName = description.getClassName(); 76 // } 77 testcaseEl = doc.createElement("testcase"); 78 testcaseEl.setAttribute("name", description.getDisplayName()); 79 testcaseEl.setAttribute("classname", description.getClassName()); 80 testcaseEl.setAttribute("methodname", description.getMethodName()); 81 testsuiteEl.appendChild(testcaseEl); 82 testStart = System.currentTimeMillis(); 83 } 84 85 @Override testAssumptionFailure(Failure failure)86 public void testAssumptionFailure(Failure failure) { 87 88 } 89 90 @Override testFailure(Failure failure)91 public void testFailure(Failure failure) throws Exception { 92 if (failure.getException() instanceof AssertionError) { 93 failures++; 94 Element failureEl = doc.createElement("failure"); 95 failureEl.setAttribute("message", failure.getMessage()); 96 failureEl.setAttribute("type", failure.getTestHeader()); 97 failureEl.setTextContent(failure.getTrace()); 98 testcaseEl.appendChild(failureEl); 99 } else { 100 errors++; 101 Element errorEl = doc.createElement("error"); 102 errorEl.setAttribute("message", failure.getMessage()); 103 errorEl.setAttribute("type", failure.getTestHeader()); 104 errorEl.setTextContent(failure.getTrace()); 105 testcaseEl.appendChild(errorEl); 106 } 107 } 108 109 @Override testFinished(Description description)110 public void testFinished(Description description) throws Exception { 111 tests++; 112 testcaseEl.setAttribute("time", Double.toString((System.currentTimeMillis() - testStart) / 1000.0)); 113 store(); 114 } 115 116 @Override testIgnored(Description description)117 public void testIgnored(Description description) throws Exception { 118 testStarted(description); 119 ignored++; 120 Ignore ignore = description.getAnnotation(Ignore.class); 121 Element ignoredEl = doc.createElement("ignored"); 122 ignoredEl.setAttribute("message", ignore.value()); 123 testcaseEl.appendChild(ignoredEl); 124 testFinished(description); 125 } 126 127 @Override testRunFinished(Result result)128 public void testRunFinished(Result result) throws Exception { 129 finishSuite(); 130 File outputBackupDir = new File(outputDir.getAbsolutePath() + "." + suiteName); 131 if (outputBackupDir.exists()) { 132 outputBackupDir.renameTo(new File(outputBackupDir.getAbsolutePath() + "." + System.currentTimeMillis())); 133 FileUtil.deleteFile(outputBackupDir); 134 } 135 136 outputDir.renameTo(outputBackupDir); 137 } 138 139 @Override testRunStarted(Description description)140 public void testRunStarted(Description description) throws Exception { 141 suiteName = description.getDisplayName(); 142 FileUtil.deleteFile(outputDir);//clear all old output 143 runStart = System.currentTimeMillis(); 144 startSuite(); 145 } 146 startSuite()147 private void startSuite() { 148 suiteStart = System.currentTimeMillis(); 149 failures = 0; 150 errors = 0; 151 tests = 0; 152 ignored = 0; 153 154 file = new File(outputDir, "result.xml"); 155 doc = FileUtil.newXML(); 156 157 testsuiteEl = doc.createElement("testsuite"); 158 testsuiteEl.setAttribute("name", suiteName); 159 testsuiteEl.setAttribute("start", Long.toString(suiteStart)); 160 doc.appendChild(testsuiteEl); 161 } 162 finishSuite()163 private void finishSuite() { 164 store(); 165 } 166 store()167 private void store() { 168 if (doc != null) { 169 testsuiteEl.setAttribute("time", Double.toString((System.currentTimeMillis() - testStart) / 1000.0)); 170 testsuiteEl.setAttribute("failures", Long.toString(failures)); 171 testsuiteEl.setAttribute("errors", Long.toString(errors)); 172 testsuiteEl.setAttribute("tests", Long.toString(tests)); 173 testsuiteEl.setAttribute("ignored", Long.toString(ignored)); 174 NodeList els = testsuiteEl.getElementsByTagName("properties"); 175 if (els.getLength() > 0) 176 testsuiteEl.removeChild(els.item(0)); 177 178 Element props = doc.createElement("properties"); 179 testsuiteEl.appendChild(props); 180 // Add some extra information 181 System.setProperty("info.os.name", SystemUtil.getOSName()); 182 System.setProperty("info.os.version", SystemUtil.getOSVersion()); 183 System.setProperty("info.os.arch", SystemUtil.getOSArch()); 184 String ipaddrStr = SystemUtil.getIPAddress(); 185 System.setProperty("info.ip", (ipaddrStr!=null) ? ipaddrStr : "UNKNOWN"); 186 String hostnameStr = SystemUtil.getHostName(); 187 System.setProperty("info.hostname", (hostnameStr!=null) ? hostnameStr : "UNKNOWN"); 188 Set<Entry<Object, Object>> entries = System.getProperties().entrySet(); 189 for (Entry<Object, Object> e : entries) { 190 Element prop = doc.createElement("property"); 191 prop.setAttribute("name", "" + e.getKey()); 192 prop.setAttribute("value", "" + e.getValue()); 193 props.appendChild(prop); 194 } 195 196 SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss"); 197 String aRunStartStr = dateFormat.format( new Date( runStart)); 198 long nRunEnd = System.currentTimeMillis(); 199 String aRunEndStr = dateFormat.format( new Date( nRunEnd)); 200 double fDuration = (nRunEnd - runStart) / 1000.0; 201 if( fDuration < 20*3600e3) // strip the end date if it is obvious 202 aRunEndStr = aRunEndStr.substring( 11); 203 String aTestTimeStr = String.format( "From %s to %s (%.1f secs)", aRunStartStr, aRunEndStr, fDuration); 204 System.setProperty( "info.test.date", aTestTimeStr); 205 206 FileUtil.storeXML(doc, file); 207 File htmlFile = new File(outputDir, "result.html"); 208 InputStream is = getClass().getResourceAsStream("XMLReporter.xsl"); 209 if (is != null) { 210 FileUtil.storeXML(doc, htmlFile, is); 211 } 212 } 213 } 214 215 } 216 217