# HG changeset patch # User Doug Simon # Date 1443603717 -7200 # Node ID 0995fbcf3e60e607188f27efc1c91d0afc2d55ee # Parent 3d9e283e2487a7e79759f6fca69ee0d2a0caf240 SLTestRunner unpacks jars to temp directories to ensure SL test sources and expected output files in a jar are loadable diff -r 3d9e283e2487 -r 0995fbcf3e60 truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java --- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Tue Sep 29 18:04:11 2015 +0200 +++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Wed Sep 30 11:01:57 2015 +0200 @@ -40,16 +40,12 @@ */ package com.oracle.truffle.sl.test; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.vm.PolyglotEngine; -import com.oracle.truffle.sl.SLLanguage; -import com.oracle.truffle.sl.builtins.SLBuiltinNode; -import com.oracle.truffle.sl.test.SLTestRunner.TestCase; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.PrintStream; import java.io.PrintWriter; import java.net.URL; import java.nio.charset.Charset; @@ -60,8 +56,13 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + import org.junit.Assert; +import org.junit.Assume; import org.junit.internal.TextListener; import org.junit.runner.Description; import org.junit.runner.JUnitCore; @@ -73,6 +74,12 @@ import org.junit.runners.ParentRunner; import org.junit.runners.model.InitializationError; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.vm.PolyglotEngine; +import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.builtins.SLBuiltinNode; +import com.oracle.truffle.sl.test.SLTestRunner.TestCase; + public final class SLTestRunner extends ParentRunner { private static int repeats = 1; @@ -174,30 +181,80 @@ return foundCases; } + /** + * Recursively deletes a file that may represent a directory. + */ + private static void delete(File f) { + if (f.isDirectory()) { + for (File c : f.listFiles()) { + delete(c); + } + } + if (!f.delete()) { + PrintStream err = System.err; + err.println("Failed to delete file: " + f); + } + } + + /** + * Unpacks a jar file to a temporary directory that will be removed when the VM exits. + * + * @param jarfilePath the path of the jar to unpack + * @return the path of the temporary directory + */ + private static String explodeJarToTempDir(File jarfilePath) { + try { + final Path jarfileDir = Files.createTempDirectory(jarfilePath.getName()); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + delete(jarfileDir.toFile()); + } + }); + jarfileDir.toFile().deleteOnExit(); + JarFile jarfile = new JarFile(jarfilePath); + Enumeration entries = jarfile.entries(); + while (entries.hasMoreElements()) { + JarEntry e = entries.nextElement(); + if (!e.isDirectory()) { + File path = new File(jarfileDir.toFile(), e.getName().replace('/', File.separatorChar)); + File dir = path.getParentFile(); + dir.mkdirs(); + assert dir.exists(); + Files.copy(jarfile.getInputStream(e), path.toPath()); + } + } + return jarfileDir.toFile().getAbsolutePath(); + } catch (IOException e) { + throw new AssertionError(e); + } + } + public static Path getRootViaResourceURL(final Class c, String[] paths) { URL url = c.getResource(c.getSimpleName() + ".class"); if (url != null) { char sep = File.separatorChar; String externalForm = url.toExternalForm(); String classPart = sep + c.getName().replace('.', sep) + ".class"; - String suffix = null; String prefix = null; + String base; if (externalForm.startsWith("jar:file:")) { prefix = "jar:file:"; - suffix = sep + "build/truffle-sl.jar!" + classPart; + int bang = externalForm.indexOf('!', prefix.length()); + Assume.assumeTrue(bang != -1); + File jarfilePath = new File(externalForm.substring(prefix.length(), bang)); + Assume.assumeTrue(jarfilePath.exists()); + base = explodeJarToTempDir(jarfilePath); } else if (externalForm.startsWith("file:")) { prefix = "file:"; - suffix = classPart; + base = externalForm.substring(prefix.length(), externalForm.length() - classPart.length()); } else { return null; } - if (externalForm.endsWith(suffix)) { - String base = externalForm.substring(prefix.length(), externalForm.length() - suffix.length()); - for (String path : paths) { - String candidate = base + sep + path; - if (new File(candidate).exists()) { - return FileSystems.getDefault().getPath(candidate); - } + for (String path : paths) { + String candidate = base + sep + path; + if (new File(candidate).exists()) { + return FileSystems.getDefault().getPath(candidate); } } }