Browse Source

The code that tries to detect a crashing forked VM in <junit> breaks

down when the VM runs multiple tests.

The old code used a TestFormatter and detected a crash if the expected
output had not been written.  If multiple tests get run in one VM, the
TestRunner ignores the filename that has been passed in - and the task
doesn't find any output.

Even if it didn't ignore the file name, a single non-crashing test
would have made the task think, the VM finished in a healthy way.

Make the crash-detection more explcit and let the TestRunner cooperate
more than before.

This bug has been presented by Gump in cooperation with the Hivemind
build.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276942 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 20 years ago
parent
commit
3c231b4ee7
3 changed files with 24 additions and 111 deletions
  1. +0
    -108
      src/main/org/apache/tools/ant/taskdefs/optional/junit/ForkedVMWatcher.java
  2. +1
    -3
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  3. +23
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java

+ 0
- 108
src/main/org/apache/tools/ant/taskdefs/optional/junit/ForkedVMWatcher.java View File

@@ -1,108 +0,0 @@
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant.taskdefs.optional.junit;

import java.io.IOException;
import java.io.OutputStream;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.tools.ant.BuildException;

/**
* writes a single 0 byte to the given output stream in endTestSuite.
*/
public class ForkedVMWatcher implements JUnitResultFormatter {

/**
* OutputStream to write to.
*/
private OutputStream out;

/**
* Empty
*/
public ForkedVMWatcher() {
}
/**
* Empty
*/
public void startTestSuite(JUnitTest suite) {
}
/**
* Empty
*/
public void startTest(Test t) {
}
/**
* Empty
*/
public void endTest(Test test) {
}
/**
* Empty
*/
public void addFailure(Test test, Throwable t) {
}
/**
* Interface TestListener for JUnit &gt; 3.4.
*
* <p>A Test failed.
*/
public void addFailure(Test test, AssertionFailedError t) {
addFailure(test, (Throwable) t);
}
/**
* Empty
*/
public void addError(Test test, Throwable t) {
}
/**
* Empty
*/
public void setSystemOutput(String out) {
}
/**
* Empty
*/
public void setSystemError(String err) {
}

public void setOutput(OutputStream out) {
this.out = out;
}

/**
* The whole testsuite ended.
*/
public void endTestSuite(JUnitTest suite) throws BuildException {
try {
out.write(0);
out.flush();
} catch (IOException ioex) {
throw new BuildException("Unable to write output", ioex);
} finally {
if (out != System.out && out != System.err) {
try {
out.close();
} catch (IOException e) {
// ignore
}
}
}
}
}

+ 1
- 3
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -847,9 +847,7 @@ public class JUnitTask extends Task {
}

File vmWatcher = createTempPropertiesFile("junitvmwatcher");
formatterArg.append("formatter=");
formatterArg.append(ForkedVMWatcher.class.getName());
formatterArg.append(",");
formatterArg.append("nocrashfile=");
formatterArg.append(vmWatcher);
cmd.createArgument().setValue(formatterArg.toString());



+ 23
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java View File

@@ -21,6 +21,7 @@ import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -475,6 +476,7 @@ public class JUnitTestRunner implements TestListener {
boolean stackfilter = true;
Properties props = new Properties();
boolean showOut = false;
String noCrashFile = null;

if (args.length == 0) {
System.err.println("required argument TestClassName missing");
@@ -493,6 +495,8 @@ public class JUnitTestRunner implements TestListener {
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("formatter=")) {
try {
createAndStoreFormatter(args[i].substring(10));
@@ -540,6 +544,7 @@ public class JUnitTestRunner implements TestListener {
if (errorOccured || failureOccured ) {
if ((errorOccured && haltError)
|| (failureOccured && haltFail)) {
registerNonCrash(noCrashFile);
System.exit(code);
} else {
if (code > returnCode) {
@@ -558,6 +563,7 @@ public class JUnitTestRunner implements TestListener {
stackfilter, haltFail, showOut, props);
}

registerNonCrash(noCrashFile);
System.exit(returnCode);
}

@@ -655,4 +661,21 @@ public class JUnitTestRunner implements TestListener {
runner.run();
return runner.getRetCode();
}

/**
* @since Ant 1.7
*/
private static void registerNonCrash(String noCrashFile)
throws IOException {
if (noCrashFile != null) {
FileOutputStream out = null;
try {
out = new FileOutputStream(noCrashFile);
out.write(0);
out.flush();
} finally {
out.close();
}
}
}
} // JUnitTestRunner

Loading…
Cancel
Save