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
This commit is contained in:
Stepan Koltsov
2012-01-23 03:37:09 +04:00
parent 19b206378d
commit 4767e5c935
6 changed files with 205 additions and 15 deletions
@@ -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;
}
@@ -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 {
@@ -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<Pair<String, File>> toCopy = new Stack<Pair<String, File>>();
toCopy.add(new Pair<String, File>("", root));
while (!toCopy.empty()) {
Pair<String, File> 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<String, File>(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;
}
}
@@ -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();
@@ -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();
}
}
@@ -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();
}
}