KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quilt > runner > BaseTestRunner


1 /* BaseTestRunner.java */
2
3 package org.quilt.runner;
4
5 import java.io.ByteArrayOutputStream JavaDoc;
6 import java.io.File JavaDoc;
7 import java.io.FileInputStream JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.io.OutputStream JavaDoc;
10 import java.io.PrintStream JavaDoc;
11
12 import java.lang.reflect.Method JavaDoc;
13 import java.util.Enumeration JavaDoc;
14 import java.util.Properties JavaDoc;
15 import java.util.Vector JavaDoc;
16
17 import org.apache.tools.ant.AntClassLoader;
18 import org.apache.tools.ant.BuildException;
19 import org.apache.tools.ant.Project;
20
21 import junit.framework.*;
22
23 import org.quilt.cl.*;
24 import org.quilt.framework.QuiltTest;
25 import org.quilt.reports.*;
26
27 /**
28  * Stand-along Quilt test runner, fully compatible with Ant's JUnit
29  * options. Accepts options from Ant via QuiltTask; can also be run
30  * from the command line using TestRunner.
31  *
32  * @see QuiltTask
33  * @see QuiltTest
34  * @see TestRunner
35  */

36
37 public class BaseTestRunner extends Runner {
38
39     /** The QuiltTest we are currently running. */
40     private QuiltTest qt;
41
42     /** The JUnit test suite for this QuiltTest. Built by the constructor.*/
43     private Test suite = null;
44
45     /** Exception caught in constructor. */
46     private Exception JavaDoc exception = null;
47
48     /** Status code returned by main() */
49     private int retCode = SUCCESS;
50
51     /** JUnit test result - which has the run() method. */
52     private TestResult res;
53
54     // RUN PARAMETERS ///////////////////////////////////////////////
55

56     /** Formatters for this particular test. */
57     private Vector JavaDoc formatters = new Vector JavaDoc();
58
59     /** Do we stop on errors? */
60 // private boolean haltOnError = false;
61

62     /** Do we stop on test failures? */
63 // private boolean haltOnFailure = false;
64

65     /**
66      * Do we send output to System.out/.err as well as to the formatters.
67      * XXX BUG or inconsistency in documentation.
68      */

69 // private boolean showOutput = false;
70

71     /** Error output during the test */
72     private PrintStream JavaDoc systemError;
73
74     /** Output written during the test */
75     private PrintStream JavaDoc systemOut;
76
77     // CONSTRUCTORS /////////////////////////////////////////////////
78

79     /**
80      * Constructor used by command line test runner. And so also
81      * used when Ant forks the test runner. XXX No longer true.
82      *
83      * @param test Data structure holding parameters for a single
84      * test suite.
85      */

86     public BaseTestRunner (QuiltTest test) {
87         this (test, null);
88     }
89     /**
90      * Constructor used when not using Quilt class loader. XXX Not true.
91      * Uses BaseTestRunner.retCode to signal whether construction
92      * successful or not. If the operation fails, the exception
93      * involved is passed back in BaseTestRunner.exception.
94      *
95      * @param test Data structure holding parameters for a single
96      * test suite.
97      * @param loader Class loader passed from parent.
98      */

99     public BaseTestRunner(QuiltTest test, ClassLoader JavaDoc loader) {
100         qt = test;
101
102         try {
103             Class JavaDoc testClass = null;
104             if (loader == null) {
105                 testClass = Class.forName(qt.getName());
106             } else {
107                 testClass = loader.loadClass(qt.getName());
108                 if (!(loader instanceof QuiltClassLoader)) {
109                     // trick JVM into initializing class statics
110
AntClassLoader.initializeClass(testClass);
111                 }
112             }
113
114             Method JavaDoc suiteMethod = null;
115             try {
116                 // check if there is a no-arg "suite" method in the class
117
suiteMethod = testClass.getMethod("suite", new Class JavaDoc[0]);
118             } catch (Exception JavaDoc e) {
119                 // not found
120
}
121             if (suiteMethod != null){
122                 // we somehow have a suiteMethod; try to use it to
123
// extract the suite
124
suite = (Test) suiteMethod.invoke(null, new Class JavaDoc[0]);
125             } else {
126                 // use the JUnit TestSuite constructor to extract a
127
// test suite
128
suite = new TestSuite(testClass);
129             }
130
131         } catch (Exception JavaDoc e) {
132             retCode = ERRORS;
133             exception = e;
134         }
135     }
136 // /**
137
// * Constructor using Quilt class loader. Uses
138
// * BaseTestRunner.retCode to signal whether construction
139
// * successful or not. If the operation fails, the exception
140
// * involved is passed back in BaseTestRunner.exception.
141
// *
142
// * @param test Data structure holding parameters for a single
143
// * test suite.
144
// * @param loader QuiltClassLoader passed from parent.
145
// */
146
// public BaseTestRunner(QuiltTest test, QuiltClassLoader loader) {
147
// this.qt = test;
148

149 // try {
150
// Class testClass = null;
151
// if (loader == null) {
152
// testClass = Class.forName(test.getName());
153
// } else {
154
// testClass = loader.loadClass(test.getName());
155
// // trick JVM into initializing class statics
156
// AntClassLoader.initializeClass(testClass);
157
// }
158
//
159
// Method suiteMethod = null;
160
// try {
161
// // check if there is a no-arg "suite" method in the class
162
// suiteMethod = testClass.getMethod("suite", new Class[0]);
163
// } catch (Exception e) {
164
// // not found
165
// }
166
// if (suiteMethod != null){
167
// // if there is a suite method available, then try
168
// // to extract the suite from it. If there is an error
169
// // here it will be caught below and reported.
170
// suite = (Test) suiteMethod.invoke(null, new Class[0]);
171
// } else {
172
// // use the JUnit TestSuite constructor to extract a
173
// // test suite
174
// suite = new TestSuite(testClass);
175
// }
176
//
177
// } catch (Exception e) {
178
// retCode = ERRORS;
179
// exception = e;
180
// }
181
// } // GEEP
182

183     public void run() {
184         res = new TestResult();
185         res.addListener(this);
186         for (int i = 0; i < formatters.size(); i++) {
187             res.addListener((TestListener) formatters.elementAt(i));
188         }
189
190         long start = System.currentTimeMillis();
191
192         fireStartTestSuite();
193         if (exception != null) { // had an exception in the constructor
194
for (int i = 0; i < formatters.size(); i++) {
195                 ((TestListener) formatters.elementAt(i)).addError(null,
196                                                                  exception);
197             }
198             qt.setCounts(1, 0, 1);
199             qt.setRunTime(0);
200         } else {
201
202
203             ByteArrayOutputStream JavaDoc errStrm = new ByteArrayOutputStream JavaDoc();
204             systemError = new PrintStream JavaDoc(errStrm);
205
206             ByteArrayOutputStream JavaDoc outStrm = new ByteArrayOutputStream JavaDoc();
207             systemOut = new PrintStream JavaDoc(outStrm);
208
209             PrintStream JavaDoc savedOut = null;
210             PrintStream JavaDoc savedErr = null;
211
212             if ( qt.getFork() ) {
213                 savedOut = System.out;
214                 savedErr = System.err;
215                 if (!qt.getShowOutput()) {
216                     System.setOut(systemOut);
217                     System.setErr(systemError);
218                 } else {
219                     System.setOut(new PrintStream JavaDoc(
220                                       new TeeOutputStream(
221                                           new OutputStream JavaDoc[] {savedOut,
222                                                               systemOut}
223                                           )
224                                       )
225                                   );
226                     System.setErr(new PrintStream JavaDoc(
227                                       new TeeOutputStream(
228                                           new OutputStream JavaDoc[] {savedErr,
229                                                               systemError}
230                                           )
231                                       )
232                                   );
233                 }
234             }
235
236
237             try {
238                 suite.run(res);
239             } finally {
240                 if (savedOut != null) {
241                     System.setOut(savedOut);
242                 }
243                 if (savedErr != null) {
244                     System.setErr(savedErr);
245                 }
246
247                 systemError.close();
248                 systemError = null;
249                 systemOut.close();
250                 systemOut = null;
251                 sendOutAndErr(new String JavaDoc(outStrm.toByteArray()),
252                               new String JavaDoc(errStrm.toByteArray()));
253
254                 qt.setCounts(res.runCount(), res.failureCount(),
255                                     res.errorCount());
256                 qt.setRunTime(System.currentTimeMillis() - start);
257             }
258         }
259         fireEndTestSuite();
260
261         if (retCode != SUCCESS || res.errorCount() != 0) {
262             retCode = ERRORS;
263         } else if (res.failureCount() != 0) {
264             retCode = FAILURES;
265         }
266     }
267
268     /**
269      * Get status code from run.
270      *
271      * @return Status codes from RunnerConst
272      */

273     public int getRetCode() {
274         return retCode;
275     }
276
277     /////////////////////////////////////////////////////////////////
278
// INTERFACE TESTLISTENER
279
//
280
// NEEDS TO BE CHECKED CAREFULLY
281
/////////////////////////////////////////////////////////////////
282

283     /** Called at start of test run. */
284     public void startTest(Test t) {}
285
286     /** Called at end of test suite. */
287     public void endTest(Test test) {}
288
289     /** A test failure (or error) has occurred. */
290     public void addFailure(Test test, Throwable JavaDoc t) {
291         if (qt.getHaltOnFailure()) {
292             res.stop();
293         }
294     }
295
296     /** A test failure (or error) has occurred. */
297     public void addFailure(Test test, AssertionFailedError t) {
298         addFailure(test, (Throwable JavaDoc) t);
299     }
300
301     /** An unexpected error occurred. */
302     public void addError(Test test, Throwable JavaDoc t) {
303         if (qt.getHaltOnError()) {
304             res.stop();
305         }
306     }
307
308     /** Handle a block of output. */
309     public void handleOutput(String JavaDoc line) {
310         if (systemOut != null) {
311             systemOut.println(line);
312         }
313     }
314
315     /** Process an error message. */
316     public void handleErrorOutput(String JavaDoc line) {
317         if (systemError != null) {
318             systemError.println(line);
319         }
320     }
321     /** Flush standard output. */
322     public void handleFlush(String JavaDoc line) {
323         if (systemOut != null) {
324             systemOut.print(line);
325         }
326     }
327     /** Flush error output. */
328     public void handleErrorFlush(String JavaDoc line) {
329         if (systemError != null) {
330             systemError.print(line);
331         }
332     }
333     /**
334      * Whether to duplicate test output to standard output and error
335      * output streams.
336      */

337     private void sendOutAndErr(String JavaDoc out, String JavaDoc err) {
338         for (int i = 0; i < formatters.size(); i++) {
339             Formatter formatter =
340                 ((Formatter) formatters.elementAt(i));
341
342             formatter.setSystemOutput(out);
343             formatter.setSystemError(err);
344         }
345     }
346
347     /** Notifies each formatter at start of processing test suite. */
348     private void fireStartTestSuite() {
349         for (int i = 0; i < formatters.size(); i++) {
350             ((Formatter) formatters.elementAt(i))
351                 .startTestSuite(qt);
352             // actually has nothing to do with fireStart but it's
353
// convenient to drop it in here
354
((Formatter) formatters.elementAt(i))
355                 .setFiltertrace(qt.getFiltertrace());
356         }
357     }
358     /** Called at end of test suite, notifies each formatter. */
359     private void fireEndTestSuite() {
360         for (int i = 0; i < formatters.size(); i++) {
361             ((Formatter) formatters.elementAt(i))
362                 .endTestSuite(qt);
363         }
364     }
365
366     /** Add a result formatter */
367     public void addFormatter(Formatter f) {
368         formatters.addElement(f);
369     }
370
371     // OTHER METHODS ////////////////////////////////////////////////
372
private class TeeOutputStream extends OutputStream JavaDoc {
373
374         private OutputStream JavaDoc[] outs;
375
376         private TeeOutputStream(OutputStream JavaDoc[] outs) {
377             this.outs = outs;
378         }
379
380         public void write(int b) throws IOException JavaDoc {
381             for (int i = 0; i < outs.length; i++) {
382                 outs[i].write(b);
383             }
384         }
385     }
386 }
387
Popular Tags