1 | /*
|
---|
2 | * Copyright 2000-2005 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.taskdefs.optional.junit;
|
---|
19 |
|
---|
20 | import java.io.BufferedReader;
|
---|
21 | import java.io.ByteArrayOutputStream;
|
---|
22 | import java.io.File;
|
---|
23 | import java.io.FileInputStream;
|
---|
24 | import java.io.IOException;
|
---|
25 | import java.io.PrintStream;
|
---|
26 | import java.io.PrintWriter;
|
---|
27 | import java.io.StringReader;
|
---|
28 | import java.io.StringWriter;
|
---|
29 | import java.lang.reflect.Method;
|
---|
30 | import java.util.Enumeration;
|
---|
31 | import java.util.Hashtable;
|
---|
32 | import java.util.Properties;
|
---|
33 | import java.util.StringTokenizer;
|
---|
34 | import java.util.Vector;
|
---|
35 | import junit.framework.AssertionFailedError;
|
---|
36 | import junit.framework.Test;
|
---|
37 | import junit.framework.TestListener;
|
---|
38 | import junit.framework.TestResult;
|
---|
39 | import junit.framework.TestSuite;
|
---|
40 | import org.apache.tools.ant.BuildException;
|
---|
41 | import org.apache.tools.ant.Project;
|
---|
42 | import org.apache.tools.ant.types.Permissions;
|
---|
43 | import org.apache.tools.ant.util.StringUtils;
|
---|
44 | import org.apache.tools.ant.util.TeeOutputStream;
|
---|
45 |
|
---|
46 | /**
|
---|
47 | * Simple Testrunner for JUnit that runs all tests of a testsuite.
|
---|
48 | *
|
---|
49 | * <p>This TestRunner expects a name of a TestCase class as its
|
---|
50 | * argument. If this class provides a static suite() method it will be
|
---|
51 | * called and the resulting Test will be run. So, the signature should be
|
---|
52 | * <pre><code>
|
---|
53 | * public static junit.framework.Test suite()
|
---|
54 | * </code></pre>
|
---|
55 | *
|
---|
56 | * <p> If no such method exists, all public methods starting with
|
---|
57 | * "test" and taking no argument will be run.
|
---|
58 | *
|
---|
59 | * <p> Summary output is generated at the end.
|
---|
60 | *
|
---|
61 | * @since Ant 1.2
|
---|
62 | */
|
---|
63 |
|
---|
64 | public class JUnitTestRunner implements TestListener {
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * No problems with this test.
|
---|
68 | */
|
---|
69 | public static final int SUCCESS = 0;
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * Some tests failed.
|
---|
73 | */
|
---|
74 | public static final int FAILURES = 1;
|
---|
75 |
|
---|
76 | /**
|
---|
77 | * An error occurred.
|
---|
78 | */
|
---|
79 | public static final int ERRORS = 2;
|
---|
80 |
|
---|
81 | /**
|
---|
82 | * Used in formatter arguments as a placeholder for the basename
|
---|
83 | * of the output file (which gets replaced by a test specific
|
---|
84 | * output file name later).
|
---|
85 | *
|
---|
86 | * @since Ant 1.6.3
|
---|
87 | */
|
---|
88 | public static final String IGNORED_FILE_NAME = "IGNORETHIS";
|
---|
89 |
|
---|
90 | /**
|
---|
91 | * Holds the registered formatters.
|
---|
92 | */
|
---|
93 | private Vector formatters = new Vector();
|
---|
94 |
|
---|
95 | /**
|
---|
96 | * Collects TestResults.
|
---|
97 | */
|
---|
98 | private TestResult res;
|
---|
99 |
|
---|
100 | /**
|
---|
101 | * Do we filter junit.*.* stack frames out of failure and error exceptions.
|
---|
102 | */
|
---|
103 | private static boolean filtertrace = true;
|
---|
104 |
|
---|
105 | /**
|
---|
106 | * Do we send output to System.out/.err in addition to the formatters?
|
---|
107 | */
|
---|
108 | private boolean showOutput = false;
|
---|
109 |
|
---|
110 | /**
|
---|
111 | * The permissions set for the test to run.
|
---|
112 | */
|
---|
113 | private Permissions perm = null;
|
---|
114 |
|
---|
115 | private static final String[] DEFAULT_TRACE_FILTERS = new String[] {
|
---|
116 | "junit.framework.TestCase",
|
---|
117 | "junit.framework.TestResult",
|
---|
118 | "junit.framework.TestSuite",
|
---|
119 | "junit.framework.Assert.", // don't filter AssertionFailure
|
---|
120 | "junit.swingui.TestRunner",
|
---|
121 | "junit.awtui.TestRunner",
|
---|
122 | "junit.textui.TestRunner",
|
---|
123 | "java.lang.reflect.Method.invoke(",
|
---|
124 | "sun.reflect.",
|
---|
125 | "org.apache.tools.ant."
|
---|
126 | };
|
---|
127 |
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * Do we stop on errors.
|
---|
131 | */
|
---|
132 | private boolean haltOnError = false;
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * Do we stop on test failures.
|
---|
136 | */
|
---|
137 | private boolean haltOnFailure = false;
|
---|
138 |
|
---|
139 | /**
|
---|
140 | * Returncode
|
---|
141 | */
|
---|
142 | private int retCode = SUCCESS;
|
---|
143 |
|
---|
144 | /**
|
---|
145 | * The TestSuite we are currently running.
|
---|
146 | */
|
---|
147 | private JUnitTest junitTest;
|
---|
148 |
|
---|
149 | /** output written during the test */
|
---|
150 | private PrintStream systemError;
|
---|
151 |
|
---|
152 | /** Error output during the test */
|
---|
153 | private PrintStream systemOut;
|
---|
154 |
|
---|
155 | /** is this runner running in forked mode? */
|
---|
156 | private boolean forked = false;
|
---|
157 |
|
---|
158 | /** Running more than one test suite? */
|
---|
159 | private static boolean multipleTests = false;
|
---|
160 |
|
---|
161 | /** ClassLoader passed in in non-forked mode. */
|
---|
162 | private ClassLoader loader;
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * Constructor for fork=true or when the user hasn't specified a
|
---|
166 | * classpath.
|
---|
167 | */
|
---|
168 | public JUnitTestRunner(JUnitTest test, boolean haltOnError,
|
---|
169 | boolean filtertrace, boolean haltOnFailure) {
|
---|
170 | this(test, haltOnError, filtertrace, haltOnFailure, false);
|
---|
171 | }
|
---|
172 |
|
---|
173 | /**
|
---|
174 | * Constructor for fork=true or when the user hasn't specified a
|
---|
175 | * classpath.
|
---|
176 | */
|
---|
177 | public JUnitTestRunner(JUnitTest test, boolean haltOnError,
|
---|
178 | boolean filtertrace, boolean haltOnFailure,
|
---|
179 | boolean showOutput) {
|
---|
180 | this(test, haltOnError, filtertrace, haltOnFailure, showOutput, null);
|
---|
181 | }
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * Constructor to use when the user has specified a classpath.
|
---|
185 | */
|
---|
186 | public JUnitTestRunner(JUnitTest test, boolean haltOnError,
|
---|
187 | boolean filtertrace, boolean haltOnFailure,
|
---|
188 | ClassLoader loader) {
|
---|
189 | this(test, haltOnError, filtertrace, haltOnFailure, false, loader);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /**
|
---|
193 | * Constructor to use when the user has specified a classpath.
|
---|
194 | */
|
---|
195 | public JUnitTestRunner(JUnitTest test, boolean haltOnError,
|
---|
196 | boolean filtertrace, boolean haltOnFailure,
|
---|
197 | boolean showOutput, ClassLoader loader) {
|
---|
198 | this.filtertrace = filtertrace;
|
---|
199 | this.junitTest = test;
|
---|
200 | this.haltOnError = haltOnError;
|
---|
201 | this.haltOnFailure = haltOnFailure;
|
---|
202 | this.showOutput = showOutput;
|
---|
203 | this.loader = loader;
|
---|
204 | }
|
---|
205 |
|
---|
206 | public void run() {
|
---|
207 | res = new TestResult();
|
---|
208 | res.addListener(this);
|
---|
209 | for (int i = 0; i < formatters.size(); i++) {
|
---|
210 | res.addListener((TestListener) formatters.elementAt(i));
|
---|
211 | }
|
---|
212 |
|
---|
213 | ByteArrayOutputStream errStrm = new ByteArrayOutputStream();
|
---|
214 | systemError = new PrintStream(errStrm);
|
---|
215 |
|
---|
216 | ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
|
---|
217 | systemOut = new PrintStream(outStrm);
|
---|
218 |
|
---|
219 | PrintStream savedErr = null;
|
---|
220 | PrintStream savedOut = null;
|
---|
221 |
|
---|
222 | if (forked) {
|
---|
223 | savedOut = System.out;
|
---|
224 | savedErr = System.err;
|
---|
225 | if (!showOutput) {
|
---|
226 | System.setOut(systemOut);
|
---|
227 | System.setErr(systemError);
|
---|
228 | } else {
|
---|
229 | System.setOut(new PrintStream(
|
---|
230 | new TeeOutputStream(savedOut, systemOut)
|
---|
231 | )
|
---|
232 | );
|
---|
233 | System.setErr(new PrintStream(
|
---|
234 | new TeeOutputStream(savedErr,
|
---|
235 | systemError)
|
---|
236 | )
|
---|
237 | );
|
---|
238 | }
|
---|
239 | perm = null;
|
---|
240 | } else {
|
---|
241 | if (perm != null) {
|
---|
242 | perm.setSecurityManager();
|
---|
243 | }
|
---|
244 | }
|
---|
245 |
|
---|
246 | Test suite = null;
|
---|
247 | Throwable exception = null;
|
---|
248 |
|
---|
249 | try {
|
---|
250 |
|
---|
251 | try {
|
---|
252 | Class testClass = null;
|
---|
253 | if (loader == null) {
|
---|
254 | testClass = Class.forName(junitTest.getName());
|
---|
255 | } else {
|
---|
256 | testClass = Class.forName(junitTest.getName(), true,
|
---|
257 | loader);
|
---|
258 | }
|
---|
259 |
|
---|
260 | Method suiteMethod = null;
|
---|
261 | try {
|
---|
262 | // check if there is a suite method
|
---|
263 | suiteMethod = testClass.getMethod("suite", new Class[0]);
|
---|
264 | } catch (NoSuchMethodException e) {
|
---|
265 | // no appropriate suite method found. We don't report any
|
---|
266 | // error here since it might be perfectly normal.
|
---|
267 | }
|
---|
268 | if (suiteMethod != null) {
|
---|
269 | // if there is a suite method available, then try
|
---|
270 | // to extract the suite from it. If there is an error
|
---|
271 | // here it will be caught below and reported.
|
---|
272 | suite = (Test) suiteMethod.invoke(null, new Class[0]);
|
---|
273 | } else {
|
---|
274 | // try to extract a test suite automatically this
|
---|
275 | // will generate warnings if the class is no
|
---|
276 | // suitable Test
|
---|
277 | suite = new TestSuite(testClass);
|
---|
278 | }
|
---|
279 |
|
---|
280 | } catch (Throwable e) {
|
---|
281 | retCode = ERRORS;
|
---|
282 | exception = e;
|
---|
283 | }
|
---|
284 |
|
---|
285 | long start = System.currentTimeMillis();
|
---|
286 |
|
---|
287 | fireStartTestSuite();
|
---|
288 | if (exception != null) { // had an exception constructing suite
|
---|
289 | for (int i = 0; i < formatters.size(); i++) {
|
---|
290 | ((TestListener) formatters.elementAt(i))
|
---|
291 | .addError(null, exception);
|
---|
292 | }
|
---|
293 | junitTest.setCounts(1, 0, 1);
|
---|
294 | junitTest.setRunTime(0);
|
---|
295 | } else {
|
---|
296 | try {
|
---|
297 | suite.run(res);
|
---|
298 | } finally {
|
---|
299 | junitTest.setCounts(res.runCount(), res.failureCount(),
|
---|
300 | res.errorCount());
|
---|
301 | junitTest.setRunTime(System.currentTimeMillis() - start);
|
---|
302 | }
|
---|
303 | }
|
---|
304 | } finally {
|
---|
305 | if (perm != null) {
|
---|
306 | perm.restoreSecurityManager();
|
---|
307 | }
|
---|
308 | if (savedOut != null) {
|
---|
309 | System.setOut(savedOut);
|
---|
310 | }
|
---|
311 | if (savedErr != null) {
|
---|
312 | System.setErr(savedErr);
|
---|
313 | }
|
---|
314 |
|
---|
315 | systemError.close();
|
---|
316 | systemError = null;
|
---|
317 | systemOut.close();
|
---|
318 | systemOut = null;
|
---|
319 | sendOutAndErr(new String(outStrm.toByteArray()),
|
---|
320 | new String(errStrm.toByteArray()));
|
---|
321 | }
|
---|
322 | fireEndTestSuite();
|
---|
323 |
|
---|
324 | if (retCode != SUCCESS || res.errorCount() != 0) {
|
---|
325 | retCode = ERRORS;
|
---|
326 | } else if (res.failureCount() != 0) {
|
---|
327 | retCode = FAILURES;
|
---|
328 | }
|
---|
329 | }
|
---|
330 |
|
---|
331 | /**
|
---|
332 | * Returns what System.exit() would return in the standalone version.
|
---|
333 | *
|
---|
334 | * @return 2 if errors occurred, 1 if tests failed else 0.
|
---|
335 | */
|
---|
336 | public int getRetCode() {
|
---|
337 | return retCode;
|
---|
338 | }
|
---|
339 |
|
---|
340 | /**
|
---|
341 | * Interface TestListener.
|
---|
342 | *
|
---|
343 | * <p>A new Test is started.
|
---|
344 | */
|
---|
345 | public void startTest(Test t) {
|
---|
346 | }
|
---|
347 |
|
---|
348 | /**
|
---|
349 | * Interface TestListener.
|
---|
350 | *
|
---|
351 | * <p>A Test is finished.
|
---|
352 | */
|
---|
353 | public void endTest(Test test) {
|
---|
354 | }
|
---|
355 |
|
---|
356 | /**
|
---|
357 | * Interface TestListener for JUnit <= 3.4.
|
---|
358 | *
|
---|
359 | * <p>A Test failed.
|
---|
360 | */
|
---|
361 | public void addFailure(Test test, Throwable t) {
|
---|
362 | if (haltOnFailure) {
|
---|
363 | res.stop();
|
---|
364 | }
|
---|
365 | }
|
---|
366 |
|
---|
367 | /**
|
---|
368 | * Interface TestListener for JUnit > 3.4.
|
---|
369 | *
|
---|
370 | * <p>A Test failed.
|
---|
371 | */
|
---|
372 | public void addFailure(Test test, AssertionFailedError t) {
|
---|
373 | addFailure(test, (Throwable) t);
|
---|
374 | }
|
---|
375 |
|
---|
376 | /**
|
---|
377 | * Interface TestListener.
|
---|
378 | *
|
---|
379 | * <p>An error occurred while running the test.
|
---|
380 | */
|
---|
381 | public void addError(Test test, Throwable t) {
|
---|
382 | if (haltOnError) {
|
---|
383 | res.stop();
|
---|
384 | }
|
---|
385 | }
|
---|
386 |
|
---|
387 | /**
|
---|
388 | * Permissions for the test run.
|
---|
389 | * @since Ant 1.6
|
---|
390 | * @param permissions
|
---|
391 | */
|
---|
392 | public void setPermissions(Permissions permissions) {
|
---|
393 | perm = permissions;
|
---|
394 | }
|
---|
395 |
|
---|
396 | protected void handleOutput(String output) {
|
---|
397 | if (systemOut != null) {
|
---|
398 | systemOut.print(output);
|
---|
399 | }
|
---|
400 | }
|
---|
401 |
|
---|
402 | /**
|
---|
403 | * @see org.apache.tools.ant.Task#handleInput(byte[], int, int)
|
---|
404 | *
|
---|
405 | * @since Ant 1.6
|
---|
406 | */
|
---|
407 | protected int handleInput(byte[] buffer, int offset, int length)
|
---|
408 | throws IOException {
|
---|
409 | return -1;
|
---|
410 | }
|
---|
411 |
|
---|
412 | protected void handleErrorOutput(String output) {
|
---|
413 | if (systemError != null) {
|
---|
414 | systemError.print(output);
|
---|
415 | }
|
---|
416 | }
|
---|
417 |
|
---|
418 | protected void handleFlush(String output) {
|
---|
419 | if (systemOut != null) {
|
---|
420 | systemOut.print(output);
|
---|
421 | }
|
---|
422 | }
|
---|
423 |
|
---|
424 | protected void handleErrorFlush(String output) {
|
---|
425 | if (systemError != null) {
|
---|
426 | systemError.print(output);
|
---|
427 | }
|
---|
428 | }
|
---|
429 |
|
---|
430 | private void sendOutAndErr(String out, String err) {
|
---|
431 | for (int i = 0; i < formatters.size(); i++) {
|
---|
432 | JUnitResultFormatter formatter =
|
---|
433 | ((JUnitResultFormatter) formatters.elementAt(i));
|
---|
434 |
|
---|
435 | formatter.setSystemOutput(out);
|
---|
436 | formatter.setSystemError(err);
|
---|
437 | }
|
---|
438 | }
|
---|
439 |
|
---|
440 | private void fireStartTestSuite() {
|
---|
441 | for (int i = 0; i < formatters.size(); i++) {
|
---|
442 | ((JUnitResultFormatter) formatters.elementAt(i))
|
---|
443 | .startTestSuite(junitTest);
|
---|
444 | }
|
---|
445 | }
|
---|
446 |
|
---|
447 | private void fireEndTestSuite() {
|
---|
448 | for (int i = 0; i < formatters.size(); i++) {
|
---|
449 | ((JUnitResultFormatter) formatters.elementAt(i))
|
---|
450 | .endTestSuite(junitTest);
|
---|
451 | }
|
---|
452 | }
|
---|
453 |
|
---|
454 | public void addFormatter(JUnitResultFormatter f) {
|
---|
455 | formatters.addElement(f);
|
---|
456 | }
|
---|
457 |
|
---|
458 | /**
|
---|
459 | * Entry point for standalone (forked) mode.
|
---|
460 | *
|
---|
461 | * Parameters: testcaseclassname plus parameters in the format
|
---|
462 | * key=value, none of which is required.
|
---|
463 | *
|
---|
464 | * <table cols="4" border="1">
|
---|
465 | * <tr><th>key</th><th>description</th><th>default value</th></tr>
|
---|
466 | *
|
---|
467 | * <tr><td>haltOnError</td><td>halt test on
|
---|
468 | * errors?</td><td>false</td></tr>
|
---|
469 | *
|
---|
470 | * <tr><td>haltOnFailure</td><td>halt test on
|
---|
471 | * failures?</td><td>false</td></tr>
|
---|
472 | *
|
---|
473 | * <tr><td>formatter</td><td>A JUnitResultFormatter given as
|
---|
474 | * classname,filename. If filename is ommitted, System.out is
|
---|
475 | * assumed.</td><td>none</td></tr>
|
---|
476 | *
|
---|
477 | * <tr><td>showoutput</td><td>send output to System.err/.out as
|
---|
478 | * well as to the formatters?</td><td>false</td></tr>
|
---|
479 | *
|
---|
480 | * </table>
|
---|
481 | */
|
---|
482 | public static void main(String[] args) throws IOException {
|
---|
483 | boolean haltError = false;
|
---|
484 | boolean haltFail = false;
|
---|
485 | boolean stackfilter = true;
|
---|
486 | Properties props = new Properties();
|
---|
487 | boolean showOut = false;
|
---|
488 |
|
---|
489 | if (args.length == 0) {
|
---|
490 | System.err.println("required argument TestClassName missing");
|
---|
491 | System.exit(ERRORS);
|
---|
492 | }
|
---|
493 |
|
---|
494 | if (args[0].startsWith("testsfile=")) {
|
---|
495 | multipleTests = true;
|
---|
496 | args[0] = args[0].substring(10 /* "testsfile=".length() */);
|
---|
497 | }
|
---|
498 |
|
---|
499 | for (int i = 1; i < args.length; i++) {
|
---|
500 | if (args[i].startsWith("haltOnError=")) {
|
---|
501 | haltError = Project.toBoolean(args[i].substring(12));
|
---|
502 | } else if (args[i].startsWith("haltOnFailure=")) {
|
---|
503 | haltFail = Project.toBoolean(args[i].substring(14));
|
---|
504 | } else if (args[i].startsWith("filtertrace=")) {
|
---|
505 | stackfilter = Project.toBoolean(args[i].substring(12));
|
---|
506 | } else if (args[i].startsWith("formatter=")) {
|
---|
507 | try {
|
---|
508 | createAndStoreFormatter(args[i].substring(10));
|
---|
509 | } catch (BuildException be) {
|
---|
510 | System.err.println(be.getMessage());
|
---|
511 | System.exit(ERRORS);
|
---|
512 | }
|
---|
513 | } else if (args[i].startsWith("propsfile=")) {
|
---|
514 | FileInputStream in = new FileInputStream(args[i]
|
---|
515 | .substring(10));
|
---|
516 | props.load(in);
|
---|
517 | in.close();
|
---|
518 | } else if (args[i].startsWith("showoutput=")) {
|
---|
519 | showOut = Project.toBoolean(args[i].substring(11));
|
---|
520 | }
|
---|
521 | }
|
---|
522 |
|
---|
523 | // Add/overlay system properties on the properties from the Ant project
|
---|
524 | Hashtable p = System.getProperties();
|
---|
525 | for (Enumeration e = p.keys(); e.hasMoreElements();) {
|
---|
526 | Object key = e.nextElement();
|
---|
527 | props.put(key, p.get(key));
|
---|
528 | }
|
---|
529 |
|
---|
530 | int returnCode = SUCCESS;
|
---|
531 | if (multipleTests) {
|
---|
532 | try {
|
---|
533 | java.io.BufferedReader reader =
|
---|
534 | new java.io.BufferedReader(new java.io.FileReader(args[0]));
|
---|
535 | String testCaseName;
|
---|
536 | int code = 0;
|
---|
537 | boolean errorOccured = false;
|
---|
538 | boolean failureOccured = false;
|
---|
539 | String line = null;
|
---|
540 | while ((line = reader.readLine()) != null) {
|
---|
541 | StringTokenizer st = new StringTokenizer(line, ",");
|
---|
542 | testCaseName = st.nextToken();
|
---|
543 | JUnitTest t = new JUnitTest(testCaseName);
|
---|
544 | t.setTodir(new File(st.nextToken()));
|
---|
545 | t.setOutfile(st.nextToken());
|
---|
546 | code = launch(t, haltError, stackfilter, haltFail,
|
---|
547 | showOut, props);
|
---|
548 | errorOccured = (code == ERRORS);
|
---|
549 | failureOccured = (code != SUCCESS);
|
---|
550 | if (errorOccured || failureOccured ) {
|
---|
551 | if ((errorOccured && haltError)
|
---|
552 | || (failureOccured && haltFail)) {
|
---|
553 | System.exit(code);
|
---|
554 | } else {
|
---|
555 | if (code > returnCode) {
|
---|
556 | returnCode = code;
|
---|
557 | }
|
---|
558 | System.out.println("TEST " + t.getName()
|
---|
559 | + " FAILED");
|
---|
560 | }
|
---|
561 | }
|
---|
562 | }
|
---|
563 | } catch(IOException e) {
|
---|
564 | e.printStackTrace();
|
---|
565 | }
|
---|
566 | } else {
|
---|
567 | returnCode = launch(new JUnitTest(args[0]), haltError,
|
---|
568 | stackfilter, haltFail, showOut, props);
|
---|
569 | }
|
---|
570 |
|
---|
571 | System.exit(returnCode);
|
---|
572 | }
|
---|
573 |
|
---|
574 | private static Vector fromCmdLine = new Vector();
|
---|
575 |
|
---|
576 | private static void transferFormatters(JUnitTestRunner runner,
|
---|
577 | JUnitTest test) {
|
---|
578 | for (int i = 0; i < fromCmdLine.size(); i++) {
|
---|
579 | FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i);
|
---|
580 | if (multipleTests && fe.getUseFile()) {
|
---|
581 | File destFile =
|
---|
582 | new File(test.getTodir(),
|
---|
583 | test.getOutfile() + fe.getExtension());
|
---|
584 | fe.setOutfile(destFile);
|
---|
585 | }
|
---|
586 | runner.addFormatter(fe.createFormatter());
|
---|
587 | }
|
---|
588 | }
|
---|
589 |
|
---|
590 | /**
|
---|
591 | * Line format is: formatter=<classname>(,<pathname>)?
|
---|
592 | */
|
---|
593 | private static void createAndStoreFormatter(String line)
|
---|
594 | throws BuildException {
|
---|
595 | FormatterElement fe = new FormatterElement();
|
---|
596 | int pos = line.indexOf(',');
|
---|
597 | if (pos == -1) {
|
---|
598 | fe.setClassname(line);
|
---|
599 | fe.setUseFile(false);
|
---|
600 | } else {
|
---|
601 | fe.setClassname(line.substring(0, pos));
|
---|
602 | fe.setUseFile(true);
|
---|
603 | if (!multipleTests) {
|
---|
604 | fe.setOutfile(new File(line.substring(pos + 1)));
|
---|
605 | } else {
|
---|
606 | int fName = line.indexOf(IGNORED_FILE_NAME);
|
---|
607 | if (fName > -1) {
|
---|
608 | fe.setExtension(line
|
---|
609 | .substring(fName
|
---|
610 | + IGNORED_FILE_NAME.length()));
|
---|
611 | }
|
---|
612 | }
|
---|
613 | }
|
---|
614 | fromCmdLine.addElement(fe);
|
---|
615 | }
|
---|
616 |
|
---|
617 | /**
|
---|
618 | * Returns a filtered stack trace.
|
---|
619 | * This is ripped out of junit.runner.BaseTestRunner.
|
---|
620 | */
|
---|
621 | public static String getFilteredTrace(Throwable t) {
|
---|
622 | String trace = StringUtils.getStackTrace(t);
|
---|
623 | return JUnitTestRunner.filterStack(trace);
|
---|
624 | }
|
---|
625 |
|
---|
626 | /**
|
---|
627 | * Filters stack frames from internal JUnit and Ant classes
|
---|
628 | */
|
---|
629 | public static String filterStack(String stack) {
|
---|
630 | if (!filtertrace) {
|
---|
631 | return stack;
|
---|
632 | }
|
---|
633 | StringWriter sw = new StringWriter();
|
---|
634 | PrintWriter pw = new PrintWriter(sw);
|
---|
635 | StringReader sr = new StringReader(stack);
|
---|
636 | BufferedReader br = new BufferedReader(sr);
|
---|
637 |
|
---|
638 | String line;
|
---|
639 | try {
|
---|
640 | while ((line = br.readLine()) != null) {
|
---|
641 | if (!filterLine(line)) {
|
---|
642 | pw.println(line);
|
---|
643 | }
|
---|
644 | }
|
---|
645 | } catch (Exception IOException) {
|
---|
646 | return stack; // return the stack unfiltered
|
---|
647 | }
|
---|
648 | return sw.toString();
|
---|
649 | }
|
---|
650 |
|
---|
651 | private static boolean filterLine(String line) {
|
---|
652 | for (int i = 0; i < DEFAULT_TRACE_FILTERS.length; i++) {
|
---|
653 | if (line.indexOf(DEFAULT_TRACE_FILTERS[i]) > 0) {
|
---|
654 | return true;
|
---|
655 | }
|
---|
656 | }
|
---|
657 | return false;
|
---|
658 | }
|
---|
659 |
|
---|
660 | /**
|
---|
661 | * @since Ant 1.6.2
|
---|
662 | */
|
---|
663 | private static int launch(JUnitTest t, boolean haltError,
|
---|
664 | boolean stackfilter, boolean haltFail,
|
---|
665 | boolean showOut, Properties props) {
|
---|
666 | t.setProperties(props);
|
---|
667 | JUnitTestRunner runner =
|
---|
668 | new JUnitTestRunner(t, haltError, stackfilter, haltFail, showOut);
|
---|
669 | runner.forked = true;
|
---|
670 | transferFormatters(runner, t);
|
---|
671 |
|
---|
672 | runner.run();
|
---|
673 | return runner.getRetCode();
|
---|
674 | }
|
---|
675 | } // JUnitTestRunner
|
---|