Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java @ 18485:e3c95cbbb50c
Truffle Instrumentation: major API revision, based around the Probe and Instrument classes; add Instrumentable API for language implementors, with most details automated; reimplemented to handle AST splitting automatically; more JUnit tests.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Sun, 23 Nov 2014 16:07:23 -0800 |
parents | dc2e000bed40 |
children | 128586040207 |
comparison
equal
deleted
inserted
replaced
18484:e97e1f07a3d6 | 18485:e3c95cbbb50c |
---|---|
34 import org.junit.runner.manipulation.*; | 34 import org.junit.runner.manipulation.*; |
35 import org.junit.runner.notification.*; | 35 import org.junit.runner.notification.*; |
36 import org.junit.runners.*; | 36 import org.junit.runners.*; |
37 import org.junit.runners.model.*; | 37 import org.junit.runners.model.*; |
38 | 38 |
39 import com.oracle.truffle.api.*; | 39 import com.oracle.truffle.api.frame.*; |
40 import com.oracle.truffle.api.instrument.*; | 40 import com.oracle.truffle.api.instrument.*; |
41 import com.oracle.truffle.api.instrument.impl.*; | |
42 import com.oracle.truffle.api.nodes.*; | |
41 import com.oracle.truffle.api.source.*; | 43 import com.oracle.truffle.api.source.*; |
44 import com.oracle.truffle.sl.factory.*; | |
42 import com.oracle.truffle.sl.nodes.instrument.*; | 45 import com.oracle.truffle.sl.nodes.instrument.*; |
46 import com.oracle.truffle.sl.nodes.local.*; | |
43 import com.oracle.truffle.sl.parser.*; | 47 import com.oracle.truffle.sl.parser.*; |
44 import com.oracle.truffle.sl.runtime.*; | 48 import com.oracle.truffle.sl.runtime.*; |
45 import com.oracle.truffle.sl.test.instrument.SLInstrumentTestRunner.InstrumentTestCase; | 49 import com.oracle.truffle.sl.test.instrument.SLInstrumentTestRunner.InstrumentTestCase; |
46 | 50 |
47 /** | 51 /** |
83 | 87 |
84 private final List<InstrumentTestCase> testCases; | 88 private final List<InstrumentTestCase> testCases; |
85 | 89 |
86 public SLInstrumentTestRunner(Class<?> testClass) throws InitializationError { | 90 public SLInstrumentTestRunner(Class<?> testClass) throws InitializationError { |
87 super(testClass); | 91 super(testClass); |
92 final SLStandardASTProber prober = new SLStandardASTProber(); | |
93 Probe.registerASTProber(prober); | |
88 try { | 94 try { |
89 testCases = createTests(testClass); | 95 testCases = createTests(testClass); |
90 } catch (IOException e) { | 96 } catch (IOException e) { |
91 throw new InitializationError(e); | 97 throw new InitializationError(e); |
98 } finally { | |
99 Probe.unregisterASTProber(prober); | |
92 } | 100 } |
93 } | 101 } |
94 | 102 |
95 @Override | 103 @Override |
96 protected List<InstrumentTestCase> getChildren() { | 104 protected List<InstrumentTestCase> getChildren() { |
195 // TODO Current tests are hard-coded, automate this eventually | 203 // TODO Current tests are hard-coded, automate this eventually |
196 notifier.fireTestStarted(testCase.name); | 204 notifier.fireTestStarted(testCase.name); |
197 | 205 |
198 ByteArrayOutputStream out = new ByteArrayOutputStream(); | 206 ByteArrayOutputStream out = new ByteArrayOutputStream(); |
199 PrintStream printer = new PrintStream(out); | 207 PrintStream printer = new PrintStream(out); |
208 final ASTProber prober = new SLStandardASTProber(); | |
209 Probe.registerASTProber(prober); | |
200 try { | 210 try { |
201 // We use the name of the file to determine what visitor to attach to it. | 211 // We use the name of the file to determine what visitor to attach to it. |
202 if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) { | 212 if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) { |
203 // Set up the execution context for Simple and register our two listeners | 213 // Set up the execution context for Simple and register our two listeners |
204 slContext = new SLContext(new BufferedReader(new StringReader(testCase.testInput)), printer); | 214 slContext = SLContextFactory.create(new BufferedReader(new StringReader(testCase.testInput)), printer); |
205 | 215 |
206 final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName); | 216 final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName); |
207 Parser.parseSL(slContext, source); | 217 Parser.parseSL(slContext, source); |
208 List<SLFunction> functionList = slContext.getFunctionRegistry().getFunctions(); | 218 |
209 | 219 // Attach an instrument to every probe tagged as an assignment |
210 // Since only functions can be global in SL, this guarantees that we instrument | 220 for (Probe probe : Probe.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) { |
211 // everything of interest. Parsing must occur before accepting the visitors since | 221 SLPrintAssigmentValueReciever slPrintAssigmentValueReceiver = new SLPrintAssigmentValueReciever(printer); |
212 // the visitor which creates our instrumentation points expects a complete AST. | 222 probe.attach(Instrument.create(slPrintAssigmentValueReceiver, "SL print assignment value")); |
213 | |
214 for (SLFunction function : functionList) { | |
215 RootCallTarget rootCallTarget = function.getCallTarget(); | |
216 if (rootCallTarget != null) { | |
217 rootCallTarget.getRootNode().accept(new SLInstrumenter()); | |
218 } | |
219 } | |
220 | |
221 // We iterate over all tags the SLInsturmenter tagged as assignments and attach our | |
222 // test instrument to those. | |
223 for (Probe probe : slContext.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) { | |
224 if (probe.isTaggedAs(StandardSyntaxTag.ASSIGNMENT)) { | |
225 probe.addInstrument(new SLPrintAssigmentValueInstrument(printer)); | |
226 } | |
227 } | 223 } |
228 | 224 |
229 SLFunction main = slContext.getFunctionRegistry().lookup("main"); | 225 SLFunction main = slContext.getFunctionRegistry().lookup("main"); |
230 main.getCallTarget().call(); | 226 main.getCallTarget().call(); |
231 } else { | 227 } else { |
235 String actualOutput = new String(out.toByteArray()); | 231 String actualOutput = new String(out.toByteArray()); |
236 Assert.assertEquals(testCase.expectedOutput, actualOutput); | 232 Assert.assertEquals(testCase.expectedOutput, actualOutput); |
237 } catch (Throwable ex) { | 233 } catch (Throwable ex) { |
238 notifier.fireTestFailure(new Failure(testCase.name, ex)); | 234 notifier.fireTestFailure(new Failure(testCase.name, ex)); |
239 } finally { | 235 } finally { |
236 Probe.unregisterASTProber(prober); | |
240 notifier.fireTestFinished(testCase.name); | 237 notifier.fireTestFinished(testCase.name); |
241 } | 238 } |
242 | 239 |
243 } | 240 } |
244 | 241 |
270 @Override | 267 @Override |
271 public String describe() { | 268 public String describe() { |
272 return "Filter contains " + pattern; | 269 return "Filter contains " + pattern; |
273 } | 270 } |
274 } | 271 } |
272 | |
273 /** | |
274 * This sample instrument receiver provides prints the value of an assignment (after the | |
275 * assignment is complete) to the {@link PrintStream} specified in the constructor. This | |
276 * instrument can only be attached to a wrapped {@link SLWriteLocalVariableNode}, but provides | |
277 * no guards to protect it from being attached elsewhere. | |
278 */ | |
279 public final class SLPrintAssigmentValueReciever extends DefaultEventReceiver { | |
280 | |
281 private PrintStream output; | |
282 | |
283 public SLPrintAssigmentValueReciever(PrintStream output) { | |
284 this.output = output; | |
285 } | |
286 | |
287 @Override | |
288 public void returnValue(Node node, VirtualFrame frame, Object result) { | |
289 output.println(result); | |
290 } | |
291 } | |
292 | |
275 } | 293 } |