From 778a6800cfdfe174d4e21108400d4827124dadac Mon Sep 17 00:00:00 2001 From: Stephane Bailliez Date: Thu, 14 Feb 2002 23:22:34 +0000 Subject: [PATCH] Use a wrapper for exceptions rather than the full stacktrace. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271354 13f79535-47bb-0310-9956-ffa450edef68 --- .../rjunit/formatter/BriefFormatter.java | 6 +- .../formatter/FilterStackFormatter.java | 16 +- .../rjunit/formatter/PlainFormatter.java | 4 +- .../rjunit/formatter/XMLFormatter.java | 48 +++--- .../rjunit/remote/EventDispatcher.java | 161 ++++++++---------- .../optional/rjunit/remote/ExceptionData.java | 133 +++++++++++++++ .../optional/rjunit/remote/Messenger.java | 9 +- .../optional/rjunit/remote/TestRunEvent.java | 14 +- 8 files changed, 259 insertions(+), 132 deletions(-) create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/ExceptionData.java diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/BriefFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/BriefFormatter.java index 87f5cbc9c..90e94999a 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/BriefFormatter.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/BriefFormatter.java @@ -69,13 +69,15 @@ public class BriefFormatter extends SummaryFormatter { ResourceManager.getPackageResources(BriefFormatter.class); public void onTestFailure(TestRunEvent evt) { - String msg = RES.getString("brief.status-failure.msg", evt.getName(), evt.getStackTrace()); + String msg = RES.getString("brief.status-failure.msg", evt.getName(), + evt.getError().getStackTrace()); getWriter().println(msg); super.onTestFailure(evt); } public void onTestError(TestRunEvent evt) { - String msg = RES.getString("brief.status-error.msg", evt.getName(), evt.getStackTrace()); + String msg = RES.getString("brief.status-error.msg", evt.getName(), + evt.getError().getStackTrace()); getWriter().println(msg); super.onTestError(evt); } diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java index 320532dbd..60e1e48d8 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java @@ -57,6 +57,7 @@ import java.util.StringTokenizer; import org.apache.tools.ant.util.StringUtils; import org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunEvent; +import org.apache.tools.ant.taskdefs.optional.rjunit.remote.ExceptionData; /** * Filtered Formatter that strips out unwanted stack frames from the full @@ -103,17 +104,24 @@ public class FilterStackFormatter extends FilterFormatter { } public void onTestFailure(TestRunEvent evt) { - String filteredTrace = filter(evt.getStackTrace()); - evt.setStackTrace(filteredTrace); + filterEvent(evt); super.onTestFailure(evt); } public void onTestError(TestRunEvent evt) { - String filteredTrace = filter(evt.getStackTrace()); - evt.setStackTrace(filteredTrace); + filterEvent(evt); super.onTestFailure(evt); } + protected void filterEvent(TestRunEvent evt){ + String filteredTrace = filter(evt.getError().getStackTrace()); + ExceptionData error = new ExceptionData( + evt.getError().getType(), + evt.getError().getMessage(), + filteredTrace); + evt.setError(error); + } + protected String filter(String trace){ StringTokenizer st = new StringTokenizer(trace, "\r\n"); StringBuffer buf = new StringBuffer(trace.length()); diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/PlainFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/PlainFormatter.java index ea59c0304..63cb4feb2 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/PlainFormatter.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/PlainFormatter.java @@ -84,12 +84,12 @@ public class PlainFormatter extends BaseStreamFormatter { public void onTestFailure(TestRunEvent evt) { getWriter().println(" failure: " + evt.getName()); - getWriter().println(evt.getStackTrace()); + getWriter().println(evt.getError().getStackTrace()); } public void onTestError(TestRunEvent evt) { getWriter().println(" error: " + evt.getName()); - getWriter().println(evt.getStackTrace()); + getWriter().println(evt.getError().getStackTrace()); } public void onRunEnded(TestRunEvent evt) { diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java index 94b44cb3b..b9b34e858 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java @@ -57,6 +57,7 @@ import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; +import java.util.Date; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -68,7 +69,10 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.optional.rjunit.JUnitHelper; import org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunEvent; import org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestSummary; +import org.apache.tools.ant.taskdefs.optional.rjunit.remote.ExceptionData; import org.apache.tools.ant.util.DOMElementWriter; +import org.apache.tools.ant.util.DateUtils; +import org.apache.tools.ant.util.StringUtils; /** * XML Formatter. Due to the nature of the XML we are forced to store @@ -153,6 +157,7 @@ public class XMLFormatter extends BaseStreamFormatter { private Element lastTestElement = null; private TestRunEvent lastTestEvent = null; private Element lastSuiteElement = null; + private long programStart; public void onSuiteStarted(TestRunEvent evt) { String fullclassname = evt.getName(); @@ -180,10 +185,12 @@ public class XMLFormatter extends BaseStreamFormatter { } public void onRunEnded(TestRunEvent evt) { + final String elapsedTime = String.valueOf(evt.getTimeStamp() - programStart); + rootElement.setAttribute("elapsed_time", elapsedTime); // Output properties - Element propsElement = doc.createElement(PROPERTIES); + final Element propsElement = doc.createElement(PROPERTIES); rootElement.appendChild(propsElement); - Properties props = evt.getProperties(); + final Properties props = evt.getProperties(); if (props != null) { Enumeration e = props.propertyNames(); while (e.hasMoreElements()) { @@ -198,11 +205,13 @@ public class XMLFormatter extends BaseStreamFormatter { } public void onRunStarted(TestRunEvent evt) { - // + programStart = evt.getTimeStamp(); + final String date = DateUtils.format(programStart, DateUtils.ISO8601_DATETIME_PATTERN); + rootElement.setAttribute("program_start", date); } public void onRunStopped(TestRunEvent evt) { - // add a stop attribute ? + rootElement.setAttribute("stopped", "true"); onRunEnded(evt); } @@ -242,22 +251,21 @@ public class XMLFormatter extends BaseStreamFormatter { String type = evt.getType() == TestRunEvent.TEST_FAILURE ? FAILURE : ERROR; Element nested = doc.createElement(type); lastTestElement.appendChild(nested); - - String[] args = parseFirstLine(evt.getStackTrace()); - if (args[1] != null && args[1].length() > 0) { - nested.setAttribute(ATTR_MESSAGE, args[1]); - } - nested.setAttribute(ATTR_TYPE, args[0]); - Text text = doc.createTextNode(evt.getStackTrace()); + ExceptionData error = evt.getError(); + nested.setAttribute(ATTR_MESSAGE, error.getMessage()); + nested.setAttribute(ATTR_TYPE, error.getType()); + Text text = doc.createTextNode(error.getStackTrace()); nested.appendChild(text); onTestEnded(evt); } protected void close() { - DOMElementWriter domWriter = new DOMElementWriter(); // the underlying writer uses UTF8 encoding - getWriter().println(""); + getWriter().println(""); + String now = DateUtils.format(new Date(), DateUtils.ISO8601_DATETIME_PATTERN); + rootElement.setAttribute("snapshot_created", now); try { + final DOMElementWriter domWriter = new DOMElementWriter(); domWriter.write(rootElement, getWriter(), 0, " "); } catch (IOException e) { throw new BuildException(e); @@ -274,18 +282,4 @@ public class XMLFormatter extends BaseStreamFormatter { } } - protected static String[] parseFirstLine(String trace) { - int pos = trace.indexOf('\n'); - if (pos == -1) { - return new String[]{trace, ""}; - } - String line = trace.substring(0, pos); - pos = line.indexOf(": "); - if (pos != -1) { - String classname = line.substring(0, pos).trim(); - String message = line.substring(pos + 1).trim(); - return new String[]{classname, message}; - } - return new String[]{trace, ""}; - } } diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/EventDispatcher.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/EventDispatcher.java index 56a56ebcd..72d57efd6 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/EventDispatcher.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/EventDispatcher.java @@ -53,142 +53,127 @@ */ package org.apache.tools.ant.taskdefs.optional.rjunit.remote; -import java.util.Vector; -import java.io.InputStream; -import java.io.IOException; -import java.io.BufferedReader; -import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; /** + * Dispatch messages to appropriate listener methode based on event id. * * @author Stephane Bailliez */ public class EventDispatcher { + private final static HashMap eventMap = new HashMap(3); + + static { + registerDefaults(); + } + /** the set of registered listeners */ - private Vector listeners = new Vector(); + private ArrayList listeners = new ArrayList(); - /** + /** * Add a new listener. * @param listener a listener that will receive events from the client. */ public void addListener(TestRunListener listener) { - listeners.addElement(listener); + listeners.add(listener); } - public void removeListener(org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener listener) { - listeners.removeElement(listener); + public void removeListener(TestRunListener listener) { + listeners.remove(listener); } - /** + /** * Process a message from the client and dispatch the * appropriate message to the listeners. */ public void dispatchEvent(TestRunEvent evt) { - // I hate switch/case but no need to design a complex - // system for limited events. - switch (evt.getType()){ - case TestRunEvent.RUN_STARTED: - fireRunStarted(evt); - break; - case TestRunEvent.RUN_ENDED: - fireRunEnded(evt); - break; - case TestRunEvent.RUN_STOPPED: - fireRunStopped(evt); - break; - case TestRunEvent.TEST_STARTED: - fireTestStarted(evt); - break; - case TestRunEvent.TEST_ERROR: - fireTestError(evt); - break; - case TestRunEvent.TEST_FAILURE: - fireTestFailure(evt); - break; - case TestRunEvent.TEST_ENDED: - fireTestEnded(evt); - break; - case TestRunEvent.SUITE_ENDED: - fireSuiteEnded(evt); - break; - case TestRunEvent.SUITE_STARTED: - fireSuiteStarted(evt); - break; - default: - // should not happen + final Integer type = new Integer(evt.getType()); + final EventAction action = (EventAction) eventMap.get(type); + if (action == null) { + return; } - } - - protected void fireRunStarted(TestRunEvent evt) { synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onRunStarted(evt); + final int count = listeners.size(); + for (int i = 0; i < count; i++) { + TestRunListener listener = (TestRunListener) listeners.get(i); + action.dispatch(listener, evt); } } } - protected void fireRunEnded(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onRunEnded(evt); - } + private static void registerDefaults() { + registerAction(TestRunEvent.RUN_STARTED, new RunStartedAction()); + registerAction(TestRunEvent.RUN_ENDED, new RunEndedAction()); + registerAction(TestRunEvent.TEST_STARTED, new TestStartedAction()); + registerAction(TestRunEvent.TEST_ENDED, new TestEndedAction()); + registerAction(TestRunEvent.TEST_FAILURE, new TestFailureAction()); + registerAction(TestRunEvent.TEST_ERROR, new TestErrorAction()); + registerAction(TestRunEvent.SUITE_STARTED, new SuiteStartedAction()); + registerAction(TestRunEvent.SUITE_ENDED, new SuiteEndedAction()); + registerAction(TestRunEvent.RUN_STOPPED, new RunStoppedAction()); + } + + private static void registerAction(int id, EventAction action){ + eventMap.put(new Integer(id), action); + } + + public interface EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt); + } + + private static class RunStartedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onRunStarted(evt); } } - protected void fireTestStarted(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onTestStarted(evt); - } + private static class RunEndedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onRunEnded(evt); } } - protected void fireTestEnded(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onTestEnded(evt); - } + private static class TestStartedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onTestStarted(evt); } } - protected void fireTestFailure(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onTestFailure(evt); - } + private static class TestEndedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onTestEnded(evt); } } - protected void fireTestError(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onTestError(evt); - } + private static class TestFailureAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onTestFailure(evt); } } - protected void fireSuiteStarted(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onSuiteStarted(evt); - } + private static class TestErrorAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onTestError(evt); } } - protected void fireSuiteEnded(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onSuiteEnded(evt); - } + private static class SuiteStartedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onSuiteStarted(evt); } } - protected void fireRunStopped(TestRunEvent evt) { - synchronized (listeners) { - for (int i = 0; i < listeners.size(); i++) { - ((org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunListener) listeners.elementAt(i)).onRunStopped(evt); - } + private static class SuiteEndedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onSuiteEnded(evt); + } + } + + private static class RunStoppedAction implements EventAction { + public void dispatch(TestRunListener listener, TestRunEvent evt) { + listener.onRunStopped(evt); } } diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/ExceptionData.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/ExceptionData.java new file mode 100644 index 000000000..2d345a3aa --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/ExceptionData.java @@ -0,0 +1,133 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.rjunit.remote; + +import java.io.Serializable; + +import org.apache.tools.ant.util.StringUtils; + +/** + * A wrapper around an exception since an exception stacktrace is + * not serializable. + * + * @author Stephane Bailliez + */ +public class ExceptionData implements Serializable { + + /** the stacktrace of the exception */ + private final String stacktrace; + + /** the classname of an exception */ + private final String type; + + /** the message associated to this exception */ + private final String message; + + /** + * Create a new error. + * @param exception the exception to run as + */ + public ExceptionData(Throwable exception) { + this(exception.getClass().getName(), + exception.getMessage(), + StringUtils.getStackTrace(exception)); + } + + /** + * Create a new error. + * @param type the type of the error (ie classname). + * @param message the message associated to this error. + * @param stacktrace the full stacktrace of this error. + */ + public ExceptionData(String type, String message, String stacktrace) { + this.stacktrace = stacktrace; + this.type = type; + this.message = message; + } + + /** + * @return the type of the error (ie classname) + */ + public String getType() { + return type; + } + + /** + * @return the message associated to this error. + */ + public String getMessage() { + return message; + } + + /** + * @return the stacktrace for this error. + */ + public String getStackTrace() { + return stacktrace; + } + + public boolean equals(Object o){ + if ( o instanceof ExceptionData ){ + ExceptionData other = (ExceptionData)o; + return ( ( type == null ? other.type == null : type.equals(other.type) ) && + ( message == null ? other.message == null : message.equals(other.message) ) && + ( stacktrace == null ? other.stacktrace == null : stacktrace.equals(other.stacktrace) ) ); + } + return false; + } + + public String toString() { + return (message != null) ? (type + ": " + message) : type; + } +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Messenger.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Messenger.java index 7de44cea0..2f0a18aab 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Messenger.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Messenger.java @@ -60,6 +60,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** + * Read or write events to/from appropriate streams. * * @author Stephane Bailliez */ @@ -90,8 +91,12 @@ public class Messenger { } } - public TestRunEvent read() throws Exception { - return (TestRunEvent)((ObjectInputStream)in).readObject(); + public TestRunEvent read() { + try { + return (TestRunEvent)((ObjectInputStream)in).readObject(); + } catch (Exception e){ + return null; + } } public void writeEvent(TestRunEvent evt) throws IOException { diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java index c44ef3e74..3ef093168 100644 --- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java @@ -91,7 +91,7 @@ public class TestRunEvent extends EventObject { private String name; /** stacktrace for error or failure */ - private String stacktrace; + private ExceptionData error; /** properties for end of testrun */ private Properties props; @@ -122,7 +122,7 @@ public class TestRunEvent extends EventObject { public TestRunEvent(Integer id, int type, String name, Throwable t){ this(id, type, name); - this.stacktrace = StringUtils.getStackTrace(t); + this.error = new ExceptionData(t); } public void setType(int type) { @@ -133,8 +133,8 @@ public class TestRunEvent extends EventObject { this.timestamp = timestamp; } - public void setStackTrace(String stacktrace) { - this.stacktrace = stacktrace; + public void setError(ExceptionData error) { + this.error = error; } public void setName(String name) { @@ -161,8 +161,8 @@ public class TestRunEvent extends EventObject { return result; } - public String getStackTrace(){ - return stacktrace; + public ExceptionData getError(){ + return error; } public Properties getProperties(){ @@ -175,7 +175,7 @@ public class TestRunEvent extends EventObject { return ( (type == other.type) && (timestamp == other.timestamp) && ( name == null ? other.name == null : name.equals(other.name) ) && - ( stacktrace == null ? other.stacktrace == null : stacktrace.equals(other.stacktrace) ) && + ( error == null ? other.error == null : error.equals(other.error) ) && ( props == null ? other.props == null : props.equals(other.props) ) && ( result == null ? other.result == null : result.equals(other.result) ) ); }