-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
TestRunner.java
179 lines (153 loc) · 5.92 KB
/
TestRunner.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/*
This class compiles and runs all java files under a directory.
Usage : java TestRunner [expected] [dir]
expected : can be 'SUCCESS' or 'FAIL' depicting the success/failing of a test case
dir : the directory containing all java test files
*/
public class TestRunner {
private enum ExpectedOutcome {
SUCCESS,
FAIL;
public static ExpectedOutcome parse(String s) {
try {
return ExpectedOutcome.valueOf(s);
} catch (Exception e) {
return null;
}
}
}
public static void main(String[] args) throws Exception {
if (args.length < 2) {
throw new Exception("unexpected : missing arguments. usage : java TestRunner [SUCCESS/FAIL] [dir]");
}
String mode = args[0], testDirectory = args[1];
ExpectedOutcome expectedOutcome = ExpectedOutcome.parse(mode);
if (expectedOutcome == null) {
throw new Exception("unexpected : missing arguments. usage : java TestRunner [SUCCESS/FAIL] [dir]");
}
Result result = runTests(expectedOutcome, testDirectory);
// Clean up all generated files before throwing the exception
cleanup();
if (!result.isSuccess()) {
throw new Exception(result.getException().getMessage());
}
}
// Runs all test in the {testsDirectory} and checks that each test has the expected outcome
private static Result runTests(ExpectedOutcome expected, String testsDirectory) throws Exception {
List<File> tests = listJavaFiles(testsDirectory);
for (File test : tests) {
Result testResult = runTest(test);
switch (expected) {
case SUCCESS:
if (testResult.isSuccess()) {
break;
}
// This test should have "PASSED" but "FAILED
return failureResult(
String.format("\n\nTest [%s]\nResult : [FAILED]\nExcepted: [SUCCESS]\nCause: %s\n",
test.getName(), testResult.getException().getMessage()));
case FAIL:
if (!testResult.isSuccess()) {
break;
}
// This test should have "FAILED" but "PASSED".
return failureResult
(String.format("\n\nTest [%s]\nResult: [PASSED]\nExcepted: [FAILURE].",
test.getName()));
}
}
return successResult();
}
// Lists all java files in a directory
private static List<File> listJavaFiles(String path) {
List<File> javaFiles = new ArrayList<>();
File directory = new File(path);
File[] files = directory.listFiles();
if (files == null) {
return javaFiles;
}
for (File file : files) {
if (!file.getName().contains(".java")) {
continue;
}
javaFiles.add(file);
}
return javaFiles;
}
// Compiles and runs the test java file and returns the result
private static Result runTest(File test) {
String javaFile = test.getName();
String javaFilePrefix = javaFile.substring(0, javaFile.lastIndexOf("."));
File parent = test.getParentFile();
String classPath = String.format("/postgres.jar:%s:.", parent.getAbsolutePath());
String[] compileCmds = new String[] {"javac", test.getAbsolutePath()};
String[] runCmds = new String[] {"java", "-cp", classPath, javaFilePrefix};
try {
// Compiles the java code
Process compileTest = Runtime.getRuntime().exec(compileCmds);
String errorTrace = toString(compileTest.getErrorStream());
compileTest.waitFor();
if (compileTest.exitValue() != 0) {
return failureResult(errorTrace);
}
// Runs the java code
Process runTest = Runtime.getRuntime().exec(runCmds);
errorTrace = toString(runTest.getErrorStream());
runTest.waitFor();
if (runTest.exitValue() != 0) {
return failureResult(errorTrace);
}
return successResult();
} catch (Exception e) {
return failureResult(e.getMessage());
}
}
// Runs the clean up script
private static void cleanup() {
try {
run(new String[]{"/bin/bash", "-c", "./run_cleanup.sh"});
} catch (Exception e) {
}
}
private static Process run(String[] cmds) throws Exception {
Process exec = Runtime.getRuntime().exec(cmds);
exec.waitFor();
return exec;
}
private static String toString(InputStream ins) throws Exception {
StringBuilder sb = new StringBuilder();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(ins));
while ((line = in.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
}
private static Result failureResult(String message) {
return new Result(false, new Exception(message));
}
private static Result successResult() {
return new Result(true, null);
}
// A wrapper object containing test case execution result and the exception
private static class Result {
private final boolean success;
private final Exception exception;
public Result(boolean success, Exception exception) {
this.success = success;
this.exception = exception;
}
public boolean isSuccess() {
return success;
}
public Exception getException() {
return exception;
}
}
}