diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java index 1441bd34f..30773fdcd 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java @@ -68,12 +68,15 @@ import org.apache.tools.ant.types.CommandlineJava; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.EnumeratedAttribute; - import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Random; import java.util.Vector; /** @@ -90,6 +93,7 @@ import java.util.Vector; * @author Stefan Bodewig * @author Stephane Bailliez * @author Gerrit Riessen - + * @author Erik Hatcher */ public class JUnitTask extends Task { @@ -363,6 +367,23 @@ public class JUnitTask extends Task { formatterArg.setLength(0); } + // Create a temporary file to pass the Ant properties to the forked test + File propsFile = new File("junit" + (new Random(System.currentTimeMillis())).nextLong() + ".properties"); + cmd.createArgument().setValue("propsfile=" + propsFile.getAbsolutePath()); + Hashtable p = project.getProperties(); + Properties props = new Properties(); + for (Enumeration enum = p.keys(); enum.hasMoreElements(); ) { + Object key = enum.nextElement(); + props.put(key, p.get(key)); + } + try { + FileOutputStream outstream = new FileOutputStream(propsFile); + props.save(outstream,"Ant JUnitTask generated properties file"); + outstream.close(); + } catch (java.io.IOException e) { + throw new BuildException("Error creating temporary properties file.", e, location); + } + Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), watchdog); execute.setCommandline(cmd.getCommandline()); if (dir != null) { @@ -371,11 +392,16 @@ public class JUnitTask extends Task { } log("Executing: "+cmd.toString(), Project.MSG_VERBOSE); + int retVal; try { - return execute.execute(); + retVal = execute.execute(); } catch (IOException e) { throw new BuildException("Process fork failed.", e, location); + } finally { + if (! propsFile.delete()) throw new BuildException("Could not delete temporary properties file."); } + + return retVal; } // in VM is not very nice since it could probably hang the @@ -386,6 +412,7 @@ public class JUnitTask extends Task { * Execute inside VM. */ private int executeInVM(JUnitTest test) throws BuildException { + test.setProperties(project.getProperties()); if (dir != null) { log("dir attribute ignored if running in the same VM", Project.MSG_WARN); } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java index e568f8ec2..a7a17294a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java @@ -58,6 +58,9 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Commandline; import java.io.File; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; import java.util.Vector; /** @@ -80,6 +83,9 @@ public class JUnitTest extends BaseTest { private long runs, failures, errors; private long runTime; + // Snapshot of the system properties + private Properties props = null; + public JUnitTest() { } @@ -127,6 +133,15 @@ public class JUnitTest extends BaseTest { public long errorCount() {return errors;} public long getRunTime() {return runTime;} + public Properties getProperties() { return props;} + public void setProperties(Hashtable p) { + props = new Properties(); + for (Enumeration enum = p.keys(); enum.hasMoreElements(); ) { + Object key = enum.nextElement(); + props.put(key, p.get(key)); + } + } + public boolean shouldRun(Project p) { if (ifProperty != null && p.getProperty(ifProperty) == null) { return false; @@ -134,6 +149,7 @@ public class JUnitTest extends BaseTest { p.getProperty(unlessProperty) != null) { return false; } + return true; } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java index aa6d2b2a9..fd0f52c31 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java @@ -59,6 +59,9 @@ import org.apache.tools.ant.*; import junit.framework.*; import java.lang.reflect.*; import java.io.*; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; @@ -75,6 +78,7 @@ import java.util.Vector; *
Summary output is generated at the end. * * @author Stefan Bodewig + * @author Erik Hatcher */ public class JUnitTestRunner implements TestListener { @@ -346,6 +350,7 @@ public class JUnitTestRunner implements TestListener { boolean exitAtEnd = true; boolean haltError = false; boolean haltFail = false; + Properties props = new Properties(); if (args.length == 0) { System.err.println("required argument TestClassName missing"); @@ -364,10 +369,23 @@ public class JUnitTestRunner implements TestListener { System.err.println(be.getMessage()); System.exit(ERRORS); } + } else if (args[i].startsWith("propsfile=")) { + FileInputStream in = new FileInputStream(args[i].substring(10)); + props.load(in); + in.close(); } } JUnitTest t = new JUnitTest(args[0]); + + // Add/overlay system properties on the properties from the Ant project + Hashtable p = System.getProperties(); + for (Enumeration enum = p.keys(); enum.hasMoreElements(); ) { + Object key = enum.nextElement(); + props.put(key, p.get(key)); + } + t.setProperties(props); + JUnitTestRunner runner = new JUnitTestRunner(t, haltError, haltFail); transferFormatters(runner); runner.run(); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java index 07f930fbc..303968b21 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java @@ -89,7 +89,7 @@ public interface XMLConstants { /** package attribute for the aggregate document */ public final static String ATTR_PACKAGE = "package"; - /** name attribute for testcase and testsuite elements */ + /** name attribute for property, testcase and testsuite elements */ public final static String ATTR_NAME = "name"; /** time attribute for testcase and testsuite elements */ @@ -109,4 +109,14 @@ public interface XMLConstants { /** message attribute for failure elements */ public final static String ATTR_MESSAGE = "message"; + + /** the properties element */ + public final static String PROPERTIES = "properties"; + + /** the property element */ + public final static String PROPERTY = "property"; + + /** value attribute for property elements */ + public final static String ATTR_VALUE = "value"; + } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java index 0291246c5..3159c10de 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java @@ -72,6 +72,7 @@ import junit.framework.TestCase; * Prints XML output of the test to a specified Writer. * * @author Stefan Bodewig + * @author Erik Hatcher */ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants { @@ -132,6 +133,21 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan doc = getDocumentBuilder().newDocument(); rootElement = doc.createElement(TESTSUITE); rootElement.setAttribute(ATTR_NAME, suite.getName()); + + // Output properties + Element propsElement = doc.createElement(PROPERTIES); + rootElement.appendChild(propsElement); + Properties props = suite.getProperties(); + if (props != null) { + Enumeration e = props.propertyNames(); + while (e.hasMoreElements()) { + String name = (String) e.nextElement(); + Element propElement = doc.createElement(PROPERTY); + propElement.setAttribute(ATTR_NAME, name); + propElement.setAttribute(ATTR_VALUE, props.getProperty(name)); + propsElement.appendChild(propElement); + } + } } /**