Mercurial > hg > truffle
comparison graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java @ 13809:030e75d4d7dc
SL: added junit integration for external tests.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 28 Jan 2014 19:37:26 +0100 |
parents | b5b64fe6963f |
children | b16ec83edc73 |
comparison
equal
deleted
inserted
replaced
13808:5dfc531a5af1 | 13809:030e75d4d7dc |
---|---|
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package com.oracle.truffle.sl.test; | 23 package com.oracle.truffle.sl.test; |
24 | 24 |
25 import java.io.*; | 25 import java.io.*; |
26 import java.nio.charset.*; | |
26 import java.nio.file.*; | 27 import java.nio.file.*; |
27 import java.nio.file.attribute.*; | 28 import java.nio.file.attribute.*; |
28 import java.util.*; | 29 import java.util.*; |
29 | 30 |
30 import org.junit.*; | 31 import org.junit.*; |
32 import org.junit.internal.*; | |
33 import org.junit.runner.*; | |
34 import org.junit.runner.manipulation.*; | |
35 import org.junit.runner.notification.*; | |
36 import org.junit.runners.*; | |
37 import org.junit.runners.model.*; | |
31 | 38 |
32 import com.oracle.truffle.api.*; | 39 import com.oracle.truffle.api.*; |
33 import com.oracle.truffle.api.source.*; | 40 import com.oracle.truffle.api.source.*; |
34 import com.oracle.truffle.sl.*; | 41 import com.oracle.truffle.sl.*; |
35 import com.oracle.truffle.sl.runtime.*; | 42 import com.oracle.truffle.sl.runtime.*; |
36 | 43 import com.oracle.truffle.sl.test.SLTestRunner.TestCase; |
37 public class SLTestRunner { | 44 |
45 public final class SLTestRunner extends ParentRunner<TestCase> { | |
38 | 46 |
39 private static final int REPEATS = 10; | 47 private static final int REPEATS = 10; |
40 private static final String TEST_DIR = "graal/com.oracle.truffle.sl.test/tests"; | 48 |
41 private static final String INPUT_SUFFIX = ".sl"; | 49 private static final String INPUT_SUFFIX = ".sl"; |
42 private static final String OUTPUT_SUFFIX = ".output"; | 50 private static final String OUTPUT_SUFFIX = ".output"; |
43 | 51 |
44 static class TestCase { | 52 private static final String LF = System.getProperty("line.separator"); |
45 protected final String name; | 53 |
46 protected final Source input; | 54 public static final class TestCase { |
47 protected final String expectedOutput; | 55 private final Source input; |
48 protected String actualOutput; | 56 private final String expectedOutput; |
49 | 57 private final Description name; |
50 protected TestCase(String name, Source input, String expectedOutput) { | 58 |
51 this.name = name; | 59 public TestCase(Class<?> testClass, String name, Source input, String expectedOutput) { |
52 this.input = input; | 60 this.input = input; |
53 this.expectedOutput = expectedOutput; | 61 this.expectedOutput = expectedOutput; |
54 } | 62 this.name = Description.createTestDescription(testClass, name); |
55 } | 63 } |
56 | 64 } |
57 protected boolean useConsole = false; | 65 |
58 | 66 private final SourceManager sourceManager = new SourceManager(); |
59 protected final SourceManager sourceManager = new SourceManager(); | 67 private final List<TestCase> testCases; |
60 protected final List<TestCase> testCases = new ArrayList<>(); | 68 |
61 | 69 public SLTestRunner(Class<?> runningClass) throws InitializationError { |
62 protected boolean runTests(String namePattern) throws IOException { | 70 super(runningClass); |
63 Path testsRoot = FileSystems.getDefault().getPath(TEST_DIR); | 71 try { |
64 | 72 testCases = createTests(runningClass); |
65 Files.walkFileTree(testsRoot, new SimpleFileVisitor<Path>() { | 73 } catch (IOException e) { |
74 throw new InitializationError(e); | |
75 } | |
76 } | |
77 | |
78 @Override | |
79 protected Description describeChild(TestCase child) { | |
80 return child.name; | |
81 } | |
82 | |
83 @Override | |
84 protected List<TestCase> getChildren() { | |
85 return testCases; | |
86 } | |
87 | |
88 @Override | |
89 public void filter(Filter filter) throws NoTestsRemainException { | |
90 super.filter(filter); | |
91 } | |
92 | |
93 protected List<TestCase> createTests(final Class<?> c) throws IOException, InitializationError { | |
94 SLTestSuite suite = c.getAnnotation(SLTestSuite.class); | |
95 if (suite == null) { | |
96 throw new InitializationError(String.format("@%s annotation required on class '%s' to run with '%s'.", SLTestSuite.class.getSimpleName(), c.getName(), SLTestRunner.class.getSimpleName())); | |
97 } | |
98 | |
99 String[] pathes = suite.value(); | |
100 | |
101 Path root = null; | |
102 for (String path : pathes) { | |
103 root = FileSystems.getDefault().getPath(path); | |
104 if (Files.exists(root)) { | |
105 break; | |
106 } | |
107 } | |
108 if (root == null && pathes.length > 0) { | |
109 throw new FileNotFoundException(pathes[0]); | |
110 } | |
111 | |
112 final Path rootPath = root; | |
113 | |
114 final List<TestCase> foundCases = new ArrayList<>(); | |
115 Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() { | |
66 @Override | 116 @Override |
67 public FileVisitResult visitFile(Path inputFile, BasicFileAttributes attrs) throws IOException { | 117 public FileVisitResult visitFile(Path inputFile, BasicFileAttributes attrs) throws IOException { |
68 String name = inputFile.getFileName().toString(); | 118 String name = inputFile.getFileName().toString(); |
69 if (name.endsWith(INPUT_SUFFIX)) { | 119 if (name.endsWith(INPUT_SUFFIX)) { |
70 name = name.substring(0, name.length() - INPUT_SUFFIX.length()); | 120 String baseName = name.substring(0, name.length() - INPUT_SUFFIX.length()); |
71 Path outputFile = inputFile.resolveSibling(name + OUTPUT_SUFFIX); | 121 |
122 Path outputFile = inputFile.resolveSibling(baseName + OUTPUT_SUFFIX); | |
72 if (!Files.exists(outputFile)) { | 123 if (!Files.exists(outputFile)) { |
73 throw new Error("Output file does not exist: " + outputFile); | 124 throw new Error("Output file does not exist: " + outputFile); |
74 } | 125 } |
75 | 126 |
76 testCases.add(new TestCase(name, sourceManager.get(inputFile.toString()), new String(Files.readAllBytes(outputFile)))); | 127 // fix line feeds for non unix os |
128 StringBuilder outFile = new StringBuilder(); | |
129 for (String line : Files.readAllLines(outputFile, Charset.defaultCharset())) { | |
130 outFile.append(line); | |
131 outFile.append(LF); | |
132 } | |
133 foundCases.add(new TestCase(c, baseName, sourceManager.get(inputFile.toString()), outFile.toString())); | |
77 } | 134 } |
78 return FileVisitResult.CONTINUE; | 135 return FileVisitResult.CONTINUE; |
79 } | 136 } |
80 }); | 137 }); |
81 | 138 return foundCases; |
82 if (testCases.size() == 0) { | 139 } |
83 System.out.format("No test cases match filter %s", namePattern); | 140 |
84 return false; | 141 @Override |
85 } | 142 protected void runChild(TestCase testCase, RunNotifier notifier) { |
86 | 143 notifier.fireTestStarted(testCase.name); |
87 boolean success = true; | |
88 for (TestCase testCase : testCases) { | |
89 if (namePattern.length() == 0 || testCase.name.toLowerCase().contains(namePattern.toLowerCase())) { | |
90 success = success & executeTest(testCase); | |
91 } | |
92 } | |
93 return success; | |
94 } | |
95 | |
96 protected boolean executeTest(TestCase testCase) { | |
97 System.out.format("Running %s\n", testCase.name); | |
98 | 144 |
99 ByteArrayOutputStream out = new ByteArrayOutputStream(); | 145 ByteArrayOutputStream out = new ByteArrayOutputStream(); |
100 PrintStream printer = new PrintStream(useConsole ? new SplitOutputStream(out, System.err) : out); | 146 PrintStream printer = new PrintStream(out); |
101 PrintStream origErr = System.err; | 147 PrintStream origErr = System.err; |
102 try { | 148 try { |
103 System.setErr(printer); | 149 System.setErr(printer); |
104 SLContext context = new SLContext(sourceManager, printer); | 150 SLContext context = new SLContext(sourceManager, printer); |
105 SLMain.run(context, testCase.input, null, REPEATS); | 151 SLMain.run(context, testCase.input, null, REPEATS); |
152 | |
153 String actualOutput = new String(out.toByteArray()); | |
154 | |
155 Assert.assertEquals(repeat(testCase.expectedOutput, REPEATS), actualOutput); | |
156 } catch (AssertionError e) { | |
157 notifier.fireTestFailure(new Failure(testCase.name, e)); | |
106 } catch (Throwable ex) { | 158 } catch (Throwable ex) { |
107 ex.printStackTrace(printer); | 159 notifier.fireTestFailure(new Failure(testCase.name, ex)); |
108 } finally { | 160 } finally { |
109 System.setErr(origErr); | 161 System.setErr(origErr); |
110 } | 162 notifier.fireTestFinished(testCase.name); |
111 testCase.actualOutput = new String(out.toByteArray()); | |
112 | |
113 if (testCase.actualOutput.equals(repeat(testCase.expectedOutput, REPEATS))) { | |
114 System.out.format("OK %s\n", testCase.name); | |
115 return true; | |
116 } else { | |
117 if (!useConsole) { | |
118 System.out.format("== Expected ==\n%s\n", testCase.expectedOutput); | |
119 System.out.format("== Actual ==\n%s\n", testCase.actualOutput); | |
120 } | |
121 System.out.format("FAILED %s\n", testCase.name); | |
122 return false; | |
123 } | 163 } |
124 } | 164 } |
125 | 165 |
126 private static String repeat(String s, int count) { | 166 private static String repeat(String s, int count) { |
127 StringBuilder result = new StringBuilder(s.length() * count); | 167 StringBuilder result = new StringBuilder(s.length() * count); |
129 result.append(s); | 169 result.append(s); |
130 } | 170 } |
131 return result.toString(); | 171 return result.toString(); |
132 } | 172 } |
133 | 173 |
134 public static void main(String[] args) throws IOException { | 174 public static void runInMain(Class<?> testClass, String[] args) throws InitializationError, NoTestsRemainException { |
135 String namePattern = ""; | 175 JUnitCore core = new JUnitCore(); |
176 core.addListener(new TextListener(System.out)); | |
177 SLTestRunner suite = new SLTestRunner(testClass); | |
136 if (args.length > 0) { | 178 if (args.length > 0) { |
137 namePattern = args[0]; | 179 suite.filter(new NameFilter(args[0])); |
138 } | 180 } |
139 boolean success = new SLTestRunner().runTests(namePattern); | 181 Result r = core.run(suite); |
140 if (!success) { | 182 if (!r.wasSuccessful()) { |
141 System.exit(1); | 183 System.exit(1); |
142 } | 184 } |
143 } | 185 } |
144 | 186 |
145 @Test | 187 private static final class NameFilter extends Filter { |
146 public void test() throws IOException { | 188 private final String pattern; |
147 Assert.assertTrue(runTests("")); | 189 |
148 } | 190 private NameFilter(String pattern) { |
191 this.pattern = pattern.toLowerCase(); | |
192 } | |
193 | |
194 @Override | |
195 public boolean shouldRun(Description description) { | |
196 return description.getMethodName().toLowerCase().contains(pattern); | |
197 } | |
198 | |
199 @Override | |
200 public String describe() { | |
201 return "Filter contains " + pattern; | |
202 } | |
203 } | |
204 | |
149 } | 205 } |