1180e3c91SLiu Zhe /************************************************************** 2180e3c91SLiu Zhe * 3180e3c91SLiu Zhe * Licensed to the Apache Software Foundation (ASF) under one 4180e3c91SLiu Zhe * or more contributor license agreements. See the NOTICE file 5180e3c91SLiu Zhe * distributed with this work for additional information 6180e3c91SLiu Zhe * regarding copyright ownership. The ASF licenses this file 7180e3c91SLiu Zhe * to you under the Apache License, Version 2.0 (the 8180e3c91SLiu Zhe * "License"); you may not use this file except in compliance 9180e3c91SLiu Zhe * with the License. You may obtain a copy of the License at 10180e3c91SLiu Zhe * 11180e3c91SLiu Zhe * http://www.apache.org/licenses/LICENSE-2.0 12180e3c91SLiu Zhe * 13180e3c91SLiu Zhe * Unless required by applicable law or agreed to in writing, 14180e3c91SLiu Zhe * software distributed under the License is distributed on an 15180e3c91SLiu Zhe * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16180e3c91SLiu Zhe * KIND, either express or implied. See the License for the 17180e3c91SLiu Zhe * specific language governing permissions and limitations 18180e3c91SLiu Zhe * under the License. 19180e3c91SLiu Zhe * 20180e3c91SLiu Zhe *************************************************************/ 219e9f0f63SLiu Zhe package org.openoffice.test.common; 229e9f0f63SLiu Zhe 239e9f0f63SLiu Zhe import java.io.File; 24a7a6f583SLiu Zhe import java.io.InputStream; 25e8da46a6SHerbert Dürr import java.text.SimpleDateFormat; 26e8da46a6SHerbert Dürr import java.util.Date; 27a7a6f583SLiu Zhe import java.util.Map.Entry; 28a7a6f583SLiu Zhe import java.util.Set; 299e9f0f63SLiu Zhe 309e9f0f63SLiu Zhe import org.junit.Ignore; 319e9f0f63SLiu Zhe import org.junit.runner.Description; 329e9f0f63SLiu Zhe import org.junit.runner.Result; 339e9f0f63SLiu Zhe import org.junit.runner.notification.Failure; 349e9f0f63SLiu Zhe import org.junit.runner.notification.RunListener; 359e9f0f63SLiu Zhe import org.w3c.dom.Document; 369e9f0f63SLiu Zhe import org.w3c.dom.Element; 37da7831cbSLiu Zhe import org.w3c.dom.NodeList; 389e9f0f63SLiu Zhe 39da7831cbSLiu Zhe /** 40da7831cbSLiu Zhe * Generate XML test report 41da7831cbSLiu Zhe * 42da7831cbSLiu Zhe */ 439e9f0f63SLiu Zhe public class XMLReporter extends RunListener { 449e9f0f63SLiu Zhe 456467ecbfSLiu Zhe private File outputDir = Testspace.getFile("output"); 466467ecbfSLiu Zhe 479e9f0f63SLiu Zhe private File file = null; 489e9f0f63SLiu Zhe 499e9f0f63SLiu Zhe private Document doc = null; 509e9f0f63SLiu Zhe 51a7a6f583SLiu Zhe private Element testsuiteEl = null; 52a7a6f583SLiu Zhe 53a7a6f583SLiu Zhe private Element testcaseEl = null; 54a7a6f583SLiu Zhe 556467ecbfSLiu Zhe private String suiteName = null; 56a7a6f583SLiu Zhe 57a7a6f583SLiu Zhe private long suiteStart = 0; 58a7a6f583SLiu Zhe 59a7a6f583SLiu Zhe private long failures = 0; 60a7a6f583SLiu Zhe 61a7a6f583SLiu Zhe private long errors = 0; 62a7a6f583SLiu Zhe 63a7a6f583SLiu Zhe private long tests = 0; 64a7a6f583SLiu Zhe 65a7a6f583SLiu Zhe private long ignored = 0; 66a7a6f583SLiu Zhe 67*f1afe80aSHerbert Dürr private long runStart = 0; 68a7a6f583SLiu Zhe private long testStart = 0; 69a7a6f583SLiu Zhe 70a7a6f583SLiu Zhe @Override testStarted(Description description)71a7a6f583SLiu Zhe public void testStarted(Description description) throws Exception { 726467ecbfSLiu Zhe // if (!description.getClassName().equals(testClassName)) { 736467ecbfSLiu Zhe // finishSuite(); 746467ecbfSLiu Zhe // startSuite(description); 756467ecbfSLiu Zhe // testClassName = description.getClassName(); 766467ecbfSLiu Zhe // } 77a7a6f583SLiu Zhe testcaseEl = doc.createElement("testcase"); 78a7a6f583SLiu Zhe testcaseEl.setAttribute("name", description.getDisplayName()); 79a7a6f583SLiu Zhe testcaseEl.setAttribute("classname", description.getClassName()); 80a7a6f583SLiu Zhe testcaseEl.setAttribute("methodname", description.getMethodName()); 81a7a6f583SLiu Zhe testsuiteEl.appendChild(testcaseEl); 82a7a6f583SLiu Zhe testStart = System.currentTimeMillis(); 83a7a6f583SLiu Zhe } 849e9f0f63SLiu Zhe 859e9f0f63SLiu Zhe @Override testAssumptionFailure(Failure failure)869e9f0f63SLiu Zhe public void testAssumptionFailure(Failure failure) { 87a7a6f583SLiu Zhe 889e9f0f63SLiu Zhe } 899e9f0f63SLiu Zhe 909e9f0f63SLiu Zhe @Override testFailure(Failure failure)919e9f0f63SLiu Zhe public void testFailure(Failure failure) throws Exception { 92a7a6f583SLiu Zhe if (failure.getException() instanceof AssertionError) { 93a7a6f583SLiu Zhe failures++; 94a7a6f583SLiu Zhe Element failureEl = doc.createElement("failure"); 95a7a6f583SLiu Zhe failureEl.setAttribute("message", failure.getMessage()); 96a7a6f583SLiu Zhe failureEl.setAttribute("type", failure.getTestHeader()); 97a7a6f583SLiu Zhe failureEl.setTextContent(failure.getTrace()); 98a7a6f583SLiu Zhe testcaseEl.appendChild(failureEl); 99a7a6f583SLiu Zhe } else { 100a7a6f583SLiu Zhe errors++; 101a7a6f583SLiu Zhe Element errorEl = doc.createElement("error"); 102a7a6f583SLiu Zhe errorEl.setAttribute("message", failure.getMessage()); 103a7a6f583SLiu Zhe errorEl.setAttribute("type", failure.getTestHeader()); 104a7a6f583SLiu Zhe errorEl.setTextContent(failure.getTrace()); 105a7a6f583SLiu Zhe testcaseEl.appendChild(errorEl); 106a7a6f583SLiu Zhe } 1079e9f0f63SLiu Zhe } 1089e9f0f63SLiu Zhe 1099e9f0f63SLiu Zhe @Override testFinished(Description description)1109e9f0f63SLiu Zhe public void testFinished(Description description) throws Exception { 111a7a6f583SLiu Zhe tests++; 112a7a6f583SLiu Zhe testcaseEl.setAttribute("time", Double.toString((System.currentTimeMillis() - testStart) / 1000.0)); 113a7a6f583SLiu Zhe store(); 1149e9f0f63SLiu Zhe } 1159e9f0f63SLiu Zhe 1169e9f0f63SLiu Zhe @Override testIgnored(Description description)1179e9f0f63SLiu Zhe public void testIgnored(Description description) throws Exception { 118a7a6f583SLiu Zhe testStarted(description); 119a7a6f583SLiu Zhe ignored++; 120a7a6f583SLiu Zhe Ignore ignore = description.getAnnotation(Ignore.class); 121a7a6f583SLiu Zhe Element ignoredEl = doc.createElement("ignored"); 122a7a6f583SLiu Zhe ignoredEl.setAttribute("message", ignore.value()); 123a7a6f583SLiu Zhe testcaseEl.appendChild(ignoredEl); 124a7a6f583SLiu Zhe testFinished(description); 1259e9f0f63SLiu Zhe } 1269e9f0f63SLiu Zhe 1279e9f0f63SLiu Zhe @Override testRunFinished(Result result)1289e9f0f63SLiu Zhe public void testRunFinished(Result result) throws Exception { 129a7a6f583SLiu Zhe finishSuite(); 1306467ecbfSLiu Zhe File outputBackupDir = new File(outputDir.getAbsolutePath() + "." + suiteName); 1316467ecbfSLiu Zhe if (outputBackupDir.exists()) { 132e7b83f73SLiu Zhe outputBackupDir.renameTo(new File(outputBackupDir.getAbsolutePath() + "." + System.currentTimeMillis())); 1336467ecbfSLiu Zhe FileUtil.deleteFile(outputBackupDir); 1346467ecbfSLiu Zhe } 1356467ecbfSLiu Zhe 1366467ecbfSLiu Zhe outputDir.renameTo(outputBackupDir); 1379e9f0f63SLiu Zhe } 1389e9f0f63SLiu Zhe 1399e9f0f63SLiu Zhe @Override testRunStarted(Description description)1409e9f0f63SLiu Zhe public void testRunStarted(Description description) throws Exception { 1416467ecbfSLiu Zhe suiteName = description.getDisplayName(); 1426467ecbfSLiu Zhe FileUtil.deleteFile(outputDir);//clear all old output 143*f1afe80aSHerbert Dürr runStart = System.currentTimeMillis(); 1446467ecbfSLiu Zhe startSuite(); 145a7a6f583SLiu Zhe } 146a7a6f583SLiu Zhe startSuite()1476467ecbfSLiu Zhe private void startSuite() { 148a7a6f583SLiu Zhe suiteStart = System.currentTimeMillis(); 149a7a6f583SLiu Zhe failures = 0; 150a7a6f583SLiu Zhe errors = 0; 151a7a6f583SLiu Zhe tests = 0; 152a7a6f583SLiu Zhe ignored = 0; 153a7a6f583SLiu Zhe 154180e3c91SLiu Zhe file = new File(outputDir, "result.xml"); 1559e9f0f63SLiu Zhe doc = FileUtil.newXML(); 1569e9f0f63SLiu Zhe 157a7a6f583SLiu Zhe testsuiteEl = doc.createElement("testsuite"); 1586467ecbfSLiu Zhe testsuiteEl.setAttribute("name", suiteName); 159a7a6f583SLiu Zhe testsuiteEl.setAttribute("start", Long.toString(suiteStart)); 160a7a6f583SLiu Zhe doc.appendChild(testsuiteEl); 1619e9f0f63SLiu Zhe } 1629e9f0f63SLiu Zhe finishSuite()163a7a6f583SLiu Zhe private void finishSuite() { 164da7831cbSLiu Zhe store(); 165da7831cbSLiu Zhe } 166da7831cbSLiu Zhe store()167da7831cbSLiu Zhe private void store() { 168da7831cbSLiu Zhe if (doc != null) { 169a7a6f583SLiu Zhe testsuiteEl.setAttribute("time", Double.toString((System.currentTimeMillis() - testStart) / 1000.0)); 170a7a6f583SLiu Zhe testsuiteEl.setAttribute("failures", Long.toString(failures)); 171a7a6f583SLiu Zhe testsuiteEl.setAttribute("errors", Long.toString(errors)); 172a7a6f583SLiu Zhe testsuiteEl.setAttribute("tests", Long.toString(tests)); 173a7a6f583SLiu Zhe testsuiteEl.setAttribute("ignored", Long.toString(ignored)); 174da7831cbSLiu Zhe NodeList els = testsuiteEl.getElementsByTagName("properties"); 175da7831cbSLiu Zhe if (els.getLength() > 0) 176da7831cbSLiu Zhe testsuiteEl.removeChild(els.item(0)); 177da7831cbSLiu Zhe 178a7a6f583SLiu Zhe Element props = doc.createElement("properties"); 179a7a6f583SLiu Zhe testsuiteEl.appendChild(props); 18022cec863SLiu Zhe // Add some extra information 18122cec863SLiu Zhe System.setProperty("info.os.name", SystemUtil.getOSName()); 18222cec863SLiu Zhe System.setProperty("info.os.version", SystemUtil.getOSVersion()); 18322cec863SLiu Zhe System.setProperty("info.os.arch", SystemUtil.getOSArch()); 18443261468SHerbert Dürr String ipaddrStr = SystemUtil.getIPAddress(); 18543261468SHerbert Dürr System.setProperty("info.ip", (ipaddrStr!=null) ? ipaddrStr : "UNKNOWN"); 18643261468SHerbert Dürr String hostnameStr = SystemUtil.getHostName(); 18743261468SHerbert Dürr System.setProperty("info.hostname", (hostnameStr!=null) ? hostnameStr : "UNKNOWN"); 188a7a6f583SLiu Zhe Set<Entry<Object, Object>> entries = System.getProperties().entrySet(); 189a7a6f583SLiu Zhe for (Entry<Object, Object> e : entries) { 190a7a6f583SLiu Zhe Element prop = doc.createElement("property"); 191a7a6f583SLiu Zhe prop.setAttribute("name", "" + e.getKey()); 192a7a6f583SLiu Zhe prop.setAttribute("value", "" + e.getValue()); 193a7a6f583SLiu Zhe props.appendChild(prop); 1949e9f0f63SLiu Zhe } 1959e9f0f63SLiu Zhe 196*f1afe80aSHerbert Dürr SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss"); 197*f1afe80aSHerbert Dürr String aRunStartStr = dateFormat.format( new Date( runStart)); 198*f1afe80aSHerbert Dürr long nRunEnd = System.currentTimeMillis(); 199*f1afe80aSHerbert Dürr String aRunEndStr = dateFormat.format( new Date( nRunEnd)); 200*f1afe80aSHerbert Dürr double fDuration = (nRunEnd - runStart) / 1000.0; 201*f1afe80aSHerbert Dürr if( fDuration < 20*3600e3) // strip the end date if it is obvious 202*f1afe80aSHerbert Dürr aRunEndStr = aRunEndStr.substring( 11); 203*f1afe80aSHerbert Dürr String aTestTimeStr = String.format( "From %s to %s (%.1f secs)", aRunStartStr, aRunEndStr, fDuration); 204*f1afe80aSHerbert Dürr System.setProperty( "info.test.date", aTestTimeStr); 205e8da46a6SHerbert Dürr 206a7a6f583SLiu Zhe FileUtil.storeXML(doc, file); 207180e3c91SLiu Zhe File htmlFile = new File(outputDir, "result.html"); 208a7a6f583SLiu Zhe InputStream is = getClass().getResourceAsStream("XMLReporter.xsl"); 209a7a6f583SLiu Zhe if (is != null) { 210a7a6f583SLiu Zhe FileUtil.storeXML(doc, htmlFile, is); 211a7a6f583SLiu Zhe } 212a7a6f583SLiu Zhe } 213a7a6f583SLiu Zhe } 2149e9f0f63SLiu Zhe 2159e9f0f63SLiu Zhe } 21643261468SHerbert Dürr 217