git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@420194 13f79535-47bb-0310-9956-ffa450edef68master
@@ -17,9 +17,11 @@ | |||||
package org.apache.tools.ant.taskdefs.optional.junit; | package org.apache.tools.ant.taskdefs.optional.junit; | ||||
import java.io.BufferedReader; | |||||
import java.io.BufferedWriter; | import java.io.BufferedWriter; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
import java.io.FileReader; | |||||
import java.io.FileWriter; | import java.io.FileWriter; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
@@ -35,6 +37,7 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import org.apache.tools.ant.AntClassLoader; | import org.apache.tools.ant.AntClassLoader; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
@@ -42,6 +45,7 @@ import org.apache.tools.ant.Task; | |||||
import org.apache.tools.ant.taskdefs.Execute; | import org.apache.tools.ant.taskdefs.Execute; | ||||
import org.apache.tools.ant.taskdefs.ExecuteWatchdog; | import org.apache.tools.ant.taskdefs.ExecuteWatchdog; | ||||
import org.apache.tools.ant.taskdefs.LogOutputStream; | import org.apache.tools.ant.taskdefs.LogOutputStream; | ||||
import org.apache.tools.ant.taskdefs.PumpStreamHandler; | |||||
import org.apache.tools.ant.types.Assertions; | import org.apache.tools.ant.types.Assertions; | ||||
import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
import org.apache.tools.ant.types.CommandlineJava; | import org.apache.tools.ant.types.CommandlineJava; | ||||
@@ -52,7 +56,6 @@ import org.apache.tools.ant.types.Permissions; | |||||
import org.apache.tools.ant.types.PropertySet; | import org.apache.tools.ant.types.PropertySet; | ||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
import org.apache.tools.ant.util.LoaderUtils; | import org.apache.tools.ant.util.LoaderUtils; | ||||
import org.apache.tools.ant.taskdefs.PumpStreamHandler; | |||||
/** | /** | ||||
* Runs JUnit tests. | * Runs JUnit tests. | ||||
@@ -938,7 +941,7 @@ public class JUnitTask extends Task { | |||||
} | } | ||||
File vmWatcher = createTempPropertiesFile("junitvmwatcher"); | File vmWatcher = createTempPropertiesFile("junitvmwatcher"); | ||||
formatterArg.append("nocrashfile="); | |||||
formatterArg.append("crashfile="); | |||||
formatterArg.append(vmWatcher); | formatterArg.append(vmWatcher); | ||||
cmd.createArgument().setValue(formatterArg.toString()); | cmd.createArgument().setValue(formatterArg.toString()); | ||||
@@ -988,12 +991,20 @@ public class JUnitTask extends Task { | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new BuildException("Process fork failed.", e, getLocation()); | throw new BuildException("Process fork failed.", e, getLocation()); | ||||
} finally { | } finally { | ||||
String vmCrashString = "unknown"; | |||||
try { | |||||
BufferedReader br = new BufferedReader(new FileReader(vmWatcher)); | |||||
vmCrashString = br.readLine(); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
// ignored. | |||||
} | |||||
if (watchdog != null && watchdog.killedProcess()) { | if (watchdog != null && watchdog.killedProcess()) { | ||||
result.timedOut = true; | result.timedOut = true; | ||||
logTimeout(feArray, test); | |||||
} else if (vmWatcher.length() == 0) { | |||||
logTimeout(feArray, test, vmCrashString); | |||||
} else if (!"terminated successfully".equals(vmCrashString)) { | |||||
result.crashed = true; | result.crashed = true; | ||||
logVmCrash(feArray, test); | |||||
logVmCrash(feArray, test, vmCrashString); | |||||
} | } | ||||
vmWatcher.delete(); | vmWatcher.delete(); | ||||
@@ -1335,8 +1346,8 @@ public class JUnitTask extends Task { | |||||
* @since Ant 1.5.2 | * @since Ant 1.5.2 | ||||
*/ | */ | ||||
private void logTimeout(FormatterElement[] feArray, JUnitTest test) { | |||||
logVmExit(feArray, test, "Timeout occurred. Please note the time in the report does not reflect the time until the timeout."); | |||||
private void logTimeout(FormatterElement[] feArray, JUnitTest test, String testCase) { | |||||
logVmExit(feArray, test, "Timeout occurred. Please note the time in the report does not reflect the time until the timeout.", testCase); | |||||
} | } | ||||
/** | /** | ||||
@@ -1346,8 +1357,8 @@ public class JUnitTask extends Task { | |||||
* | * | ||||
* @since Ant 1.7 | * @since Ant 1.7 | ||||
*/ | */ | ||||
private void logVmCrash(FormatterElement[] feArray, JUnitTest test) { | |||||
logVmExit(feArray, test, "Forked Java VM exited abnormally. Please note the time in the report does not reflect the time until the VM exit."); | |||||
private void logVmCrash(FormatterElement[] feArray, JUnitTest test, String testCase) { | |||||
logVmExit(feArray, test, "Forked Java VM exited abnormally. Please note the time in the report does not reflect the time until the VM exit.", testCase); | |||||
} | } | ||||
/** | /** | ||||
@@ -1357,7 +1368,7 @@ public class JUnitTask extends Task { | |||||
* @since Ant 1.7 | * @since Ant 1.7 | ||||
*/ | */ | ||||
private void logVmExit(FormatterElement[] feArray, JUnitTest test, | private void logVmExit(FormatterElement[] feArray, JUnitTest test, | ||||
String message) { | |||||
String message, String testCase) { | |||||
try { | try { | ||||
log("Using System properties " + System.getProperties(), | log("Using System properties " + System.getProperties(), | ||||
Project.MSG_VERBOSE); | Project.MSG_VERBOSE); | ||||
@@ -1380,7 +1391,7 @@ public class JUnitTask extends Task { | |||||
if (outFile != null && formatter != null) { | if (outFile != null && formatter != null) { | ||||
try { | try { | ||||
OutputStream out = new FileOutputStream(outFile); | OutputStream out = new FileOutputStream(outFile); | ||||
delegate.addVmExit(test, formatter, out, message); | |||||
delegate.addVmExit(test, formatter, out, message, testCase); | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
// ignore | // ignore | ||||
} | } | ||||
@@ -1390,7 +1401,7 @@ public class JUnitTask extends Task { | |||||
JUnitTaskMirror.SummaryJUnitResultFormatterMirror f = | JUnitTaskMirror.SummaryJUnitResultFormatterMirror f = | ||||
delegate.newSummaryJUnitResultFormatter(); | delegate.newSummaryJUnitResultFormatter(); | ||||
f.setWithOutAndErr("withoutanderr".equalsIgnoreCase(summaryValue)); | f.setWithOutAndErr("withoutanderr".equalsIgnoreCase(summaryValue)); | ||||
delegate.addVmExit(test, f, getDefaultOutput(), message); | |||||
delegate.addVmExit(test, f, getDefaultOutput(), message, testCase); | |||||
} | } | ||||
} finally { | } finally { | ||||
if (classLoader != null) { | if (classLoader != null) { | ||||
@@ -41,7 +41,8 @@ import org.apache.tools.ant.types.Permissions; | |||||
public interface JUnitTaskMirror { | public interface JUnitTaskMirror { | ||||
void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter, | void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter, | ||||
OutputStream out, String message); | |||||
OutputStream out, String message, String testCase); | |||||
JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, boolean haltOnError, | JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, boolean haltOnError, | ||||
boolean filterTrace, boolean haltOnFailure, boolean showOutput, | boolean filterTrace, boolean haltOnFailure, boolean showOutput, | ||||
@@ -39,14 +39,14 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||||
} | } | ||||
public void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror aFormatter, | public void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror aFormatter, | ||||
OutputStream out, final String message) { | |||||
OutputStream out, String message, String testCase) { | |||||
JUnitResultFormatter formatter = (JUnitResultFormatter) aFormatter; | JUnitResultFormatter formatter = (JUnitResultFormatter) aFormatter; | ||||
formatter.setOutput(out); | formatter.setOutput(out); | ||||
formatter.startTestSuite(test); | formatter.startTestSuite(test); | ||||
//the trick to integrating test output to the formatter, is to | //the trick to integrating test output to the formatter, is to | ||||
//create a special test class that asserts an error | //create a special test class that asserts an error | ||||
//and tell the formatter that it raised. | //and tell the formatter that it raised. | ||||
TestCase t = new VmExitErrorTest(message, test); | |||||
TestCase t = new VmExitErrorTest(message, test, testCase); | |||||
formatter.startTest(t); | formatter.startTest(t); | ||||
formatter.addError(t, new AssertionFailedError(message)); | formatter.addError(t, new AssertionFailedError(message)); | ||||
formatter.endTestSuite(test); | formatter.endTestSuite(test); | ||||
@@ -67,10 +67,12 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||||
private String message; | private String message; | ||||
private JUnitTest test; | private JUnitTest test; | ||||
private String testCase; | |||||
VmExitErrorTest(String aMessage, JUnitTest anOriginalTest) { | |||||
VmExitErrorTest(String aMessage, JUnitTest anOriginalTest, String aTestCase) { | |||||
message = aMessage; | message = aMessage; | ||||
test = anOriginalTest; | test = anOriginalTest; | ||||
testCase = aTestCase; | |||||
} | } | ||||
public int countTestCases() { | public int countTestCases() { | ||||
@@ -81,12 +83,16 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||||
throw new AssertionFailedError(message); | throw new AssertionFailedError(message); | ||||
} | } | ||||
public String getName() { | |||||
return testCase; | |||||
} | |||||
String getClassName() { | String getClassName() { | ||||
return test.getName(); | return test.getName(); | ||||
} | } | ||||
public String toString() { | public String toString() { | ||||
return test.getName(); | |||||
return test.getName()+":"+testCase; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -22,7 +22,9 @@ import java.io.ByteArrayOutputStream; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
import java.io.FileWriter; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | |||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.io.StringReader; | import java.io.StringReader; | ||||
@@ -151,6 +153,12 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
/** Turned on if we are using JUnit 4 for this test suite. see #38811 */ | /** Turned on if we are using JUnit 4 for this test suite. see #38811 */ | ||||
private boolean junit4; | private boolean junit4; | ||||
/** | |||||
* The file used to indicate that the build crashed. | |||||
* File will be empty in case the build did not crash. | |||||
*/ | |||||
private static String crashFile = null; | |||||
/** | /** | ||||
* Constructor for fork=true or when the user hasn't specified a | * Constructor for fork=true or when the user hasn't specified a | ||||
* classpath. | * classpath. | ||||
@@ -574,7 +582,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
Properties props = new Properties(); | Properties props = new Properties(); | ||||
boolean showOut = false; | boolean showOut = false; | ||||
boolean logTestListenerEvents = false; | boolean logTestListenerEvents = false; | ||||
String noCrashFile = null; | |||||
if (args.length == 0) { | if (args.length == 0) { | ||||
System.err.println("required argument TestClassName missing"); | System.err.println("required argument TestClassName missing"); | ||||
@@ -593,8 +601,9 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
haltFail = Project.toBoolean(args[i].substring(14)); | haltFail = Project.toBoolean(args[i].substring(14)); | ||||
} else if (args[i].startsWith("filtertrace=")) { | } else if (args[i].startsWith("filtertrace=")) { | ||||
stackfilter = Project.toBoolean(args[i].substring(12)); | stackfilter = Project.toBoolean(args[i].substring(12)); | ||||
} else if (args[i].startsWith("nocrashfile=")) { | |||||
noCrashFile = args[i].substring(12); | |||||
} else if (args[i].startsWith("crashfile=")) { | |||||
crashFile = args[i].substring(12); | |||||
registerTestCase("BeforeFirstTest"); | |||||
} else if (args[i].startsWith("formatter=")) { | } else if (args[i].startsWith("formatter=")) { | ||||
try { | try { | ||||
createAndStoreFormatter(args[i].substring(10)); | createAndStoreFormatter(args[i].substring(10)); | ||||
@@ -644,7 +653,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
if (errorOccurred || failureOccurred) { | if (errorOccurred || failureOccurred) { | ||||
if ((errorOccurred && haltError) | if ((errorOccurred && haltError) | ||||
|| (failureOccurred && haltFail)) { | || (failureOccurred && haltFail)) { | ||||
registerNonCrash(noCrashFile); | |||||
registerNonCrash(); | |||||
System.exit(code); | System.exit(code); | ||||
} else { | } else { | ||||
if (code > returnCode) { | if (code > returnCode) { | ||||
@@ -664,7 +673,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
logTestListenerEvents, props); | logTestListenerEvents, props); | ||||
} | } | ||||
registerNonCrash(noCrashFile); | |||||
registerNonCrash(); | |||||
System.exit(returnCode); | System.exit(returnCode); | ||||
} | } | ||||
@@ -672,6 +681,37 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
private static void transferFormatters(JUnitTestRunner runner, | private static void transferFormatters(JUnitTestRunner runner, | ||||
JUnitTest test) { | JUnitTest test) { | ||||
runner.addFormatter(new JUnitResultFormatter() { | |||||
public void startTestSuite(JUnitTest suite) throws BuildException { | |||||
} | |||||
public void endTestSuite(JUnitTest suite) throws BuildException { | |||||
} | |||||
public void setOutput(OutputStream out) { | |||||
} | |||||
public void setSystemOutput(String out) { | |||||
} | |||||
public void setSystemError(String err) { | |||||
} | |||||
public void addError(Test arg0, Throwable arg1) { | |||||
} | |||||
public void addFailure(Test arg0, AssertionFailedError arg1) { | |||||
} | |||||
public void endTest(Test arg0) { | |||||
} | |||||
public void startTest(Test arg0) { | |||||
System.out.println(this.getClass().getName() + ":" + arg0); | |||||
registerTestCase(JUnitVersionHelper.getTestCaseName(arg0)); | |||||
} | |||||
}); | |||||
for (int i = 0; i < fromCmdLine.size(); i++) { | for (int i = 0; i < fromCmdLine.size(); i++) { | ||||
FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i); | FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i); | ||||
if (multipleTests && fe.getUseFile()) { | if (multipleTests && fe.getUseFile()) { | ||||
@@ -775,23 +815,45 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||||
/** | /** | ||||
* @since Ant 1.7 | * @since Ant 1.7 | ||||
*/ | */ | ||||
private static void registerNonCrash(String noCrashFile) | |||||
throws IOException { | |||||
if (noCrashFile != null) { | |||||
FileOutputStream out = null; | |||||
private static void registerNonCrash() | |||||
throws IOException { | |||||
if (crashFile != null) { | |||||
FileWriter out = null; | |||||
try { | try { | ||||
out = new FileOutputStream(noCrashFile); | |||||
out.write(0); | |||||
out = new FileWriter(crashFile); | |||||
out.write("terminated successfully\n"); | |||||
out.flush(); | out.flush(); | ||||
} finally { | } finally { | ||||
out.close(); | |||||
if (out != null) { | |||||
out.close(); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private static void registerTestCase(String testCase) { | |||||
if (crashFile != null) { | |||||
try { | |||||
FileWriter out = null; | |||||
try { | |||||
out = new FileWriter(crashFile); | |||||
out.write(testCase + "\n"); | |||||
out.flush(); | |||||
} finally { | |||||
if (out != null) { | |||||
out.close(); | |||||
} | |||||
} | |||||
} catch (IOException e) { | |||||
// ignored. | |||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Modifies a TestListener when running JUnit 4: | |||||
* treats AssertionFailedError as a failure not an error. | |||||
* Modifies a TestListener when running JUnit 4: treats AssertionFailedError | |||||
* as a failure not an error. | |||||
* | |||||
* @since Ant 1.7 | * @since Ant 1.7 | ||||
*/ | */ | ||||
private TestListener wrapListener(final TestListener testListener) { | private TestListener wrapListener(final TestListener testListener) { | ||||