Skip to content

Commit

Permalink
[Tests] Allow NativeEnvironmentConfigurator to use custom targets
Browse files Browse the repository at this point in the history
By default, `NativeEnvironmentConfigurator` uses the "host"
Kotlin/Native target, which is equivalent to the host OS and arch.

Now, with these changes, it becomes possible to adjust the target
by specifying custom target name via the
`-Pkotlin.internal.native.test.target=<target_name>` Gradle CLI
parameter. This CLI parameter name is already used in Kotlin/Native
test infrastructure, and there are multiple configurations at
TeamCity that pass different target names to Gradle via this
parameter.

^KT-71333
  • Loading branch information
ddolovov authored and qodana-bot committed Oct 1, 2024
1 parent a53c225 commit 4cc9523
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ object ConfigurationDirectives : SimpleDirectivesContainer() {

val WITH_KOTLIN_JVM_ANNOTATIONS by directive("Add kotlin-annotations-jvm.jar to classpath")

val WITH_PLATFORM_LIBS by directive("Add platform libs to classpath")
/** See also [org.jetbrains.kotlin.test.services.configuration.NativeEnvironmentConfigurator.getRuntimePathsForModule] */
val WITH_PLATFORM_LIBS by directive(
"""
Add all available Kotlin/Native platform libs for the Kotlin/Native target in effect to the classpath.
The Kotlin/Native target is determined by the NativeEnvironmentConfigurator class.
""".trimIndent()
)

val DISABLE_TYPEALIAS_EXPANSION by directive("Disables automatic expansion of aliased types in type resolution")
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,63 @@ package org.jetbrains.kotlin.test.services.configuration

import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.TargetSupportException
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.runtimeClasspathProviders
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File

class NativeEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
companion object : KlibBasedEnvironmentConfiguratorUtils {
private val nativeHome
get() = System.getProperty("kotlin.internal.native.test.nativeHome")
?: error("No nativeHome provided. Are you sure the test are executed within :native:native.tests?")

fun distributionKlibPath(): File = File(nativeHome, "klib")
fun hostTarget(): KonanTarget = HostManager.host
private const val TEST_PROPERTY_NATIVE_HOME = "kotlin.internal.native.test.nativeHome"
private const val TEST_PROPERTY_TEST_TARGET = "kotlin.internal.native.test.target"

fun getRuntimePathsForModule(module: TestModule, testServices: TestServices): List<String> {
val result = mutableListOf<String>()
return testServices.nativeEnvironmentConfigurator.getRuntimePathsForModule(module)
}
}

if (ConfigurationDirectives.WITH_STDLIB in module.directives) {
result += File("$nativeHome/klib/common/stdlib").absolutePath
private val nativeHome: String by lazy {
System.getProperty(TEST_PROPERTY_NATIVE_HOME)
?: testServices.assertions.fail {
"No '$TEST_PROPERTY_NATIVE_HOME' provided. Are you sure the test are executed within :native:native.tests?"
}
}

if (ConfigurationDirectives.WITH_PLATFORM_LIBS in module.directives) {
// Diagnostic tests are agnostic of native target, so host is enforced to be a target.
File("$nativeHome/klib/platform/${hostOsArch()}").listFiles()?.forEach {
result += it.absolutePath
}
}
val nativeTarget: KonanTarget by lazy {
val userDefinedTarget = System.getProperty(TEST_PROPERTY_TEST_TARGET)
if (userDefinedTarget != null) {
HostManager().targets[userDefinedTarget]
?: testServices.assertions.fail { "Unsupported target name specified in '$TEST_PROPERTY_TEST_TARGET': $userDefinedTarget" }
} else {
HostManager.host
}
}

testServices.runtimeClasspathProviders
.flatMap { it.runtimeClassPaths(module) }
.mapTo(result) { it.absolutePath }
fun distributionKlibPath(): File = File(nativeHome, "klib")

return result
fun getRuntimePathsForModule(module: TestModule): List<String> {
val result = mutableListOf<String>()

if (ConfigurationDirectives.WITH_STDLIB in module.directives) {
result += distributionKlibPath().resolve("common").resolve("stdlib").absolutePath
}
}
}

private fun hostOsArch() = "${hostOs()}_${hostArch()}"
if (ConfigurationDirectives.WITH_PLATFORM_LIBS in module.directives) {
// Diagnostic tests are agnostic of native target, so host is enforced to be a target.
distributionKlibPath().resolve("platform").resolve(nativeTarget.name).listFiles()?.forEach {
result += it.absolutePath
}
}

testServices.runtimeClasspathProviders
.flatMap { it.runtimeClassPaths(module) }
.mapTo(result) { it.absolutePath }

// `:native` module cannot be imported here, so functions are just copy/pasted here.
// `hostOs()` and `hostArch()` are similar to functions in org.jetbrains.kotlin.konan.target.HostManager
private fun hostOs(): String {
val javaOsName = System.getProperty("os.name")
return when {
javaOsName == "Mac OS X" -> "macos"
javaOsName == "Linux" -> "linux"
javaOsName.startsWith("Windows") -> "mingw"
else -> throw TargetSupportException("Unknown operating system: $javaOsName")
return result
}
}

fun hostArch(): String =
when (val arch = System.getProperty("os.arch")) {
"x86_64" -> "x64"
"amd64" -> "x64"
"arm64" -> "arm64"
"aarch64" -> "arm64"
else -> throw TargetSupportException("Unknown hardware platform: $arch")
}
val TestServices.nativeEnvironmentConfigurator: NativeEnvironmentConfigurator
get() = environmentConfigurators.firstIsInstanceOrNull<NativeEnvironmentConfigurator>()
?: assertions.fail { "No registered ${NativeEnvironmentConfigurator::class.java.simpleName}" }
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import org.jetbrains.kotlin.test.frontend.fir.*
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.test.services.configuration.NativeEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.nativeEnvironmentConfigurator

class Fir2IrNativeResultsConverter(testServices: TestServices) : AbstractFir2IrResultsConverter(testServices) {

Expand Down Expand Up @@ -111,8 +111,11 @@ class Fir2IrNativeResultsConverter(testServices: TestServices) : AbstractFir2IrR
*/
private fun resolveKotlinLibrariesWithProperDefaults(module: TestModule, testServices: TestServices): List<KotlinLibrary> {
val directDependencies = getTransitivesAndFriendsPaths(module, testServices)
val nativeTarget = NativeEnvironmentConfigurator.hostTarget()
val nativeDistributionKlibPath = NativeEnvironmentConfigurator.distributionKlibPath().absolutePath

val nativeEnvironmentConfigurator = testServices.nativeEnvironmentConfigurator

val nativeTarget = nativeEnvironmentConfigurator.nativeTarget
val nativeDistributionKlibPath = nativeEnvironmentConfigurator.distributionKlibPath().absolutePath
val logger = testServices.compilerConfigurationProvider.getCompilerConfiguration(module).getLogger(treatWarningsAsErrors = true)

val libraryResolver = KonanLibraryProperResolver(
Expand Down

0 comments on commit 4cc9523

Please sign in to comment.