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) { | ||||