Skip to content

Commit

Permalink
Make compiler tests cacheable: compiler-tests-convention
Browse files Browse the repository at this point in the history
- add compiler-tests-convention
- track ideaHome directory
- migrate the first project, tests-common-new
- extract paths

^KTI-1685
  • Loading branch information
CristianGM authored and Space Team committed May 3, 2024
1 parent 1e9b36b commit 6eec64f
Show file tree
Hide file tree
Showing 20 changed files with 438 additions and 63 deletions.
1 change: 0 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,6 @@ tasks {
}

register("testsForBootstrapBuildTest") {
dependsOn("dist")
dependsOn(":compiler:tests-common-new:test")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@
import java.util.ArrayList;
import java.util.List;

import static java.lang.System.*;
import static org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.*;

public class ForTestCompileRuntime {
private static volatile SoftReference<ClassLoader> reflectJarClassLoader = new SoftReference<>(null);
private static volatile SoftReference<ClassLoader> runtimeJarClassLoader = new SoftReference<>(null);

@NotNull
public static File runtimeJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-stdlib.jar"));
return propertyOrDist(KOTLIN_FULL_STDLIB_PATH, "dist/kotlinc/lib/kotlin-stdlib.jar");
}

@NotNull
public static File runtimeJarForTestsWithJdk8() {
return assertExists(new File("dist/kotlinc/lib/kotlin-stdlib-jdk8.jar"));
return propertyOrDist(KOTLIN_FULL_STDLIB_PATH, "dist/kotlinc/lib/kotlin-stdlib-jdk8.jar");
}

@NotNull
Expand All @@ -37,62 +40,39 @@ public static File minimalRuntimeJarForTests() {

@NotNull
public static File kotlinTestJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-test.jar"));
}

@NotNull
public static File kotlinTestJUnitJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-test-junit.jar"));
}

@NotNull
public static File kotlinTestJsJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-test-js.jar"));
return propertyOrDist(KOTLIN_TEST_JAR_PATH, "dist/kotlinc/lib/kotlin-test.jar");
}

@NotNull
public static File reflectJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-reflect.jar"));
return propertyOrDist(KOTLIN_REFLECT_JAR_PATH, "dist/kotlinc/lib/kotlin-reflect.jar");
}

@NotNull
public static File scriptRuntimeJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-script-runtime.jar"));
return propertyOrDist(KOTLIN_SCRIPT_RUNTIME_PATH, "dist/kotlinc/lib/kotlin-script-runtime.jar");
}

@NotNull
public static File runtimeSourcesJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-stdlib-sources.jar"));
}

@NotNull
public static File stdlibMavenSourcesJarForTests() {
return assertExists(new File("dist/maven/kotlin-stdlib-sources.jar"));
}

@NotNull
public static File stdlibCommonForTests() {
return assertExists(new File("dist/common/kotlin-stdlib-common.jar"));
return propertyOrDist(KOTLIN_COMMON_STDLIB_PATH, "dist/common/kotlin-stdlib-common.jar");
}

@NotNull
public static File stdlibCommonSourcesForTests() {
return assertExists(new File("dist/common/kotlin-stdlib-common-sources.jar"));
}

@NotNull
public static File stdlibJsForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-stdlib-js.klib"));
}

@NotNull
public static File jetbrainsAnnotationsForTests() {
return assertExists(new File("dist/kotlinc/lib/annotations-13.0.jar"));
private static File propertyOrDist(String property, String distPath) {
String path = getProperty(property, distPath);
File file = new File(path);
assert(file.exists()) : path + " doesn't exist";
return file;
}

@NotNull
public static File jvmAnnotationsForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-annotations-jvm.jar"));
return propertyOrDist(KOTLIN_ANNOTATIONS_PATH, "dist/kotlinc/lib/kotlin-annotations-jvm.jar");
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jetbrains.kotlin.codegen.forTestCompile/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

// This file is duplicated at repo/gradle-build-conventions/compiler-tests-convention/src/main/kotlin/TestCompilePaths.kt
object TestCompilePaths {
const val KOTLIN_FULL_STDLIB_PATH: String = "kotlin.full.stdlib.path"
const val KOTLIN_MINIMAL_STDLIB_PATH: String = "kotlin.minimal.stdlib.path"
const val KOTLIN_TEST_JAR_PATH: String = "kotlin.test.jar.path"
const val KOTLIN_REFLECT_JAR_PATH: String = "kotlin.reflect.jar.path"
const val KOTLIN_SCRIPT_RUNTIME_PATH: String = "kotlin.script.runtime.path"
const val KOTLIN_COMMON_STDLIB_PATH: String = "kotlin.common.stdlib.path"
const val KOTLIN_ANNOTATIONS_PATH: String = "kotlin.annotations.path"
const val KOTLIN_JS_STDLIB_KLIB_PATH: String = "kotlin.js.stdlib.klib.path"
const val KOTLIN_JS_REDUCED_STDLIB_PATH: String = "kotlin.js.reduced.stdlib.path"
const val KOTLIN_JS_KOTLIN_TEST_KLIB_PATH: String = "kotlin.js.kotlin.test.klib.path"
const val KOTLIN_SCRIPTING_PLUGIN_CLASSPATH = "kotlin.scriptingPlugin.classpath"
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ fun loadScriptingPlugin(configuration: CompilerConfiguration) {
}
PluginCliParser.loadPluginsSafe(pluginClasspath, emptyList(), emptyList(), configuration)
}

fun loadScriptingPlugin(configuration: CompilerConfiguration, pluginClasspath: Collection<String>) {
PluginCliParser.loadPluginsSafe(pluginClasspath, emptyList(), emptyList(), configuration)
}
24 changes: 23 additions & 1 deletion compiler/tests-common-new/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
kotlin("jvm")
id("jps-compatible")
id("compiler-tests-convention")
}

dependencies {
Expand Down Expand Up @@ -54,16 +55,37 @@ sourceSets {
}
}

compilerTests {
withStdlibCommon()
withScriptRuntime()
withTestJar()
withAnnotations()
withScriptingPlugin()
withStdlibJsRuntime()
withTestJsRuntime()
}

projectTest(
jUnitMode = JUnitMode.JUnit5,
defineJDKEnvVariables = listOf(
JdkMajorVersion.JDK_11_0, // e.g. org.jetbrains.kotlin.test.runners.ForeignAnnotationsCompiledJavaTestGenerated.Java11Tests
JdkMajorVersion.JDK_21_0, // e.g. org.jetbrains.kotlin.test.runners.codegen.FirLightTreeBlackBoxModernJdkCodegenTestGenerated.TestsWithJava21
)
) {
dependsOn(":dist")
workingDir = rootDir
useJUnitPlatform()

inputs.dir(layout.projectDirectory.dir("../testData")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.file(File(rootDir, "compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.file(File(rootDir, "compiler/testData/mockJDK/jre/lib/rt.jar")).withNormalizer(ClasspathNormalizer::class)
inputs.dir(File(rootDir, "third-party/annotations")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir(File(rootDir, "third-party/java8-annotations")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir(File(rootDir, "third-party/java9-annotations")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir(File(rootDir, "third-party/jsr305")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir(File(rootDir, "libraries/stdlib/unsigned/src/kotlin")).withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir(File(rootDir, "libraries/stdlib/jvm/src/kotlin")).withPathSensitivity(PathSensitivity.RELATIVE) //util/UnsignedJVM.kt
inputs.dir(File(rootDir, "libraries/stdlib/src/kotlin")).withPathSensitivity(PathSensitivity.RELATIVE) //ranges/Progressions.kt
inputs.dir(File(rootDir, "libraries/stdlib/jvm/runtime/kotlin")).withPathSensitivity(PathSensitivity.RELATIVE) //TypeAliases.kt
}

testsJar()
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@ package org.jetbrains.kotlin.test.services
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.jvm.configureStandardLibs
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_FULL_STDLIB_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_JS_KOTLIN_TEST_KLIB_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_JS_REDUCED_STDLIB_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_JS_STDLIB_KLIB_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_MINIMAL_STDLIB_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_REFLECT_JAR_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_SCRIPTING_PLUGIN_CLASSPATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_SCRIPT_RUNTIME_PATH
import org.jetbrains.kotlin.codegen.forTestCompile.TestCompilePaths.KOTLIN_TEST_JAR_PATH
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.lang.ref.SoftReference
import java.net.URL
Expand Down Expand Up @@ -87,6 +97,11 @@ abstract class KotlinStandardLibrariesPathProvider : TestService {
*/
abstract fun kotlinTestJsKLib(): File

/**
* scriptingPlugin classpath jars
*/
abstract fun scriptingPluginFilesForTests(): Collection<File>

fun getRuntimeJarClassLoader(): ClassLoader = synchronized(this) {
var loader = runtimeJarClassLoader.get()
if (loader == null) {
Expand All @@ -107,32 +122,82 @@ abstract class KotlinStandardLibrariesPathProvider : TestService {
runtimeJarForTests(),
reflectJarForTests(),
scriptRuntimeJarForTests(),
kotlinTestJarForTests())
kotlinTestJarForTests()
)
reflectJarClassLoader = SoftReference(loader)
}
loader
}
}

object StandardLibrariesPathProviderForKotlinProject : KotlinStandardLibrariesPathProvider() {
override fun runtimeJarForTests(): File = ForTestCompileRuntime.runtimeJarForTests()
override fun runtimeJarForTests(): File =
extractFromPropertyFirstFile(KOTLIN_FULL_STDLIB_PATH) { ForTestCompileRuntime.runtimeJarForTests() }

override fun runtimeJarForTestsWithJdk8(): File = ForTestCompileRuntime.runtimeJarForTestsWithJdk8()
override fun minimalRuntimeJarForTests(): File = ForTestCompileRuntime.minimalRuntimeJarForTests()
override fun reflectJarForTests(): File = ForTestCompileRuntime.reflectJarForTests()
override fun kotlinTestJarForTests(): File = ForTestCompileRuntime.kotlinTestJarForTests()
override fun scriptRuntimeJarForTests(): File = ForTestCompileRuntime.scriptRuntimeJarForTests()
override fun minimalRuntimeJarForTests(): File =
extractFromPropertyFirstFile(KOTLIN_MINIMAL_STDLIB_PATH) { ForTestCompileRuntime.minimalRuntimeJarForTests() }

override fun reflectJarForTests(): File =
extractFromPropertyFirstFile(KOTLIN_REFLECT_JAR_PATH) { ForTestCompileRuntime.reflectJarForTests() }

override fun kotlinTestJarForTests(): File =
extractFromPropertyFirstFile(KOTLIN_TEST_JAR_PATH) { ForTestCompileRuntime.kotlinTestJarForTests() }

override fun scriptRuntimeJarForTests(): File =
extractFromPropertyFirstFile(KOTLIN_SCRIPT_RUNTIME_PATH) { ForTestCompileRuntime.scriptRuntimeJarForTests() }

override fun jvmAnnotationsForTests(): File = ForTestCompileRuntime.jvmAnnotationsForTests()
override fun getAnnotationsJar(): File = KtTestUtil.getAnnotationsJar()
override fun getAnnotationsJar(): File =
KtTestUtil.getAnnotationsJar().also {
assert(it.exists()) { "AnnotationJar missing: $it does not exist" }
}

override fun fullJsStdlib(): File = extractFromPropertyFirst("kotlin.js.full.stdlib.path") { "kotlin-stdlib-js.klib".dist() }
override fun defaultJsStdlib(): File = extractFromPropertyFirst("kotlin.js.reduced.stdlib.path") { "kotlin-stdlib-js.klib".dist() }
override fun kotlinTestJsKLib(): File = extractFromPropertyFirst("kotlin.js.kotlin.test.klib.path") { "kotlin-test-js.klib".dist() }
override fun fullJsStdlib(): File = extractFromPropertyFirst(KOTLIN_JS_STDLIB_KLIB_PATH) { "kotlin-stdlib-js.klib".dist() }
override fun defaultJsStdlib(): File = extractFromPropertyFirst(KOTLIN_JS_REDUCED_STDLIB_PATH) { "kotlin-stdlib-js.klib".dist() }
override fun kotlinTestJsKLib(): File = extractFromPropertyFirst(KOTLIN_JS_KOTLIN_TEST_KLIB_PATH) { "kotlin-test-js.klib".dist() }
override fun scriptingPluginFilesForTests(): Collection<File> =
extractFromPropertyFirstFiles(KOTLIN_SCRIPTING_PLUGIN_CLASSPATH) {
val libPath = PathUtil.kotlinPathsForCompiler.libPath
val pluginClasspath = with(PathUtil) {
listOf(
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR,
KOTLIN_SCRIPTING_COMPILER_IMPL_JAR,
KOTLIN_SCRIPTING_COMMON_JAR,
KOTLIN_SCRIPTING_JVM_JAR
).map {
val file = File(libPath, it)
if (!file.exists()) {
throw Error("Missing ${file.path}")
}
file
}
}
pluginClasspath
}

private inline fun extractFromPropertyFirst(prop: String, onMissingProperty: () -> String): File {
val path = System.getProperty(prop, null) ?: onMissingProperty()
assert(File(path).exists()) { "$path not found" }
return File(path)
}

private inline fun extractFromPropertyFirstFile(prop: String, onMissingProperty: () -> File): File {
return System.getProperty(prop, null)?.let {
val f = File(it)
assert(f.exists()) { "$it not found" }
f
} ?: onMissingProperty()
}

private inline fun extractFromPropertyFirstFiles(prop: String, onMissingProperty: () -> Collection<File>): Collection<File> {
return System.getProperty(prop, null)?.split(",")?.map {
val f = File(it)
assert(f.exists()) { "$it not found" }
f
} ?: onMissingProperty()
}

private fun String.dist(): String {
return "dist/kotlinc/lib/$this"
}
Expand Down Expand Up @@ -166,6 +231,9 @@ object EnvironmentBasedStandardLibrariesPathProvider : KotlinStandardLibrariesPa
override fun fullJsStdlib(): File = getFile(KOTLIN_STDLIB_JS_PROP)
override fun defaultJsStdlib(): File = getFile(KOTLIN_STDLIB_JS_PROP)
override fun kotlinTestJsKLib(): File = getFile(KOTLIN_TEST_JS_PROP)
override fun scriptingPluginFilesForTests(): Collection<File> {
TODO("KT-67573")
}
}

val TestServices.standardLibrariesPathProvider: KotlinStandardLibrariesPathProvider by TestServices.testServiceAccessor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
}

private val METADATA_CACHE by lazy {
(JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).flatMap { path ->
listOf(StandardLibrariesPathProviderForKotlinProject.fullJsStdlib().absolutePath, StandardLibrariesPathProviderForKotlinProject.kotlinTestJsKLib().absolutePath).flatMap { path ->
KotlinJavascriptMetadataUtils.loadMetadata(path).map { metadata ->
val parts = KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body, metadata.version)
JsModuleDescriptor(metadata.moduleName, parts.kind, parts.importedModules, parts)
Expand Down Expand Up @@ -113,7 +113,14 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
project: Project, configuration: CompilerConfiguration, compilerEnvironment: TargetEnvironment = CompilerEnvironment
): JsConfig {
return JsConfig(
project, configuration, compilerEnvironment, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet()
project,
configuration,
compilerEnvironment,
METADATA_CACHE,
setOf(
StandardLibrariesPathProviderForKotlinProject.fullJsStdlib().absolutePath,
StandardLibrariesPathProviderForKotlinProject.kotlinTestJsKLib().absolutePath
)
)
}

Expand Down Expand Up @@ -206,9 +213,12 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
val friends = module.friendDependencies.map { getJsModuleArtifactPath(testServices, it.moduleName) + ".meta.js" }

val libraries = when (module.targetBackend) {
null -> JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST
null -> listOf(
testServices.standardLibrariesPathProvider.fullJsStdlib().absolutePath,
testServices.standardLibrariesPathProvider.kotlinTestJsKLib().absolutePath
)
TargetBackend.JS_IR, TargetBackend.JS_IR_ES6 -> dependencies + friends
TargetBackend.JS -> JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST + dependencies + friends
TargetBackend.JS -> listOf(testServices.standardLibrariesPathProvider.fullJsStdlib().absolutePath, testServices.standardLibrariesPathProvider.kotlinTestJsKLib().absolutePath) + dependencies + friends
else -> error("Unsupported target backend: ${module.targetBackend}")
}
configuration.put(JSConfigurationKeys.LIBRARIES, libraries)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ package org.jetbrains.kotlin.test.services.configuration
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.script.loadScriptingPlugin
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.isKtsFile
import org.jetbrains.kotlin.test.services.*

class ScriptingEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
if (module.files.any { it.isKtsFile }) {
loadScriptingPlugin(configuration)
val pluginFiles = testServices.standardLibrariesPathProvider.scriptingPluginFilesForTests().map { it.path }
loadScriptingPlugin(configuration, pluginFiles)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.serialization.AbstractVersionRequirementTest
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.services.StandardLibrariesPathProviderForKotlinProject
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.io.File

Expand Down Expand Up @@ -84,7 +85,7 @@ class JsVersionRequirementTest : AbstractVersionRequirementTest() {
KotlinCoreEnvironment.createForTests(
testRootDisposable,
KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK).apply {
put(JSConfigurationKeys.LIBRARIES, extraDependencies.map(File::getPath) + JsConfig.JS_STDLIB)
put(JSConfigurationKeys.LIBRARIES, extraDependencies.map(File::getPath) + StandardLibrariesPathProviderForKotlinProject.fullJsStdlib().absolutePath)
put(JSConfigurationKeys.META_INFO, true)

if (languageVersion != null) {
Expand Down
Loading

0 comments on commit 6eec64f

Please sign in to comment.