From a234e4149b4464073a649faeddd463110e0005e6 Mon Sep 17 00:00:00 2001 From: "Alexander.Likhachev" Date: Thu, 7 Dec 2023 21:00:25 +0100 Subject: [PATCH] [BTA tests] Add scenario DSL for writing typical IC tests ^KT-61860 In Progress --- .../kotlin/compilation/scenario/Scenario.kt | 14 +++ .../compilation/scenario/ScenarioModule.kt | 37 +++++++ .../compilation/scenario/scenarioDsl.kt | 100 ++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/Scenario.kt create mode 100644 compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/ScenarioModule.kt create mode 100644 compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/scenarioDsl.kt diff --git a/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/Scenario.kt b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/Scenario.kt new file mode 100644 index 00000000000..5faa4393f0e --- /dev/null +++ b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/Scenario.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2023 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. + */ + +package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario + +interface Scenario { + fun module( + moduleName: String, + dependencies: List = emptyList(), + additionalCompilationArguments: List = emptyList(), + ): ScenarioModule +} \ No newline at end of file diff --git a/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/ScenarioModule.kt b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/ScenarioModule.kt new file mode 100644 index 00000000000..94cf7e49a12 --- /dev/null +++ b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/ScenarioModule.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2023 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. + */ + +package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario + +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.CompilationOutcome +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.LogLevel +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Module + +interface ScenarioModule { + /** + * Performs registered existing file modification. + */ + fun changeFile( + fileName: String, + addedOutputs: Set = emptySet(), + removedOutputs: Set = emptySet(), + transform: (String) -> String, + ) + + /** + * Performs registered file deletion. + */ + fun deleteFile(fileName: String, removedOutputs: Set) + + /** + * Performs registered new file creation. + */ + fun createFile(fileName: String, addedOutputs: Set, content: String) + + fun compile( + forceOutput: LogLevel? = null, + assertions: context(Module) CompilationOutcome.() -> Unit = {}, + ) +} \ No newline at end of file diff --git a/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/scenarioDsl.kt b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/scenarioDsl.kt new file mode 100644 index 00000000000..432c415013b --- /dev/null +++ b/compiler/build-tools/kotlin-build-tools-api-tests/src/testCommon/kotlin/compilation/scenario/scenarioDsl.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2010-2023 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. + */ + +package org.jetbrains.kotlin.buildtools.api.tests.compilation.scenario + +import org.jetbrains.kotlin.buildtools.api.CompilerExecutionStrategyConfiguration +import org.jetbrains.kotlin.buildtools.api.SourcesChanges +import org.jetbrains.kotlin.buildtools.api.tests.compilation.assertions.assertOutputs +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.BaseCompilationTest +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.CompilationOutcome +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.LogLevel +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Module +import org.jetbrains.kotlin.buildtools.api.tests.compilation.model.Project +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import kotlin.io.path.* + +private class ScenarioModuleImpl( + val module: Module, + val outputs: MutableSet, + private val strategyConfig: CompilerExecutionStrategyConfiguration, +) : ScenarioModule { + override fun changeFile( + fileName: String, + addedOutputs: Set, + removedOutputs: Set, + transform: (String) -> String, + ) { + val file = module.sourcesDirectory.resolve(fileName) + file.writeText(transform(file.readText())) + outputs.addAll(addedOutputs) + outputs.removeAll(removedOutputs) + sourcesChanges = SourcesChanges.Known( + modifiedFiles = sourcesChanges.modifiedFiles + file.toFile(), + removedFiles = sourcesChanges.removedFiles, + ) + } + + override fun deleteFile(fileName: String, removedOutputs: Set) { + val file = module.sourcesDirectory.resolve(fileName) + file.deleteExisting() + outputs.removeAll(removedOutputs) + sourcesChanges = SourcesChanges.Known( + modifiedFiles = sourcesChanges.modifiedFiles, + removedFiles = sourcesChanges.removedFiles + file.toFile(), + ) + } + + override fun createFile(fileName: String, addedOutputs: Set, content: String) { + val file = module.sourcesDirectory.resolve(fileName) + file.writeText(content) + outputs.addAll(addedOutputs) + sourcesChanges = SourcesChanges.Known( + modifiedFiles = sourcesChanges.modifiedFiles + file.toFile(), + removedFiles = sourcesChanges.removedFiles, + ) + } + + var sourcesChanges = SourcesChanges.Known(emptyList(), emptyList()) + + override fun compile( + forceOutput: LogLevel?, + assertions: context(Module) CompilationOutcome.() -> Unit, + ) { + module.compileIncrementally(strategyConfig, sourcesChanges, forceOutput, assertions = { + assertions(module, this) + assertOutputs(outputs) + }) + } + +} + +private class ScenarioDsl( + private val project: Project, + private val strategyConfig: CompilerExecutionStrategyConfiguration, +) : Scenario { + @Synchronized + override fun module( + moduleName: String, + dependencies: List, + additionalCompilationArguments: List, + ): ScenarioModule { + val transformedDependencies = dependencies.map { (it as ScenarioModuleImpl).module } + val module = project.module(moduleName, transformedDependencies, additionalCompilationArguments) + module.compileIncrementally(strategyConfig, SourcesChanges.Unknown) + val initialOutputs = mutableSetOf() + for (file in module.outputDirectory.walk()) { + if (!file.isRegularFile()) continue + initialOutputs.add(file.relativeTo(module.outputDirectory).toString()) + } + return ScenarioModuleImpl(module, initialOutputs, strategyConfig) + } +} + +fun BaseCompilationTest.scenario(strategyConfig: CompilerExecutionStrategyConfiguration, action: Scenario.() -> Unit) { + action(ScenarioDsl(Project(workingDirectory), strategyConfig)) +} \ No newline at end of file