Gradle IT: Fix Gradle output checks in Kotlin/Native ITs

This commit is contained in:
Dmitriy Dolovov
2020-11-06 13:17:41 +03:00
parent e3db96354d
commit 3cb202f576
3 changed files with 80 additions and 50 deletions
@@ -4,6 +4,8 @@
*/ */
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.checkNativeCommandLineArguments
import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.containsSequentially
import org.jetbrains.kotlin.gradle.native.MPPNativeTargets import org.jetbrains.kotlin.gradle.native.MPPNativeTargets
import org.jetbrains.kotlin.gradle.native.configureMemoryInGradleProperties import org.jetbrains.kotlin.gradle.native.configureMemoryInGradleProperties
import org.jetbrains.kotlin.gradle.native.transformNativeTestProject import org.jetbrains.kotlin.gradle.native.transformNativeTestProject
@@ -123,14 +125,6 @@ class NewMultiplatformIT : BaseGradleIT() {
// we use `maven { setUrl(...) }` because this syntax actually works both for Groovy and Kotlin DSLs in Gradle // we use `maven { setUrl(...) }` because this syntax actually works both for Groovy and Kotlin DSLs in Gradle
gradleBuildScript().appendText("\nrepositories { maven { setUrl(\"$libLocalRepoUri\") } }") gradleBuildScript().appendText("\nrepositories { maven { setUrl(\"$libLocalRepoUri\") } }")
fun CompiledProject.checkProgramCompilationCommandLine(check: (String) -> Unit) {
output.lineSequence().filter {
it.contains("Run tool: \"konanc\"") && it.contains("-p program")
}.toList().also {
assertTrue(it.isNotEmpty())
}.forEach(check)
}
fun CompiledProject.checkAppBuild() { fun CompiledProject.checkAppBuild() {
assertSuccessful() assertSuccessful()
assertTasksExecuted(*compileTasksNames.toTypedArray()) assertTasksExecuted(*compileTasksNames.toTypedArray())
@@ -159,8 +153,8 @@ class NewMultiplatformIT : BaseGradleIT() {
assertFileExists("build/bin/linux64/mainDebugExecutable/$nativeExeName") assertFileExists("build/bin/linux64/mainDebugExecutable/$nativeExeName")
// Check that linker options were correctly passed to the K/N compiler. // Check that linker options were correctly passed to the K/N compiler.
checkProgramCompilationCommandLine { checkNativeCommandLineArguments(":linkMainDebugExecutableLinux64") { arguments ->
assertTrue(it.contains("-linker-option -L.")) assertTrue(arguments.containsSequentially("-linker-option", "-L."))
} }
} }
@@ -712,7 +706,7 @@ class NewMultiplatformIT : BaseGradleIT() {
assertTasksExecuted(":$it") assertTasksExecuted(":$it")
assertContains( assertContains(
"-XXLanguage:+InlineClasses", "-XXLanguage:+InlineClasses",
" -progressive", "-Xopt-in=kotlin.ExperimentalUnsignedTypes", "-progressive", "-Xopt-in=kotlin.ExperimentalUnsignedTypes",
"-Xopt-in=kotlin.contracts.ExperimentalContracts", "-Xopt-in=kotlin.contracts.ExperimentalContracts",
"-Xno-inline" "-Xno-inline"
) )
@@ -25,6 +25,7 @@ import org.junit.Assume
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@@ -261,27 +262,27 @@ class GeneralNativeIT : BaseGradleIT() {
fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported") fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported")
// Check that by default release frameworks have bitcode embedded. // Check that by default release frameworks have bitcode embedded.
checkNativeCommandLineFor(":linkMainReleaseFrameworkIos") { checkNativeCommandLineArguments(":linkMainReleaseFrameworkIos") { arguments ->
assertTrue(it.contains("-Xembed-bitcode")) assertTrue("-Xembed-bitcode" in arguments)
assertTrue(it.contains("-opt")) assertTrue("-opt" in arguments)
} }
// Check that by default debug frameworks have bitcode marker embedded. // Check that by default debug frameworks have bitcode marker embedded.
checkNativeCommandLineFor(":linkMainDebugFrameworkIos") { checkNativeCommandLineArguments(":linkMainDebugFrameworkIos") { arguments ->
assertTrue(it.contains("-Xembed-bitcode-marker")) assertTrue("-Xembed-bitcode-marker" in arguments)
assertTrue(it.contains("-g")) assertTrue("-g" in arguments)
} }
// Check that bitcode can be disabled by setting custom compiler options // Check that bitcode can be disabled by setting custom compiler options
checkNativeCommandLineFor(":linkCustomDebugFrameworkIos") { checkNativeCommandLineArguments(":linkCustomDebugFrameworkIos") { arguments ->
assertTrue(it.contains("-linker-option -L.")) assertTrue(arguments.containsSequentially("-linker-option", "-L."))
assertTrue(it.contains("-Xtime")) assertTrue("-Xtime" in arguments)
assertTrue(it.contains("-Xstatic-framework")) assertTrue("-Xstatic-framework" in arguments)
assertFalse(it.contains("-Xembed-bitcode-marker")) assertFalse("-Xembed-bitcode-marker" in arguments)
assertFalse(it.contains("-Xembed-bitcode")) assertFalse("-Xembed-bitcode" in arguments)
} }
// Check that bitcode is disabled for iOS simulator. // Check that bitcode is disabled for iOS simulator.
checkNativeCommandLineFor(":linkMainReleaseFrameworkIosSim", ":linkMainDebugFrameworkIosSim") { checkNativeCommandLineArguments(":linkMainReleaseFrameworkIosSim", ":linkMainDebugFrameworkIosSim") { arguments ->
assertFalse(it.contains("-Xembed-bitcode")) assertFalse("-Xembed-bitcode" in arguments)
assertFalse(it.contains("-Xembed-bitcode-marker")) assertFalse("-Xembed-bitcode-marker" in arguments)
} }
} }
@@ -302,10 +303,12 @@ class GeneralNativeIT : BaseGradleIT() {
fun testExportApiOnlyToLibraries() { fun testExportApiOnlyToLibraries() {
val project = transformNativeTestProjectWithPluginDsl("libraries", directoryPrefix = "native-binaries") val project = transformNativeTestProjectWithPluginDsl("libraries", directoryPrefix = "native-binaries")
testExportApi(project, listOf( testExportApi(
ExportApiTestData("linkDebugSharedHost", "debugShared"), project, listOf(
ExportApiTestData("linkDebugStaticHost", "debugStatic"), ExportApiTestData("linkDebugSharedHost", "debugShared"),
)) ExportApiTestData("linkDebugStaticHost", "debugStatic"),
)
)
} }
@Test @Test
@@ -313,9 +316,11 @@ class GeneralNativeIT : BaseGradleIT() {
Assume.assumeTrue(HostManager.hostIsMac) Assume.assumeTrue(HostManager.hostIsMac)
val project = transformNativeTestProjectWithPluginDsl("frameworks", directoryPrefix = "native-binaries") val project = transformNativeTestProjectWithPluginDsl("frameworks", directoryPrefix = "native-binaries")
testExportApi(project, listOf( testExportApi(
ExportApiTestData("linkMainDebugFrameworkIos", "mainDebugFramework") project, listOf(
)) ExportApiTestData("linkMainDebugFrameworkIos", "mainDebugFramework")
)
)
} }
private data class ExportApiTestData(val taskName: String, val binaryName: String) private data class ExportApiTestData(val taskName: String, val binaryName: String)
@@ -337,16 +342,6 @@ class GeneralNativeIT : BaseGradleIT() {
} }
} }
private fun CompiledProject.checkNativeCommandLineFor(vararg taskPaths: String, check: (String) -> Unit) =
taskPaths.forEach { taskPath ->
val commandLine = output.lineSequence().dropWhile {
!it.contains("Executing actions for task '$taskPath'")
}.first {
it.contains("Run tool: \"konanc\"")
}
check(commandLine)
}
@Test @Test
fun testNativeExecutables() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) { fun testNativeExecutables() = with(transformNativeTestProjectWithPluginDsl("executables", directoryPrefix = "native-binaries")) {
val binaries = mutableListOf( val binaries = mutableListOf(
@@ -424,8 +419,8 @@ class GeneralNativeIT : BaseGradleIT() {
) { ) {
build(":compileKotlinHost") { build(":compileKotlinHost") {
assertSuccessful() assertSuccessful()
checkNativeCommandLineFor(":compileKotlinHost") { checkNativeCommandLineArguments(":compileKotlinHost") { arguments ->
assertFalse(it.contains("-verbose")) assertFalse("-verbose" in arguments)
} }
} }
@@ -438,8 +433,8 @@ class GeneralNativeIT : BaseGradleIT() {
) )
build(":compileKotlinHost") { build(":compileKotlinHost") {
assertSuccessful() assertSuccessful()
checkNativeCommandLineFor(":compileKotlinHost") { checkNativeCommandLineArguments(":compileKotlinHost") { arguments ->
assertTrue(it.contains("-verbose")) assertTrue("-verbose" in arguments)
} }
} }
} }
@@ -822,9 +817,47 @@ class GeneralNativeIT : BaseGradleIT() {
build("compileKotlin${nativeHostTargetName.capitalize()}") { build("compileKotlin${nativeHostTargetName.capitalize()}") {
assertSuccessful() assertSuccessful()
checkNativeCommandLineFor(":compileKotlin${nativeHostTargetName.capitalize()}") { checkNativeCommandLineArguments(":compileKotlin${nativeHostTargetName.capitalize()}") { arguments ->
it.contains(fileWithSpacesInPath.absolutePath) val escapedQuotedPath = "\"${fileWithSpacesInPath.absolutePath.replace("\"", "\\\"")}\""
assertTrue(escapedQuotedPath in arguments)
} }
} }
} }
companion object {
fun List<String>.containsSequentially(vararg elements: String): Boolean {
check(elements.isNotEmpty())
return Collections.indexOfSubList(this, elements.toList()) != -1
}
fun CompiledProject.extractNativeCommandLineArguments(taskPath: String? = null, toolName: String): List<String> {
val arguments = 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)
"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)
"Arguments = [" !in it
}
val argumentsHeader = arguments.firstOrNull()
check(argumentsHeader != null && "Arguments = [" in argumentsHeader)
return if (argumentsHeader.trimEnd().endsWith(']'))
emptyList() // no arguments
else
arguments.drop(1).map { it.trim() }.takeWhile { it != "]" }.toList()
}
fun CompiledProject.checkNativeCommandLineArguments(
vararg taskPaths: String,
toolName: String = "konanc",
check: (List<String>) -> Unit
) = taskPaths.forEach { taskPath -> check(extractNativeCommandLineArguments(taskPath, toolName)) }
}
} }
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.native
import org.jetbrains.kotlin.gradle.* import org.jetbrains.kotlin.gradle.*
import org.jetbrains.kotlin.gradle.embedProject 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.transformProjectWithPluginsDsl import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.util.modify
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
@@ -17,6 +19,7 @@ import org.jetbrains.kotlin.konan.util.DependencyDirectories
import org.junit.Assume import org.junit.Assume
import org.junit.BeforeClass import org.junit.BeforeClass
import org.junit.Test import org.junit.Test
import kotlin.test.assertTrue
class NativePlatformLibsIT : BaseGradleIT() { class NativePlatformLibsIT : BaseGradleIT() {
@@ -213,7 +216,7 @@ class NativePlatformLibsIT : BaseGradleIT() {
// Check that user can change generation mode used by the cinterop tool. // Check that user can change generation mode used by the cinterop tool.
buildWithLightDist("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") { buildWithLightDist("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") {
assertSuccessful() assertSuccessful()
assertContainsRegex("Run tool: \"generatePlatformLibraries\" with args: .* -mode metadata".toRegex()) assertTrue(extractNativeCommandLineArguments(toolName = "generatePlatformLibraries").containsSequentially("-mode", "metadata"))
} }
} }