From 4767e5c93533ed5347c2ae4d8cec045e7366b8ba Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 23 Jan 2012 03:37:09 +0400 Subject: [PATCH] split TestlibTest into two tests * old tests attaches stdlib sources to testlib classpath * new test compiles stdlib into stdlib.jar and then adds stdlib.jar to testlib classpath --- .../jet/codegen/GeneratedClassLoader.java | 6 +- .../tests/org/jetbrains/jet/JetTestUtils.java | 14 ++- .../jet/codegen/ForTestCompileStdlib.java | 116 ++++++++++++++++++ ...{TestlibTest.java => TestlibTestBase.java} | 48 ++++++-- .../codegen/TestlibWithStdlibBinaryTest.java | 18 +++ .../jet/codegen/TestlibWithStdlibSrcTest.java | 18 +++ 6 files changed, 205 insertions(+), 15 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java rename compiler/tests/org/jetbrains/jet/codegen/{TestlibTest.java => TestlibTestBase.java} (81%) create mode 100644 compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibBinaryTest.java create mode 100644 compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibSrcTest.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java index f9f9e790c8f..ec8a3eaffdd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java @@ -9,7 +9,11 @@ public class GeneratedClassLoader extends ClassLoader { private final ClassFileFactory state; public GeneratedClassLoader(@NotNull ClassFileFactory state) { - super(GeneratedClassLoader.class.getClassLoader()); + this(state, GeneratedClassLoader.class.getClassLoader()); + } + + public GeneratedClassLoader(@NotNull ClassFileFactory state, ClassLoader parentClassLoader) { + super(parentClassLoader); this.state = state; } diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 59f6207f9ee..3d1dee44547 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -172,8 +172,20 @@ public class JetTestUtils { } } + public static File tmpRoot() { + return new File("tmp"); + } + public static File tmpDirForTest(TestCase test) { - return new File("tmp/" + test.getClass().getSimpleName() + "/" + test.getName()); + return new File(tmpRoot(), test.getClass().getSimpleName() + "/" + test.getName()); + } + + public static File tmpDirForTest(Class clazz) { + return tmpDirForTest(clazz.getSimpleName()); + } + + public static File tmpDirForTest(String name) { + return new File(tmpRoot(), name); } public static void recreateDirectory(File file) throws IOException { diff --git a/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java new file mode 100644 index 00000000000..5e5e866eb77 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java @@ -0,0 +1,116 @@ +package org.jetbrains.jet.codegen; + +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.intellij.openapi.util.Pair; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.cli.KotlinCompiler; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Stack; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +/** + * Compile stdlib.jar that can be used in tests + * + * @see #stdlibJarForTests() + * + * @author Stepan Koltsov + */ +class ForTestCompileStdlib { + + public static final File stdlibJarForTests = new File( + JetTestUtils.tmpDirForTest(ForTestCompileStdlib.class), "stdlib.jar"); + + private static boolean compiled = false; + + static void compileStdlibForTest() { + if (compiled) { + return; + } + + try { + doCompile(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + compiled = true; + } + + private static void doCompile() throws Exception { + System.err.println("compiling stdlib for tests, resulting file: " + stdlibJarForTests); + + File tmp = new File(stdlibJarForTests.getPath() + "~"); + JetTestUtils.mkdirs(tmp.getParentFile()); + + FileOutputStream stdlibJar = new FileOutputStream(tmp); + try { + JarOutputStream jarOutputStream = new JarOutputStream(stdlibJar); + + copyJavaPartOfStdlib(jarOutputStream); + compileKotlinPartOfStdlibToJar(jarOutputStream); + + jarOutputStream.close(); + stdlibJar.close(); + + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + stdlibJar.close(); + } catch (Throwable e) { } + } + + if (!tmp.renameTo(stdlibJarForTests)) { + throw new RuntimeException(); + } + } + + private static void copyJavaPartOfStdlib(JarOutputStream os) throws IOException { + File root = new File("out/production/stdlib"); + if (!new File(root, "jet/JetObject.class").isFile()) { + throw new RuntimeException(); + } + + copyToJar(root, os); + } + + private static void copyToJar(File root, JarOutputStream os) throws IOException { + Stack> toCopy = new Stack>(); + toCopy.add(new Pair("", root)); + while (!toCopy.empty()) { + Pair pop = toCopy.pop(); + File file = pop.getSecond(); + if (file.isFile()) { + os.putNextEntry(new JarEntry(pop.getFirst())); + Files.copy(file, os); + } else if (file.isDirectory()) { + for (File child : file.listFiles()) { + String path = pop.getFirst().isEmpty() ? child.getName() : pop.getFirst() + "/" + child.getName(); + toCopy.add(new Pair(path, child)); + } + } else { + throw new IllegalStateException(); + } + } + } + + private static void compileKotlinPartOfStdlibToJar(JarOutputStream jarOutputStream) throws IOException { + File file = JetTestUtils.tmpDirForTest(ForTestCompileStdlib.class + "/stdlib-kt"); + JetTestUtils.recreateDirectory(file); + // lame + KotlinCompiler.main("-excludeStdlib", "-output", file.getPath(), "-src", "./stdlib/ktSrc"); + copyToJar(file, jarOutputStream); + } + + + public static File stdlibJarForTests() { + compileStdlibForTest(); + return stdlibJarForTests; + } + +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/TestlibTestBase.java similarity index 81% rename from compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java rename to compiler/tests/org/jetbrains/jet/codegen/TestlibTestBase.java index 67bb0336481..3eef4a16e06 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TestlibTestBase.java @@ -26,12 +26,19 @@ import java.util.Set; /** * @author alex.tkachman */ -public class TestlibTest extends CodegenTestCase { - public static TestSuite suite() { - TestlibTest testlibTest = new TestlibTest(); +public abstract class TestlibTestBase extends CodegenTestCase { + + /** Binary or source */ + private final boolean binary; + + protected TestlibTestBase(boolean binary) { + this.binary = binary; + } + + protected TestSuite buildSuite() { try { - testlibTest.setUp(); - return testlibTest.buildSuite(); + setUp(); + return doBuildSuite(); } catch (RuntimeException e) { throw e; } catch (Exception e) { @@ -39,20 +46,25 @@ public class TestlibTest extends CodegenTestCase { } finally { try { - testlibTest.tearDown(); + tearDown(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } - } - - public TestSuite buildSuite () { + + private TestSuite doBuildSuite() { try { CompileSession session = new CompileSession(myEnvironment); - CompileEnvironment.initializeKotlinRuntime(myEnvironment); + + if (binary) { + myEnvironment.addToClasspath(ForTestCompileStdlib.stdlibJarForTests()); + } else { + CompileEnvironment.initializeKotlinRuntime(myEnvironment); + } + URLClassLoader classLoader = (URLClassLoader) TestCase.class.getClassLoader(); CoreLocalFileSystem localFileSystem = myEnvironment.getLocalFileSystem(); for(URL url: classLoader.getURLs()) { @@ -65,14 +77,24 @@ public class TestlibTest extends CodegenTestCase { } VirtualFile path = localFileSystem.findFileByPath(JetParsingTest.getTestDataDir() + "/../../testlib/test"); session.addSources(path); - session.addStdLibSources(true); + + if (!binary) { + session.addStdLibSources(true); + } if (!session.analyze(System.out)) { throw new RuntimeException(); } ClassFileFactory classFileFactory = session.generate(); - GeneratedClassLoader loader = new GeneratedClassLoader(classFileFactory); + GeneratedClassLoader loader; + if (binary) { + URLClassLoader parentClassLoader = new URLClassLoader(new URL[]{ + ForTestCompileStdlib.stdlibJarForTests().toURI().toURL() }); + loader = new GeneratedClassLoader(classFileFactory, parentClassLoader); + } else { + loader = new GeneratedClassLoader(classFileFactory); + } JetTypeMapper typeMapper = new JetTypeMapper(classFileFactory.state.getStandardLibrary(), session.getMyBindingContext()); TestSuite suite = new TestSuite("StandardLibrary"); @@ -122,7 +144,7 @@ public class TestlibTest extends CodegenTestCase { throw new RuntimeException(e); } } - + @Override public void setUp() throws Exception { super.setUp(); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibBinaryTest.java b/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibBinaryTest.java new file mode 100644 index 00000000000..ec4eb70f1e0 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibBinaryTest.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.codegen; + +import junit.framework.TestSuite; + +/** + * @author Stepan Koltsov + */ +public class TestlibWithStdlibBinaryTest extends TestlibTestBase { + + protected TestlibWithStdlibBinaryTest() { + super(true); + } + + public static TestSuite suite() { + return new TestlibWithStdlibBinaryTest().buildSuite(); + } + +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibSrcTest.java b/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibSrcTest.java new file mode 100644 index 00000000000..e19153458e4 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/TestlibWithStdlibSrcTest.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.codegen; + +import junit.framework.TestSuite; + +/** + * @author Stepan Koltsov + */ +public class TestlibWithStdlibSrcTest extends TestlibTestBase { + + protected TestlibWithStdlibSrcTest() { + super(false); + } + + public static TestSuite suite() { + return new TestlibWithStdlibSrcTest().buildSuite(); + } + +}