Parcel: Invoke box tests as an external process to prevent class clashes with IntelliJ platform
This commit is contained in:
committed by
Yan Zhulanow
parent
11b6382518
commit
5641909d1d
Generated
+15
-33
@@ -2,58 +2,40 @@
|
||||
<library name="robolectric">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/accessibility-test-framework-2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/android-all-6.0.0_r1-robolectric-0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/annotations-12.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-launcher-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-analysis-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-commons-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-tree-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/assertj-core-2.6.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/backport-util-concurrent-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-util-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/bcprov-jdk16-1.46.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/classworlds-1.1-alpha-2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/guava-20.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/guava-19.0-rc2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-core-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-library-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/icu4j-53.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/junit-4.8.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-ant-tasks-2.1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-manager-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-error-diagnostics-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-model-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-plugin-registry-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-profile-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-project-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-repository-metadata-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-settings-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/nekohtml-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-container-default-1.0-alpha-9-stable-1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-interpolation-1.11.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-utils-1.5.15.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/protobuf-java-2.6.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-annotations-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-junit-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-resources-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-sandbox-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-utils-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadow-api-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadows-core-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-annotations-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-resources-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-utils-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadows-core-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/sqlite4java-0.282.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-file-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-lightweight-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-shared-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-provider-api-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xercesMinimal-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/vtd-xml-2.11.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xmlpull-1.1.3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xpp3_min-1.1.4c.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xstream-1.4.8.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources-source.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-ant-tasks-2.1.3-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
+118
-28
@@ -22,52 +22,142 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.codegen.getClassFiles
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter.COMPUTE_MAXS
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.junit.runner.JUnitCore
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.ProtectionDomain
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
abstract class AbstractParcelBoxTest : CodegenTestCase() {
|
||||
protected companion object {
|
||||
val BASE_DIR = "plugins/android-extensions/android-extensions-compiler/testData/parcel/box"
|
||||
val LIBRARY_KT = File(File(BASE_DIR).parentFile, "boxLib.kt")
|
||||
|
||||
private val JUNIT_GENERATED_TEST_CLASS_BYTES by lazy { constructSyntheticTestClass() }
|
||||
private val JUNIT_GENERATED_TEST_CLASS_FQNAME = "test.JunitTest"
|
||||
|
||||
private fun constructSyntheticTestClass(): ByteArray {
|
||||
return with(ClassWriter(COMPUTE_MAXS or COMPUTE_FRAMES)) {
|
||||
visit(49, ACC_PUBLIC, JUNIT_GENERATED_TEST_CLASS_FQNAME.replace('.', '/'), null, "java/lang/Object", emptyArray())
|
||||
visitSource(null, null)
|
||||
|
||||
with(visitAnnotation("Lorg/junit/runner/RunWith;", true)) {
|
||||
visit("value", Type.getType("Lorg/robolectric/RobolectricTestRunner;"))
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
with(visitAnnotation("Lorg/robolectric/annotation/Config;", true)) {
|
||||
visit("manifest", "--none")
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
with(visitMethod(ACC_PUBLIC, "<init>", "()V", null, null)) {
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
|
||||
|
||||
visitInsn(RETURN)
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
with(visitMethod(ACC_PUBLIC, "test", "()V", null, null)) {
|
||||
visitAnnotation("Lorg/junit/Test;", true).visitEnd()
|
||||
|
||||
val v = InstructionAdapter(this)
|
||||
|
||||
val assertionOk = Label()
|
||||
|
||||
v.invokestatic("test/TestKt", "box", "()Ljava/lang/String;", false) // -> ret
|
||||
v.dup() // -> ret, ret
|
||||
v.aconst("OK") // -> ret, ret, ok
|
||||
v.invokevirtual("java/lang/String", "equals", "(Ljava/lang/Object;)Z", false) // -> ret, eq
|
||||
v.ifne(assertionOk) // -> ret
|
||||
|
||||
val assertionErrorType = Type.getObjectType("java/lang/AssertionError")
|
||||
|
||||
v.anew(assertionErrorType) // -> ret, ae
|
||||
v.dupX1() // -> ae, ret, ae
|
||||
v.swap() // -> ae, ae, ret
|
||||
v.invokespecial(assertionErrorType.internalName, "<init>", "(Ljava/lang/Object;)V", false) // -> ae
|
||||
v.athrow()
|
||||
|
||||
v.visitLabel(assertionOk)
|
||||
v.pop() // -> [empty]
|
||||
v.areturn(Type.VOID_TYPE)
|
||||
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
visitEnd()
|
||||
toByteArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun doTest(filePath: String) {
|
||||
super.doTest(File(BASE_DIR, filePath + ".kt").absolutePath)
|
||||
}
|
||||
|
||||
open protected fun getClassLoaderWithGeneratedFiles(): ClassLoader {
|
||||
return object : URLClassLoader(arrayOf(), this::class.java.classLoader) {
|
||||
init {
|
||||
for (classFile in classFileFactory.getClassFiles().sortedBy { it.relativePath }) {
|
||||
val bytes = classFile.asByteArray()
|
||||
val className = ClassNode().also { ClassReader(bytes).accept(it, ClassReader.EXPAND_FRAMES) }.name
|
||||
try {
|
||||
defineClass(className.replace('/', '.'), ByteBuffer.wrap(bytes), null as ProtectionDomain?)
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("Can't load class $className", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun getClasspathForTest(): List<File> {
|
||||
val kotlinRuntimeJar = PathUtil.kotlinPathsForIdeaPlugin.stdlibPath
|
||||
val layoutLibJars = listOf(File("ideaSDK/plugins/android/lib/layoutlib.jar"), File("ideaSDK/plugins/android/lib/layoutlib-api.jar"))
|
||||
|
||||
val robolectricJars = File("dependencies/robolectric")
|
||||
.listFiles { f: File -> f.extension == "jar" }
|
||||
.sortedBy { it.nameWithoutExtension }
|
||||
|
||||
val junitCoreResourceName = JUnitCore::class.java.name.replace('.', '/') + ".class"
|
||||
val junitJar = File(JUnitCore::class.java.classLoader.getResource(junitCoreResourceName).file.substringBeforeLast('!'))
|
||||
|
||||
val androidExtensionsRuntime = File("out/production/android-extensions-runtime")
|
||||
|
||||
return listOf(kotlinRuntimeJar) + layoutLibJars + robolectricJars + junitJar + androidExtensionsRuntime
|
||||
}
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
if (true) { // TODO Parcelable box tests are disabled because of OOM. Currently investigating
|
||||
return
|
||||
}
|
||||
|
||||
compile(files + TestFile(LIBRARY_KT.name, LIBRARY_KT.readText()), javaFilesDir)
|
||||
|
||||
val testClass = Class.forName("test.TestKt", false, getClassLoaderWithGeneratedFiles())
|
||||
val javaBin = File(System.getProperty("java.home").takeIf { it.isNotEmpty() } ?: error("JAVA_HOME is not set"), "bin")
|
||||
val javaExe = File(javaBin, "java.exe").takeIf { it.exists() } ?: File(javaBin, "java")
|
||||
assert(javaExe.exists()) { "Can't find 'java' executable in $javaBin" }
|
||||
|
||||
val libraryClasspath = getClasspathForTest()
|
||||
val dirForTestClasses = Files.createTempDirectory("parcel").toFile()
|
||||
|
||||
fun writeClass(fqNameOrPath: String, bytes: ByteArray) {
|
||||
val path = if (fqNameOrPath.endsWith(".class")) fqNameOrPath else (fqNameOrPath.replace('.', '/') + ".class")
|
||||
File(dirForTestClasses, path).also { it.parentFile.mkdirs() }.writeBytes(bytes)
|
||||
}
|
||||
|
||||
try {
|
||||
testClass.getDeclaredMethod("box").invoke(testClass)
|
||||
} catch (e: Throwable) {
|
||||
throw AssertionError(classFileFactory.createText(), e)
|
||||
writeClass(JUNIT_GENERATED_TEST_CLASS_FQNAME, JUNIT_GENERATED_TEST_CLASS_BYTES)
|
||||
classFileFactory.getClassFiles().forEach { writeClass(it.relativePath, it.asByteArray()) }
|
||||
|
||||
val process = ProcessBuilder(
|
||||
javaExe.absolutePath,
|
||||
"-ea",
|
||||
"-classpath",
|
||||
(libraryClasspath + dirForTestClasses).joinToString(File.pathSeparator),
|
||||
JUnitCore::class.java.name,
|
||||
JUNIT_GENERATED_TEST_CLASS_FQNAME
|
||||
).inheritIO().start()
|
||||
|
||||
process.waitFor(3, TimeUnit.MINUTES)
|
||||
if (process.exitValue() != 0) {
|
||||
throw AssertionError(classFileFactory.createText())
|
||||
}
|
||||
} finally {
|
||||
if (!dirForTestClasses.deleteRecursively()) {
|
||||
throw AssertionError("Unable to delete $dirForTestClasses")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.android.parcel
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
//import org.robolectric.RobolectricTestRunner
|
||||
//import org.robolectric.annotation.Config
|
||||
|
||||
// This class is not generated because it uses the custom test runner
|
||||
//@RunWith(RobolectricTestRunner::class)
|
||||
//@Config(manifest = Config.NONE)
|
||||
class ParcelBoxTest : AbstractParcelBoxTest() {
|
||||
fun testSimple() = doTest("simple")
|
||||
fun testPrimitiveTypes() = doTest("primitiveTypes")
|
||||
|
||||
@@ -247,9 +247,12 @@
|
||||
<get-maven-library-with-dependencies
|
||||
group="org.robolectric"
|
||||
artifact="robolectric"
|
||||
version="3.3.2"
|
||||
version="3.1"
|
||||
target.dir="robolectric"/>
|
||||
|
||||
<get-maven-library prefix="org/apache/maven" lib="maven-ant-tasks" version="2.1.3"
|
||||
target.jar.name.base="maven-ant-tasks" download="${dependencies}/robolectric" />
|
||||
|
||||
<!-- kotlinx.coroutines -->
|
||||
<get-maven-library prefix="org/jetbrains/kotlinx" lib="kotlinx-coroutines-core" version="${kotlinx.coroutines.version}"
|
||||
target.jar.name.base="kotlinx-coroutines-core" server="http://dl.bintray.com/kotlin/kotlinx/"/>
|
||||
|
||||
Reference in New Issue
Block a user