Mercurial > hg > truffle
diff truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java @ 21951:9c8c0937da41
Moving all sources into truffle subdirectory
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Wed, 17 Jun 2015 10:58:08 +0200 |
parents | graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java@894f82515e38 |
children | c07e64ecb528 fee42ec8c59b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Wed Jun 17 10:58:08 2015 +0200 @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.sl.test; + +import java.io.*; +import java.nio.charset.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.util.*; + +import org.junit.*; +import org.junit.internal.*; +import org.junit.runner.*; +import org.junit.runner.manipulation.*; +import org.junit.runner.notification.*; +import org.junit.runners.*; +import org.junit.runners.model.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.vm.*; +import com.oracle.truffle.sl.*; +import com.oracle.truffle.sl.builtins.*; +import com.oracle.truffle.sl.test.SLTestRunner.TestCase; + +public final class SLTestRunner extends ParentRunner<TestCase> { + + private static int repeats = 1; + + private static final String SOURCE_SUFFIX = ".sl"; + private static final String INPUT_SUFFIX = ".input"; + private static final String OUTPUT_SUFFIX = ".output"; + + private static final String LF = System.getProperty("line.separator"); + + static class TestCase { + protected final Description name; + protected final Path path; + protected final String sourceName; + protected final String testInput; + protected final String expectedOutput; + protected String actualOutput; + + protected TestCase(Class<?> testClass, String baseName, String sourceName, Path path, String testInput, String expectedOutput) { + this.name = Description.createTestDescription(testClass, baseName); + this.sourceName = sourceName; + this.path = path; + this.testInput = testInput; + this.expectedOutput = expectedOutput; + } + } + + private final List<TestCase> testCases; + + public SLTestRunner(Class<?> runningClass) throws InitializationError { + super(runningClass); + try { + testCases = createTests(runningClass); + } catch (IOException e) { + throw new InitializationError(e); + } + } + + @Override + protected Description describeChild(TestCase child) { + return child.name; + } + + @Override + protected List<TestCase> getChildren() { + return testCases; + } + + protected static List<TestCase> createTests(final Class<?> c) throws IOException, InitializationError { + SLTestSuite suite = c.getAnnotation(SLTestSuite.class); + if (suite == null) { + throw new InitializationError(String.format("@%s annotation required on class '%s' to run with '%s'.", SLTestSuite.class.getSimpleName(), c.getName(), SLTestRunner.class.getSimpleName())); + } + + String[] pathes = suite.value(); + + Path root = null; + for (String path : pathes) { + root = FileSystems.getDefault().getPath(path); + if (Files.exists(root)) { + break; + } + } + if (root == null && pathes.length > 0) { + throw new FileNotFoundException(pathes[0]); + } + + final Path rootPath = root; + + final List<TestCase> foundCases = new ArrayList<>(); + Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { + String sourceName = sourceFile.getFileName().toString(); + if (sourceName.endsWith(SOURCE_SUFFIX)) { + String baseName = sourceName.substring(0, sourceName.length() - SOURCE_SUFFIX.length()); + + Path inputFile = sourceFile.resolveSibling(baseName + INPUT_SUFFIX); + String testInput = ""; + if (Files.exists(inputFile)) { + testInput = readAllLines(inputFile); + } + + Path outputFile = sourceFile.resolveSibling(baseName + OUTPUT_SUFFIX); + String expectedOutput = ""; + if (Files.exists(outputFile)) { + expectedOutput = readAllLines(outputFile); + } + + foundCases.add(new TestCase(c, baseName, sourceName, sourceFile, testInput, expectedOutput)); + } + return FileVisitResult.CONTINUE; + } + }); + return foundCases; + } + + private static String readAllLines(Path file) throws IOException { + // fix line feeds for non unix os + StringBuilder outFile = new StringBuilder(); + for (String line : Files.readAllLines(file, Charset.defaultCharset())) { + outFile.append(line).append(LF); + } + return outFile.toString(); + } + + public static void setRepeats(int repeats) { + SLTestRunner.repeats = repeats; + } + + private static final List<NodeFactory<? extends SLBuiltinNode>> builtins = new ArrayList<>(); + + public static void installBuiltin(NodeFactory<? extends SLBuiltinNode> builtin) { + builtins.add(builtin); + } + + @Override + protected void runChild(TestCase testCase, RunNotifier notifier) { + notifier.fireTestStarted(testCase.name); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrintWriter printer = new PrintWriter(out); + try { + TruffleVM vm = TruffleVM.newVM().stdIn(new BufferedReader(new StringReader(repeat(testCase.testInput, repeats)))).stdOut(printer).build(); + + String script = readAllLines(testCase.path); + SLLanguage.run(vm, testCase.path.toUri(), null, printer, repeats, builtins); + + printer.flush(); + String actualOutput = new String(out.toByteArray()); + Assert.assertEquals(script, repeat(testCase.expectedOutput, repeats), actualOutput); + } catch (Throwable ex) { + notifier.fireTestFailure(new Failure(testCase.name, new IllegalStateException("Cannot run " + testCase.sourceName, ex))); + } finally { + notifier.fireTestFinished(testCase.name); + } + } + + private static String repeat(String s, int count) { + StringBuilder result = new StringBuilder(s.length() * count); + for (int i = 0; i < count; i++) { + result.append(s); + } + return result.toString(); + } + + public static void runInMain(Class<?> testClass, String[] args) throws InitializationError, NoTestsRemainException { + JUnitCore core = new JUnitCore(); + core.addListener(new TextListener(System.out)); + SLTestRunner suite = new SLTestRunner(testClass); + if (args.length > 0) { + suite.filter(new NameFilter(args[0])); + } + Result r = core.run(suite); + if (!r.wasSuccessful()) { + System.exit(1); + } + } + + private static final class NameFilter extends Filter { + private final String pattern; + + private NameFilter(String pattern) { + this.pattern = pattern.toLowerCase(); + } + + @Override + public boolean shouldRun(Description description) { + return description.getMethodName().toLowerCase().contains(pattern); + } + + @Override + public String describe() { + return "Filter contains " + pattern; + } + } + +}