/** * Executes the passed in test case. Instrumentation is added according to the name of the file as * explained in {@link #createTests(Class)}. Note that this code is not generalizable. */ @Override protected void runChild(InstrumentTestCase testCase, RunNotifier notifier) { // TODO Current tests are hard-coded, automate this eventually notifier.fireTestStarted(testCase.name); ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(out); PolyglotEngine vm = null; try { // We use the name of the file to determine what visitor to attach to it. if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) { // Set up the execution context for Simple and register our two listeners vm = PolyglotEngine.newBuilder() .setIn(new ByteArrayInputStream(testCase.testInput.getBytes("UTF-8"))) .setOut(out) .build(); final String src = readAllLines(testCase.path); vm.eval(Source.fromText(src, testCase.path.toString()).withMimeType("application/x-sl")); PolyglotEngine.Value main = vm.findGlobalSymbol("main"); main.execute(); } else { notifier.fireTestFailure( new Failure( testCase.name, new UnsupportedOperationException("No instrumentation found."))); } ps.flush(); String actualOutput = new String(out.toByteArray()); Assert.assertEquals(testCase.expectedOutput, actualOutput); } catch (Throwable ex) { notifier.fireTestFailure(new Failure(testCase.name, ex)); } finally { if (vm != null) { vm.dispose(); } notifier.fireTestFinished(testCase.name); } }
/** * The read-eval-print loop, which can take input from a console, command line expression or a * file. There are two ways the repl can terminate: * * <ol> * <li>A {@code quit} command is executed successfully, which case the system exits from the * {@link Quit} {@code .Internal} . * <li>EOF on the input. * </ol> * * In case 2, we must implicitly execute a {@code quit("default, 0L, TRUE} command before exiting. * So,in either case, we never return. */ static int readEvalPrint(PolyglotEngine vm) { int lastStatus = 0; ContextInfo contextInfo = ContextInfo.getContextInfo(vm); ConsoleHandler consoleHandler = contextInfo.getConsoleHandler(); try { // console.println("initialize time: " + (System.currentTimeMillis() - start)); REPL: for (; ; ) { boolean doEcho = doEcho(vm); consoleHandler.setPrompt(doEcho ? "> " : null); try { String input = consoleHandler.readLine(); if (input == null) { throw new EOFException(); } String trInput = input.trim(); if (trInput.equals("") || trInput.charAt(0) == '#') { // nothing to parse continue; } String continuePrompt = getContinuePrompt(); StringBuffer sb = new StringBuffer(input); Source source = RSource.fromTextInternal(sb.toString(), RSource.Internal.SHELL_INPUT); while (true) { lastStatus = 0; try { try { vm.eval(source); // checked exceptions are wrapped in RuntimeExceptions } catch (RuntimeException e) { if (e.getCause() instanceof com.oracle.truffle.api.vm.IncompleteSourceException) { throw e.getCause().getCause(); } throw e; } } catch (IncompleteSourceException e) { // read another line of input consoleHandler.setPrompt(doEcho ? continuePrompt : null); String additionalInput = consoleHandler.readLine(); if (additionalInput == null) { throw new EOFException(); } sb.append(additionalInput); source = RSource.fromTextInternal(sb.toString(), RSource.Internal.SHELL_INPUT); // The only continuation in the while loop continue; } catch (ParseException e) { e.report(consoleHandler); lastStatus = 1; } catch (RError e) { // drop through to continue REPL and remember last eval was an error lastStatus = 1; } catch (JumpToTopLevelException e) { // drop through to continue REPL } catch (DebugExitException e) { throw (RuntimeException) e.getCause(); } catch (ExitException e) { // usually from quit int status = e.getStatus(); if (contextInfo.getParent() == null) { vm.dispose(); Utils.systemExit(status); } else { return status; } } catch (Throwable e) { RInternalError.reportErrorAndConsoleLog(e, consoleHandler, 0); // We continue the repl even though the system may be broken lastStatus = 1; } continue REPL; } } catch (UserInterruptException e) { // interrupted by ctrl-c } } } catch (JumpToTopLevelException | EOFException ex) { // JumpToTopLevelException can happen if user profile invokes browser (unlikely but // possible) try { vm.eval(QUIT_EOF); } catch (JumpToTopLevelException e) { Utils.systemExit(0); } catch (ExitException e) { // normal quit, but with exit code based on lastStatus if (contextInfo.getParent() == null) { Utils.systemExit(lastStatus); } else { return lastStatus; } } catch (Throwable e) { throw RInternalError.shouldNotReachHere(e); } } finally { vm.dispose(); } return 0; }