bodewig     2004/04/15 06:53:47

  Modified:    .        CONTRIBUTORS build.xml
               src/main/org/apache/tools/ant/taskdefs/optional/junit
                        FormatterElement.java JUnitTask.java
                        JUnitTestRunner.java
  Log:
  Add forkStyle attribute to <junit> with possible values of once,
  perTest and perBatch.
  
  once will create a single Java VM for all forked tests, perTest is
  what we have traditionally (and the default), perBatch uses a VM per
  <batchtest>.
  
  Actually, this is not entirely true since only tests with the same
  configuration of filtetrace and haltonfailure and friends can run
  inside the same VM, so we may end up with mutliple VMs anyway - but
  once really should be a lot faster than perTest in general.
  
  Based on
  
  PR: 24697
  Submitted by: Anton <anton at atlassian dot com>
  
  Revision  Changes    Path
  1.13      +2 -0      ant/CONTRIBUTORS
  
  Index: CONTRIBUTORS
  ===================================================================
  RCS file: /home/cvs/ant/CONTRIBUTORS,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- CONTRIBUTORS      14 Apr 2004 15:33:31 -0000      1.12
  +++ CONTRIBUTORS      15 Apr 2004 13:53:47 -0000      1.13
  @@ -63,6 +63,7 @@
   Glenn Twiggs
   Greg Nelson
   Harish Prabandham
  +Haroon Rafique
   Hiroaki Nakamura
   Holger Engels
   Ingenonsya France
  @@ -165,6 +166,7 @@
   Russell Gold
   Sam Ruby
   Scott Carlson
  +Scott M. Stirling
   Sean Egan
   Sean P. Kane
   Shiraz Kanga
  
  
  
  1.416     +2 -1      ant/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/ant/build.xml,v
  retrieving revision 1.415
  retrieving revision 1.416
  diff -u -r1.415 -r1.416
  --- build.xml 26 Mar 2004 13:08:11 -0000      1.415
  +++ build.xml 15 Apr 2004 13:53:47 -0000      1.416
  @@ -53,6 +53,7 @@
     <property name="junit.filtertrace" value="off"/>
     <property name="junit.summary" value="no"/>
     <property name="test.haltonfailure" value="yes" />
  +  <property name="junit.forkstyle" value="once"/>
     <property name="unfiltered.files" 
value="**/*.gif,**/*.jpg,**/*.ico,**/*.pdf,**/*.zip"/>
   
     <!--
  @@ -1428,7 +1429,7 @@
   
       <junit printsummary="${junit.summary}" 
haltonfailure="${test.haltonfailure}"
              filtertrace="${junit.filtertrace}"
  -           fork="${junit.fork}"
  +           fork="${junit.fork}" forkstyle="${junit.forkstyle}"
              failureproperty="tests.failed">
   <!--      <jvmarg value="-classic"/> -->
         <classpath refid="tests-classpath"/>
  
  
  
  1.22      +17 -5     
ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
  
  Index: FormatterElement.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- FormatterElement.java     9 Mar 2004 16:48:31 -0000       1.21
  +++ FormatterElement.java     15 Apr 2004 13:53:47 -0000      1.22
  @@ -56,6 +56,13 @@
       private String ifProperty;
       private String unlessProperty;
   
  +    public static final String XML_FORMATTER_CLASS_NAME =
  +        
"org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter";
  +    public static final String BRIEF_FORMATTER_CLASS_NAME =
  +        
"org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter";
  +    public static final String PLAIN_FORMATTER_CLASS_NAME =
  +        
"org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
  +
       /**
        * <p> Quick way to use a standard formatter.
        *
  @@ -71,15 +78,13 @@
        */
       public void setType(TypeAttribute type) {
           if ("xml".equals(type.getValue())) {
  -            
setClassname("org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter");
  -            setExtension(".xml");
  +            setClassname(XML_FORMATTER_CLASS_NAME);
           } else {
               if ("brief".equals(type.getValue())) {
  -                
setClassname("org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter");
  +                setClassname(BRIEF_FORMATTER_CLASS_NAME);
               } else { // must be plain, ensured by TypeAttribute
  -                
setClassname("org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter");
  +                setClassname(PLAIN_FORMATTER_CLASS_NAME);
               }
  -            setExtension(".txt");
           }
       }
   
  @@ -90,6 +95,13 @@
        */
       public void setClassname(String classname) {
           this.classname = classname;
  +        if (XML_FORMATTER_CLASS_NAME.equals(classname)) {
  +           setExtension(".xml");
  +        } else if (PLAIN_FORMATTER_CLASS_NAME.equals(classname)) {
  +           setExtension(".txt");
  +        } else if (BRIEF_FORMATTER_CLASS_NAME.equals(classname)) {
  +           setExtension(".txt");
  +        }
       }
   
       /**
  
  
  
  1.95      +269 -33   
ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  
  Index: JUnitTask.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java,v
  retrieving revision 1.94
  retrieving revision 1.95
  diff -u -r1.94 -r1.95
  --- JUnitTask.java    9 Mar 2004 16:48:31 -0000       1.94
  +++ JUnitTask.java    15 Apr 2004 13:53:47 -0000      1.95
  @@ -17,12 +17,21 @@
   
   package org.apache.tools.ant.taskdefs.optional.junit;
   
  +import java.io.BufferedWriter;
   import java.io.File;
   import java.io.FileOutputStream;
  +import java.io.FileWriter;
   import java.io.IOException;
   import java.io.OutputStream;
  +import java.io.PrintWriter;
  +import java.util.ArrayList;
  +import java.util.Collection;
   import java.util.Enumeration;
  +import java.util.HashMap;
   import java.util.Hashtable;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.Map;
   import java.util.Properties;
   import java.util.Vector;
   import org.apache.tools.ant.AntClassLoader;
  @@ -138,13 +147,15 @@
       private File tmpDir;
       private AntClassLoader classLoader = null;
       private Permissions perm = null;
  +    private ForkStyle forkStyle = new ForkStyle("perTest");
   
       private static final int STRING_BUFFER_SIZE = 128;
  +
       /**
  -    * If true, force ant to re-classload all classes for each JUnit TestCase
  -    *
  -    * @param value force class reloading for each test case
  -    */
  +     * If true, force ant to re-classload all classes for each JUnit TestCase
  +     *
  +     * @param value force class reloading for each test case
  +     */
       public void setReloading(boolean value) {
           reloading = value;
       }
  @@ -266,6 +277,29 @@
       }
   
       /**
  +     * Set the bahvior when [EMAIL PROTECTED] #setFork fork} fork has been 
enabled.
  +     *
  +     * <p>Possible values are "once", "perTest" and "perBatch".  If
  +     * set to "once", only a single Java VM will be forked for all
  +     * tests, with "perTest" (the default) each test will run in a
  +     * fresh Java VM and "perBatch" will run all tests from the same
  +     * &lt;batchtest&gt; in the same Java VM.</p>
  +     *
  +     * <p>This attribute will be ignored if tests run in the same VM
  +     * as Ant.</p>
  +     *
  +     * <p>Only tests with the same configuration of haltonerror,
  +     * haltonfailure, errorproperty, failureproperty and filtertrace
  +     * can share a forked Java VM, so even if you set the value to
  +     * "once", Ant may need to fork mutliple VMs.</p>
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void setForkStyle(ForkStyle style) {
  +        this.forkStyle = style;
  +    }
  +
  +    /**
        * If true, print one-line statistics for each test, or "withOutAndErr"
        * to also show standard output and error.
        *
  @@ -599,12 +633,29 @@
        * @since Ant 1.2
        */
       public void execute() throws BuildException {
  -        Enumeration list = getIndividualTests();
  -        while (list.hasMoreElements()) {
  -            JUnitTest test = (JUnitTest) list.nextElement();
  -            if (test.shouldRun(getProject())) {
  -                execute(test);
  +        List testLists = new ArrayList();
  +
  +        boolean forkPerTest = 
forkStyle.getValue().equals(ForkStyle.PER_TEST);
  +        if (forkPerTest || forkStyle.getValue().equals(ForkStyle.ONCE)) {
  +            testLists.addAll(executeOrQueue(getIndividualTests(),
  +                                            forkPerTest));
  +        } else { /* forkStyle.getValue().equals(ForkStyle.PER_BATCH) */
  +            final int count = batchTests.size();
  +            for (int i = 0; i < count; i++) {
  +                BatchTest batchtest = (BatchTest) batchTests.elementAt(i);
  +                testLists.addAll(executeOrQueue(batchtest.elements(), 
false));
               }
  +            testLists.addAll(executeOrQueue(tests.elements(), forkPerTest));
  +        }
  +
  +        Iterator iter = testLists.iterator();
  +        while (iter.hasNext()) {
  +            List l = (List) iter.next();
  +            if (l.size() == 1) {
  +                execute((JUnitTest) l.get(0));
  +            } else {
  +                execute(l);
  +            }            
           }
       }
   
  @@ -632,34 +683,75 @@
               exitValue = executeInVM(test);
           } else {
               ExecuteWatchdog watchdog = createWatchdog();
  -            exitValue = executeAsForked(test, watchdog);
  +            exitValue = executeAsForked(test, watchdog, null);
               // null watchdog means no timeout, you'd better not check with 
null
               if (watchdog != null) {
                   wasKilled = watchdog.killedProcess();
               }
           }
  +        actOnTestResult(exitValue, wasKilled, test, "Test " + 
test.getName());
  +    }
   
  -        // if there is an error/failure and that it should halt, stop
  -        // everything otherwise just log a statement
  -        boolean errorOccurredHere =
  -            exitValue == JUnitTestRunner.ERRORS || wasKilled;
  -        boolean failureOccurredHere =
  -            exitValue != JUnitTestRunner.SUCCESS || wasKilled;
  -        if (errorOccurredHere || failureOccurredHere) {
  -            if ((errorOccurredHere && test.getHaltonerror())
  -                || (failureOccurredHere && test.getHaltonfailure())) {
  -                throw new BuildException("Test " + test.getName() + " failed"
  -                    + (wasKilled ? " (timeout)" : ""), getLocation());
  -            } else {
  -                log("TEST " + test.getName() + " FAILED"
  -                    + (wasKilled ? " (timeout)" : ""), Project.MSG_ERR);
  -                if (errorOccurredHere && test.getErrorProperty() != null) {
  -                    getProject().setNewProperty(test.getErrorProperty(), 
"true");
  +    /**
  +     * Execute a list of tests in a single forked Java VM.
  +     */
  +    protected void execute(List tests) throws BuildException {
  +        JUnitTest test = null;
  +        // Create a temporary file to pass the test cases to run to 
  +        // the runner (one test case per line)
  +        File casesFile = 
  +            FileUtils.newFileUtils().createTempFile("junittestcases", 
  +                                                    ".properties",
  +                                                    
getProject().getBaseDir());
  +        casesFile.deleteOnExit();
  +        PrintWriter writer = null;
  +        try {
  +            writer = 
  +                new PrintWriter(new BufferedWriter(new 
FileWriter(casesFile)));
  +            Iterator iter = tests.iterator();
  +            while (iter.hasNext()) {
  +                test = (JUnitTest) iter.next();
  +                writer.print(test.getName()); 
  +                if (test.getTodir() == null) {
  +                    writer.print("," + getProject().resolveFile("."));
  +                } else {
  +                    writer.print("," + test.getTodir());
                   }
  -                if (failureOccurredHere && test.getFailureProperty() != 
null) {
  -                    getProject().setNewProperty(test.getFailureProperty(), 
"true");
  +
  +                if (test.getOutfile() == null) {
  +                    writer.println("," + "TEST-" + test.getName());
  +                } else {
  +                    writer.println("," + test.getOutfile());
                   }
               }
  +            writer.flush();
  +            writer.close();
  +            writer = null;
  +
  +            // execute the test and get the return code
  +            int exitValue = JUnitTestRunner.ERRORS;
  +            boolean wasKilled = false;
  +            ExecuteWatchdog watchdog = createWatchdog();
  +            exitValue = executeAsForked(test, watchdog, casesFile);
  +            // null watchdog means no timeout, you'd better not check
  +            // with null
  +            if (watchdog != null) {
  +                wasKilled = watchdog.killedProcess();
  +            }
  +            actOnTestResult(exitValue, wasKilled, test, "Tests");
  +        } catch(IOException e) {
  +            log(e.toString(), Project.MSG_ERR);
  +            throw new BuildException(e);
  +        } finally {
  +            if (writer != null) {
  +                writer.close();
  +            }
  +            
  +            try {
  +                casesFile.delete();
  +            } catch (Exception e) {
  +                log(e.toString(), Project.MSG_ERR);
  +            }
           }
       }
   
  @@ -674,17 +766,25 @@
        * @throws BuildException in case of error creating a temporary property 
file,
        * or if the junit process can not be forked
        */
  -    private int executeAsForked(JUnitTest test, ExecuteWatchdog watchdog)
  +    private int executeAsForked(JUnitTest test, ExecuteWatchdog watchdog, 
  +                                File casesFile)
           throws BuildException {
   
  -        if(perm != null) {
  -            log("Permissions ignored when running in forked mode!", 
Project.MSG_WARN);
  +        if (perm != null) {
  +            log("Permissions ignored when running in forked mode!",
  +                Project.MSG_WARN);
           }
   
           CommandlineJava cmd = (CommandlineJava) getCommandline().clone();
   
           
cmd.setClassname("org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner");
  -        cmd.createArgument().setValue(test.getName());
  +        if (casesFile == null) {
  +            cmd.createArgument().setValue(test.getName());
  +        } else {
  +            log("Running multiple tests in the same VM", 
Project.MSG_VERBOSE);
  +            cmd.createArgument().setValue("testsfile=" + casesFile);
  +        }
  +        
           cmd.createArgument().setValue("filtertrace=" + 
test.getFiltertrace());
           cmd.createArgument().setValue("haltOnError=" + 
test.getHaltonerror());
           cmd.createArgument().setValue("haltOnFailure="
  @@ -1179,4 +1279,140 @@
           }
           return commandline;
       }
  +
  +    /**
  +     * @since Ant 1.6.2
  +     */
  +    private final class ForkedTestConfiguration {
  +        private boolean filterTrace;
  +        private boolean haltOnError;
  +        private boolean haltOnFailure;
  +        private String errorProperty;
  +        private String failureProperty;
  +        ForkedTestConfiguration(boolean filterTrace, boolean haltOnError,
  +                                boolean haltOnFailure, String errorProperty,
  +                                String failureProperty) {
  +            this.filterTrace = filterTrace;
  +            this.haltOnError = haltOnError;
  +            this.haltOnFailure = haltOnFailure;
  +            this.errorProperty = errorProperty;
  +            this.failureProperty = failureProperty;
  +        }
  +
  +        public boolean equals(Object other) {
  +            if (other == null 
  +                || other.getClass() != ForkedTestConfiguration.class) {
  +                return false;
  +            }
  +            ForkedTestConfiguration o = (ForkedTestConfiguration) other;
  +            return filterTrace == o.filterTrace 
  +                && haltOnError == o.haltOnError
  +                && haltOnFailure == o.haltOnFailure
  +                && ((errorProperty == null && o.errorProperty == null)
  +                    || 
  +                    (errorProperty != null 
  +                     && errorProperty.equals(o.errorProperty)))
  +                && ((failureProperty == null && o.failureProperty == null)
  +                    || 
  +                    (failureProperty != null 
  +                     && failureProperty.equals(o.failureProperty)));
  +        }
  +
  +        public int hashCode() {
  +            return (filterTrace ? 1 : 0) 
  +                + (haltOnError ? 2 : 0)
  +                + (haltOnFailure ? 4 : 0);
  +        }
  +    }
  +
  +    /**
  +     * @since 1.6.2
  +     */
  +    public static final class ForkStyle extends EnumeratedAttribute {
  +        public static final String ONCE = "once";
  +        public static final String PER_TEST = "perTest";
  +        public static final String PER_BATCH = "perBatch";
  +
  +        public ForkStyle() {
  +            super();
  +        }
  +
  +        public ForkStyle(String value) {
  +            super();
  +            setValue(value);
  +        }
  +
  +        public String[] getValues() {
  +            return new String[] {ONCE, PER_TEST, PER_BATCH};
  +        }
  +    }
  +
  +    /**
  +     * Executes all tests that don't need to be forked (or all tests
  +     * if the runIndividual argument is true.  Returns a collection of
  +     * lists of tests that share the same VM configuration and haven't
  +     * been executed yet.
  +     *
  +     * @since 1.6.2
  +     */
  +    protected Collection executeOrQueue(Enumeration testList,
  +                                        boolean runIndividual) {
  +        Map testConfigurations = new HashMap();
  +        while (testList.hasMoreElements()) {
  +            JUnitTest test = (JUnitTest) testList.nextElement();
  +            if (test.shouldRun(getProject())) {
  +                if (runIndividual || !test.getFork()) {
  +                    execute(test);
  +                } else {
  +                    ForkedTestConfiguration c =
  +                        new ForkedTestConfiguration(test.getFiltertrace(),
  +                                                    test.getHaltonerror(),
  +                                                    test.getHaltonfailure(),
  +                                                    test.getErrorProperty(),
  +                                                    
test.getFailureProperty());
  +                    List l = (List) testConfigurations.get(c);
  +                    if (l == null) {
  +                        l = new ArrayList();
  +                        testConfigurations.put(c, l);
  +                    }
  +                    l.add(test);
  +                }
  +            }
  +        }
  +        return testConfigurations.values();
  +    }
  +
  +    /**
  +     * Logs information about failed tests, potentially stops
  +     * processing (by throwing a BuildException) if a failure/error
  +     * occured or sets a property.
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    protected void actOnTestResult(int exitValue, boolean wasKilled,
  +                                   JUnitTest test, String name) {
  +        // if there is an error/failure and that it should halt, stop
  +        // everything otherwise just log a statement
  +        boolean errorOccurredHere =
  +            exitValue == JUnitTestRunner.ERRORS || wasKilled;
  +        boolean failureOccurredHere =
  +            exitValue != JUnitTestRunner.SUCCESS || wasKilled;
  +        if (errorOccurredHere || failureOccurredHere) {
  +            if ((errorOccurredHere && test.getHaltonerror())
  +                || (failureOccurredHere && test.getHaltonfailure())) {
  +                throw new BuildException(name + " failed"
  +                    + (wasKilled ? " (timeout)" : ""), getLocation());
  +            } else {
  +                log(name + " FAILED"
  +                    + (wasKilled ? " (timeout)" : ""), Project.MSG_ERR);
  +                if (errorOccurredHere && test.getErrorProperty() != null) {
  +                    getProject().setNewProperty(test.getErrorProperty(), 
"true");
  +                }
  +                if (failureOccurredHere && test.getFailureProperty() != 
null) {
  +                    getProject().setNewProperty(test.getFailureProperty(), 
"true");
  +                }
  +            }
  +        }
  +    }
  +
   }
  
  
  
  1.48      +82 -15    
ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  
  Index: JUnitTestRunner.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- JUnitTestRunner.java      9 Mar 2004 16:48:31 -0000       1.47
  +++ JUnitTestRunner.java      15 Apr 2004 13:53:47 -0000      1.48
  @@ -30,6 +30,7 @@
   import java.util.Enumeration;
   import java.util.Hashtable;
   import java.util.Properties;
  +import java.util.StringTokenizer;
   import java.util.Vector;
   import junit.framework.AssertionFailedError;
   import junit.framework.Test;
  @@ -154,6 +155,9 @@
       /** is this runner running in forked mode? */
       private boolean forked = false;
   
  +    /** Running more than one test suite? */
  +    private static boolean multipleTests = false;
  +
       /**
        * Constructor for fork=true or when the user hasn't specified a
        * classpath.
  @@ -478,6 +482,11 @@
               System.exit(ERRORS);
           }
   
  +        if (args[0].startsWith("testsfile=")) {
  +            multipleTests = true;
  +            args[0] = args[0].substring(10 /* "testsfile=".length() */);
  +        }
  +
           for (int i = 1; i < args.length; i++) {
               if (args[i].startsWith("haltOnError=")) {
                   haltError = Project.toBoolean(args[i].substring(12));
  @@ -502,30 +511,70 @@
               }
           }
   
  -        JUnitTest t = new JUnitTest(args[0]);
  -
           // Add/overlay system properties on the properties from the Ant 
project
           Hashtable p = System.getProperties();
           for (Enumeration e = p.keys(); e.hasMoreElements();) {
               Object key = e.nextElement();
               props.put(key, p.get(key));
           }
  -        t.setProperties(props);
   
  -        JUnitTestRunner runner = new JUnitTestRunner(t, haltError, 
stackfilter,
  -                                                     haltFail, showOut);
  -        runner.forked = true;
  -        transferFormatters(runner);
  -        runner.run();
  -        System.exit(runner.getRetCode());
  +        int returnCode = SUCCESS;
  +        if (multipleTests) {
  +            try {
  +                java.io.BufferedReader reader = 
  +                    new java.io.BufferedReader(new 
java.io.FileReader(args[0]));
  +                String testCaseName;
  +                int code = 0;
  +                boolean errorOccured = false;
  +                boolean failureOccured = false;
  +                String line = null;
  +                while ((line = reader.readLine()) != null) {
  +                    StringTokenizer st = new StringTokenizer(line, ",");
  +                    testCaseName = st.nextToken();
  +                    JUnitTest t = new JUnitTest(testCaseName);
  +                    t.setTodir(new File(st.nextToken()));
  +                    t.setOutfile(st.nextToken());
  +                    code = launch(t, haltError, stackfilter, haltFail, 
  +                                  showOut, props);
  +                    errorOccured = (code == ERRORS);
  +                    failureOccured = (code != SUCCESS);
  +                    if (errorOccured || failureOccured ) {
  +                        if ((errorOccured && haltError) 
  +                            || (failureOccured && haltFail)) {
  +                            System.exit(code);
  +                        } else {
  +                            if (code > returnCode) {
  +                                returnCode = code;
  +                            }
  +                            System.out.println("TEST " + t.getName() 
  +                                               + " FAILED");
  +                        }
  +                    }
  +                }
  +            } catch(IOException e) {
  +                e.printStackTrace();
  +            }
  +        } else {
  +            returnCode = launch(new JUnitTest(args[0]), haltError,
  +                                stackfilter, haltFail, showOut, props);
  +        }
  +
  +        System.exit(returnCode);
       }
   
       private static Vector fromCmdLine = new Vector();
   
  -    private static void transferFormatters(JUnitTestRunner runner) {
  +    private static void transferFormatters(JUnitTestRunner runner,
  +                                           JUnitTest test) {
           for (int i = 0; i < fromCmdLine.size(); i++) {
  -            runner.addFormatter((JUnitResultFormatter) fromCmdLine
  -                                .elementAt(i));
  +            FormatterElement fe = (FormatterElement) 
fromCmdLine.elementAt(i);
  +            if (multipleTests && fe.getUseFile()) {
  +                File destFile = 
  +                    new File(test.getTodir(), 
  +                             test.getOutfile() + fe.getExtension());
  +                fe.setOutfile(destFile);
  +            }
  +            runner.addFormatter(fe.createFormatter());
           }
       }
   
  @@ -538,17 +587,20 @@
           int pos = line.indexOf(',');
           if (pos == -1) {
               fe.setClassname(line);
  +            fe.setUseFile(false);
           } else {
               fe.setClassname(line.substring(0, pos));
  -            fe.setOutfile(new File(line.substring(pos + 1)));
  +            fe.setUseFile(true);
  +            if (!multipleTests) {
  +                fe.setOutfile(new File(line.substring(pos + 1)));
  +            }
           }
  -        fromCmdLine.addElement(fe.createFormatter());
  +        fromCmdLine.addElement(fe);
       }
   
       /**
        * Returns a filtered stack trace.
        * This is ripped out of junit.runner.BaseTestRunner.
  -     * Scott M. Stirling.
        */
       public static String getFilteredTrace(Throwable t) {
           String trace = StringUtils.getStackTrace(t);
  @@ -589,4 +641,19 @@
           return false;
       }
   
  +    /**
  +     * @since Ant 1.6.2
  +     */
  +    private static int launch(JUnitTest t, boolean haltError,
  +                              boolean stackfilter, boolean haltFail, 
  +                              boolean showOut, Properties props) {
  +        t.setProperties(props);
  +        JUnitTestRunner runner = 
  +            new JUnitTestRunner(t, haltError, stackfilter, haltFail, 
showOut);
  +        runner.forked = true;
  +        transferFormatters(runner, t);
  +
  +        runner.run();
  +        return runner.getRetCode();
  +     }
   } // JUnitTestRunner
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to