Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/9e312657-9d30-4092-9877-a70b40d34e74.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "9e312657-9d30-4092-9877-a70b40d34e74",
"type": "misc",
"description": "⚠️ **IMPORTANT**: Upgrade to Kotlin 2.3.0",
"requiresMinorVersionBump": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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
Expand Down Expand Up @@ -143,6 +144,7 @@ class EcsCredentialsProviderTest {
engine.assertRequests()
}

@IgnoreNative
@Test
fun testNonLocalFullUri() = runTest {
val uri = "http://amazonaws.com/full"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package aws.sdk.kotlin.runtime.auth.credentials
import aws.sdk.kotlin.runtime.auth.credentials.internal.credentials
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.http.Headers
import aws.smithy.kotlin.runtime.http.HttpBody
import aws.smithy.kotlin.runtime.http.HttpStatusCode
Expand All @@ -27,14 +28,15 @@ import kotlin.time.Duration.Companion.minutes
import kotlin.to

class LoginCredentialsProviderTest {

@IgnoreNative
@Test
fun testCacheFilename() {
val expected = "36db1d138ff460920374e4c3d8e01f53f9f73537e89c88d639f68393df0e2726.json"
val actual = getLoginCacheFilename("arn:aws:iam::0123456789012:user/Admin")
assertEquals(expected, actual)
}

@IgnoreNative
@Test
fun testExpiredToken() = runTest(
// TODO: Figure out why this test takes so long to run on some developer machines (@aoperez)
Expand Down Expand Up @@ -82,6 +84,7 @@ class LoginCredentialsProviderTest {
}.message.shouldMatch(Regex("Login token for login-session: .* is expired"))
}

@IgnoreNative
@Test
fun testSuccess() = runTest {
val expectedExpiration = Instant.fromIso8601("2020-10-16T04:56:00Z")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package aws.sdk.kotlin.runtime.auth.credentials

import aws.sdk.kotlin.runtime.client.AwsClientOption
import aws.smithy.kotlin.runtime.IgnoreNative
import aws.smithy.kotlin.runtime.http.Headers
import aws.smithy.kotlin.runtime.http.HttpBody
import aws.smithy.kotlin.runtime.http.HttpStatusCode
Expand Down Expand Up @@ -95,6 +96,7 @@ class LoginTokenProviderTest {
data class Error(val message: String) : TestOutcome()
}

@IgnoreNative
@Test
fun testLoginTokenCacheBehavior() = runTest(timeout = 2.minutes) {
val testList = Json.parseToJsonElement(LOGIN_TOKEN_PROVIDER_TEST_SUITE).jsonArray
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import aws.sdk.kotlin.runtime.client.AwsClientOption
import aws.sdk.kotlin.runtime.http.interceptors.businessmetrics.AwsBusinessMetric
import aws.sdk.kotlin.runtime.http.interceptors.businessmetrics.withBusinessMetric
import aws.sdk.kotlin.runtime.util.testAttributes
import aws.smithy.kotlin.runtime.IgnoreNative
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
import aws.smithy.kotlin.runtime.auth.awscredentials.copy
import aws.smithy.kotlin.runtime.collections.attributesOf
Expand Down Expand Up @@ -106,6 +107,7 @@ class ProfileCredentialsProviderTest {
assertEquals(expected, actual)
}

@IgnoreNative
@Test
fun testBasicAssumeRole() = runTest {
// smoke test for assume role, more involved scenarios are tested through the default chain
Expand Down Expand Up @@ -275,6 +277,7 @@ class ProfileCredentialsProviderTest {
assertEquals(Host.Domain("sts.us-west-2.amazonaws.com"), requests.actual.url.host)
}

@IgnoreNative
@Test
fun testPlatformRegion() = runTest {
val testArn = "arn:aws:iam::1234567:role/test-role"
Expand Down Expand Up @@ -335,6 +338,7 @@ class ProfileCredentialsProviderTest {
assertEquals(expected, actual)
}

@IgnoreNative
@Test
fun assumeRoleWithNamedProviderBusinessMetrics() = runTest {
val testArn = "arn:aws:iam::1234567:role/test-role"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
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.*
Expand All @@ -21,6 +22,7 @@ class DefaultRegionProviderChainTest {
val targets: List<String> = emptyList(),
)

@IgnoreNative
@Test
fun testSuite() = runTest {
val tests = Json.parseToJsonElement(REGION_PROVIDER_CHAIN_TEST_SUITE).jsonArray
Expand Down
5 changes: 0 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ kotlinx.atomicfu.enableJvmIrTransformation=true
# FIXME - https://github.com/Kotlin/kotlinx-atomicfu/issues/274
kotlinx.atomicfu.enableNativeIrTransformation=false

# https://github.com/google/ksp/blob/main/docs/ksp2.md
# Disable KSP2 due to a bug around subsequent invocations
# https://github.com/google/dagger/issues/4181 / https://github.com/google/ksp/issues/1678
ksp.useKSP2=false

# FIXME Remove after Dokka 2.0 Gradle plugin is stable
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
27 changes: 12 additions & 15 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[versions]
kotlin-version = "2.2.0"
ksp-version = "2.2.0-2.0.2" # Keep in sync with kotlin-version
kotlin-version = "2.3.0"
ksp-version = "2.3.4"

dokka-version = "2.0.0"

# TODO Upgrade to 0.5.0 before merging
aws-kotlin-repo-tools-version = "0.4.65"

# libs
Expand All @@ -12,27 +13,28 @@ atomicfu-version = "0.29.0"
binary-compatibility-validator-version = "0.18.0"

# smithy-kotlin codegen and runtime are versioned separately
# TODO Upgrade to 1.6.0 before merging
smithy-kotlin-runtime-version = "1.5.24"
# TODO Upgrade to 0.36.0 before merging
smithy-kotlin-codegen-version = "0.35.24"

# codegen
smithy-version = "1.64.0"
smithy-version = "1.65.0"

# testing
ddb-local-version = "2.5.2"
junit-version = "5.13.2"
junit-version = "5.14.1"
kotest-version = "5.9.1"
kotlinx-benchmark-version = "0.4.12"
kotlinx-serialization-version = "1.7.3"
mockk-version = "1.13.13"
slf4j-version = "2.0.16"
jsoup-version = "1.20.1"
kotlinx-benchmark-version = "0.4.15"
kotlinx-serialization-version = "1.9.0"
mockk-version = "1.14.7"
slf4j-version = "2.0.17"
jsoup-version = "1.21.2"

[libraries]
aws-kotlin-repo-tools-build-support = { module="aws.sdk.kotlin.gradle:build-support", version.ref = "aws-kotlin-repo-tools-version" }

kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin-version" }
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin-version" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-version" }
kotlin-test-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "kotlin-version" }
Expand All @@ -43,11 +45,8 @@ dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", vers
kotlinx-atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu-version" }
kotlinx-atomicfu-plugin = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "atomicfu-version" }

kotlinx-coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "coroutines-version" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines-version" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines-version" }
kotlinx-coroutines-jdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8", version.ref = "coroutines-version" }
kotlinx-coroutines-slf4j = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j", version.ref = "coroutines-version" }

ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp-version" }
ksp-gradle-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp-version" }
Expand Down Expand Up @@ -146,10 +145,8 @@ smithy-kotlin-service-client = [
]

[plugins]
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka-version"}
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-version" }
kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlinx-benchmark-version" }
kotlinx-binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator-version" }
kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version"}
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp-version" }
Expand Down
116 changes: 57 additions & 59 deletions hll/dynamodb-mapper/dynamodb-mapper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import aws.sdk.kotlin.gradle.kmp.NATIVE_ENABLED
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner
import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
import com.google.devtools.ksp.gradle.KspTaskJvm
import com.google.devtools.ksp.gradle.KspTaskMetadata
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import java.net.ServerSocket
import java.nio.file.Files
Expand Down Expand Up @@ -68,68 +65,69 @@ ksp {
)
arg("op-allowlist", allowlist.joinToString(";"))
}
// FIXME dynamodb-mapper native compilation never worked?
//if (project.NATIVE_ENABLED) {
// // Configure KSP for multiplatform: https://kotlinlang.org/docs/ksp-multiplatform.html
// // https://github.com/google/ksp/issues/963#issuecomment-1894144639
// // https://github.com/google/ksp/issues/965
// dependencies.kspCommonMainMetadata(project(":hll:dynamodb-mapper:dynamodb-mapper-ops-codegen"))
//
// kotlin.sourceSets.commonMain {
// // Wire up the generated source to the commonMain source set
// kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
// }
//}

// FIXME This is a dirty hack for JVM-only builds which KSP doesn't consider to be "multiplatform".
// Explanation of hack follows in narrative, minimally-opinionated comments.

// Start by invoking the JVM-only KSP configuration
dependencies.kspJvm(project(":hll:dynamodb-mapper:dynamodb-mapper-ops-codegen"))

// Then we need to move the generated source from jvm to common
val moveGenSrc by tasks.registering {
// Can't move src until the src is generated
dependsOn(tasks.named("kspKotlinJvm"))

// Detecting these paths programmatically is complex; just hardcode them
val srcDir = file("build/generated/ksp/jvm/jvmMain")
val destDir = file("build/generated/ksp/common/commonMain")

inputs.dir(srcDir)
outputs.dirs(srcDir, destDir)

if (project.NATIVE_ENABLED) {
// Configure KSP for multiplatform: https://kotlinlang.org/docs/ksp-multiplatform.html
// https://github.com/google/ksp/issues/963#issuecomment-1894144639
// https://github.com/google/ksp/issues/965
dependencies.kspCommonMainMetadata(project(":hll:dynamodb-mapper:dynamodb-mapper-ops-codegen"))

kotlin.sourceSets.commonMain {
tasks.withType<KspTaskMetadata> {
// Wire up the generated source to the commonMain source set
kotlin.srcDir(destinationDirectory)
doLast {
if (destDir.exists()) {
// Clean out the existing destination, otherwise move fails
require(destDir.deleteRecursively()) { "Failed to delete $destDir before moving from $srcDir" }
} else {
// Create the destination directories, otherwise move fails
require(destDir.mkdirs()) { "Failed to create path $destDir" }
}
}
} else {
// FIXME This is a dirty hack for JVM-only builds which KSP doesn't consider to be "multiplatform". Explanation of
// hack follows in narrative, minimally-opinionated comments.

// Start by invoking the JVM-only KSP configuration
dependencies.kspJvm(project(":hll:dynamodb-mapper:dynamodb-mapper-ops-codegen"))

// Then we need to move the generated source from jvm to common
val moveGenSrc by tasks.registering {
// Can't move src until the src is generated
dependsOn(tasks.named("kspKotlinJvm"))

// Detecting these paths programmatically is complex; just hardcode them
val srcDir = file("build/generated/ksp/jvm/jvmMain")
val destDir = file("build/generated/ksp/common/commonMain")

inputs.dir(srcDir)
outputs.dirs(srcDir, destDir)

doLast {
if (destDir.exists()) {
// Clean out the existing destination, otherwise move fails
require(destDir.deleteRecursively()) { "Failed to delete $destDir before moving from $srcDir" }
} else {
// Create the destination directories, otherwise move fails
require(destDir.mkdirs()) { "Failed to create path $destDir" }
}

Files.move(srcDir.toPath(), destDir.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
Files.move(srcDir.toPath(), destDir.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
}

listOf("jvmSourcesJar", "metadataSourcesJar", "jvmProcessResources").forEach {
tasks.named(it) {
dependsOn(moveGenSrc)
}
}
// Ensure all source jar tasks depend on the generated source move
tasks.matching { it.name.endsWith("SourcesJar") || it.name == "sourcesJar" }.configureEach {
dependsOn(moveGenSrc)
}

tasks.withType<KotlinCompilationTask<*>> {
if (this !is KspTaskJvm) {
// Ensure that any **non-KSP** compile tasks depend on the generated src move
dependsOn(moveGenSrc)
}
// Also ensure specific tasks depend on the move
listOf("jvmProcessResources", "metadataSourcesJar").forEach { taskName ->
tasks.matching { it.name == taskName }.configureEach {
dependsOn(moveGenSrc)
}
}

// Finally, wire up the generated source to the commonMain source set
kotlin.sourceSets.commonMain {
kotlin.srcDir("build/generated/ksp/common/commonMain/kotlin")
}
tasks.withType<KotlinCompilationTask<*>> {
dependsOn(moveGenSrc)
}

// Finally, wire up the generated source to the commonMain source set
kotlin.sourceSets.commonMain {
kotlin.srcDir("build/generated/ksp/common/commonMain/kotlin")
}

open class DynamoDbLocalInstance : DefaultTask() {
Expand Down Expand Up @@ -174,14 +172,14 @@ open class DynamoDbLocalInstance : DefaultTask() {
}
}

val startDdbLocal = task<DynamoDbLocalInstance>("startDdbLocal") {
val startDdbLocal = tasks.register<DynamoDbLocalInstance>("startDdbLocal") {
portFile.set(file("build/ddblocal/port.info")) // Keep in sync with DdbLocalTest.kt
outputs.upToDateWhen { false } // Always run this task even if a portFile already exists
}

tasks.withType<Test> {
dependsOn(startDdbLocal)
doLast {
startDdbLocal.stop()
startDdbLocal.get().stop()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal class MapperConfigBuilderImpl : DynamoDbMapper.Config.Builder {
/**
* An interceptor that emits the DynamoDB Mapper business metric
*/
private object BusinessMetricInterceptor : HttpInterceptor {
internal object BusinessMetricInterceptor : HttpInterceptor {
override suspend fun modifyBeforeSerialization(context: RequestInterceptorContext<Any>): Any {
context.executionContext.emitBusinessMetric(AwsBusinessMetric.DDB_MAPPER)
return context.request
Expand Down
Loading