/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: LoadTestRunner.java 2326 2007-03-27 21:59:44Z mlipp $
*
* $Log$
* Revision 1.2 2006/09/29 12:32:11 drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.1.1.1 2003/12/19 13:01:37 drmlipp
* Updated to 1.1rc1
*
* Revision 1.3 2003/10/22 10:53:02 lipp
* Updated documentation.
*
* Revision 1.2 2003/10/22 08:34:50 lipp
* Some fixes/additions.
*
* Revision 1.1 2003/10/21 20:25:36 lipp
* Added load test support classes.
*
* Revision 1.1 2003/10/21 15:51:42 lipp
* Specific load test output.
*
*/
package de.danet.an.util.junit;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestResult;
import junit.textui.TestRunner;
/**
* This class provides a runner for junit tests that writes additional
* execution time related information. The runner extends the JUnit
* text user interface runner. The only difference is that this runner
* adds an additional TestListener that outputs execution times in an
* XML format together with grouping information from
* <code>NamedTestGroup</code>s. <P>
*
* The output file can be specified with the system property
* <code>de.danet.an.util.junit.loadTestOut</code>. It defaults to
* "<code>loadTestResults.xml</code>".
*
* @author <a href="mailto:lipp@danet.de"></a>
* @version $Revision: 2326 $
*/
public class LoadTestRunner extends TestRunner {
private static OutputStreamWriter loadOut = null;
private static LoadListener loadListener = null;
public class LoadListener implements TestListener {
public class GroupData {
private NamedTestGroup group;
private List entries = new ArrayList ();
private Map entriesIndex = new HashMap ();
public GroupData (NamedTestGroup g) {
group = g;
}
public void addData (String test, long time) {
entries.add (new Object [] { test, new Long (time) });
}
public GroupData getGroupData (NamedTestGroup[] groups) {
return getGroupData (groups, 0);
}
private GroupData getGroupData (NamedTestGroup[] groups, int idx) {
if (groups.length == idx) {
return this;
}
GroupData gd = (GroupData)entriesIndex.get (groups[idx]);
if (gd == null) {
gd = new GroupData (groups[idx]);
entries.add (gd);
entriesIndex.put (groups[idx], gd);
}
return gd.getGroupData (groups, idx + 1);
}
public void print () {
print ("");
}
public void print (String indent) {
indent = indent + " ";
for (Iterator i = entries.iterator (); i.hasNext ();) {
Object o = i.next ();
if (o instanceof GroupData) {
GroupData gd = (GroupData)o;
out.print (indent + "<Group name=\""
+ gd.group.groupName() + "\"");
Map m = gd.group.groupAttributes();
if (m != null) {
for (Iterator ai = m.entrySet().iterator();
ai.hasNext();) {
Map.Entry e = (Map.Entry)ai.next();
out.print (" " + e.getKey() + "=\""
+ e.getValue() + "\"");
}
}
out.println (">");
gd.print (indent);
out.println (indent + "</Group>");
continue;
}
Object[] data = (Object[])o;
out.println
(indent + "<TestCase name=\"" + data[0] + "\" time=\""
+ (((Long)data[1]).longValue() / 1000.0) + "\"/>");
}
}
}
private PrintWriter out = null;
private ThreadLocal startTime = new ThreadLocal ();
private GroupData dataRoot = new GroupData (null);
public LoadListener (OutputStreamWriter resultWriter) {
out = new PrintWriter(resultWriter);
String enc = resultWriter.getEncoding();
if (enc.equals ("UTF8")) {
enc = "UTF-8";
}
out.println ("<?xml version=\"1.0\" encoding=\"" + enc + "\"?>");
}
/**
* Finalize output.
*/
public void close () {
out.println ("<LoadTestResults>");
dataRoot.print ();
out.println ("</LoadTestResults>");
out.close ();
}
// Implementation of junit.framework.TestListener
/**
* Describe <code>addError</code> method here.
*
* @param test a <code>Test</code> value
* @param throwable a <code>Throwable</code> value
*/
public void addError(Test test, Throwable throwable) {
}
/**
* Describe <code>addFailure</code> method here.
*
* @param test a <code>Test</code> value
* @param assertionFailedError an <code>AssertionFailedError</code> value
*/
public void addFailure(Test test, AssertionFailedError assertionFailedError) {
}
/**
* Describe <code>startTest</code> method here.
*
* @param test a <code>Test</code> value
*/
public void startTest(Test test) {
startTime.set(new Long (System.currentTimeMillis()));
}
/**
* Describe <code>endTest</code> method here.
*
* @param test a <code>Test</code> value
*/
public synchronized void endTest(Test test) {
long endTime = System.currentTimeMillis();
long spent = endTime - ((Long)startTime.get()).longValue ();
NamedTestGroup[] groups = NamedTestGroup.getGroups ();
GroupData gd = dataRoot.getGroupData (groups);
gd.addData (test.toString(), spent);
}
}
/**
* Creates the TestResult to be used for the test run.
*/
protected TestResult createTestResult() {
TestResult res = new TestResult();
loadListener = new LoadListener (loadOut);
res.addListener(loadListener);
return res;
}
public static void main(String[] args) {
try {
LoadTestRunner aTestRunner = new LoadTestRunner();
loadOut = new OutputStreamWriter
(new FileOutputStream
(System.getProperty ("de.danet.an.util.junit.loadTestOut",
"loadTestResults.xml")),
"UTF-8");
int exitCode;
try {
TestResult r = aTestRunner.start(args);
if (!r.wasSuccessful()) {
exitCode = FAILURE_EXIT;
}
exitCode = SUCCESS_EXIT;
} catch(Exception e) {
System.err.println(e.getMessage());
exitCode = EXCEPTION_EXIT;
} finally {
if (loadListener != null) {
loadListener.close ();
}
}
System.exit(exitCode);
} catch (Exception e) {
e.printStackTrace();
}
}
}