migrated NativeEmbeddableCompilerJarIT to junit 5 and gradle TestKit

#KT-51553


Co-authored-by: Alexander Likhachev <me@alikhachev.com>

Merge-request: KT-MR-9579
Merged-by: Dmitrii Krasnov <Dmitrii.Krasnov@jetbrains.com>
This commit is contained in:
Dmitrii Krasnov
2023-04-20 11:10:30 +00:00
committed by Space Team
parent 594b044c26
commit aea7f4b6d2
13 changed files with 239 additions and 171 deletions
@@ -10,7 +10,6 @@ import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.tooling.GradleConnector
import org.gradle.util.GradleVersion
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties.COMPILE_INCREMENTAL_WITH_ARTIFACT_TRANSFORM
import org.jetbrains.kotlin.gradle.model.ModelContainer
import org.jetbrains.kotlin.gradle.model.ModelFetcherBuildAction
@@ -743,29 +742,6 @@ abstract class BaseGradleIT {
}
}
fun CompiledProject.getOutputForTask(taskName: String): String {
@Language("RegExp")
val taskOutputRegex = """
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task :$taskName' started
([\s\S]+?)
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task :$taskName' completed
""".trimIndent()
.replace("\n", "")
.toRegex()
return taskOutputRegex.find(output)?.run { groupValues[1] } ?: error("Cannot find output for task $taskName")
}
fun CompiledProject.assertCompiledKotlinSources(
sources: Iterable<String>,
weakTesting: Boolean = false,
tasks: List<String>
) {
for (task in tasks) {
assertCompiledKotlinSources(sources, weakTesting, getOutputForTask(task), suffix = " in task ${task}")
}
}
fun CompiledProject.assertCompiledKotlinSources(
expectedSourcesRelativePaths: Iterable<String>,
weakTesting: Boolean = false,
@@ -8,12 +8,10 @@ package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.parseCompilerArguments
import org.jetbrains.kotlin.gradle.util.parseCompilerArgumentsFromBuildOutput
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.fail
import kotlin.io.path.appendText
import kotlin.test.assertEquals
import kotlin.test.fail
@@ -255,7 +253,7 @@ internal class CompilerOptionsIT : KGPBaseTest() {
build("compileNativeMainKotlinMetadata") {
assertTasksExecuted(":compileNativeMainKotlinMetadata")
val taskOutput = getOutputForTask("compileNativeMainKotlinMetadata")
val taskOutput = getOutputForTask(":compileNativeMainKotlinMetadata")
val arguments = parseCompilerArgumentsFromBuildOutput(K2NativeCompilerArguments::class, taskOutput)
assertEquals(
setOf("another.custom.UnderOptIn", "my.custom.OptInAnnotation"), arguments.optIn?.toSet(),
@@ -265,7 +263,7 @@ internal class CompilerOptionsIT : KGPBaseTest() {
build("compileKotlinLinux64") {
assertTasksExecuted(":compileKotlinLinux64")
val taskOutput = getOutputForTask("compileKotlinLinux64")
val taskOutput = getOutputForTask(":compileKotlinLinux64")
val arguments = parseCompilerArgumentsFromBuildOutput(K2NativeCompilerArguments::class, taskOutput)
assertEquals(
setOf("another.custom.UnderOptIn", "my.custom.OptInAnnotation"), arguments.optIn?.toSet(),
@@ -283,7 +283,7 @@ open class KaptIncrementalIT : KGPBaseTest() {
val useBKt = javaSourcesDir().resolve("bar/useB.kt")
assertCompiledKotlinSources(
listOf(projectPath.relativize(bKt), projectPath.relativize(useBKt)),
getOutputForTask("kaptGenerateStubsKotlin"),
getOutputForTask(":kaptGenerateStubsKotlin"),
errorMessageSuffix = " in task 'kaptGenerateStubsKotlin'"
)
@@ -344,13 +344,13 @@ open class KaptIncrementalIT : KGPBaseTest() {
) {
assertCompiledKotlinSources(
sources,
buildResult.getOutputForTask("kaptGenerateStubsKotlin"),
buildResult.getOutputForTask(":kaptGenerateStubsKotlin"),
errorMessageSuffix = " in task 'kaptGenerateStubsKotlin"
)
assertCompiledKotlinSources(
sources,
buildResult.getOutputForTask("compileKotlin"),
buildResult.getOutputForTask(":compileKotlin"),
errorMessageSuffix = " in task 'compileKotlin'"
)
}
@@ -185,12 +185,12 @@ open class Kapt3AndroidIncrementalIT : Kapt3BaseIT() {
.resolve(useUtilFileName).relativeTo(projectPath)
assertCompiledKotlinSources(
listOf(affectedFile),
getOutputForTask("app:kaptGenerateStubsDebugKotlin"),
getOutputForTask(":app:kaptGenerateStubsDebugKotlin"),
errorMessageSuffix = " in task ':app:kaptGenerateStubsDebugKotlin"
)
assertCompiledKotlinSources(
listOf(affectedFile),
getOutputForTask("app:compileDebugKotlin"),
getOutputForTask(":app:compileDebugKotlin"),
errorMessageSuffix = " in task ':app:compileDebugKotlin"
)
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.native
import com.intellij.testFramework.TestDataFile
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.util.GradleVersion
import org.jdom.input.SAXBuilder
@@ -15,8 +16,7 @@ import org.jetbrains.kotlin.gradle.internals.DISABLED_NATIVE_TARGETS_REPORTER_WA
import org.jetbrains.kotlin.gradle.internals.NO_NATIVE_STDLIB_PROPERTY_WARNING
import org.jetbrains.kotlin.gradle.internals.NO_NATIVE_STDLIB_WARNING
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind
import org.jetbrains.kotlin.gradle.testbase.TestVersions
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.modify
import org.jetbrains.kotlin.gradle.util.runProcess
import org.jetbrains.kotlin.gradle.utils.Xcode
@@ -498,7 +498,8 @@ class GeneralNativeIT : BaseGradleIT() {
"releaseExecutable" to "native-binary",
"bazDebugExecutable" to "my-baz",
)
val linkTasks = binaries.map { (name, _) -> "link${name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}Host" }
val linkTasks =
binaries.map { (name, _) -> "link${name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}Host" }
val outputFiles = binaries.map { (name, fileBaseName) ->
val outputKind = NativeOutputKind.values().single { name.endsWith(it.taskNameClassifier, true) }.compilerOutputKind
val prefix = outputKind.prefix(HostManager.host)
@@ -874,7 +875,7 @@ class GeneralNativeIT : BaseGradleIT() {
assertSuccessful()
assertTasksExecuted(":projectLibrary:cinteropAnotherNumberHost")
libraryFiles("projectLibrary", "anotherNumber").forEach { assertFileExists(it) }
withNativeCustomEnvironment(":projectLibrary:cinteropAnotherNumberHost", toolName = "cinterop") { env ->
withNativeCustomEnvironment(":projectLibrary:cinteropAnotherNumberHost", toolName = NativeToolKind.C_INTEROP) { env ->
assertEquals("1", env["LIBCLANG_DISABLE_CRASH_RECOVERY"])
}
}
@@ -1173,18 +1174,19 @@ class GeneralNativeIT : BaseGradleIT() {
// KT-52303
@Test
fun testBuildDirChangeAppliedToBinaries() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
gradleBuildScript().appendText(
"""
fun testBuildDirChangeAppliedToBinaries() =
with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
gradleBuildScript().appendText(
"""
project.buildDir = file("${'$'}{project.buildDir.absolutePath}/mydir")
""".trimIndent()
)
build(":linkDebugExecutableHost") {
assertSuccessful()
assertDirectoryExists("build/mydir/bin/host/debugExecutable")
assertNoSuchFile("build/bin")
)
build(":linkDebugExecutableHost") {
assertSuccessful()
assertDirectoryExists("build/mydir/bin/host/debugExecutable")
assertNoSuchFile("build/bin")
}
}
}
// KT-54439
@Test
@@ -1215,70 +1217,35 @@ class GeneralNativeIT : BaseGradleIT() {
return Collections.indexOfSubList(this, elements.toList()) != -1
}
private enum class NativeToolSettingsKind(val title: String) {
COMPILER_CLASSPATH("Classpath"),
COMMAND_LINE_ARGUMENTS("Arguments"),
CUSTOM_ENV_VARIABLES("Custom ENV variables")
}
/**
* Filter output for specific task with given [taskPath]
*
* Requires using [LogLevel.DEBUG].
*/
fun CompiledProject.getOutputForTask(taskPath: String): String = getOutputForTask(taskPath, output)
private fun CompiledProject.extractNativeToolSettings(
toolName: String,
taskPath: String?,
settingsKind: NativeToolSettingsKind
): Sequence<String> {
val settingsPrefix = "${settingsKind.title} = ["
val settings = output.lineSequence()
.run {
if (taskPath != null) dropWhile { "Executing actions for task '$taskPath'" !in it }.drop(1) else this
}
.dropWhile {
check(taskPath == null || "Executing actions for task" !in it) { "Unexpected log line with new Gradle task: $it" }
"Run in-process tool \"$toolName\"" !in it && "Run \"$toolName\" tool in a separate JVM process" !in it
}
.drop(1)
.dropWhile {
check(taskPath == null || "Executing actions for task" !in it) { "Unexpected log line with new Gradle task: $it" }
settingsPrefix !in it
}
fun CompiledProject.extractNativeCommandLineArguments(taskPath: String? = null, toolName: NativeToolKind): List<String> =
extractNativeToolSettings(taskPath?.let { getOutputForTask(taskPath) } ?: output,
toolName,
NativeToolSettingsKind.COMMAND_LINE_ARGUMENTS).toList()
val settingsHeader = settings.firstOrNull()
check(settingsHeader != null && settingsPrefix in settingsHeader) {
"Cannot find setting '${settingsKind.title}' for task ${taskPath}"
}
return if (settingsHeader.trimEnd().endsWith(']'))
emptySequence() // No parameters.
else
settings.drop(1).map { it.trim() }.takeWhile { it != "]" }
}
fun CompiledProject.extractNativeCommandLineArguments(taskPath: String? = null, toolName: String): List<String> =
extractNativeToolSettings(toolName, taskPath, NativeToolSettingsKind.COMMAND_LINE_ARGUMENTS).toList()
fun CompiledProject.extractNativeCompilerClasspath(taskPath: String? = null, toolName: String): List<String> =
extractNativeToolSettings(toolName, taskPath, NativeToolSettingsKind.COMPILER_CLASSPATH).toList()
fun CompiledProject.extractNativeCustomEnvironment(taskPath: String? = null, toolName: String): Map<String, String> =
extractNativeToolSettings(toolName, taskPath, NativeToolSettingsKind.CUSTOM_ENV_VARIABLES).map {
fun CompiledProject.extractNativeCustomEnvironment(taskPath: String? = null, toolName: NativeToolKind): Map<String, String> =
extractNativeToolSettings(taskPath?.let { getOutputForTask(taskPath) } ?: output,
toolName,
NativeToolSettingsKind.CUSTOM_ENV_VARIABLES).map {
val (key, value) = it.split("=")
key.trim() to value.trim()
}.toMap()
fun CompiledProject.withNativeCommandLineArguments(
vararg taskPaths: String,
toolName: String = "konanc",
toolName: NativeToolKind = NativeToolKind.KONANC,
check: (List<String>) -> Unit
) = taskPaths.forEach { taskPath -> check(extractNativeCommandLineArguments(taskPath, toolName)) }
fun CompiledProject.withNativeCompilerClasspath(
vararg taskPaths: String,
toolName: String = "konanc",
check: (List<String>) -> Unit
) = taskPaths.forEach { taskPath -> check(extractNativeCompilerClasspath(taskPath, toolName)) }
fun CompiledProject.withNativeCustomEnvironment(
vararg taskPaths: String,
toolName: String = "konanc",
toolName: NativeToolKind = NativeToolKind.KONANC,
check: (Map<String, String>) -> Unit
) = taskPaths.forEach { taskPath -> check(extractNativeCustomEnvironment(taskPath, toolName)) }
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.embedProject
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.containsSequentially
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.extractNativeCommandLineArguments
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.withNativeCommandLineArguments
import org.jetbrains.kotlin.gradle.testbase.NativeToolKind
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
import org.jetbrains.kotlin.gradle.util.modify
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
@@ -186,7 +187,7 @@ class NativeDownloadAndPlatformLibsIT : BaseGradleIT() {
// Check that user can change generation mode used by the cinterop tool.
buildWithLightDist("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") {
assertSuccessful()
assertTrue(extractNativeCommandLineArguments(toolName = "generatePlatformLibraries").containsSequentially("-mode", "metadata"))
assertTrue(extractNativeCommandLineArguments(toolName = NativeToolKind.GENERATE_PLATFORM_LIBRARIES).containsSequentially("-mode", "metadata"))
}
}
@@ -1,21 +1,21 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.gradle.native
import org.jetbrains.kotlin.gradle.BaseGradleIT
import org.jetbrains.kotlin.gradle.GradleVersionRequired
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.withNativeCompilerClasspath
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import org.gradle.api.logging.LogLevel
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
class NativeEmbeddableCompilerJarIT : BaseGradleIT() {
@DisplayName("Tests for K/N builds with embeddable compiler jar")
@NativeGradlePluginTests
internal class NativeEmbeddableCompilerJarIT : KGPBaseTest() {
override val defaultGradleVersion: GradleVersionRequired
get() = GradleVersionRequired.FOR_MPP_SUPPORT
override val defaultBuildOptions = super.defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
private fun String.isRegularJar() = this.endsWith("/kotlin-native.jar")
private fun String.isEmbeddableJar() = this.endsWith("/kotlin-native-compiler-embeddable.jar")
@@ -23,60 +23,103 @@ class NativeEmbeddableCompilerJarIT : BaseGradleIT() {
private fun List<String>.includesRegularJar() = any { it.isRegularJar() }
private fun List<String>.includesEmbeddableJar() = any { it.isEmbeddableJar() }
@Test
fun testDefault() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
build(":linkDebugExecutableHost") {
assertSuccessful()
withNativeCompilerClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assertFalse(it.includesRegularJar())
assertTrue(it.includesEmbeddableJar())
private val String.withPrefix get() = "native-binaries/$this"
@DisplayName("K/N with default config shouldn't contain kotlin-native.jar and should contain kotlin-native-compiler-embeddable.jar")
@GradleTest
fun shouldNotUseRegularJarInDefaultConfig(gradleVersion: GradleVersion) {
nativeProject("executables".withPrefix, gradleVersion) {
build(":linkDebugExecutableHost") {
assertNativeTasksClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assert(!it.includesRegularJar()) {
assertionFailedMessage(it)
}
assert(it.includesEmbeddableJar()) {
assertionFailedMessage(it)
}
}
}
}
}
@Test
fun testEmbeddableJarFalse() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
build(":linkDebugExecutableHost", "-Pkotlin.native.useEmbeddableCompilerJar=false") {
assertSuccessful()
withNativeCompilerClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assertTrue(it.includesRegularJar())
assertFalse(it.includesEmbeddableJar())
@DisplayName("K/N with embeddable compiler flag turned off config should contain kotlin-native.jar and shouldn't contain kotlin-native-compiler-embeddable.jar")
@GradleTest
fun shouldUseRegularJarWithoutUseEmbeddableCompilerJar(gradleVersion: GradleVersion) {
nativeProject("executables".withPrefix, gradleVersion) {
build(
":linkDebugExecutableHost",
"-Pkotlin.native.useEmbeddableCompilerJar=false",
) {
assertNativeTasksClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assert(it.includesRegularJar()) {
assertionFailedMessage(it)
}
assert(!it.includesEmbeddableJar()) {
assertionFailedMessage(it)
}
}
}
}
}
@Test
fun testEmbeddableJarTrue() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
build(":linkDebugExecutableHost", "-Pkotlin.native.useEmbeddableCompilerJar=true") {
assertSuccessful()
withNativeCompilerClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assertFalse(it.includesRegularJar())
assertTrue(it.includesEmbeddableJar())
@DisplayName("K/N with embeddable compiler flag turned on config shouldn't contain kotlin-native.jar and should contain kotlin-native-compiler-embeddable.jar")
@GradleTest
fun shouldUseRegularJarWithUseEmbeddableCompilerJar(gradleVersion: GradleVersion) {
nativeProject("executables".withPrefix, gradleVersion) {
build(
":linkDebugExecutableHost",
"-Pkotlin.native.useEmbeddableCompilerJar=true",
) {
assertNativeTasksClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assert(!it.includesRegularJar()) {
assertionFailedMessage(it)
}
assert(it.includesEmbeddableJar()) {
assertionFailedMessage(it)
}
}
}
}
}
@Test
fun testSwitch() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
build(":linkDebugExecutableHost") {
assertSuccessful()
withNativeCompilerClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assertFalse(it.includesRegularJar())
assertTrue(it.includesEmbeddableJar())
@DisplayName("K/N project's builds with switching embeddable compiler flag turned from on to off")
@GradleTest
fun testSwitch(gradleVersion: GradleVersion) {
nativeProject("executables".withPrefix, gradleVersion) {
build(":linkDebugExecutableHost") {
assertNativeTasksClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assert(!it.includesRegularJar()) {
assertionFailedMessage(it)
}
assert(it.includesEmbeddableJar()) {
assertionFailedMessage(it)
}
}
}
}
build(":linkDebugExecutableHost") {
assertTasksUpToDate(":linkDebugExecutableHost", ":compileKotlinHost")
}
build(":linkDebugExecutableHost") {
assertTasksUpToDate(":linkDebugExecutableHost", ":compileKotlinHost")
}
build(":linkDebugExecutableHost", "-Pkotlin.native.useEmbeddableCompilerJar=false") {
assertSuccessful()
assertTasksExecuted(":linkDebugExecutableHost", ":compileKotlinHost")
withNativeCompilerClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assertTrue(it.includesRegularJar())
assertFalse(it.includesEmbeddableJar())
build(
":linkDebugExecutableHost",
"-Pkotlin.native.useEmbeddableCompilerJar=false",
) {
assertTasksExecuted(":linkDebugExecutableHost", ":compileKotlinHost")
assertNativeTasksClasspath(":linkDebugExecutableHost", ":compileKotlinHost") {
assert(it.includesRegularJar()) {
assertionFailedMessage(it)
}
assert(!it.includesEmbeddableJar()) {
assertionFailedMessage(it)
}
}
}
}
}
}
private fun BuildResult.assertionFailedMessage(classPathValues: List<String>): String {
printBuildOutput()
return "Actual classpath is: ${classPathValues}"
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.native
import org.jetbrains.kotlin.gradle.BaseGradleIT
import org.jetbrains.kotlin.gradle.GradleVersionRequired
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.getOutputForTask
import org.jetbrains.kotlin.gradle.testbase.DEFAULT_CURRENT_PLATFORM_TARGET_NAME_POSTFIX
import org.jetbrains.kotlin.gradle.testbase.findParameterInOutput
import org.jetbrains.kotlin.konan.library.KONAN_PLATFORM_LIBS_NAME_PREFIX
@@ -271,7 +272,7 @@ class NativeIrLinkerIssuesIT : BaseGradleIT() {
val kotlinNativeCompilerVersion = findKotlinNativeCompilerVersion(output)
assertNotNull(kotlinNativeCompilerVersion)
val errorMessage = ERROR_LINE_REGEX.findAll(getOutputForTask("linkDebugExecutableNative"))
val errorMessage = ERROR_LINE_REGEX.findAll(getOutputForTask(":linkDebugExecutableNative"))
.map { matchResult -> matchResult.groupValues[1] }
.filterNot { it.startsWith("w:") || it.startsWith("v:") || it.startsWith("i:") }
.map { line ->
@@ -17,27 +17,6 @@ private val kotlinSrcRegex by lazy { Regex("\\[KOTLIN] compile iteration: ([^\\r
private val javaSrcRegex by lazy { Regex("\\[DEBUG] \\[[^]]*JavaCompiler] Compiler arguments: ([^\\r\\n]*)") }
@Language("RegExp")
private fun taskOutputRegex(
taskName: String
) = """
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task :$taskName' started
([\s\S]+?)
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task :$taskName' completed
""".trimIndent()
.replace("\n", "")
.toRegex()
/**
* Filter [BuildResult.getOutput] for specific task with given [taskName].
*
* Requires using [LogLevel.DEBUG].
*/
fun BuildResult.getOutputForTask(taskName: String): String = taskOutputRegex(taskName)
.find(output)
?.let { it.groupValues[1] }
?: error("Could not find output for task $taskName")
/**
* Extracts the list of compiled .kt files from the build output.
*
@@ -9,4 +9,53 @@ import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.presetName
import java.util.*
val DEFAULT_CURRENT_PLATFORM_TARGET_NAME_POSTFIX = HostManager.host.presetName.lowercase(Locale.getDefault())
val DEFAULT_CURRENT_PLATFORM_TARGET_NAME_POSTFIX = HostManager.host.presetName.lowercase(Locale.getDefault())
/**
* Extracts classpath of given task's output
*
* @param taskOutput debug level output of the task
* @param toolName compiler type
*
* @return list of dependencies in classpath
*/
fun extractNativeCompilerClasspath(taskOutput: String, toolName: NativeToolKind): List<String> =
extractNativeToolSettings(taskOutput, toolName, NativeToolSettingsKind.COMPILER_CLASSPATH).toList()
enum class NativeToolKind(val title: String) {
KONANC("konanc"),
GENERATE_PLATFORM_LIBRARIES("generatePlatformLibraries"),
C_INTEROP("cinterop")
}
enum class NativeToolSettingsKind(val title: String) {
COMPILER_CLASSPATH("Classpath"),
COMMAND_LINE_ARGUMENTS("Arguments"),
CUSTOM_ENV_VARIABLES("Custom ENV variables")
}
fun extractNativeToolSettings(
taskOutput: String,
toolName: NativeToolKind,
settingsKind: NativeToolSettingsKind
): Sequence<String> {
val settingsPrefix = "${settingsKind.title} = ["
val settings = taskOutput.lineSequence()
.dropWhile {
"Run in-process tool \"${toolName.title}\"" !in it && "Run \"${toolName.title}\" tool in a separate JVM process" !in it
}
.drop(1)
.dropWhile {
settingsPrefix !in it
}
val settingsHeader = settings.firstOrNull()
check(settingsHeader != null && settingsPrefix in settingsHeader) {
"Cannot find setting '${settingsKind.title}'"
}
return if (settingsHeader.trimEnd().endsWith(']'))
emptySequence() // No parameters.
else
settings.drop(1).map { it.trim() }.takeWhile { it != "]" }
}
@@ -0,0 +1,38 @@
/*
* 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.gradle.testbase
import org.gradle.api.logging.LogLevel
import org.gradle.testkit.runner.BuildResult
import org.intellij.lang.annotations.Language
@Language("RegExp")
private fun taskOutputRegex(
taskName: String
) = """
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task $taskName' started
([\s\S]+?)
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task $taskName' completed
""".trimIndent()
.replace("\n", "")
.toRegex()
/**
* Filter [BuildResult.getOutput] for specific task with given [taskPath]
*
* Requires using [LogLevel.DEBUG].
*/
fun BuildResult.getOutputForTask(taskPath: String): String = getOutputForTask(taskPath, output)
/**
* Filter give output for specific task with given [taskPath]
*
* Requires using [LogLevel.DEBUG].
*/
fun getOutputForTask(taskPath: String, output: String): String = taskOutputRegex(taskPath)
.find(output)
?.let { it.groupValues[1] }
?: error("Could not find output for task $taskPath")
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle.testbase
import org.gradle.api.logging.LogLevel
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.TaskOutcome
@@ -122,3 +123,18 @@ fun BuildResult.assertTasksPackedToCache(vararg tasks: String) {
assertOutputContains("Stored cache entry for task '$it' with cache key ")
}
}
/**
* Asserts classpath of the given K/N compiler tool for given tasks' paths.
*
* Note: Log level of output must be set to [LogLevel.DEBUG].
*
* @param tasksPaths names of the tasks, which classpath should be checked with give assertions
* @param toolName name of build tool
* @param assertions assertions, with will be applied to each classpath of each given task
*/
fun BuildResult.assertNativeTasksClasspath(
vararg tasksPaths: String,
toolName: NativeToolKind = NativeToolKind.KONANC,
assertions: (List<String>) -> Unit
) = tasksPaths.forEach { taskPath -> assertions(extractNativeCompilerClasspath(getOutputForTask(taskPath), toolName)) }
@@ -1,5 +1,5 @@
plugins {
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
id("org.jetbrains.kotlin.multiplatform")
}
repositories {