[reflect] Fix flaky tests that depend on Reflection.clearCaches()
* Use ReflectionFactoryImpl as single point of synchronization * Synchronize all cache-sensitive tests on it in order to be robust in parallel test runners * Remove redundant cache clear after each test Merge-request: KT-MR-6842 Merged-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
This commit is contained in:
committed by
Space
parent
94abeb64c5
commit
e32e5c26a4
@@ -2,12 +2,15 @@
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
import kotlin.jvm.internal.*
|
||||
import kotlin.reflect.jvm.internal.*
|
||||
|
||||
class A
|
||||
fun box(): String {
|
||||
val pckg = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
System.gc()
|
||||
val pckg2 = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
if (pckg === pckg2) return "OK"
|
||||
return "Fail"
|
||||
return synchronized(ReflectionFactoryImpl::class.java) {
|
||||
val pckg = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
System.gc()
|
||||
val pckg2 = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
if (pckg === pckg2) return@synchronized "OK"
|
||||
return@synchronized "Fail"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
import kotlin.reflect.jvm.internal.*
|
||||
|
||||
class A
|
||||
|
||||
fun box(): String {
|
||||
val clz = A::class
|
||||
System.gc()
|
||||
val clz2 = A::class
|
||||
if (clz === clz2) return "OK"
|
||||
return "Fail"
|
||||
return synchronized(ReflectionFactoryImpl::class.java) {
|
||||
val clz = A::class
|
||||
System.gc()
|
||||
val clz2 = A::class
|
||||
if (clz === clz2) return@synchronized "OK"
|
||||
return@synchronized "Fail"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -12,7 +12,9 @@ inline fun check(message: String, generate: () -> Any?) {
|
||||
x1 = generate()
|
||||
|
||||
// Force clear the internal maps, as if the weak values in them are garbage-collected.
|
||||
kotlin.reflect.jvm.internal.ReflectionFactoryImpl.clearCaches()
|
||||
synchronized(kotlin.reflect.jvm.internal.ReflectionFactoryImpl::class.java) {
|
||||
kotlin.reflect.jvm.internal.ReflectionFactoryImpl.clearCaches()
|
||||
}
|
||||
|
||||
x2 = generate()
|
||||
} catch (e: Throwable) {
|
||||
|
||||
Vendored
+3
-1
@@ -11,7 +11,9 @@ inline fun check(message: String, generate: () -> Any?) {
|
||||
x1 = generate()
|
||||
|
||||
// Force clear the internal maps, as if the weak values in them are garbage-collected.
|
||||
kotlin.reflect.jvm.internal.ReflectionFactoryImpl.clearCaches()
|
||||
synchronized(kotlin.reflect.jvm.internal.ReflectionFactoryImpl::class.java) {
|
||||
kotlin.reflect.jvm.internal.ReflectionFactoryImpl.clearCaches()
|
||||
}
|
||||
|
||||
x2 = generate()
|
||||
} catch (e: Throwable) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertSame
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.jvm.internal.*
|
||||
|
||||
private inline fun <reified T> check(isNullable: Boolean = false) {
|
||||
val t1 = typeOf<T>()
|
||||
@@ -15,10 +16,12 @@ private inline fun <reified T> check(isNullable: Boolean = false) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
check<Int>()
|
||||
check<Int?>(true)
|
||||
check<List<Int>?>(true)
|
||||
check<List<Int>>()
|
||||
check<List<Int?>?>(true)
|
||||
synchronized(ReflectionFactoryImpl::class.java) {
|
||||
check<Int>()
|
||||
check<Int?>(true)
|
||||
check<List<Int>?>(true)
|
||||
check<List<Int>>()
|
||||
check<List<Int?>?>(true)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
-2
@@ -97,8 +97,6 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
}
|
||||
}
|
||||
throw e
|
||||
} finally {
|
||||
clearReflectionCache(classLoader)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-4
@@ -21,7 +21,6 @@ import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.TestUtilsKt.clearReflectionCache;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.assertEqualsToFile;
|
||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getBoxMethodOrNull;
|
||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getGeneratedClass;
|
||||
@@ -100,9 +99,6 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
}
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
finally {
|
||||
clearReflectionCache(generatedClassLoader);
|
||||
}
|
||||
}
|
||||
fail("Can't find box method!");
|
||||
}
|
||||
|
||||
@@ -5,19 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
|
||||
fun clearReflectionCache(classLoader: ClassLoader) {
|
||||
try {
|
||||
val klass = classLoader.loadClass(JvmAbi.REFLECTION_FACTORY_IMPL.asSingleFqName().asString())
|
||||
val method = klass.getDeclaredMethod("clearCaches")
|
||||
method.invoke(null)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
// This is OK for a test without kotlin-reflect in the dependencies
|
||||
}
|
||||
}
|
||||
|
||||
fun ClassLoader?.extractUrls(): List<URL> {
|
||||
return (this as? URLClassLoader)?.let {
|
||||
|
||||
Reference in New Issue
Block a user