migrated CommonNativeIT to junit 5 and gradle TestKit
#KT-51553 In Progress Co-authored-by: Alexander Likhachev <Alexander.Likhachev@jetbrains.com> Merge-request: KT-MR-9750 Merged-by: Dmitrii Krasnov <Dmitrii.Krasnov@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
530725c6bf
commit
4dd54e4de4
+70
-78
@@ -1,101 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2020 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.
|
* 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
|
package org.jetbrains.kotlin.gradle.native
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
import org.jetbrains.kotlin.gradle.util.capitalize
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.Assume
|
import org.junit.jupiter.api.condition.OS
|
||||||
import org.junit.BeforeClass
|
|
||||||
import org.junit.Test
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CommonNativeIT : BaseGradleIT() {
|
@OsCondition(supportedOn = [OS.MAC], enabledOnCI = [OS.MAC])
|
||||||
|
@DisplayName("K/N tests of apple native common libs")
|
||||||
|
@NativeGradlePluginTests
|
||||||
|
class CommonNativeIT : KGPBaseTest() {
|
||||||
|
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
// TODO(Dmitrii Krasnov): remove it, when KT-58104 will be fixed
|
||||||
get() = GradleVersionRequired.FOR_MPP_SUPPORT
|
override val defaultBuildOptions = super.defaultBuildOptions.copy(statisticsForceValidation = false)
|
||||||
|
|
||||||
|
private val String.withPrefix get() = "native-apple-devices-common/$this"
|
||||||
|
|
||||||
|
@DisplayName("Common ios")
|
||||||
|
@GradleTest
|
||||||
|
fun testCommonIos(gradleVersion: GradleVersion) {
|
||||||
|
doCommonNativeTest(
|
||||||
|
"common-ios",
|
||||||
|
libTargets = listOf("iosLibArm64", "iosLibX64"),
|
||||||
|
appTargets = listOf("iosArm64", "iosX64"),
|
||||||
|
gradleVersion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("Common watchos")
|
||||||
|
@GradleTest
|
||||||
|
fun testCommonWatchos(gradleVersion: GradleVersion) {
|
||||||
|
doCommonNativeTest(
|
||||||
|
"common-watchos",
|
||||||
|
libTargets = listOf("watchosLibArm32", "watchosLibArm64", "watchosLibX64"),
|
||||||
|
appTargets = listOf("watchosArm32", "watchosArm64", "watchosX64"),
|
||||||
|
gradleVersion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("Common tvos")
|
||||||
|
@GradleTest
|
||||||
|
fun testCommonTvos(gradleVersion: GradleVersion) {
|
||||||
|
doCommonNativeTest(
|
||||||
|
"common-tvos",
|
||||||
|
libTargets = listOf("tvosLibArm64", "tvosLibX64"),
|
||||||
|
appTargets = listOf("tvosArm64", "tvosX64"),
|
||||||
|
gradleVersion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun doCommonNativeTest(
|
private fun doCommonNativeTest(
|
||||||
projectName: String,
|
projectName: String,
|
||||||
libTargets: List<String>,
|
libTargets: List<String>,
|
||||||
appTargets: List<String>
|
appTargets: List<String>,
|
||||||
) = with(transformProjectWithPluginsDsl(projectName, directoryPrefix = "native-apple-devices-common")) {
|
gradleVersion: GradleVersion
|
||||||
gradleProperties().apply {
|
) {
|
||||||
|
nativeProject(projectName.withPrefix, gradleVersion) {
|
||||||
|
|
||||||
configureJvmMemory()
|
configureJvmMemory()
|
||||||
}
|
|
||||||
|
|
||||||
val libCompileTasks = libTargets.map { ":lib:compileKotlin${it.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}" }
|
val libCompileTasks = libTargets.map { ":lib:compileKotlin${it.capitalize()}" }
|
||||||
val appCompileTasks = appTargets.map { ":app:compileKotlin${it.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}" }
|
val appCompileTasks = appTargets.map { ":app:compileKotlin${it.capitalize()}" }
|
||||||
val appLinkFrameworkTasks = appTargets.map {
|
val appLinkFrameworkTasks = appTargets.map { ":app:linkDebugFramework${it.capitalize()}" }
|
||||||
":app:linkDebugFramework${
|
val appLinkTestTasks = appTargets.map { ":app:linkDebugTest${it.capitalize()}" }
|
||||||
it.replaceFirstChar {
|
build(":lib:publish") {
|
||||||
if (it.isLowerCase()) it.titlecase(
|
assertTasksExecuted(libCompileTasks)
|
||||||
Locale.getDefault()
|
libTargets.forEach {
|
||||||
) else it.toString()
|
assertOutputContains("Configuring $it")
|
||||||
|
assertFileInProjectExists("lib/build/classes/kotlin/$it/main/klib/lib.klib")
|
||||||
}
|
}
|
||||||
}" }
|
|
||||||
val appLinkTestTasks = appTargets.map { ":app:linkDebugTest${it.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}" }
|
|
||||||
|
|
||||||
build(":lib:publish") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertTasksExecuted(libCompileTasks)
|
|
||||||
libTargets.forEach {
|
|
||||||
assertContains("Configuring $it")
|
|
||||||
assertFileExists("lib/build/classes/kotlin/$it/main/klib/lib.klib")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
build(":app:build", *appLinkTestTasks.toTypedArray()) {
|
build(":app:build", *appLinkTestTasks.toTypedArray()) {
|
||||||
assertSuccessful()
|
assertTasksExecuted(appCompileTasks)
|
||||||
assertTasksExecuted(appCompileTasks)
|
assertTasksExecuted(appLinkFrameworkTasks)
|
||||||
assertTasksExecuted(appLinkFrameworkTasks)
|
assertTasksExecuted(appLinkTestTasks)
|
||||||
assertTasksExecuted(appLinkTestTasks)
|
|
||||||
|
|
||||||
appTargets.forEach {
|
appTargets.forEach {
|
||||||
assertFileExists("app/build/classes/kotlin/$it/main/klib/app.klib")
|
assertFileInProjectExists("app/build/classes/kotlin/$it/main/klib/app.klib")
|
||||||
assertFileExists("app/build/bin/$it/debugFramework")
|
assertDirectoryInProjectExists("app/build/bin/$it/debugFramework")
|
||||||
assertFileExists("app/build/bin/$it/debugTest")
|
assertDirectoryInProjectExists("app/build/bin/$it/debugTest")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testCommonIos() {
|
|
||||||
doCommonNativeTest(
|
|
||||||
"common-ios",
|
|
||||||
libTargets = listOf("iosLibArm64", "iosLibX64"),
|
|
||||||
appTargets = listOf("iosArm64", "iosX64")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testCommonWatchos() {
|
|
||||||
doCommonNativeTest(
|
|
||||||
"common-watchos",
|
|
||||||
libTargets = listOf("watchosLibArm32", "watchosLibArm64", "watchosLibX64"),
|
|
||||||
appTargets = listOf("watchosArm32", "watchosArm64", "watchosX64")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testCommonTvos() {
|
|
||||||
doCommonNativeTest(
|
|
||||||
"common-tvos",
|
|
||||||
libTargets = listOf("tvosLibArm64", "tvosLibX64"),
|
|
||||||
appTargets = listOf("tvosArm64", "tvosX64")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@BeforeClass
|
|
||||||
@JvmStatic
|
|
||||||
fun assumeItsMac() {
|
|
||||||
Assume.assumeTrue(HostManager.hostIsMac)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ class FatFrameworkIT : KGPBaseTest() {
|
|||||||
nativeProject(
|
nativeProject(
|
||||||
"native-fat-framework/smoke",
|
"native-fat-framework/smoke",
|
||||||
gradleVersion,
|
gradleVersion,
|
||||||
// TODO(d.krasnov): return default statisticsForceValidation, when KT-58104 will be fixed
|
// TODO(Dmitrii Krasnov): return default statisticsForceValidation, when KT-58104 will be fixed
|
||||||
buildOptions = defaultBuildOptions.copy(statisticsForceValidation = false)
|
buildOptions = defaultBuildOptions.copy(statisticsForceValidation = false)
|
||||||
) {
|
) {
|
||||||
buildGradleKts.modify {
|
buildGradleKts.modify {
|
||||||
|
|||||||
+10
-44
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.util.modify
|
|||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@@ -56,7 +57,6 @@ fun KGPBaseTest.project(
|
|||||||
projectPath.enableCacheRedirector()
|
projectPath.enableCacheRedirector()
|
||||||
projectPath.enableAndroidSdk()
|
projectPath.enableAndroidSdk()
|
||||||
|
|
||||||
if (addHeapDumpOptions) projectPath.addHeapDumpOptions()
|
|
||||||
|
|
||||||
val gradleRunner = GradleRunner
|
val gradleRunner = GradleRunner
|
||||||
.create()
|
.create()
|
||||||
@@ -74,6 +74,7 @@ fun KGPBaseTest.project(
|
|||||||
enableBuildScan = enableBuildScan,
|
enableBuildScan = enableBuildScan,
|
||||||
enableGradleDebug = enableGradleDebug,
|
enableGradleDebug = enableGradleDebug,
|
||||||
)
|
)
|
||||||
|
addHeapDumpOptions.ifTrue { testProject.addHeapDumpOptions() }
|
||||||
localRepoDir?.let { testProject.configureLocalRepository(localRepoDir) }
|
localRepoDir?.let { testProject.configureLocalRepository(localRepoDir) }
|
||||||
if (buildJdk != null) testProject.setupNonDefaultJdk(buildJdk)
|
if (buildJdk != null) testProject.setupNonDefaultJdk(buildJdk)
|
||||||
testProject.addKotlinCompilerArgumentsPlugin()
|
testProject.addKotlinCompilerArgumentsPlugin()
|
||||||
@@ -595,49 +596,14 @@ internal fun Path.enableCacheRedirector() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Path.addHeapDumpOptions() {
|
private fun GradleProject.addHeapDumpOptions() {
|
||||||
val propertiesFile = resolve("gradle.properties")
|
addPropertyToGradleProperties(
|
||||||
if (!propertiesFile.exists()) propertiesFile.createFile()
|
propertyName = "org.gradle.jvmargs",
|
||||||
|
mapOf(
|
||||||
val propertiesContent = propertiesFile.readText()
|
"-XX:+HeapDumpOnOutOfMemoryError" to "-XX:+HeapDumpOnOutOfMemoryError",
|
||||||
val (existingJvmArgsLine, otherLines) = propertiesContent
|
"-XX:HeapDumpPath" to "-XX:HeapDumpPath=\"${System.getProperty("user.dir")}${File.separatorChar}build\""
|
||||||
.lines()
|
),
|
||||||
.partition {
|
)
|
||||||
it.trim().startsWith("org.gradle.jvmargs")
|
|
||||||
}
|
|
||||||
|
|
||||||
val heapDumpOutOfErrorStr = "-XX:+HeapDumpOnOutOfMemoryError"
|
|
||||||
val heapDumpPathStr = "-XX:HeapDumpPath=\"${System.getProperty("user.dir")}${File.separatorChar}build\""
|
|
||||||
|
|
||||||
if (existingJvmArgsLine.isEmpty()) {
|
|
||||||
propertiesFile.writeText(
|
|
||||||
"""
|
|
||||||
|# modified in addHeapDumpOptions
|
|
||||||
|org.gradle.jvmargs=$heapDumpOutOfErrorStr $heapDumpPathStr
|
|
||||||
|
|
|
||||||
|$propertiesContent
|
|
||||||
""".trimMargin()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val argsLine = existingJvmArgsLine.first()
|
|
||||||
val appendedOptions = buildString {
|
|
||||||
if (!argsLine.contains("HeapDumpOnOutOfMemoryError")) append(" $heapDumpOutOfErrorStr")
|
|
||||||
if (!argsLine.contains("HeapDumpPath")) append(" $heapDumpPathStr")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appendedOptions.isNotEmpty()) {
|
|
||||||
propertiesFile.writeText(
|
|
||||||
"""
|
|
||||||
# modified in addHeapDumpOptions
|
|
||||||
$argsLine$appendedOptions
|
|
||||||
|
|
||||||
${otherLines.joinToString(separator = "\n")}
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
println("<=== Heap dump options are already exists! ===>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val SINGLE_NATIVE_TARGET_PLACEHOLDER = "<SingleNativeTarget>"
|
private const val SINGLE_NATIVE_TARGET_PLACEHOLDER = "<SingleNativeTarget>"
|
||||||
|
|||||||
+78
@@ -79,3 +79,81 @@ fun TestProject.makeSnapshotTo(destinationPath: String) {
|
|||||||
copyTo(dest.resolve(fileName))
|
copyTo(dest.resolve(fileName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Configures the JVM memory settings for the Gradle project.
|
||||||
|
* @param memorySizeInGb The amount of memory to allocate to the JVM, in gigabytes.
|
||||||
|
* Defaults to 1 gigabyte.
|
||||||
|
*/
|
||||||
|
fun GradleProject.configureJvmMemory(memorySizeInGb: Number = 1) {
|
||||||
|
addPropertyToGradleProperties(
|
||||||
|
propertyName = "org.gradle.jvmargs",
|
||||||
|
mapOf("-Xmx" to "-Xmx${memorySizeInGb}g")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given options to a Gradle property specified by name, in the project's Gradle properties file.
|
||||||
|
* If the property does not exist, it is created.
|
||||||
|
* @param propertyName The name of the Gradle property to modify or create.
|
||||||
|
* @param propertyValues Map with key = "option prefix", and value = "option value".
|
||||||
|
* For example, for options: -Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
|
* Map would be look like: Map.of("-Xmx", "-Xmx2g",
|
||||||
|
* "-XX:MaxMetaspaceSize","-XX:MaxMetaspaceSize=512m",
|
||||||
|
* "-XX:+HeapDumpOnOutOfMemoryError", "-XX:+HeapDumpOnOutOfMemoryError" )
|
||||||
|
*/
|
||||||
|
fun GradleProject.addPropertyToGradleProperties(
|
||||||
|
propertyName: String,
|
||||||
|
propertyValues: Map<String, String>
|
||||||
|
) {
|
||||||
|
if (!gradleProperties.exists()) gradleProperties.createFile()
|
||||||
|
|
||||||
|
val propertiesContent = gradleProperties.readText()
|
||||||
|
val (existingPropertyLine, otherLines) = propertiesContent
|
||||||
|
.lines()
|
||||||
|
.partition {
|
||||||
|
it.trim().startsWith(propertyName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingPropertyLine.isEmpty()) {
|
||||||
|
gradleProperties.writeText(
|
||||||
|
"""
|
||||||
|
|${propertyName}=${propertyValues.values.joinToString(" ")}
|
||||||
|
|
|
||||||
|
|$propertiesContent
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val argsLine = existingPropertyLine.single()
|
||||||
|
val optionsToRewrite = mutableListOf<String>()
|
||||||
|
val appendedOptions = buildString {
|
||||||
|
propertyValues.forEach {
|
||||||
|
if (argsLine.contains(it.key) &&
|
||||||
|
!argsLine.contains(it.value)
|
||||||
|
) optionsToRewrite.add(it.value)
|
||||||
|
else
|
||||||
|
if (!argsLine.contains(it.key)) append(" ${it.value}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(optionsToRewrite.isEmpty()) {
|
||||||
|
"""
|
||||||
|
|You are trying to write options: $optionsToRewrite
|
||||||
|
|for property: $propertyName
|
||||||
|
|in $gradleProperties
|
||||||
|
|But these options are already exists with another values.
|
||||||
|
|Current property value is: $argsLine
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
|
||||||
|
gradleProperties.writeText(
|
||||||
|
"""
|
||||||
|
|$argsLine$appendedOptions
|
||||||
|
|
|
||||||
|
|${otherLines.joinToString(separator = "\n")}
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user