Skip to content

Commit

Permalink
Added MainRunner. This removes the need for public methods in JUnitCore
Browse files Browse the repository at this point in the history
MainRunner installs a SecurityManager which traps the System.exit(), thereby
removing the need to have runMainAndExit and runMain public in JUnitCore.
MainRunner is only used in the tests of course.
  • Loading branch information
matthewfarwell committed Jan 3, 2012
1 parent 45eaab7 commit 917a88f
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 25 deletions.
1 change: 0 additions & 1 deletion src/main/java/org/junit/internal/JUnitSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
import java.io.PrintStream;

public interface JUnitSystem {
void exit(int i);
PrintStream out();
}
5 changes: 0 additions & 5 deletions src/main/java/org/junit/internal/RealSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
import java.io.PrintStream;

public class RealSystem implements JUnitSystem {

public void exit(int code) {
System.exit(code);
}

public PrintStream out() {
return System.out;
}
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/junit/runner/JUnitCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ public static void main(String... args) {
}

/**
* Do not use. Testing purposes only.
* @param system
* Runs main and exits
* @param system
* @args args from main()
*/
public static void runMainAndExit(JUnitSystem system, String... args) {
private static void runMainAndExit(JUnitSystem system, String... args) {
Result result= new JUnitCore().runMain(system, args);
system.exit(result.wasSuccessful() ? 0 : 1);
System.exit(result.wasSuccessful() ? 0 : 1);
}

/**
Expand All @@ -70,10 +71,10 @@ public static Result runClasses(Class<?>... classes) {
}

/**
* Do not use. Testing purposes only.
* @param system
* @args args from main()
*/
public Result runMain(JUnitSystem system, String... args) {
private Result runMain(JUnitSystem system, String... args) {
system.out().println("JUnit version " + Version.id());
List<Class<?>> classes= new ArrayList<Class<?>>();
List<Failure> missingClasses= new ArrayList<Failure>();
Expand Down
5 changes: 0 additions & 5 deletions src/test/java/org/junit/tests/TestSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@

public class TestSystem implements JUnitSystem {
private PrintStream out;
public int fCode;
private ByteArrayOutputStream fOutContents;

public TestSystem() {
fOutContents= new ByteArrayOutputStream();
out= new PrintStream(fOutContents);
}

public void exit(int code) {
fCode= code;
}

public PrintStream out() {
return out;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.internal.RealSystem;
import org.junit.runner.JUnitCore;

public class CommandLineTest {
Expand All @@ -34,8 +33,12 @@ static public class Example {
}

@Test public void runATest() {
testWasRun= false; // todo create a TestSystem instead
new JUnitCore().runMain(new RealSystem(), new String[]{"org.junit.tests.running.core.CommandLineTest$Example"});
testWasRun= false;
new MainRunner().runWithCheckForSystemExit(new Runnable() {
public void run() {
JUnitCore.main("org.junit.tests.running.core.CommandLineTest$Example");
}
});
assertTrue(testWasRun);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.tests.TestSystem;

public class JUnitCoreReturnsCorrectExitCodeTest {

Expand All @@ -31,9 +30,12 @@ static public class Succeed {
runClass(getClass().getName() + "$Succeed", 0);
}

private void runClass(String className, int returnCode) {
TestSystem system= new TestSystem();
JUnitCore.runMainAndExit(system, className);
assertEquals(returnCode, system.fCode);
private void runClass(final String className, int returnCode) {
Integer exitValue= new MainRunner().runWithCheckForSystemExit(new Runnable() {
public void run() {
JUnitCore.main(className);
}
});
assertEquals(Integer.valueOf(returnCode), exitValue);
}
}
69 changes: 69 additions & 0 deletions src/test/java/org/junit/tests/running/core/MainRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.junit.tests.running.core;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.security.Permission;

public class MainRunner {

private static class ExitException extends SecurityException {
private static final long serialVersionUID= -9104651568237766642L;

private final int status;

public ExitException(int status) {
super("");
this.status= status;
}

public int getStatus() {
return status;
}
}

private static class NoExitSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
// allow anything.
}

@Override
public void checkPermission(Permission perm, Object context) {
// allow anything.
}

@Override
public void checkExit(int status) {
super.checkExit(status);
throw new ExitException(status);
}
}

/**
* Execute runnable.run(), preventing System.exit(). If System.exit() is called
* in runnable.run(), the value is returned. If System.exit()
* is not called, null is returned.
*
* @param runnable
* @return null if System.exit() is not called, Integer.valueof(status) if not
*/
public Integer runWithCheckForSystemExit(Runnable runnable) {
SecurityManager oldSecurityManager = System.getSecurityManager();
System.setSecurityManager(new NoExitSecurityManager());
PrintStream oldPrintStream = System.out;

System.setOut(new PrintStream(new ByteArrayOutputStream()));
try {
runnable.run();
System.out.println("System.exit() not called, return null");
return null;
} catch (ExitException e) {
System.out.println("System.exit() called, value=" + e.getStatus());
return e.getStatus();
} finally {
System.setSecurityManager(oldSecurityManager);
System.setOut(oldPrintStream);
}
}

}

0 comments on commit 917a88f

Please sign in to comment.