Browse Source

Prepare for listener changes and event types.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271010 13f79535-47bb-0310-9956-ffa450edef68
master
Stephane Bailliez 23 years ago
parent
commit
cbf1a178e3
14 changed files with 717 additions and 175 deletions
  1. +13
    -21
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java
  2. +16
    -18
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java
  3. +9
    -8
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java
  4. +19
    -18
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java
  5. +15
    -3
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java
  6. +22
    -19
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/PlainFormatter.java
  7. +33
    -36
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java
  8. +195
    -0
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/EventDispatcher.java
  9. +4
    -4
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/MessageReader.java
  10. +116
    -0
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/Messenger.java
  11. +14
    -17
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/Server.java
  12. +159
    -0
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunEvent.java
  13. +76
    -0
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunListener.java
  14. +26
    -31
      proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunner.java

+ 13
- 21
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java View File

@@ -54,6 +54,9 @@
package org.apache.tools.ant.taskdefs.optional.junit; package org.apache.tools.ant.taskdefs.optional.junit;


import java.util.Properties; import java.util.Properties;
import java.util.EventListener;

import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;




/** /**
@@ -67,27 +70,21 @@ import java.util.Properties;
* *
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/ */
public interface TestRunListener {

/** Some tests failed. */
public final static int STATUS_FAILURE = 1;

/** An error occured. */
public final static int STATUS_ERROR = 2;
public interface TestRunListener extends EventListener{


/** /**
* A test has started. * A test has started.
* @param a testname made of the testname and testcase classname. * @param a testname made of the testname and testcase classname.
* in the following format: <tt>&lt;testname&gt;(&lt;testcase&gt;)</tt> * in the following format: <tt>&lt;testname&gt;(&lt;testcase&gt;)</tt>
*/ */
public void onTestStarted(String testname);
public void onTestStarted(TestRunEvent evt);


/** /**
* A test ended. * A test ended.
* @param a testname made of the testname and testcase classname. * @param a testname made of the testname and testcase classname.
* in the following format: <tt>&lt;testname&gt;(&lt;testcase&gt;)</tt> * in the following format: <tt>&lt;testname&gt;(&lt;testcase&gt;)</tt>
*/ */
public void onTestEnded(String testname);
public void onTestEnded(TestRunEvent evt);


/** /**
* A test has failed. * A test has failed.
@@ -97,24 +94,19 @@ public interface TestRunListener {
* @param trace the error/failure stacktrace. * @param trace the error/failure stacktrace.
* @todo change this to a testFailure / testError ? * @todo change this to a testFailure / testError ?
*/ */
public void onTestFailed(int status, String testname, String trace);

/** test logged this line on stdout */
public void onTestStdOutLine(String testname, String line);

/** test logged this line on sterr */
public void onTestStdErrLine(String testname, String line);
public void onTestFailure(TestRunEvent evt);


/** these system properties are used on the remote client */
public void onTestRunSystemProperties(Properties props);
public void onTestError(TestRunEvent evt);


/** starting a sequence of <tt>testcount</tt> tests. */ /** starting a sequence of <tt>testcount</tt> tests. */
public void onTestRunStarted(int testcount);
public void onRunStarted(TestRunEvent evt);


/** ending gracefully the sequence after <tt>elapsedtime</tt> ms. */ /** ending gracefully the sequence after <tt>elapsedtime</tt> ms. */
public void onTestRunEnded(long elapsedtime);
public void onRunEnded(TestRunEvent evt);


/** stopping the sequence after <tt>elapsedtime</tt> ms. */ /** stopping the sequence after <tt>elapsedtime</tt> ms. */
public void onTestRunStopped(long elapsedtime);
public void onRunStopped(TestRunEvent evt);


public void onSuiteStarted(TestRunEvent evt);
public void onSuiteEnded(TestRunEvent evt);
} }

+ 16
- 18
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java View File

@@ -56,6 +56,7 @@ package org.apache.tools.ant.taskdefs.optional.junit.formatter;
import java.util.Properties; import java.util.Properties;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;


/** /**
* Provide a common set of attributes and methods to factorize * Provide a common set of attributes and methods to factorize
@@ -81,42 +82,39 @@ public abstract class BaseFormatter implements Formatter {
close(); close();
} }


public void onTestStdOutLine(String testname, String line) {
public void onTestStarted(TestRunEvent evt) {
runCount++;
} }


public void onTestStdErrLine(String testname, String line) {
public void onTestEnded(TestRunEvent evt) {
} }


public void onTestRunSystemProperties(Properties props) {
public void onTestFailure(TestRunEvent evt) {
failureCount++;
} }


public void onTestStarted(String testname) {
public void onTestError(TestRunEvent evt) {
errorCount++;
} }


public void onTestEnded(String testname) {
public void onSuiteStarted(TestRunEvent evt) {
} }


public void onTestFailed(int status, String testname, String trace) {
if (status == STATUS_ERROR) {
errorCount++;
} else if (status == STATUS_FAILURE) {
failureCount++;
}
public void onSuiteEnded(TestRunEvent evt) {
} }


public void onTestRunStarted(int testcount) {
runCount = testcount;
public void onRunStarted(TestRunEvent evt) {
} }


public void onTestRunEnded(long elapsedtime) {
finished(elapsedtime);
public void onRunEnded(TestRunEvent evt) {
finished();
} }


public void onTestRunStopped(long elapsedtime) {
finished(elapsedtime);
public void onRunStopped(TestRunEvent evt) {
finished();
} }


protected void finished(long elapsedtime) {
protected void finished() {
close(); close();
} }




+ 9
- 8
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java View File

@@ -55,6 +55,7 @@ package org.apache.tools.ant.taskdefs.optional.junit.formatter;


import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources; import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;


/** /**
* Display additional messages from a <tt>SummaryFormatter</tt> * Display additional messages from a <tt>SummaryFormatter</tt>
@@ -67,15 +68,15 @@ public class BriefFormatter extends SummaryFormatter {
private final static Resources RES = private final static Resources RES =
ResourceManager.getPackageResources(BriefFormatter.class); ResourceManager.getPackageResources(BriefFormatter.class);


public void onTestFailed(int status, String testname, String trace) {
String msg = null;
if (status == STATUS_ERROR) {
msg = RES.getString("brief.status-error.msg", testname, trace);
} else {
msg = RES.getString("brief.status-failure.msg", testname, trace);
}
public void onTestFailure(TestRunEvent evt) {
String msg = RES.getString("brief.status-failure.msg", evt.getName(), evt.getStackTrace());
getWriter().println(msg); getWriter().println(msg);
super.onTestFailed(status, testname, trace);
super.onTestFailure(evt);
} }


public void onTestError(TestRunEvent evt) {
String msg = RES.getString("brief.status-error.msg", evt.getName(), evt.getStackTrace());
getWriter().println(msg);
super.onTestError(evt);
}
} }

+ 19
- 18
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java View File

@@ -56,6 +56,7 @@ package org.apache.tools.ant.taskdefs.optional.junit.formatter;
import java.util.Properties; import java.util.Properties;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;


/** /**
* A base class that can be used to filter data. * A base class that can be used to filter data.
@@ -75,40 +76,40 @@ public abstract class FilterFormatter implements Formatter {
formatter.init(props); formatter.init(props);
} }


public void onTestStdOutLine(String testname, String line) {
formatter.onTestStdOutLine(testname, line);
public void onSuiteStarted(TestRunEvent evt) {
formatter.onSuiteStarted(evt);
} }


public void onTestStdErrLine(String testname, String line) {
formatter.onTestStdErrLine(testname, line);
public void onSuiteEnded(TestRunEvent evt) {
formatter.onSuiteEnded(evt);
} }


public void onTestStarted(String testname) {
formatter.onTestStarted(testname);
public void onTestStarted(TestRunEvent evt) {
formatter.onTestStarted(evt);
} }


public void onTestEnded(String testname) {
formatter.onTestEnded(testname);
public void onTestEnded(TestRunEvent evt) {
formatter.onTestEnded(evt);
} }


public void onTestFailed(int status, String testname, String trace) {
formatter.onTestFailed(status, testname, trace);
public void onTestFailure(TestRunEvent evt) {
formatter.onTestFailure(evt);
} }


public void onTestRunSystemProperties(Properties props) {
formatter.onTestRunSystemProperties(props);
public void onTestError(TestRunEvent evt) {
formatter.onTestError(evt);
} }


public void onTestRunStarted(int testcount) {
formatter.onTestRunStarted(testcount);
public void onRunStarted(TestRunEvent evt) {
formatter.onRunStarted(evt);
} }


public void onTestRunEnded(long elapsedtime) {
formatter.onTestRunEnded(elapsedtime);
public void onRunEnded(TestRunEvent evt) {
formatter.onRunEnded(evt);
} }


public void onTestRunStopped(long elapsedtime) {
formatter.onTestRunEnded(elapsedtime);
public void onRunStopped(TestRunEvent evt) {
formatter.onRunEnded(evt);
} }


/** set the wrapped formatter */ /** set the wrapped formatter */


+ 15
- 3
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java View File

@@ -56,6 +56,7 @@ package org.apache.tools.ant.taskdefs.optional.junit.formatter;
import java.util.StringTokenizer; import java.util.StringTokenizer;


import org.apache.tools.ant.util.StringUtils; import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;


/** /**
* Filtered Formatter that strips out unwanted stack frames from the full * Filtered Formatter that strips out unwanted stack frames from the full
@@ -99,7 +100,19 @@ public class FilterStackFormatter extends FilterFormatter {
super(formatter); super(formatter);
} }


public void onTestFailed(int status, String testname, String trace) {
public void onTestFailure(TestRunEvent evt) {
String filteredTrace = filter(evt.getStackTrace());
evt.setStackTrace(filteredTrace);
super.onTestFailure(evt);
}

public void onTestError(TestRunEvent evt) {
String filteredTrace = filter(evt.getStackTrace());
evt.setStackTrace(filteredTrace);
super.onTestFailure(evt);
}

protected String filter(String trace){
StringTokenizer st = new StringTokenizer(trace, "\r\n"); StringTokenizer st = new StringTokenizer(trace, "\r\n");
StringBuffer buf = new StringBuffer(trace.length()); StringBuffer buf = new StringBuffer(trace.length());
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
@@ -108,9 +121,8 @@ public class FilterStackFormatter extends FilterFormatter {
buf.append(line).append(StringUtils.LINE_SEP); buf.append(line).append(StringUtils.LINE_SEP);
} }
} }
super.onTestFailed(status, testname, buf.toString());
return buf.toString();
} }

/** /**
* Check whether or not the line should be accepted. * Check whether or not the line should be accepted.
* @param the line to be check for acceptance. * @param the line to be check for acceptance.


+ 22
- 19
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/PlainFormatter.java View File

@@ -55,6 +55,8 @@ package org.apache.tools.ant.taskdefs.optional.junit.formatter;


import java.util.Properties; import java.util.Properties;


import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;

/** /**
* Default formatter to text. * Default formatter to text.
* *
@@ -62,38 +64,39 @@ import java.util.Properties;
*/ */
public class PlainFormatter extends BaseStreamFormatter { public class PlainFormatter extends BaseStreamFormatter {


public void onTestStarted(String testname) {
getWriter().println("Started " + testname);
}

public void onTestEnded(String testname) {
getWriter().println("Ended " + testname);
public void onSuiteStarted(TestRunEvent evt) {
getWriter().println(" suite: " + evt.getName());
super.onSuiteStarted(evt);
} }


public void onTestFailed(int status, String testname, String trace) {
getWriter().println(testname + " failed with status " + status);
getWriter().println(trace);
public void onSuiteEnded(TestRunEvent evt) {
getWriter().println(" end suite");
super.onSuiteEnded(evt);
} }


public void onTestRunSystemProperties(Properties props) {
getWriter().println("properties: " + props);
public void onTestStarted(TestRunEvent evt) {
getWriter().println(" running test: " + evt.getName());
} }


public void onTestRunStarted(int testcount) {
getWriter().println("testsuite: " + testcount);
public void onTestEnded(TestRunEvent evt) {
getWriter().println(" success: " + evt.getName());
} }


public void onTestStdOutLine(String testname, String line) {
public void onTestFailure(TestRunEvent evt) {
getWriter().println(" failure: " + evt.getName());
getWriter().println(evt.getStackTrace());
} }


public void onTestStdErrLine(String testname, String line) {
public void onTestError(TestRunEvent evt) {
getWriter().println(" error: " + evt.getName());
getWriter().println(evt.getStackTrace());
} }


public void onTestRunEnded(long elapsedtime) {
getWriter().println("testsuite ended after: " + elapsedtime);
public void onRunEnded(TestRunEvent evt) {
getWriter().println("run ended");
} }


public void onTestRunStopped(long elapsedtime) {
getWriter().println("testsuite stopped after: " + elapsedtime);
public void onRunStopped(TestRunEvent evt) {
getWriter().println("run stopped");
} }
} }

+ 33
- 36
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java View File

@@ -64,6 +64,7 @@ import org.w3c.dom.Text;


import org.apache.tools.ant.util.DOMElementWriter; import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunEvent;


/** /**
* XML Formatter. Due to the nature of the XML we are forced to store * XML Formatter. Due to the nature of the XML we are forced to store
@@ -140,67 +141,63 @@ public class XMLFormatter extends BaseStreamFormatter {
/** Timing helper. */ /** Timing helper. */
private Hashtable testStarts = new Hashtable(); private Hashtable testStarts = new Hashtable();


public void onTestStarted(String testname) {
public void onTestStarted(TestRunEvent evt) {
//@fixme, eh, a testname only can obviouslly be a duplicate... //@fixme, eh, a testname only can obviouslly be a duplicate...
testStarts.put(testname, new Long(System.currentTimeMillis()));
testStarts.put(evt.getName(), evt);
Element currentTest = doc.createElement(TESTCASE); Element currentTest = doc.createElement(TESTCASE);
currentTest.setAttribute(ATTR_NAME, testname);
currentTest.setAttribute(ATTR_NAME, evt.getName());
rootElement.appendChild(currentTest); rootElement.appendChild(currentTest);
testElements.put(testname, currentTest);
super.onTestStarted(testname);
testElements.put(evt.getName(), currentTest);
super.onTestStarted(evt);
removeEvent(evt);
} }


public void onTestEnded(String testname) {
Element currentTest = (Element) testElements.get(testname);
public void onTestEnded(TestRunEvent evt) {
Element currentTest = (Element) testElements.get(evt);
// with a TestSetup, startTest and endTest are not called. // with a TestSetup, startTest and endTest are not called.
if (currentTest == null) { if (currentTest == null) {
onTestStarted(testname);
currentTest = (Element) testElements.get(testname);
onTestStarted(evt);
currentTest = (Element) testElements.get(evt.getName());
} }
Long l = (Long) testStarts.get(testname);
float time = ((System.currentTimeMillis() - l.longValue()) / 1000.0f);
TestRunEvent start = (TestRunEvent)testStarts.get(evt);
float time = ((evt.getTimeStamp() - start.getTimeStamp()) / 1000.0f);
currentTest.setAttribute(ATTR_TIME, Float.toString(time)); currentTest.setAttribute(ATTR_TIME, Float.toString(time));
super.onTestEnded(testname);
// remove the test objects
//testStarts.remove(testname);
//testElements.remove(testname);
super.onTestEnded(evt);
removeEvent(evt);
} }


public void onTestFailed(int status, String testname, String trace) {
if (testname != null) {
onTestEnded(testname);
}
String type = status == STATUS_FAILURE ? FAILURE : ERROR;
public void onTestFailure(TestRunEvent evt) {
String type = evt == evt.getType() == TestRunEvent.TEST_FAILURE ? FAILURE : ERROR;
Element nested = doc.createElement(type); Element nested = doc.createElement(type);
Element currentTest = null;
if (testname != null) {
currentTest = (Element) testElements.get(testname);
} else {
currentTest = rootElement;
}

Element currentTest = (Element) testElements.get(evt.getName());
currentTest.appendChild(nested); currentTest.appendChild(nested);


String[] args = parseFirstLine(trace);
String[] args = parseFirstLine(evt.getStackTrace());
if (args[1] != null && args[1].length() > 0) { if (args[1] != null && args[1].length() > 0) {
nested.setAttribute(ATTR_MESSAGE, args[1]); nested.setAttribute(ATTR_MESSAGE, args[1]);
} }
nested.setAttribute(ATTR_TYPE, args[0]); nested.setAttribute(ATTR_TYPE, args[0]);
Text text = doc.createTextNode(trace);
Text text = doc.createTextNode(evt.getStackTrace());
nested.appendChild(text); nested.appendChild(text);
super.onTestFailed(status, testname, trace);
super.onTestFailure(evt);
removeEvent(evt);
}

protected void removeEvent(TestRunEvent evt){
testStarts.remove(evt.getName());
testElements.remove(evt.getName());
} }


public void onTestRunStarted(int testcount) {
super.onTestRunStarted(testcount);
public void onRunStarted(TestRunEvent evt) {
super.onRunStarted(evt);
} }


public void onTestRunEnded(long elapsedtime) {
super.onTestRunEnded(elapsedtime);
public void onRunEnded(TestRunEvent evt) {
super.onRunEnded(evt);
} }


public void onTestRunStopped(long elapsedtime) {
super.onTestRunStopped(elapsedtime);
public void onRunStopped(TestRunEvent evt) {
super.onRunStopped(evt);
} }


protected void close() { protected void close() {


+ 195
- 0
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/EventDispatcher.java View File

@@ -0,0 +1,195 @@
/*
* 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
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.junit.remote;

import java.util.Vector;
import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public class EventDispatcher {

/** the set of registered listeners */
private Vector listeners = new Vector();

/**
* Add a new listener.
* @param listener a listener that will receive events from the client.
*/
public void addListener(TestRunListener listener) {
listeners.addElement(listener);
}

public void removeListener(org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener listener) {
listeners.removeElement(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.TESTSUITE_ENDED:
fireSuiteEnded(evt);
break;
case TestRunEvent.TESTSUITE_STARTED:
fireSuiteStarted(evt);
break;
default:
// should not happen
}
}

protected void fireRunStarted(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onRunStarted(evt);
}
}
}

protected void fireRunEnded(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onRunEnded(evt);
}
}
}

protected void fireTestStarted(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onTestStarted(evt);
}
}
}

protected void fireTestEnded(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onTestEnded(evt);
}
}
}

protected void fireTestFailure(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onTestFailure(evt);
}
}
}

protected void fireTestError(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onTestError(evt);
}
}
}

protected void fireSuiteStarted(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onSuiteStarted(evt);
}
}
}

protected void fireSuiteEnded(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onSuiteEnded(evt);
}
}
}

protected void fireRunStopped(TestRunEvent evt) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((org.apache.tools.ant.taskdefs.optional.junit.remote.TestRunListener) listeners.elementAt(i)).onRunStopped(evt);
}
}
}

}

+ 4
- 4
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/MessageReader.java View File

@@ -203,7 +203,7 @@ public class MessageReader {
protected void notifyTestFailed(int kind, String testname, String trace) { protected void notifyTestFailed(int kind, String testname, String trace) {
synchronized (listeners) { synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
((TestRunListener) listeners.elementAt(i)).onTestFailed(kind, testname, trace);
((TestRunListener) listeners.elementAt(i)).onTestFailure(kind);
} }
} }
} }
@@ -211,7 +211,7 @@ public class MessageReader {
protected void notifyTestSuiteStarted(int count) { protected void notifyTestSuiteStarted(int count) {
synchronized (listeners) { synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
((TestRunListener) listeners.elementAt(i)).onTestRunStarted(count);
((TestRunListener) listeners.elementAt(i)).onRunStarted(count);
} }
} }
} }
@@ -219,7 +219,7 @@ public class MessageReader {
protected void notifyTestSuiteEnded(long elapsedtime) { protected void notifyTestSuiteEnded(long elapsedtime) {
synchronized (listeners) { synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
((TestRunListener) listeners.elementAt(i)).onTestRunEnded(elapsedtime);
((TestRunListener) listeners.elementAt(i)).onRunEnded(elapsedtime);
} }
} }
} }
@@ -227,7 +227,7 @@ public class MessageReader {
protected void notifyTestSuiteStopped(long elapsedtime) { protected void notifyTestSuiteStopped(long elapsedtime) {
synchronized (listeners) { synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
((TestRunListener) listeners.elementAt(i)).onTestRunStopped(elapsedtime);
((TestRunListener) listeners.elementAt(i)).onRunStopped(elapsedtime);
} }
} }
} }


+ 116
- 0
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/Messenger.java View File

@@ -0,0 +1,116 @@
/*
* 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
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.junit.remote;

import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public class Messenger {

private InputStream in;

private OutputStream out;

public Messenger(InputStream in, OutputStream out) throws IOException {
setOutputStream( new ObjectOutputStream(out) );
setInputStream( new ObjectInputStream(in) );
}

protected void finalize() throws Throwable {
close();
}

public void close() throws IOException {
if (in != null) {
in.close();
in = null;
}
if (out != null) {
out.flush();
out.close();
out = null;
}
}

public TestRunEvent read() throws IOException {
return (TestRunEvent)((ObjectInputStream)in).readObject();
}

public void writeEvent(TestRunEvent evt) throws IOException {
((ObjectOutputStream)out).writeObject(evt);
}

protected OutputStream getOutputStream(){
return out;
}

protected InputStream getInputStream(){
return in;
}

protected void setOutputStream(OutputStream out){
this.out = out;
}

protected void setInputStream(InputStream in){
this.in = in;
}
}

+ 14
- 17
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/Server.java View File

@@ -57,8 +57,6 @@ import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;


import org.apache.tools.ant.taskdefs.optional.junit.TestRunListener;

/** /**
* The server that will receive events from a remote client. * The server that will receive events from a remote client.
* *
@@ -83,10 +81,9 @@ public class Server {
private Socket client; private Socket client;


/** the reader in charge of interpreting messages from the client */ /** the reader in charge of interpreting messages from the client */
private MessageReader reader = new MessageReader();
private Messenger messenger;


/** writer used to send message to clients */
private MessageWriter writer;
private EventDispatcher dispatcher = new EventDispatcher();


public Server(int port) { public Server(int port) {
this.port = port; this.port = port;
@@ -102,7 +99,7 @@ public class Server {
* @param listener a instance of a listener. * @param listener a instance of a listener.
*/ */
public void addListener(TestRunListener listener) { public void addListener(TestRunListener listener) {
reader.addListener(listener);
dispatcher.addListener(listener);
} }


/** /**
@@ -110,7 +107,7 @@ public class Server {
* @param listener a instance of a listener. * @param listener a instance of a listener.
*/ */
public void removeListener(TestRunListener listener) { public void removeListener(TestRunListener listener) {
reader.removeListener(listener);
dispatcher.removeListener(listener);
} }


/** return whether there is a client running or not */ /** return whether there is a client running or not */
@@ -127,19 +124,16 @@ public class Server {
/** cancel the connection to the client */ /** cancel the connection to the client */
public void cancel() { public void cancel() {
if (isRunning()) { if (isRunning()) {
writer.sendMessage(MessageIds.TEST_STOP);
TestRunEvent evt = new TestRunEvent(new Integer(-1), TestRunEvent.RUN_STOP);
messenger.writeEvent(evt);
} }
} }


/** shutdown the server and any running client */ /** shutdown the server and any running client */
public void shutdown() { public void shutdown() {
if (writer != null) {
writer.close();
writer = null;
}
if (reader != null) {
//@fixme what about the stream ?
reader = null;
if (messenger != null) {
messenger.close();
messenger = null;
} }
try { try {
if (client != null) { if (client != null) {
@@ -166,8 +160,11 @@ public class Server {
try { try {
server = new ServerSocket(port); server = new ServerSocket(port);
client = server.accept(); client = server.accept();
writer = new MessageWriter(client.getOutputStream());
reader.process(client.getInputStream());
messenger = new Messenger(client.getInputStream(), client.getOutputStream());
TestRunEvent evt = null;
while ( (evt = messenger.read()) != null ) {
dispatcher.dispatchEvent(evt);
}
} catch (IOException e) { } catch (IOException e) {
//@fixme this stacktrace might be normal when closing //@fixme this stacktrace might be normal when closing
// the socket. So decompose the above in distinct steps // the socket. So decompose the above in distinct steps


+ 159
- 0
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunEvent.java View File

@@ -0,0 +1,159 @@
/*
* 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
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.junit.remote;

import java.util.EventObject;
import java.util.Properties;

import org.apache.tools.ant.util.StringUtils;

/**
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public class TestRunEvent extends EventObject {

// received from clients
public final static int RUN_STARTED = 0;
public final static int RUN_ENDED = 1;
public final static int RUN_STOPPED = 2;
public final static int TEST_STARTED = 3;
public final static int TEST_FAILURE = 4;
public final static int TEST_ERROR = 5;
public final static int TEST_ENDED = 6;
public final static int SUITE_STARTED = 7;
public final static int SUITE_ENDED = 8;

// received from server
public final static int RUN_STOP = 9;

/** the type of event */
private int type = -1;

/** timestamp for all tests */
private long timestamp = System.currentTimeMillis();

/** name of testcase(method name) or testsuite (classname) */
private String name;

/** stacktrace for error or failure */
private String stacktrace;

/** properties for end of testrun */
private Properties props;

public TestRunEvent(Integer id, int type){
super(id);
this.type = type;
}

public TestRunEvent(Integer id, int type, String name){
this(id, type);
this.name = name;
}

public TestRunEvent(Integer id, int type, Properties props){
this(id, type);
this.props = props;
}

public TestRunEvent(Integer id, int type, String name, Throwable t){
this(id, type, name);
this.stacktrace = StringUtils.getStackTrace(t);
}

public void setType(int type) {
this.type = type;
}

public void setTimeStamp(long timestamp) {
this.timestamp = timestamp;
}

public void setStackTrace(String stacktrace) {
this.stacktrace = stacktrace;
}

public void setName(String name) {
this.name = name;
}

public void setProperties(Properties props) {
this.props = props;
}

public int getType(){
return type;
}

public long getTimeStamp(){
return timestamp;
}

public String getName(){
return name;
}

public String getStackTrace(){
return stacktrace;
}

public Properties getProperties(){
return props;
}

public String toString(){
return "Id: " + source + ", Type: " + type;
}
}

+ 76
- 0
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunListener.java View File

@@ -0,0 +1,76 @@
/*
* 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
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.junit.remote;

import java.util.EventListener;


/**
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public interface TestRunListener extends EventListener {

void onRunStarted(TestRunEvent evt);
void onRunEnded(TestRunEvent evt);
void onRunStopped(TestRunEvent evt);

void onSuiteStarted(TestRunEvent evt);
void onSuiteEnded(TestRunEvent evt);

void onTestStarted(TestRunEvent evt);
void onTestError(TestRunEvent evt);
void onTestFailure(TestRunEvent evt);
void onTestEnded(TestRunEvent evt);
}

+ 26
- 31
proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/remote/TestRunner.java View File

@@ -61,6 +61,7 @@ import java.net.Socket;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Vector; import java.util.Vector;
import java.util.Random;


import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.Test; import junit.framework.Test;
@@ -86,6 +87,9 @@ import org.apache.tools.ant.util.StringUtils;
*/ */
public class TestRunner implements TestListener { public class TestRunner implements TestListener {


/** unique identifier for the runner */
private final Integer id = new Integer( (new Random()).nextInt() );

/** host to connect to */ /** host to connect to */
private String host = "127.0.0.1"; private String host = "127.0.0.1";


@@ -104,10 +108,7 @@ public class TestRunner implements TestListener {
private Socket clientSocket; private Socket clientSocket;


/** writer to send message to the server */ /** writer to send message to the server */
private MessageWriter writer;

/** reader to listen for a shutdown from the server */
private BufferedReader reader;
private Messenger messenger;


/** bean constructor */ /** bean constructor */
public TestRunner() { public TestRunner() {
@@ -152,9 +153,9 @@ public class TestRunner implements TestListener {
private class StopThread extends Thread { private class StopThread extends Thread {
public void run() { public void run() {
try { try {
String line = null;
if ((line = reader.readLine()) != null) {
if (line.startsWith(MessageIds.TEST_STOP)) {
TestRunEvent evt = null;
if ((evt = messenger.read()) != null) {
if (evt.getType() == TestRunEvent.RUN_STOP) {
TestRunner.this.stop(); TestRunner.this.stop();
} }
} }
@@ -298,26 +299,26 @@ public class TestRunner implements TestListener {
// count all testMethods and inform TestRunListeners // count all testMethods and inform TestRunListeners
int count = countTests(suites); int count = countTests(suites);
log("Total tests to run: " + count); log("Total tests to run: " + count);
writer.notifyTestRunStarted(count);

// send system properties to know for the JVM status
writer.notifySystemProperties();
fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STARTED));


long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (int i = 0; i < suites.length; i++) { for (int i = 0; i < suites.length; i++) {
String name = suites[i].getClass().getName();
if (suites[i] instanceof TestCase) { if (suites[i] instanceof TestCase) {
suites[i] = new TestSuite(suites[i].getClass().getName());
suites[i] = new TestSuite(name);
} }
log("running suite: " + suites[i]); log("running suite: " + suites[i]);
fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_STARTED, name));
suites[i].run(testResult); suites[i].run(testResult);
fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_ENDED, name));
} }


// inform TestRunListeners of test end // inform TestRunListeners of test end
long elapsedTime = System.currentTimeMillis() - startTime; long elapsedTime = System.currentTimeMillis() - startTime;
if (testResult == null || testResult.shouldStop()) { if (testResult == null || testResult.shouldStop()) {
writer.notifyTestRunStopped(elapsedTime);
fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STOPPED, System.getProperties()));
} else { } else {
writer.notifyTestRunEnded(elapsedTime);
fireEvent(new TestRunEvent(id, TestRunEvent.RUN_ENDED, System.getProperties()));
} }
log("Finished after " + elapsedTime + "ms"); log("Finished after " + elapsedTime + "ms");
shutDown(); shutDown();
@@ -345,23 +346,16 @@ public class TestRunner implements TestListener {
protected void connect() throws IOException { protected void connect() throws IOException {
log("Connecting to " + host + " on port " + port + "..."); log("Connecting to " + host + " on port " + port + "...");
clientSocket = new Socket(host, port); clientSocket = new Socket(host, port);
writer = new MessageWriter(clientSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
messenger = new Messenger(clientSocket.getInputStream(), clientSocket.getOutputStream());
new StopThread().start(); new StopThread().start();
} }




protected void shutDown() { protected void shutDown() {

if (writer != null) {
writer.close();
writer = null;
}

try { try {
if (reader != null) {
reader.close();
reader = null;
if (messenger != null) {
messenger.close();
messenger = null;
} }
} catch (IOException e) { } catch (IOException e) {
log(e); log(e);
@@ -377,6 +371,9 @@ public class TestRunner implements TestListener {
} }
} }


protected void fireEvent(TestRunEvent evt){
messenger.writeEvent(evt);
}


// -------- JUnit TestListener implementation // -------- JUnit TestListener implementation


@@ -384,14 +381,13 @@ public class TestRunner implements TestListener {
public void startTest(Test test) { public void startTest(Test test) {
String testName = test.toString(); String testName = test.toString();
log("starting test: " + test); log("starting test: " + test);
writer.notifyTestStarted(testName);
fireEvent(new TestRunEvent(id, TestRunEvent.TEST_STARTED, testName));
} }


public void addError(Test test, Throwable t) { public void addError(Test test, Throwable t) {
log("Adding error for test: " + test); log("Adding error for test: " + test);
String testName = test.toString(); String testName = test.toString();
String trace = StringUtils.getStackTrace(t);
writer.notifyTestFailed(TestRunListener.STATUS_ERROR, testName, trace);
fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ERROR, testName, t));
} }


/** /**
@@ -409,14 +405,13 @@ public class TestRunner implements TestListener {
public void addFailure(Test test, Throwable t) { public void addFailure(Test test, Throwable t) {
log("Adding failure for test: " + test); log("Adding failure for test: " + test);
String testName = test.toString(); String testName = test.toString();
String trace = StringUtils.getStackTrace(t);
writer.notifyTestFailed(TestRunListener.STATUS_FAILURE, testName, trace);
fireEvent(new TestRunEvent(id, TestRunEvent.TEST_FAILURE, testName, t));
} }


public void endTest(Test test) { public void endTest(Test test) {
log("Ending test: " + test); log("Ending test: " + test);
String testName = test.toString(); String testName = test.toString();
writer.notifyTestEnded(testName);
fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ENDED, testName));
} }


public void log(String msg) { public void log(String msg) {


Loading…
Cancel
Save