From cc99c91b495b9e7b77276812cae0ad58963150d1 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Thu, 8 May 2025 16:57:22 -0400 Subject: [PATCH 1/2] misc: enable disabled kotlin native tests --- .../credentials/EcsCredentialsProviderTest.kt | 4 - .../region/DefaultRegionProviderChainTest.kt | 157 +++++++----------- .../DefaultRegionProviderChainTestJVM.kt | 47 ++++++ .../auth/credentials/executeCommandNative.kt | 10 +- build.gradle.kts | 4 + 5 files changed, 121 insertions(+), 101 deletions(-) create mode 100644 aws-runtime/aws-config/jvm/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTestJVM.kt diff --git a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/auth/credentials/EcsCredentialsProviderTest.kt b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/auth/credentials/EcsCredentialsProviderTest.kt index 7b7f2cb1911..8401b507b59 100644 --- a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/auth/credentials/EcsCredentialsProviderTest.kt +++ b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/auth/credentials/EcsCredentialsProviderTest.kt @@ -9,7 +9,6 @@ import aws.sdk.kotlin.runtime.auth.credentials.internal.credentials import aws.sdk.kotlin.runtime.config.AwsSdkSetting import aws.sdk.kotlin.runtime.http.interceptors.businessmetrics.AwsBusinessMetric import aws.sdk.kotlin.runtime.http.interceptors.businessmetrics.withBusinessMetric -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProviderException import aws.smithy.kotlin.runtime.http.Headers @@ -144,9 +143,6 @@ class EcsCredentialsProviderTest { engine.assertRequests() } - // FIXME iosSimulator fails with a different exception: "Failed to resolve host amazonaws.com: nodename nor servname provided, or not known" - // Need to fix this by applying the same --standalone removal that we do in smithy-kotlin, aws-crt-kotlin. See `configureIosSimulatorTasks` in aws-kotlin-repo-tools. - @IgnoreNative @Test fun testNonLocalFullUri() = runTest { val uri = "http://amazonaws.com/full" diff --git a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt index 4595e747ab8..d5ba0ced73b 100644 --- a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt +++ b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt @@ -6,7 +6,6 @@ package aws.sdk.kotlin.runtime.region import aws.sdk.kotlin.runtime.util.TestInstanceMetadataProvider -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.util.TestPlatformProvider import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.* @@ -14,69 +13,8 @@ import kotlin.test.Test import kotlin.test.assertEquals class DefaultRegionProviderChainTest { - private data class RegionProviderChainTest( - val name: String, - val platformProvider: TestPlatformProvider, - val instanceMetadataProvider: TestInstanceMetadataProvider, - val region: String?, - val targets: List = emptyList(), - ) - - // FIXME "jvm property is favored" tests need to be made JVM-only. Native does not have system properties, so those tests will always fail. - @IgnoreNative @Test - fun testSuite() = runTest { - val tests = Json.parseToJsonElement(REGION_PROVIDER_CHAIN_TEST_SUITE).jsonArray - .map { it.jsonObject } - .map { - val name = it["name"]!!.jsonPrimitive.content - val platform = TestPlatformProvider.fromJsonNode(it["platform"]!!.jsonObject) - val instanceMetadata = TestInstanceMetadataProvider.fromJsonNode(it["imds"]!!.jsonObject) - val region = it["region"]!!.jsonPrimitive.contentOrNull - RegionProviderChainTest(name, platform, instanceMetadata, region) - } - - tests.forEach { test -> - val provider = DefaultRegionProviderChain( - platformProvider = test.platformProvider, - imdsClient = lazy { test.instanceMetadataProvider }, - ) - val actual = provider.getRegion() - assertEquals(test.region, actual, test.name) - } - } -} - -/** - * Construct a [TestPlatformProvider] from a JSON node like: - * - * ```json - * { - * "env": { - * "ENV_VAR": "value" - * }, - * "props": { - * "aws.property": "value" - * }, - * "fs": { - * "filename": "contents" - * } - * } - * ``` - */ -fun TestPlatformProvider.Companion.fromJsonNode(obj: JsonObject): TestPlatformProvider { - val env = obj["env"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - val props = obj["props"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - val fs = obj["fs"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - return TestPlatformProvider(env, props, fs) -} - -/** - * Construct a [TestInstanceMetadataProvider] from a JSON object containing metadata as key-value pairs. - */ -fun TestInstanceMetadataProvider.Companion.fromJsonNode(obj: JsonObject): TestInstanceMetadataProvider { - val metadata = obj.jsonObject.mapValues { it.value.jsonPrimitive.content } - return TestInstanceMetadataProvider(metadata) + fun testSuite() = runRegionProviderChainTestSuite(REGION_PROVIDER_CHAIN_TEST_SUITE) } // language=JSON @@ -104,20 +42,6 @@ private const val REGION_PROVIDER_CHAIN_TEST_SUITE = """ "imds": {}, "region": "us-east-2" }, - { - "name": "jvm property is favored", - "platform": { - "env": { - "AWS_REGION": "us-east-2" - }, - "props": { - "aws.region": "us-west-1" - }, - "fs": {} - }, - "imds": {}, - "region": "us-west-1" - }, { "name": "default profile", "platform": { @@ -160,10 +84,10 @@ private const val REGION_PROVIDER_CHAIN_TEST_SUITE = """ "region": "us-east-1" }, { - "name": "jvm system properties are favored over imds", + "name": "environment variables are favored over imds", "platform": { "env": { - "AWS_REGION": "us-east-2" + "AWS_REGION": "us-west-1" }, "props": {}, "fs": {} @@ -171,20 +95,6 @@ private const val REGION_PROVIDER_CHAIN_TEST_SUITE = """ "imds": { "/latest/meta-data/placement/region": "us-east-1" }, - "region": "us-east-2" - }, - { - "name": "environment variables are favored over imds", - "platform": { - "env": {}, - "props": { - "aws.region": "us-west-1" - }, - "fs": {} - }, - "imds": { - "/latest/meta-data/placement/region": "us-east-1" - }, "region": "us-west-1" }, { @@ -205,3 +115,64 @@ private const val REGION_PROVIDER_CHAIN_TEST_SUITE = """ } ] """ + +internal fun runRegionProviderChainTestSuite(testSuite: String) = runTest { + data class RegionProviderChainTest( + val name: String, + val platformProvider: TestPlatformProvider, + val instanceMetadataProvider: TestInstanceMetadataProvider, + val region: String?, + val targets: List = emptyList(), + ) + + /** + * Construct a [TestPlatformProvider] from a JSON node like: + * + * ```json + * { + * "env": { + * "ENV_VAR": "value" + * }, + * "props": { + * "aws.property": "value" + * }, + * "fs": { + * "filename": "contents" + * } + * } + * ``` + */ + fun TestPlatformProvider.Companion.fromJsonNode(obj: JsonObject): TestPlatformProvider { + val env = obj["env"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + val props = obj["props"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + val fs = obj["fs"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + return TestPlatformProvider(env, props, fs) + } + + /** + * Construct a [TestInstanceMetadataProvider] from a JSON object containing metadata as key-value pairs. + */ + fun TestInstanceMetadataProvider.Companion.fromJsonNode(obj: JsonObject): TestInstanceMetadataProvider { + val metadata = obj.jsonObject.mapValues { it.value.jsonPrimitive.content } + return TestInstanceMetadataProvider(metadata) + } + + val tests = Json.parseToJsonElement(testSuite).jsonArray + .map { it.jsonObject } + .map { + val name = it["name"]!!.jsonPrimitive.content + val platform = TestPlatformProvider.fromJsonNode(it["platform"]!!.jsonObject) + val instanceMetadata = TestInstanceMetadataProvider.fromJsonNode(it["imds"]!!.jsonObject) + val region = it["region"]!!.jsonPrimitive.contentOrNull + RegionProviderChainTest(name, platform, instanceMetadata, region) + } + + tests.forEach { test -> + val provider = DefaultRegionProviderChain( + platformProvider = test.platformProvider, + imdsClient = lazy { test.instanceMetadataProvider }, + ) + val actual = provider.getRegion() + assertEquals(test.region, actual, test.name) + } +} diff --git a/aws-runtime/aws-config/jvm/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTestJVM.kt b/aws-runtime/aws-config/jvm/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTestJVM.kt new file mode 100644 index 00000000000..3d6d1103020 --- /dev/null +++ b/aws-runtime/aws-config/jvm/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTestJVM.kt @@ -0,0 +1,47 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.sdk.kotlin.runtime.region + +import kotlin.test.Test + +class DefaultRegionProviderChainTestJVM { + @Test + fun testSuite() = runRegionProviderChainTestSuite(JVM_REGION_PROVIDER_CHAIN_TEST_SUITE) +} + +// language=JSON +private const val JVM_REGION_PROVIDER_CHAIN_TEST_SUITE = """ +[ + { + "name": "jvm property is favored", + "platform": { + "env": { + "AWS_REGION": "us-east-2" + }, + "props": { + "aws.region": "us-west-1" + }, + "fs": {} + }, + "imds": {}, + "region": "us-west-1" + }, + { + "name": "jvm system properties are favored over imds", + "platform": { + "env": {}, + "props": { + "aws.region": "us-east-2" + }, + "fs": {} + }, + "imds": { + "/latest/meta-data/placement/region": "us-east-1" + }, + "region": "us-east-2" + } +] +""" diff --git a/aws-runtime/aws-config/native/src/aws/sdk/kotlin/runtime/auth/credentials/executeCommandNative.kt b/aws-runtime/aws-config/native/src/aws/sdk/kotlin/runtime/auth/credentials/executeCommandNative.kt index 803781ec71d..2d7c21dd9b7 100644 --- a/aws-runtime/aws-config/native/src/aws/sdk/kotlin/runtime/auth/credentials/executeCommandNative.kt +++ b/aws-runtime/aws-config/native/src/aws/sdk/kotlin/runtime/auth/credentials/executeCommandNative.kt @@ -48,8 +48,8 @@ internal actual suspend fun executeCommand( } val shell = when (platformProvider.osInfo().family) { - OsFamily.Windows -> "cmd.exe" - else -> "sh" + OsFamily.Windows -> "C:\\Windows\\System32\\cmd.exe" + else -> "/bin/sh" } val shellArg = when (platformProvider.osInfo().family) { @@ -57,8 +57,10 @@ internal actual suspend fun executeCommand( else -> "-c" } - val argv = memScoped { (arrayOf(shell, shellArg, command).map { it.cstr.ptr } + null).toCValues() } - execvp(shell, argv) + memScoped { + val argv = (arrayOf(shell, shellArg, command).map { it.cstr.ptr } + null).toCValues() + execvp(shell, argv) + } _exit(127) // If exec fails } diff --git a/build.gradle.kts b/build.gradle.kts index 95f727bc5d1..074345308e8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ */ import aws.sdk.kotlin.gradle.dsl.configureLinting import aws.sdk.kotlin.gradle.dsl.configureNexus +import aws.sdk.kotlin.gradle.kmp.configureIosSimulatorTasks import aws.sdk.kotlin.gradle.util.typedProp import java.net.URL @@ -23,6 +24,7 @@ plugins { alias(libs.plugins.kotlin.multiplatform) apply false alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.aws.kotlin.repo.tools.artifactsizemetrics) + alias(libs.plugins.aws.kotlin.repo.tools.kmp) } artifactSizeMetrics { @@ -116,6 +118,8 @@ allprojects { // Enables running `./gradlew allDeps` to get a comprehensive list of dependencies for every subproject tasks.register("allDeps") { } + + configureIosSimulatorTasks() } project.afterEvaluate { From dac34d4e082be0f87b85dbd2e756a83e7f06ed17 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Fri, 9 May 2025 17:27:23 -0400 Subject: [PATCH 2/2] pr feedback --- .../region/DefaultRegionProviderChainTest.kt | 98 +++++++++++-------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt index d5ba0ced73b..79479d61cbf 100644 --- a/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt +++ b/aws-runtime/aws-config/common/test/aws/sdk/kotlin/runtime/region/DefaultRegionProviderChainTest.kt @@ -7,7 +7,7 @@ package aws.sdk.kotlin.runtime.region import aws.sdk.kotlin.runtime.util.TestInstanceMetadataProvider import aws.smithy.kotlin.runtime.util.TestPlatformProvider -import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.* import kotlin.test.Test import kotlin.test.assertEquals @@ -116,47 +116,67 @@ private const val REGION_PROVIDER_CHAIN_TEST_SUITE = """ ] """ -internal fun runRegionProviderChainTestSuite(testSuite: String) = runTest { - data class RegionProviderChainTest( - val name: String, - val platformProvider: TestPlatformProvider, - val instanceMetadataProvider: TestInstanceMetadataProvider, - val region: String?, - val targets: List = emptyList(), - ) +private data class RegionProviderChainTest( + val name: String, + val platformProvider: TestPlatformProvider, + val instanceMetadataProvider: TestInstanceMetadataProvider, + val region: String?, + val targets: List = emptyList(), +) - /** - * Construct a [TestPlatformProvider] from a JSON node like: - * - * ```json - * { - * "env": { - * "ENV_VAR": "value" - * }, - * "props": { - * "aws.property": "value" - * }, - * "fs": { - * "filename": "contents" - * } - * } - * ``` - */ - fun TestPlatformProvider.Companion.fromJsonNode(obj: JsonObject): TestPlatformProvider { - val env = obj["env"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - val props = obj["props"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - val fs = obj["fs"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() - return TestPlatformProvider(env, props, fs) - } +/** + * Construct a [TestPlatformProvider] from a JSON node like: + * + * ```json + * { + * "env": { + * "ENV_VAR": "value" + * }, + * "props": { + * "aws.property": "value" + * }, + * "fs": { + * "filename": "contents" + * } + * } + * ``` + */ +/** + * Construct a [TestPlatformProvider] from a JSON node like: + * + * ```json + * { + * "env": { + * "ENV_VAR": "value" + * }, + * "props": { + * "aws.property": "value" + * }, + * "fs": { + * "filename": "contents" + * } + * } + * ``` + */ +private fun TestPlatformProvider.Companion.fromJsonNode(obj: JsonObject): TestPlatformProvider { + val env = obj["env"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + val props = obj["props"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + val fs = obj["fs"]?.jsonObject?.mapValues { it.value.jsonPrimitive.content } ?: emptyMap() + return TestPlatformProvider(env, props, fs) +} - /** - * Construct a [TestInstanceMetadataProvider] from a JSON object containing metadata as key-value pairs. - */ - fun TestInstanceMetadataProvider.Companion.fromJsonNode(obj: JsonObject): TestInstanceMetadataProvider { - val metadata = obj.jsonObject.mapValues { it.value.jsonPrimitive.content } - return TestInstanceMetadataProvider(metadata) - } +/** + * Construct a [TestInstanceMetadataProvider] from a JSON object containing metadata as key-value pairs. + */ +/** + * Construct a [TestInstanceMetadataProvider] from a JSON object containing metadata as key-value pairs. + */ +private fun TestInstanceMetadataProvider.Companion.fromJsonNode(obj: JsonObject): TestInstanceMetadataProvider { + val metadata = obj.jsonObject.mapValues { it.value.jsonPrimitive.content } + return TestInstanceMetadataProvider(metadata) +} +internal fun runRegionProviderChainTestSuite(testSuite: String) = runBlocking { val tests = Json.parseToJsonElement(testSuite).jsonArray .map { it.jsonObject } .map {