[BTA tests] Add a way to customize IC options

^KT-61860 In Progress
This commit is contained in:
Alexander.Likhachev
2024-02-05 21:43:38 +01:00
committed by Space Team
parent 74e5b4d844
commit 2a3cc758cf
4 changed files with 82 additions and 20 deletions
@@ -6,13 +6,9 @@
package org.jetbrains.kotlin.buildtools.api.tests.compilation.model package org.jetbrains.kotlin.buildtools.api.tests.compilation.model
import org.jetbrains.kotlin.buildtools.api.CompilationResult import org.jetbrains.kotlin.buildtools.api.CompilationResult
import org.jetbrains.kotlin.buildtools.api.CompilationService
import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration
import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.buildtools.api.SourcesChanges
import org.jetbrains.kotlin.buildtools.api.jvm.AccessibleClassSnapshot import org.jetbrains.kotlin.buildtools.api.jvm.*
import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity
import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalCompilationApproachParameters
import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.tests.buildToolsVersion import org.jetbrains.kotlin.buildtools.api.tests.buildToolsVersion
import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Module import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Module
import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion
@@ -83,6 +79,7 @@ class JvmModule(
forceOutput: LogLevel?, forceOutput: LogLevel?,
forceNonIncrementalCompilation: Boolean, forceNonIncrementalCompilation: Boolean,
compilationConfigAction: (JvmCompilationConfiguration) -> Unit, compilationConfigAction: (JvmCompilationConfiguration) -> Unit,
incrementalCompilationConfigAction: (IncrementalJvmCompilationConfiguration<*>) -> Unit,
assertions: context(Module) CompilationOutcome.() -> Unit, assertions: context(Module) CompilationOutcome.() -> Unit,
): CompilationResult { ): CompilationResult {
return compile(strategyConfig, forceOutput, { compilationConfig -> return compile(strategyConfig, forceOutput, { compilationConfig ->
@@ -108,12 +105,15 @@ class JvmModule(
options.forceNonIncrementalMode() options.forceNonIncrementalMode()
} }
incrementalCompilationConfigAction(options)
compilationConfig.useIncrementalCompilation( compilationConfig.useIncrementalCompilation(
icCachesDir.toFile(), icCachesDir.toFile(),
sourcesChanges, sourcesChanges,
params, params,
options, options,
) )
compilationConfigAction(compilationConfig)
}, assertions) }, assertions)
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.buildtools.api.tests.compilation.model
import org.jetbrains.kotlin.buildtools.api.CompilationResult import org.jetbrains.kotlin.buildtools.api.CompilationResult
import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration
import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.buildtools.api.SourcesChanges
import org.jetbrains.kotlin.buildtools.api.jvm.IncrementalJvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration
import java.nio.file.Path import java.nio.file.Path
@@ -34,6 +35,7 @@ interface Module : Dependency {
forceOutput: LogLevel? = null, forceOutput: LogLevel? = null,
forceNonIncrementalCompilation: Boolean = false, forceNonIncrementalCompilation: Boolean = false,
compilationConfigAction: (JvmCompilationConfiguration) -> Unit = {}, compilationConfigAction: (JvmCompilationConfiguration) -> Unit = {},
incrementalCompilationConfigAction: (IncrementalJvmCompilationConfiguration<*>) -> Unit = {},
assertions: context(Module) CompilationOutcome.() -> Unit = {}, assertions: context(Module) CompilationOutcome.() -> Unit = {},
): CompilationResult ): CompilationResult
} }
@@ -5,10 +5,30 @@
package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario
import org.jetbrains.kotlin.buildtools.api.jvm.IncrementalJvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Module
interface Scenario { interface Scenario {
/**
* Creates a module for a scenario.
*
* Modules with the same combination of [Module.scenarioDslCacheKey], [compilationOptionsModifier], and [incrementalCompilationOptionsModifier] are compiled initially only once per tests run.
*
* In the case you are using custom values for [compilationOptionsModifier] or [incrementalCompilationOptionsModifier], consider sharing the same lambda between tests for better cacheability results.
*
* @param moduleName The name of the module.
* @param dependencies (optional) The list of scenario modules that this module depends on. Defaults to an empty list.
* @param additionalCompilationArguments (optional) The list of additional compilation arguments for this module. Defaults to an empty list.
* @param compilationOptionsModifier (optional) A function that can be used to modify the compilation configuration for this module.
* @param incrementalCompilationOptionsModifier (optional) A function that can be used to modify the incremental compilation configuration for this module.
* @return The created scenario module in the compiled state.
*/
fun module( fun module(
moduleName: String, moduleName: String,
dependencies: List<ScenarioModule> = emptyList(), dependencies: List<ScenarioModule> = emptyList(),
additionalCompilationArguments: List<String> = emptyList(), additionalCompilationArguments: List<String> = emptyList(),
compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)? = null,
incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)? = null,
): ScenarioModule ): ScenarioModule
} }
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario
import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration
import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.buildtools.api.SourcesChanges
import org.jetbrains.kotlin.buildtools.api.jvm.IncrementalJvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration
import org.jetbrains.kotlin.buildtools.api.tests.compilation.assertions.assertOutputs import org.jetbrains.kotlin.buildtools.api.tests.compilation.assertions.assertOutputs
import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.* import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.*
import java.nio.file.Files import java.nio.file.Files
@@ -18,6 +20,8 @@ private class ScenarioModuleImpl(
val module: Module, val module: Module,
val outputs: MutableSet<String>, val outputs: MutableSet<String>,
private val strategyConfig: CompilerExecutionStrategyConfiguration, private val strategyConfig: CompilerExecutionStrategyConfiguration,
private val compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)?,
private val incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)?,
) : ScenarioModule { ) : ScenarioModule {
override fun changeFile( override fun changeFile(
fileName: String, fileName: String,
@@ -61,12 +65,17 @@ private class ScenarioModuleImpl(
forceOutput: LogLevel?, forceOutput: LogLevel?,
assertions: context(Module) CompilationOutcome.() -> Unit, assertions: context(Module) CompilationOutcome.() -> Unit,
) { ) {
module.compileIncrementally(strategyConfig, sourcesChanges, forceOutput, assertions = { module.compileIncrementally(
assertions(module, this) strategyConfig,
assertOutputs(outputs) sourcesChanges,
}) forceOutput,
compilationConfigAction = { compilationOptionsModifier?.invoke(it) },
incrementalCompilationConfigAction = { incrementalCompilationOptionsModifier?.invoke(it) },
assertions = {
assertions(module, this)
assertOutputs(outputs)
})
} }
} }
private class ScenarioDsl( private class ScenarioDsl(
@@ -78,11 +87,13 @@ private class ScenarioDsl(
moduleName: String, moduleName: String,
dependencies: List<ScenarioModule>, dependencies: List<ScenarioModule>,
additionalCompilationArguments: List<String>, additionalCompilationArguments: List<String>,
compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)?,
incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)?,
): ScenarioModule { ): ScenarioModule {
val transformedDependencies = dependencies.map { (it as ScenarioModuleImpl).module } val transformedDependencies = dependencies.map { (it as ScenarioModuleImpl).module }
val module = project.module(moduleName, transformedDependencies, additionalCompilationArguments) val module = project.module(moduleName, transformedDependencies, additionalCompilationArguments)
return GlobalCompiledProjectsCache.getProjectFromCache(module, strategyConfig) return GlobalCompiledProjectsCache.getProjectFromCache(module, strategyConfig, compilationOptionsModifier, incrementalCompilationOptionsModifier)
?: GlobalCompiledProjectsCache.putProjectIntoCache(module, strategyConfig) ?: GlobalCompiledProjectsCache.putProjectIntoCache(module, strategyConfig, compilationOptionsModifier, incrementalCompilationOptionsModifier)
} }
} }
@@ -90,20 +101,45 @@ fun BaseCompilationTest.scenario(strategyConfig: CompilerExecutionStrategyConfig
action(ScenarioDsl(Project(workingDirectory), strategyConfig)) action(ScenarioDsl(Project(workingDirectory), strategyConfig))
} }
private data class GlobalCompiledProjectsCacheKey(
val moduleKey: DependencyScenarioDslCacheKey,
val compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)?,
val incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)?,
)
private object GlobalCompiledProjectsCache { private object GlobalCompiledProjectsCache {
private val globalTempDirectory = Files.createTempDirectory("compiled-test-projects-cache").apply { private val globalTempDirectory = Files.createTempDirectory("compiled-test-projects-cache").apply {
toFile().deleteOnExit() toFile().deleteOnExit()
} }
private val compiledProjectsCache = mutableMapOf<DependencyScenarioDslCacheKey, Pair<MutableSet<String>, Path>>() private val compiledProjectsCache = mutableMapOf<GlobalCompiledProjectsCacheKey, Pair<MutableSet<String>, Path>>()
fun getProjectFromCache(module: Module, strategyConfig: CompilerExecutionStrategyConfiguration): ScenarioModuleImpl? { fun getProjectFromCache(
val (initialOutputs, cachedBuildDirPath) = compiledProjectsCache[module.scenarioDslCacheKey] ?: return null module: Module,
strategyConfig: CompilerExecutionStrategyConfiguration,
compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)?,
incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)?,
): ScenarioModuleImpl? {
val (initialOutputs, cachedBuildDirPath) = compiledProjectsCache[GlobalCompiledProjectsCacheKey(
module.scenarioDslCacheKey,
compilationOptionsModifier,
incrementalCompilationOptionsModifier
)] ?: return null
cachedBuildDirPath.copyToRecursively(module.buildDirectory, followLinks = false, overwrite = true) cachedBuildDirPath.copyToRecursively(module.buildDirectory, followLinks = false, overwrite = true)
return ScenarioModuleImpl(module, initialOutputs, strategyConfig) return ScenarioModuleImpl(module, initialOutputs, strategyConfig, compilationOptionsModifier, incrementalCompilationOptionsModifier)
} }
fun putProjectIntoCache(module: Module, strategyConfig: CompilerExecutionStrategyConfiguration): ScenarioModuleImpl { fun putProjectIntoCache(
module.compileIncrementally(strategyConfig, SourcesChanges.Unknown) module: Module,
strategyConfig: CompilerExecutionStrategyConfiguration,
compilationOptionsModifier: ((JvmCompilationConfiguration) -> Unit)?,
incrementalCompilationOptionsModifier: ((IncrementalJvmCompilationConfiguration<*>) -> Unit)?,
): ScenarioModuleImpl {
module.compileIncrementally(
strategyConfig,
SourcesChanges.Unknown,
compilationConfigAction = { compilationOptionsModifier?.invoke(it) },
incrementalCompilationConfigAction = { incrementalCompilationOptionsModifier?.invoke(it) }
)
val initialOutputs = mutableSetOf<String>() val initialOutputs = mutableSetOf<String>()
for (file in module.outputDirectory.walk()) { for (file in module.outputDirectory.walk()) {
if (!file.isRegularFile()) continue if (!file.isRegularFile()) continue
@@ -111,7 +147,11 @@ private object GlobalCompiledProjectsCache {
} }
val moduleCacheDirectory = globalTempDirectory.resolve(UUID.randomUUID().toString()) val moduleCacheDirectory = globalTempDirectory.resolve(UUID.randomUUID().toString())
module.buildDirectory.copyToRecursively(moduleCacheDirectory, followLinks = false, overwrite = false) module.buildDirectory.copyToRecursively(moduleCacheDirectory, followLinks = false, overwrite = false)
compiledProjectsCache[module.scenarioDslCacheKey] = Pair(initialOutputs, moduleCacheDirectory) compiledProjectsCache[GlobalCompiledProjectsCacheKey(
return ScenarioModuleImpl(module, initialOutputs, strategyConfig) module.scenarioDslCacheKey,
compilationOptionsModifier,
incrementalCompilationOptionsModifier
)] = Pair(initialOutputs, moduleCacheDirectory)
return ScenarioModuleImpl(module, initialOutputs, strategyConfig, compilationOptionsModifier, incrementalCompilationOptionsModifier)
} }
} }