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