Submitted by: Erik Hatcher <erik@hatcher.net> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269314 13f79535-47bb-0310-9956-ffa450edef68master
@@ -68,12 +68,15 @@ import org.apache.tools.ant.types.CommandlineJava; | |||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import org.apache.tools.ant.types.EnumeratedAttribute; | import org.apache.tools.ant.types.EnumeratedAttribute; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.Hashtable; | |||||
import java.util.Properties; | |||||
import java.util.Random; | |||||
import java.util.Vector; | import java.util.Vector; | ||||
/** | /** | ||||
@@ -90,6 +93,7 @@ import java.util.Vector; | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
* @author <a href="mailto:Gerrit.Riessen@web.de">Gerrit Riessen</a> - | * @author <a href="mailto:Gerrit.Riessen@web.de">Gerrit Riessen</a> - | ||||
* @author <a href="mailto:erik@hatcher.net">Erik Hatcher</a> | |||||
*/ | */ | ||||
public class JUnitTask extends Task { | public class JUnitTask extends Task { | ||||
@@ -363,6 +367,23 @@ public class JUnitTask extends Task { | |||||
formatterArg.setLength(0); | 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 execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), watchdog); | ||||
execute.setCommandline(cmd.getCommandline()); | execute.setCommandline(cmd.getCommandline()); | ||||
if (dir != null) { | if (dir != null) { | ||||
@@ -371,11 +392,16 @@ public class JUnitTask extends Task { | |||||
} | } | ||||
log("Executing: "+cmd.toString(), Project.MSG_VERBOSE); | log("Executing: "+cmd.toString(), Project.MSG_VERBOSE); | ||||
int retVal; | |||||
try { | try { | ||||
return execute.execute(); | |||||
retVal = execute.execute(); | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new BuildException("Process fork failed.", e, location); | 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 | // in VM is not very nice since it could probably hang the | ||||
@@ -386,6 +412,7 @@ public class JUnitTask extends Task { | |||||
* Execute inside VM. | * Execute inside VM. | ||||
*/ | */ | ||||
private int executeInVM(JUnitTest test) throws BuildException { | private int executeInVM(JUnitTest test) throws BuildException { | ||||
test.setProperties(project.getProperties()); | |||||
if (dir != null) { | if (dir != null) { | ||||
log("dir attribute ignored if running in the same VM", Project.MSG_WARN); | log("dir attribute ignored if running in the same VM", Project.MSG_WARN); | ||||
} | } | ||||
@@ -58,6 +58,9 @@ import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
import java.io.File; | import java.io.File; | ||||
import java.util.Enumeration; | |||||
import java.util.Hashtable; | |||||
import java.util.Properties; | |||||
import java.util.Vector; | import java.util.Vector; | ||||
/** | /** | ||||
@@ -80,6 +83,9 @@ public class JUnitTest extends BaseTest { | |||||
private long runs, failures, errors; | private long runs, failures, errors; | ||||
private long runTime; | private long runTime; | ||||
// Snapshot of the system properties | |||||
private Properties props = null; | |||||
public JUnitTest() { | public JUnitTest() { | ||||
} | } | ||||
@@ -127,6 +133,15 @@ public class JUnitTest extends BaseTest { | |||||
public long errorCount() {return errors;} | public long errorCount() {return errors;} | ||||
public long getRunTime() {return runTime;} | 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) { | public boolean shouldRun(Project p) { | ||||
if (ifProperty != null && p.getProperty(ifProperty) == null) { | if (ifProperty != null && p.getProperty(ifProperty) == null) { | ||||
return false; | return false; | ||||
@@ -134,6 +149,7 @@ public class JUnitTest extends BaseTest { | |||||
p.getProperty(unlessProperty) != null) { | p.getProperty(unlessProperty) != null) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
@@ -59,6 +59,9 @@ import org.apache.tools.ant.*; | |||||
import junit.framework.*; | import junit.framework.*; | ||||
import java.lang.reflect.*; | import java.lang.reflect.*; | ||||
import java.io.*; | import java.io.*; | ||||
import java.util.Enumeration; | |||||
import java.util.Hashtable; | |||||
import java.util.Properties; | |||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
@@ -75,6 +78,7 @@ import java.util.Vector; | |||||
* <p>Summary output is generated at the end. | * <p>Summary output is generated at the end. | ||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @author <a href="mailto:erik@hatcher.net">Erik Hatcher</a> | |||||
*/ | */ | ||||
public class JUnitTestRunner implements TestListener { | public class JUnitTestRunner implements TestListener { | ||||
@@ -346,6 +350,7 @@ public class JUnitTestRunner implements TestListener { | |||||
boolean exitAtEnd = true; | boolean exitAtEnd = true; | ||||
boolean haltError = false; | boolean haltError = false; | ||||
boolean haltFail = false; | boolean haltFail = false; | ||||
Properties props = new Properties(); | |||||
if (args.length == 0) { | if (args.length == 0) { | ||||
System.err.println("required argument TestClassName missing"); | System.err.println("required argument TestClassName missing"); | ||||
@@ -364,10 +369,23 @@ public class JUnitTestRunner implements TestListener { | |||||
System.err.println(be.getMessage()); | System.err.println(be.getMessage()); | ||||
System.exit(ERRORS); | 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]); | 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); | JUnitTestRunner runner = new JUnitTestRunner(t, haltError, haltFail); | ||||
transferFormatters(runner); | transferFormatters(runner); | ||||
runner.run(); | runner.run(); | ||||
@@ -89,7 +89,7 @@ public interface XMLConstants { | |||||
/** package attribute for the aggregate document */ | /** package attribute for the aggregate document */ | ||||
public final static String ATTR_PACKAGE = "package"; | 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"; | public final static String ATTR_NAME = "name"; | ||||
/** time attribute for testcase and testsuite elements */ | /** time attribute for testcase and testsuite elements */ | ||||
@@ -109,4 +109,14 @@ public interface XMLConstants { | |||||
/** message attribute for failure elements */ | /** message attribute for failure elements */ | ||||
public final static String ATTR_MESSAGE = "message"; | 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"; | |||||
} | } |
@@ -72,6 +72,7 @@ import junit.framework.TestCase; | |||||
* Prints XML output of the test to a specified Writer. | * Prints XML output of the test to a specified Writer. | ||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @author <a href="mailto:erik@hatcher.net">Erik Hatcher</a> | |||||
*/ | */ | ||||
public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants { | public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants { | ||||
@@ -132,6 +133,21 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan | |||||
doc = getDocumentBuilder().newDocument(); | doc = getDocumentBuilder().newDocument(); | ||||
rootElement = doc.createElement(TESTSUITE); | rootElement = doc.createElement(TESTSUITE); | ||||
rootElement.setAttribute(ATTR_NAME, suite.getName()); | 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); | |||||
} | |||||
} | |||||
} | } | ||||
/** | /** | ||||