You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by sb...@apache.org on 2002/02/03 14:28:45 UTC
cvs commit: jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote TestSummary.java Server.java TestRunEvent.java TestRunner.java SocketUtil.java
sbailliez 02/02/03 05:28:45
Modified: proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote
Server.java TestRunEvent.java TestRunner.java
Added: proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote
TestSummary.java
Removed: proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote
SocketUtil.java
Log:
- Refactored the Server and TestRunner to deal with events.
- Added TestSummary (TestResult was better but is conflicting with JUnit)
which sole purpose is to provide a helpful summary of the sequence
to listeners.
Revision Changes Path
1.2 +18 -35 jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Server.java
Index: Server.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/Server.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Server.java 1 Feb 2002 23:53:23 -0000 1.1
+++ Server.java 3 Feb 2002 13:28:45 -0000 1.2
@@ -116,19 +116,24 @@
}
/** start a server to the specified port */
- public void start() {
- try {
- start(false);
- } catch (InterruptedException e){
- }
- }
-
- /** start a server to the specified port and wait for end */
- public void start(boolean flag) throws InterruptedException {
- Worker worker = new Worker();
- worker.start();
- if (flag){
- worker.join();
+ public void start(boolean loop) throws IOException {
+ server = new ServerSocket(port);
+ while (server != null) {
+ client = server.accept();
+ messenger = new Messenger(client.getInputStream(), client.getOutputStream());
+ TestRunEvent evt = null;
+ try {
+ while ( (evt = messenger.read()) != null ) {
+ dispatcher.dispatchEvent(evt);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ //@fixme this stacktrace might be normal when closing
+ // the socket. So decompose the above in distinct steps
+ }
+ if (!loop){
+ break;
+ }
}
}
@@ -167,28 +172,6 @@
server = null;
}
} catch (IOException e) {
- }
- }
-
-//-----
-
- private class Worker extends Thread {
- public void run() {
- try {
- server = new ServerSocket(port);
- client = server.accept();
- messenger = new Messenger(client.getInputStream(), client.getOutputStream());
- TestRunEvent evt = null;
- while ( (evt = messenger.read()) != null ) {
- dispatcher.dispatchEvent(evt);
- }
- } catch (Exception e) {
- //@fixme this stacktrace might be normal when closing
- // the socket. So decompose the above in distinct steps
- } finally {
- cancel();
- shutdown();
- }
}
}
}
1.2 +20 -3 jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java
Index: TestRunEvent.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunEvent.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestRunEvent.java 1 Feb 2002 23:53:23 -0000 1.1
+++ TestRunEvent.java 3 Feb 2002 13:28:45 -0000 1.2
@@ -59,6 +59,9 @@
import org.apache.tools.ant.util.StringUtils;
/**
+ * Provide the basic events to be used during the tests.
+ * This is not very extensible but since the events should be somewhat
+ * limited, for now this is better to do it like this.
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
@@ -81,7 +84,7 @@
/** the type of event */
private int type = -1;
- /** timestamp for all tests */
+ /** timestamp for all events */
private long timestamp = System.currentTimeMillis();
/** name of testcase(method name) or testsuite (classname) */
@@ -93,19 +96,28 @@
/** properties for end of testrun */
private Properties props;
+ /** handy result for each end of sequence */
+ private TestSummary result;
+
public TestRunEvent(Integer id, int type){
super(id);
this.type = type;
}
+ public TestRunEvent(Integer id, int type, String name, TestSummary result){
+ this(id, type, name);
+ this.result = result;
+ }
+
public TestRunEvent(Integer id, int type, String name){
this(id, type);
this.name = name;
}
- public TestRunEvent(Integer id, int type, Properties props){
+ public TestRunEvent(Integer id, int type, Properties props, TestSummary result){
this(id, type);
this.props = props;
+ this.result = result;
}
public TestRunEvent(Integer id, int type, String name, Throwable t){
@@ -145,6 +157,10 @@
return name;
}
+ public TestSummary getSummary(){
+ return result;
+ }
+
public String getStackTrace(){
return stacktrace;
}
@@ -160,7 +176,8 @@
(timestamp == other.timestamp) &&
( name == null ? other.name == null : name.equals(other.name) ) &&
( stacktrace == null ? other.stacktrace == null : stacktrace.equals(other.stacktrace) ) &&
- ( props == null ? other.props == null : props.equals(other.props) ) ) ;
+ ( props == null ? other.props == null : props.equals(other.props) ) &&
+ ( result == null ? other.result == null : result.equals(other.result) ) );
}
return false;
}
1.2 +99 -41 jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunner.java
Index: TestRunner.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestRunner.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestRunner.java 1 Feb 2002 23:53:23 -0000 1.1
+++ TestRunner.java 3 Feb 2002 13:28:45 -0000 1.2
@@ -62,6 +62,11 @@
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Random;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -71,6 +76,8 @@
import junit.framework.TestSuite;
import org.apache.tools.ant.taskdefs.optional.rjunit.JUnitHelper;
+import org.apache.tools.ant.taskdefs.optional.rjunit.formatter.Formatter;
+import org.apache.tools.ant.taskdefs.optional.rjunit.formatter.PlainFormatter;
import org.apache.tools.ant.util.StringUtils;
/**
@@ -95,10 +102,11 @@
/** port to connect to */
private int port = -1;
+ /** handy debug flag */
private boolean debug = false;
/** the list of test class names to run */
- private Vector testClassNames = new Vector();
+ private final ArrayList testClassNames = new ArrayList();
/** result of the current test */
private TestResult testResult;
@@ -109,8 +117,14 @@
/** writer to send message to the server */
private Messenger messenger;
+ /** helpful formatter to debug events directly here */
+ private final Formatter debugFormatter = new PlainFormatter();
+
/** bean constructor */
public TestRunner() {
+ Properties props = new Properties();
+ props.setProperty("file", "rjunit-client-debug.log");
+ debugFormatter.init(props);
}
/**
@@ -142,7 +156,7 @@
* @param classname the class name of the test to run.
*/
public void addTestClassName(String classname) {
- testClassNames.addElement(classname);
+ testClassNames.add(classname);
}
/**
@@ -265,16 +279,16 @@
* @throws Exception a generic exception that can be thrown while
* instantiating a test case.
*/
- protected Test[] getSuites() throws Exception {
+ protected Map getSuites() throws Exception {
final int count = testClassNames.size();
log("Extracting testcases from " + count + " classnames...");
- final Vector suites = new Vector(count);
+ final Map suites = new HashMap();
for (int i = 0; i < count; i++) {
- String classname = (String) testClassNames.elementAt(i);
+ String classname = (String) testClassNames.get(i);
try {
Test test = JUnitHelper.getTest(null, classname);
if (test != null) {
- suites.addElement(test);
+ suites.put(classname, test);
}
} catch (Exception e) {
// notify log error instead ?
@@ -283,9 +297,7 @@
}
}
log("Extracted " + suites.size() + " testcases.");
- Test[] array = new Test[suites.size()];
- suites.copyInto(array);
- return array;
+ return suites;
}
/**
@@ -293,41 +305,75 @@
*/
private void runTests() throws Exception {
- Test[] suites = getSuites();
+ Map suites = getSuites();
// count all testMethods and inform TestRunListeners
- int count = countTests(suites);
+ int count = countTests(suites.values());
log("Total tests to run: " + count);
- fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STARTED));
-
- long startTime = System.currentTimeMillis();
- for (int i = 0; i < suites.length; i++) {
- String name = suites[i].getClass().getName();
- if (suites[i] instanceof TestCase) {
- suites[i] = new TestSuite(name);
- }
- log("running suite: " + suites[i]);
- fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_STARTED, name));
- suites[i].run(testResult);
- fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_ENDED, name));
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.RUN_STARTED);
+ if (debug){
+ debugFormatter.onRunStarted(evt);
+ }
+ fireEvent(evt);
+
+ TestSummary runSummary = new TestSummary();
+ runSummary.start(testResult);
+ for (Iterator it = suites.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = (Map.Entry)it.next();
+ String name = (String)entry.getKey();
+ Test test = (Test)entry.getValue();
+ if (test instanceof TestCase) {
+ test = new TestSuite(name);
+ }
+ runTest(test, name);
}
+ runSummary.stop(testResult);
// inform TestRunListeners of test end
- long elapsedTime = System.currentTimeMillis() - startTime;
- if (testResult == null || testResult.shouldStop()) {
- fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STOPPED, System.getProperties()));
- } else {
- fireEvent(new TestRunEvent(id, TestRunEvent.RUN_ENDED, System.getProperties()));
+ int type = (testResult == null || testResult.shouldStop()) ?
+ TestRunEvent.RUN_STOPPED : TestRunEvent.RUN_ENDED;
+ evt = new TestRunEvent(id, type, System.getProperties(), runSummary);
+ if (debug){
+ debugFormatter.onRunEnded(evt);
}
- log("Finished after " + elapsedTime + "ms");
+ fireEvent(evt);
+ log("Finished after " + runSummary.elapsedTime() + "ms");
shutDown();
}
- /** count the number of test methods in all tests */
- private final int countTests(Test[] tests) {
+ /**
+ * run a single suite and dispatch its results.
+ * @param test the instance of the testsuite to run.
+ * @param name the name of the testsuite (classname)
+ */
+ private void runTest(Test test, String name){
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.SUITE_STARTED, name);
+ if (debug){
+ debugFormatter.onSuiteStarted(evt);
+ }
+ fireEvent(evt);
+ TestSummary suiteSummary = new TestSummary();
+ suiteSummary.start(testResult);
+ try {
+ test.run(testResult);
+ } finally {
+ suiteSummary.stop(testResult);
+ evt = new TestRunEvent(id, TestRunEvent.SUITE_ENDED, name, suiteSummary);
+ if (debug){
+ debugFormatter.onSuiteEnded(evt);
+ }
+ fireEvent(evt);
+ }
+ }
+
+ /**
+ * count the number of test methods in all tests
+ */
+ private final int countTests(Collection tests) {
int count = 0;
- for (int i = 0; i < tests.length; i++) {
- count = count + tests[i].countTestCases();
+ for (Iterator it = tests.iterator(); it.hasNext(); ) {
+ Test test = (Test)it.next();
+ count = count + test.countTestCases();
}
return count;
}
@@ -383,14 +429,20 @@
public void startTest(Test test) {
String testName = test.toString();
- log("starting test: " + test);
- fireEvent(new TestRunEvent(id, TestRunEvent.TEST_STARTED, testName));
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_STARTED, testName);
+ if (debug){
+ debugFormatter.onTestStarted(evt);
+ }
+ fireEvent(evt);
}
public void addError(Test test, Throwable t) {
- log("Adding error for test: " + test);
String testName = test.toString();
- fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ERROR, testName, t));
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_ERROR, testName, t);
+ if (debug){
+ debugFormatter.onTestError(evt);
+ }
+ fireEvent(evt);
}
/**
@@ -406,15 +458,21 @@
* @see addFailure(Test, AssertionFailedError)
*/
public void addFailure(Test test, Throwable t) {
- log("Adding failure for test: " + test);
String testName = test.toString();
- fireEvent(new TestRunEvent(id, TestRunEvent.TEST_FAILURE, testName, t));
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_FAILURE, testName, t);
+ if (debug){
+ debugFormatter.onTestFailure(evt);
+ }
+ fireEvent(evt);
}
public void endTest(Test test) {
- log("Ending test: " + test);
String testName = test.toString();
- fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ENDED, testName));
+ TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_ENDED, testName);
+ if (debug){
+ debugFormatter.onTestEnded(evt);
+ }
+ fireEvent(evt);
}
public void log(String msg) {
1.1 jakarta-ant/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/remote/TestSummary.java
Index: TestSummary.java
===================================================================
/*
* 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.rjunit.remote;
import java.io.Serializable;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestResult;
/**
* A helpful test summary that is somewhat similar to <tt>TestResult</tt>.
* Here the difference is that this test summary should register to
* the test result the time you wan to collect information.
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public final class TestSummary implements Serializable, TestListener {
/** time elapsed during tests run in ms */
private long elapsedTime;
/** number of errors */
private int errorCount;
/** number of successes */
private int successCount;
/** number of failures */
private int failureCount;
/** number of runs */
private int runCount;
private transient String toString;
/** bean constructor */
public TestSummary() {
}
/**
* @return the number of errors that occurred in this test.
*/
public int errorCount() {
return errorCount;
}
/**
* @return the number of successes that occurred in this test.
*/
public int successCount() {
return successCount;
}
/**
* @return the number of failures that occurred in this test.
*/
public int failureCount() {
return failureCount;
}
/**
* @return the number of runs that occurred in this test.
* a run is the sum of failures + errors + successes.
*/
public int runCount() {
return runCount;
}
/**
* @return the elapsed time in ms
*/
public long elapsedTime() {
return elapsedTime;
}
//
/**
* register to the <tt>TestResult</tt> and starts the time counter.
* @param result the instance to register to.
* @see #stop()
*/
public void start(TestResult result){
elapsedTime = System.currentTimeMillis();
result.addListener(this);
}
/**
* unregister from the <tt>TestResult</tt> and stops the time counter.
* @param result the instance to unregister from.
* @see #start()
*/
public void stop(TestResult result){
elapsedTime = System.currentTimeMillis() - elapsedTime;
result.removeListener(this);
}
// test listener implementation
public void addError(Test test, Throwable throwable) {
errorCount++;
}
public void addFailure(Test test, AssertionFailedError error) {
failureCount++;
}
public void endTest(Test test) {
successCount++;
}
public void startTest(Test test) {
runCount++;
}
public String toString(){
StringBuffer buf = new StringBuffer();
buf.append("run: ").append(runCount);
buf.append(" success: ").append(successCount);
buf.append(" failures: ").append(failureCount);
buf.append(" errors: ").append(errorCount);
buf.append(" elapsed: ").append(elapsedTime);
return buf.toString();
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>