Skip to content

Commit d5bce27

Browse files
committed
Merge pull request junit-team#370 from matthewfarwell/junit-core-run-fixes
Added MainRunner. This removes the need for public methods in JUnitCore
2 parents b1068dc + 4596630 commit d5bce27

File tree

7 files changed

+283
-25
lines changed

7 files changed

+283
-25
lines changed

src/main/java/org/junit/internal/JUnitSystem.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,5 @@
33
import java.io.PrintStream;
44

55
public interface JUnitSystem {
6-
void exit(int i);
76
PrintStream out();
87
}

src/main/java/org/junit/internal/RealSystem.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
import java.io.PrintStream;
44

55
public class RealSystem implements JUnitSystem {
6-
7-
public void exit(int code) {
8-
System.exit(code);
9-
}
10-
116
public PrintStream out() {
127
return System.out;
138
}

src/main/java/org/junit/runner/JUnitCore.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@ public static void main(String... args) {
3939
}
4040

4141
/**
42-
* Do not use. Testing purposes only.
43-
* @param system
42+
* Runs main and exits
43+
* @param system
44+
* @args args from main()
4445
*/
45-
public static void runMainAndExit(JUnitSystem system, String... args) {
46+
private static void runMainAndExit(JUnitSystem system, String... args) {
4647
Result result= new JUnitCore().runMain(system, args);
47-
system.exit(result.wasSuccessful() ? 0 : 1);
48+
System.exit(result.wasSuccessful() ? 0 : 1);
4849
}
4950

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

7273
/**
73-
* Do not use. Testing purposes only.
7474
* @param system
75+
* @args args from main()
7576
*/
76-
public Result runMain(JUnitSystem system, String... args) {
77+
private Result runMain(JUnitSystem system, String... args) {
7778
system.out().println("JUnit version " + Version.id());
7879
List<Class<?>> classes= new ArrayList<Class<?>>();
7980
List<Failure> missingClasses= new ArrayList<Failure>();

src/test/java/org/junit/tests/TestSystem.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,13 @@
88

99
public class TestSystem implements JUnitSystem {
1010
private PrintStream out;
11-
public int fCode;
1211
private ByteArrayOutputStream fOutContents;
1312

1413
public TestSystem() {
1514
fOutContents= new ByteArrayOutputStream();
1615
out= new PrintStream(fOutContents);
1716
}
1817

19-
public void exit(int code) {
20-
fCode= code;
21-
}
22-
2318
public PrintStream out() {
2419
return out;
2520
}

src/test/java/org/junit/tests/running/core/CommandLineTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import org.junit.After;
1010
import org.junit.Before;
1111
import org.junit.Test;
12-
import org.junit.internal.RealSystem;
1312
import org.junit.runner.JUnitCore;
1413

1514
public class CommandLineTest {
@@ -34,8 +33,12 @@ static public class Example {
3433
}
3534

3635
@Test public void runATest() {
37-
testWasRun= false; // todo create a TestSystem instead
38-
new JUnitCore().runMain(new RealSystem(), new String[]{"org.junit.tests.running.core.CommandLineTest$Example"});
36+
testWasRun= false;
37+
new MainRunner().runWithCheckForSystemExit(new Runnable() {
38+
public void run() {
39+
JUnitCore.main("org.junit.tests.running.core.CommandLineTest$Example");
40+
}
41+
});
3942
assertTrue(testWasRun);
4043
}
4144

src/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import static org.junit.Assert.fail;
55
import org.junit.Test;
66
import org.junit.runner.JUnitCore;
7-
import org.junit.tests.TestSystem;
87

98
public class JUnitCoreReturnsCorrectExitCodeTest {
109

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

34-
private void runClass(String className, int returnCode) {
35-
TestSystem system= new TestSystem();
36-
JUnitCore.runMainAndExit(system, className);
37-
assertEquals(returnCode, system.fCode);
33+
private void runClass(final String className, int returnCode) {
34+
Integer exitValue= new MainRunner().runWithCheckForSystemExit(new Runnable() {
35+
public void run() {
36+
JUnitCore.main(className);
37+
}
38+
});
39+
assertEquals(Integer.valueOf(returnCode), exitValue);
3840
}
3941
}
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
package org.junit.tests.running.core;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.PrintStream;
5+
import java.security.Permission;
6+
import java.io.FileDescriptor;
7+
import java.net.InetAddress;
8+
9+
public class MainRunner {
10+
private static class ExitException extends SecurityException {
11+
private static final long serialVersionUID= -9104651568237766642L;
12+
13+
private final int status;
14+
15+
public ExitException(int status) {
16+
super("");
17+
this.status= status;
18+
}
19+
20+
public int getStatus() {
21+
return status;
22+
}
23+
}
24+
25+
/**
26+
* A {@code NoExitSecurityManager} throws a {@link ExitException} exception
27+
* whenever {@link #checkExit(int)} is called. All other method calls are
28+
* delegated to the original security manager.
29+
*/
30+
public class NoExitSecurityManager extends SecurityManager {
31+
private final SecurityManager originalSecurityManager;
32+
33+
public NoExitSecurityManager(SecurityManager originalSecurityManager) {
34+
this.originalSecurityManager= originalSecurityManager;
35+
}
36+
37+
@Override
38+
public void checkExit(int status) {
39+
throw new ExitException(status);
40+
}
41+
42+
@Override
43+
public boolean getInCheck() {
44+
return (originalSecurityManager != null) && originalSecurityManager.getInCheck();
45+
}
46+
47+
@Override
48+
public Object getSecurityContext() {
49+
return (originalSecurityManager == null) ? super.getSecurityContext() : originalSecurityManager.getSecurityContext();
50+
}
51+
52+
@Override
53+
public void checkPermission(Permission perm) {
54+
if (originalSecurityManager != null)
55+
originalSecurityManager.checkPermission(perm);
56+
}
57+
58+
@Override
59+
public void checkPermission(Permission perm, Object context) {
60+
if (originalSecurityManager != null)
61+
originalSecurityManager.checkPermission(perm, context);
62+
}
63+
64+
@Override
65+
public void checkCreateClassLoader() {
66+
if (originalSecurityManager != null)
67+
originalSecurityManager.checkCreateClassLoader();
68+
}
69+
70+
@Override
71+
public void checkAccess(Thread t) {
72+
if (originalSecurityManager != null)
73+
originalSecurityManager.checkAccess(t);
74+
}
75+
76+
@Override
77+
public void checkAccess(ThreadGroup g) {
78+
if (originalSecurityManager != null)
79+
originalSecurityManager.checkAccess(g);
80+
}
81+
82+
@Override
83+
public void checkExec(String cmd) {
84+
if (originalSecurityManager != null)
85+
originalSecurityManager.checkExec(cmd);
86+
}
87+
88+
@Override
89+
public void checkLink(String lib) {
90+
if (originalSecurityManager != null)
91+
originalSecurityManager.checkLink(lib);
92+
}
93+
94+
@Override
95+
public void checkRead(FileDescriptor fd) {
96+
if (originalSecurityManager != null)
97+
originalSecurityManager.checkRead(fd);
98+
}
99+
100+
@Override
101+
public void checkRead(String file) {
102+
if (originalSecurityManager != null)
103+
originalSecurityManager.checkRead(file);
104+
}
105+
106+
@Override
107+
public void checkRead(String file, Object context) {
108+
if (originalSecurityManager != null)
109+
originalSecurityManager.checkRead(file, context);
110+
}
111+
112+
@Override
113+
public void checkWrite(FileDescriptor fd) {
114+
if (originalSecurityManager != null)
115+
originalSecurityManager.checkWrite(fd);
116+
}
117+
118+
@Override
119+
public void checkWrite(String file) {
120+
if (originalSecurityManager != null)
121+
originalSecurityManager.checkWrite(file);
122+
}
123+
124+
@Override
125+
public void checkDelete(String file) {
126+
if (originalSecurityManager != null)
127+
originalSecurityManager.checkDelete(file);
128+
}
129+
130+
@Override
131+
public void checkConnect(String host, int port) {
132+
if (originalSecurityManager != null)
133+
originalSecurityManager.checkConnect(host, port);
134+
}
135+
136+
@Override
137+
public void checkConnect(String host, int port, Object context) {
138+
if (originalSecurityManager != null)
139+
originalSecurityManager.checkConnect(host, port, context);
140+
}
141+
142+
@Override
143+
public void checkListen(int port) {
144+
if (originalSecurityManager != null)
145+
originalSecurityManager.checkListen(port);
146+
}
147+
148+
@Override
149+
public void checkAccept(String host, int port) {
150+
if (originalSecurityManager != null)
151+
originalSecurityManager.checkAccept(host, port);
152+
}
153+
154+
@Override
155+
public void checkMulticast(InetAddress maddr) {
156+
if (originalSecurityManager != null)
157+
originalSecurityManager.checkMulticast(maddr);
158+
}
159+
160+
@Override
161+
public void checkMulticast(InetAddress maddr, byte ttl) {
162+
if (originalSecurityManager != null)
163+
originalSecurityManager.checkMulticast(maddr, ttl);
164+
}
165+
166+
@Override
167+
public void checkPropertiesAccess() {
168+
if (originalSecurityManager != null)
169+
originalSecurityManager.checkPropertiesAccess();
170+
}
171+
172+
@Override
173+
public void checkPropertyAccess(String key) {
174+
if (originalSecurityManager != null)
175+
originalSecurityManager.checkPropertyAccess(key);
176+
}
177+
178+
@Override
179+
public boolean checkTopLevelWindow(Object window) {
180+
return (originalSecurityManager == null) ? super.checkTopLevelWindow(window) : originalSecurityManager.checkTopLevelWindow(window);
181+
}
182+
183+
@Override
184+
public void checkPrintJobAccess() {
185+
if (originalSecurityManager != null)
186+
originalSecurityManager.checkPrintJobAccess();
187+
}
188+
189+
@Override
190+
public void checkSystemClipboardAccess() {
191+
if (originalSecurityManager != null)
192+
originalSecurityManager.checkSystemClipboardAccess();
193+
}
194+
195+
@Override
196+
public void checkAwtEventQueueAccess() {
197+
if (originalSecurityManager != null)
198+
originalSecurityManager.checkAwtEventQueueAccess();
199+
}
200+
201+
@Override
202+
public void checkPackageAccess(String pkg) {
203+
if (originalSecurityManager != null)
204+
originalSecurityManager.checkPackageAccess(pkg);
205+
}
206+
207+
@Override
208+
public void checkPackageDefinition(String pkg) {
209+
if (originalSecurityManager != null)
210+
originalSecurityManager.checkPackageDefinition(pkg);
211+
}
212+
213+
@Override
214+
public void checkSetFactory() {
215+
if (originalSecurityManager != null)
216+
originalSecurityManager.checkSetFactory();
217+
}
218+
219+
@Override
220+
public void checkMemberAccess(Class<?> clazz, int which) {
221+
if (originalSecurityManager != null)
222+
originalSecurityManager.checkMemberAccess(clazz, which);
223+
}
224+
225+
@Override
226+
public void checkSecurityAccess(String target) {
227+
if (originalSecurityManager != null)
228+
originalSecurityManager.checkSecurityAccess(target);
229+
}
230+
231+
@Override
232+
public ThreadGroup getThreadGroup() {
233+
return (originalSecurityManager == null) ? super.getThreadGroup() : originalSecurityManager.getThreadGroup();
234+
}
235+
}
236+
237+
/**
238+
* Execute runnable.run(), preventing System.exit(). If System.exit() is called
239+
* in runnable.run(), the value is returned. If System.exit()
240+
* is not called, null is returned.
241+
*
242+
* @param runnable
243+
* @return null if System.exit() is not called, Integer.valueof(status) if not
244+
*/
245+
public Integer runWithCheckForSystemExit(Runnable runnable) {
246+
SecurityManager oldSecurityManager= System.getSecurityManager();
247+
System.setSecurityManager(new NoExitSecurityManager(oldSecurityManager));
248+
PrintStream oldPrintStream= System.out;
249+
250+
System.setOut(new PrintStream(new ByteArrayOutputStream()));
251+
try {
252+
runnable.run();
253+
System.out.println("System.exit() not called, return null");
254+
return null;
255+
} catch (ExitException e) {
256+
System.out.println("System.exit() called, value=" + e.getStatus());
257+
return e.getStatus();
258+
} finally {
259+
System.setSecurityManager(oldSecurityManager);
260+
System.setOut(oldPrintStream);
261+
}
262+
}
263+
}

0 commit comments

Comments
 (0)