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; | |||
import java.io.BufferedReader; | |||
import java.io.BufferedWriter; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.FileReader; | |||
import java.io.FileWriter; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
@@ -35,6 +37,7 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.Vector; | |||
import org.apache.tools.ant.AntClassLoader; | |||
import org.apache.tools.ant.BuildException; | |||
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.ExecuteWatchdog; | |||
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.Commandline; | |||
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.util.FileUtils; | |||
import org.apache.tools.ant.util.LoaderUtils; | |||
import org.apache.tools.ant.taskdefs.PumpStreamHandler; | |||
/** | |||
* Runs JUnit tests. | |||
@@ -938,7 +941,7 @@ public class JUnitTask extends Task { | |||
} | |||
File vmWatcher = createTempPropertiesFile("junitvmwatcher"); | |||
formatterArg.append("nocrashfile="); | |||
formatterArg.append("crashfile="); | |||
formatterArg.append(vmWatcher); | |||
cmd.createArgument().setValue(formatterArg.toString()); | |||
@@ -988,12 +991,20 @@ public class JUnitTask extends Task { | |||
} catch (IOException e) { | |||
throw new BuildException("Process fork failed.", e, getLocation()); | |||
} 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()) { | |||
result.timedOut = true; | |||
logTimeout(feArray, test); | |||
} else if (vmWatcher.length() == 0) { | |||
logTimeout(feArray, test, vmCrashString); | |||
} else if (!"terminated successfully".equals(vmCrashString)) { | |||
result.crashed = true; | |||
logVmCrash(feArray, test); | |||
logVmCrash(feArray, test, vmCrashString); | |||
} | |||
vmWatcher.delete(); | |||
@@ -1335,8 +1346,8 @@ public class JUnitTask extends Task { | |||
* @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 | |||
*/ | |||
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 | |||
*/ | |||
private void logVmExit(FormatterElement[] feArray, JUnitTest test, | |||
String message) { | |||
String message, String testCase) { | |||
try { | |||
log("Using System properties " + System.getProperties(), | |||
Project.MSG_VERBOSE); | |||
@@ -1380,7 +1391,7 @@ public class JUnitTask extends Task { | |||
if (outFile != null && formatter != null) { | |||
try { | |||
OutputStream out = new FileOutputStream(outFile); | |||
delegate.addVmExit(test, formatter, out, message); | |||
delegate.addVmExit(test, formatter, out, message, testCase); | |||
} catch (IOException e) { | |||
// ignore | |||
} | |||
@@ -1390,7 +1401,7 @@ public class JUnitTask extends Task { | |||
JUnitTaskMirror.SummaryJUnitResultFormatterMirror f = | |||
delegate.newSummaryJUnitResultFormatter(); | |||
f.setWithOutAndErr("withoutanderr".equalsIgnoreCase(summaryValue)); | |||
delegate.addVmExit(test, f, getDefaultOutput(), message); | |||
delegate.addVmExit(test, f, getDefaultOutput(), message, testCase); | |||
} | |||
} finally { | |||
if (classLoader != null) { | |||
@@ -41,7 +41,8 @@ import org.apache.tools.ant.types.Permissions; | |||
public interface JUnitTaskMirror { | |||
void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter, | |||
OutputStream out, String message); | |||
OutputStream out, String message, String testCase); | |||
JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, boolean haltOnError, | |||
boolean filterTrace, boolean haltOnFailure, boolean showOutput, | |||
@@ -39,14 +39,14 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||
} | |||
public void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror aFormatter, | |||
OutputStream out, final String message) { | |||
OutputStream out, String message, String testCase) { | |||
JUnitResultFormatter formatter = (JUnitResultFormatter) aFormatter; | |||
formatter.setOutput(out); | |||
formatter.startTestSuite(test); | |||
//the trick to integrating test output to the formatter, is to | |||
//create a special test class that asserts an error | |||
//and tell the formatter that it raised. | |||
TestCase t = new VmExitErrorTest(message, test); | |||
TestCase t = new VmExitErrorTest(message, test, testCase); | |||
formatter.startTest(t); | |||
formatter.addError(t, new AssertionFailedError(message)); | |||
formatter.endTestSuite(test); | |||
@@ -67,10 +67,12 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||
private String message; | |||
private JUnitTest test; | |||
private String testCase; | |||
VmExitErrorTest(String aMessage, JUnitTest anOriginalTest) { | |||
VmExitErrorTest(String aMessage, JUnitTest anOriginalTest, String aTestCase) { | |||
message = aMessage; | |||
test = anOriginalTest; | |||
testCase = aTestCase; | |||
} | |||
public int countTestCases() { | |||
@@ -81,12 +83,16 @@ public final class JUnitTaskMirrorImpl implements JUnitTaskMirror { | |||
throw new AssertionFailedError(message); | |||
} | |||
public String getName() { | |||
return testCase; | |||
} | |||
String getClassName() { | |||
return test.getName(); | |||
} | |||
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.FileInputStream; | |||
import java.io.FileOutputStream; | |||
import java.io.FileWriter; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.io.PrintStream; | |||
import java.io.PrintWriter; | |||
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 */ | |||
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 | |||
* classpath. | |||
@@ -574,7 +582,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||
Properties props = new Properties(); | |||
boolean showOut = false; | |||
boolean logTestListenerEvents = false; | |||
String noCrashFile = null; | |||
if (args.length == 0) { | |||
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)); | |||
} else if (args[i].startsWith("filtertrace=")) { | |||
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=")) { | |||
try { | |||
createAndStoreFormatter(args[i].substring(10)); | |||
@@ -644,7 +653,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||
if (errorOccurred || failureOccurred) { | |||
if ((errorOccurred && haltError) | |||
|| (failureOccurred && haltFail)) { | |||
registerNonCrash(noCrashFile); | |||
registerNonCrash(); | |||
System.exit(code); | |||
} else { | |||
if (code > returnCode) { | |||
@@ -664,7 +673,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||
logTestListenerEvents, props); | |||
} | |||
registerNonCrash(noCrashFile); | |||
registerNonCrash(); | |||
System.exit(returnCode); | |||
} | |||
@@ -672,6 +681,37 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||
private static void transferFormatters(JUnitTestRunner runner, | |||
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++) { | |||
FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i); | |||
if (multipleTests && fe.getUseFile()) { | |||
@@ -775,23 +815,45 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR | |||
/** | |||
* @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 { | |||
out = new FileOutputStream(noCrashFile); | |||
out.write(0); | |||
out = new FileWriter(crashFile); | |||
out.write("terminated successfully\n"); | |||
out.flush(); | |||
} 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 | |||
*/ | |||
private TestListener wrapListener(final TestListener testListener) { | |||