From a4734c7551694dd90a71aa5d1e4818ec9ae7b47f Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:30:46 -0500 Subject: [PATCH 01/65] fix: create JMESPATH flattenIfPossible functions for Lists (#1169) --- .../smithy/kotlin/runtime/util/JMESPath.kt | 10 ++++ .../kotlin/runtime/util/JmesPathTest.kt | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/JmesPathTest.kt diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt index 2a7cdd9791..9b691a79a2 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt @@ -66,6 +66,7 @@ public fun Any?.type(): String = when (this) { else -> throw Exception("Undetected type for: $this") } +// Collection `flattenIfPossible` functions @InternalApi @JvmName("noOpUnnestedCollection") public inline fun Collection.flattenIfPossible(): Collection = this @@ -73,3 +74,12 @@ public inline fun Collection.flattenIfPossible(): Collection = @InternalApi @JvmName("flattenNestedCollection") public inline fun Collection>.flattenIfPossible(): Collection = flatten() + +// List `flattenIfPossible` functions +@InternalApi +@JvmName("noOpUnnestedCollection") +public inline fun List.flattenIfPossible(): List = this + +@InternalApi +@JvmName("flattenNestedCollection") +public inline fun List>.flattenIfPossible(): List = flatten() diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/JmesPathTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/JmesPathTest.kt new file mode 100644 index 0000000000..e867f1e8a1 --- /dev/null +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/JmesPathTest.kt @@ -0,0 +1,49 @@ +package aws.smithy.kotlin.runtime.util + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class JmesPathTest { + @Test + fun flattenNestedLists() { + val nestedList = listOf( + listOf(1, 2, 3), + listOf(4, 5), + listOf(6), + ) + val flattenedList = nestedList.flattenIfPossible() + assertEquals(listOf(1, 2, 3, 4, 5, 6), flattenedList) + } + + @Test + fun flattenEmptyNestedLists() { + val nestedList = listOf( + listOf(), + listOf(), + listOf(), + ) + val flattenedList = nestedList.flattenIfPossible() + assertTrue(flattenedList.isEmpty()) + } + + @Test + fun flattenNestedEmptyAndNonEmptyNestedLists() { + val nestedList = listOf( + listOf(1, 2), + listOf(), + listOf(3, 4, 5), + ) + val flattenedList = nestedList.flattenIfPossible() + assertEquals(listOf(1, 2, 3, 4, 5), flattenedList) + } + + @Test + fun flattenList() { + val nestedList = listOf( + listOf(1, 2, 3), + ) + val flattenedList = nestedList.flattenIfPossible() + assertEquals(listOf(1, 2, 3), flattenedList) + } +} From 7911a94dd5f6ee27f2652aeb7c8031e2dce79215 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Mon, 16 Dec 2024 16:51:49 +0000 Subject: [PATCH 02/65] chore: release 1.3.30 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 892e2b1248..5633a30d73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## [1.3.30] - 12/16/2024 + ## [1.3.29] - 12/12/2024 ## [1.3.28] - 12/03/2024 diff --git a/gradle.properties b/gradle.properties index f35cfc1d5a..377ff6666b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.30-SNAPSHOT +sdkVersion=1.3.30 # codegen -codegenVersion=0.33.30-SNAPSHOT \ No newline at end of file +codegenVersion=0.33.30 \ No newline at end of file From 7085c8ab0d4b34d3ddb77bbb31a2fd41c47c288c Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Mon, 16 Dec 2024 16:51:50 +0000 Subject: [PATCH 03/65] chore: bump snapshot version to 1.3.31-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 377ff6666b..3628520e5a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.30 +sdkVersion=1.3.31-SNAPSHOT # codegen -codegenVersion=0.33.30 \ No newline at end of file +codegenVersion=0.33.31-SNAPSHOT \ No newline at end of file From 45750232626bbe4e279142e486be8bbbfccab33f Mon Sep 17 00:00:00 2001 From: Matas Date: Wed, 18 Dec 2024 14:20:08 -0500 Subject: [PATCH 04/65] misc: enhance support for replayable instances of `InputStream` (#1197) --- .../2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json | 8 ++++++ .../kotlin/runtime/content/ByteStreamJVM.kt | 23 +++++++++++++-- .../runtime/content/ByteStreamJVMTest.kt | 28 +++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 .changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json diff --git a/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json b/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json new file mode 100644 index 0000000000..fb16fa5843 --- /dev/null +++ b/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json @@ -0,0 +1,8 @@ +{ + "id": "2de8162f-e5a0-4618-b00d-8da3cfdbc6a2", + "type": "feature", + "description": "Enhance support for replayable instances of `InputStream`", + "issues": [ + "https://github.com/awslabs/aws-sdk-kotlin/issues/1473" + ] +} \ No newline at end of file diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt index 1d6124357a..5647ac15af 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt @@ -114,11 +114,30 @@ public fun ByteStream.Companion.fromInputStream( * @param contentLength If specified, indicates how many bytes remain in this stream. Defaults to `null`. */ public fun InputStream.asByteStream(contentLength: Long? = null): ByteStream.SourceStream { - val source = source() + if (markSupported() && contentLength != null) { + mark(contentLength.toInt()) + } + return object : ByteStream.SourceStream() { override val contentLength: Long? = contentLength override val isOneShot: Boolean = !markSupported() - override fun readFrom(): SdkSource = source + override fun readFrom(): SdkSource { + if (markSupported() && contentLength != null) { + reset() + mark(contentLength.toInt()) + return object : SdkSource by source() { + /* + * This is a no-op close to prevent body hashing from closing the underlying InputStream, which causes + * `IOException: Stream closed` on subsequent reads. Consider making [ByteStream.ChannelStream]/[ByteStream.SourceStream] + * (or possibly even [ByteStream] itself) implement [Closeable] to better handle closing streams. + * This should allow us to clean up our usage of [ByteStream.cancel()]. + */ + override fun close() { } + } + } + + return source() + } } } diff --git a/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/content/ByteStreamJVMTest.kt b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/content/ByteStreamJVMTest.kt index 054387b2e5..e8324fb11f 100644 --- a/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/content/ByteStreamJVMTest.kt +++ b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/content/ByteStreamJVMTest.kt @@ -5,8 +5,11 @@ package aws.smithy.kotlin.runtime.content +import aws.smithy.kotlin.runtime.io.readToByteArray import aws.smithy.kotlin.runtime.testing.RandomTempFile import kotlinx.coroutines.test.runTest +import java.io.BufferedInputStream +import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.OutputStream @@ -228,6 +231,31 @@ class ByteStreamJVMTest { assertFalse(sos.closed) } + // https://github.com/awslabs/aws-sdk-kotlin/issues/1473 + @Test + fun testReplayableInputStreamAsByteStream() = runTest { + val content = "Hello, Bytes!".encodeToByteArray() + val byteArrayIns = ByteArrayInputStream(content) + val nonReplayableIns = NonReplayableInputStream(byteArrayIns) + + // buffer the non-replayable stream, making it replayable... + val bufferedIns = BufferedInputStream(nonReplayableIns) + + val byteStream = bufferedIns.asByteStream(content.size.toLong()) + + // Test that it can be read at least twice (e.g. once for hashing the body, once for transmitting the body) + assertContentEquals(content, byteStream.readFrom().use { it.readToByteArray() }) + assertContentEquals(content, byteStream.readFrom().use { it.readToByteArray() }) + } + + private class NonReplayableInputStream(val inputStream: InputStream) : InputStream() { + override fun markSupported(): Boolean = false // not replayable + + override fun read(): Int = inputStream.read() + override fun mark(readlimit: Int) = inputStream.mark(readlimit) + override fun reset() = inputStream.reset() + } + private class StatusTrackingOutputStream(val os: OutputStream) : OutputStream() { var closed: Boolean = false From b0a4bacc3626bf2c9e8cfe9607ef8d5ece03ee4e Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Wed, 18 Dec 2024 19:23:06 +0000 Subject: [PATCH 05/65] chore: release 1.3.31 --- .changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json | 8 -------- CHANGELOG.md | 5 +++++ gradle.properties | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 .changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json diff --git a/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json b/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json deleted file mode 100644 index fb16fa5843..0000000000 --- a/.changes/2de8162f-e5a0-4618-b00d-8da3cfdbc6a2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "2de8162f-e5a0-4618-b00d-8da3cfdbc6a2", - "type": "feature", - "description": "Enhance support for replayable instances of `InputStream`", - "issues": [ - "https://github.com/awslabs/aws-sdk-kotlin/issues/1473" - ] -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5633a30d73..5473a56d69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [1.3.31] - 12/18/2024 + +### Features +* [#1473](https://github.com/awslabs/aws-sdk-kotlin/issues/1473) Enhance support for replayable instances of `InputStream` + ## [1.3.30] - 12/16/2024 ## [1.3.29] - 12/12/2024 diff --git a/gradle.properties b/gradle.properties index 3628520e5a..cf967edd0b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.31-SNAPSHOT +sdkVersion=1.3.31 # codegen -codegenVersion=0.33.31-SNAPSHOT \ No newline at end of file +codegenVersion=0.33.31 \ No newline at end of file From 80f453814d8b0c4e20ef7e729d47a364ca8b5753 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Wed, 18 Dec 2024 19:23:08 +0000 Subject: [PATCH 06/65] chore: bump snapshot version to 1.3.32-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index cf967edd0b..f902a36719 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.31 +sdkVersion=1.3.32-SNAPSHOT # codegen -codegenVersion=0.33.31 \ No newline at end of file +codegenVersion=0.33.32-SNAPSHOT \ No newline at end of file From e9d16a98b8030468e35a05f63c79cae2444e6759 Mon Sep 17 00:00:00 2001 From: Matas Date: Wed, 18 Dec 2024 16:28:30 -0500 Subject: [PATCH 07/65] fix: CBOR protocol test assertions / blob serialization (#1198) --- .changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json | 5 +++++ .../protocol/HttpProtocolUnitTestRequestGenerator.kt | 4 ++-- .../codegen/rendering/serde/SerializeStructGenerator.kt | 1 - .../codegen/rendering/serde/SerializeStructGeneratorTest.kt | 2 +- .../src/aws/smithy/kotlin/runtime/serde/xml/XmlSerializer.kt | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 .changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json diff --git a/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json b/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json new file mode 100644 index 0000000000..0fad5e0349 --- /dev/null +++ b/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json @@ -0,0 +1,5 @@ +{ + "id": "1021e75a-45f3-4f3a-820c-700d9ec6e782", + "type": "bugfix", + "description": "Fix serialization of CBOR blobs" +} \ No newline at end of file diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolUnitTestRequestGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolUnitTestRequestGenerator.kt index 74bd7db782..6fcc47c3e5 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolUnitTestRequestGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolUnitTestRequestGenerator.kt @@ -117,11 +117,11 @@ open class HttpProtocolUnitTestRequestGenerator protected constructor(builder: B write("return") } write("requireNotNull(expectedBytes) { #S }", "expected application/cbor body cannot be null") - write("requireNotNull(expectedBytes) { #S }", "actual application/cbor body cannot be null") + write("requireNotNull(actualBytes) { #S }", "actual application/cbor body cannot be null") write("") write("val expectedRequest = #L(#T(expectedBytes))", inputDeserializer.name, RuntimeTypes.Serde.SerdeCbor.CborDeserializer) - write("val actualRequest = #L(#T(expectedBytes))", inputDeserializer.name, RuntimeTypes.Serde.SerdeCbor.CborDeserializer) + write("val actualRequest = #L(#T(actualBytes))", inputDeserializer.name, RuntimeTypes.Serde.SerdeCbor.CborDeserializer) write("assertEquals(expectedRequest, actualRequest)") } writer.write("") diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGenerator.kt index e7f2e261ef..d8810044a5 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGenerator.kt @@ -647,7 +647,6 @@ open class SerializeStructGenerator( val target = member.targetOrSelf(ctx.model) val encoded = when { - target.type == ShapeType.BLOB -> writer.format("#L.#T()", identifier, RuntimeTypes.Core.Text.Encoding.encodeBase64String) target.type == ShapeType.TIMESTAMP -> { writer.addImport(RuntimeTypes.Core.TimestampFormat) val tsFormat = member diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt index 40d9c9db7d..347da007cb 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt @@ -1822,7 +1822,7 @@ class SerializeStructGeneratorTest { val expected = """ serializer.serializeStruct(OBJ_DESCRIPTOR) { - input.fooBlob?.let { field(FOOBLOB_DESCRIPTOR, it.encodeBase64String()) } + input.fooBlob?.let { field(FOOBLOB_DESCRIPTOR, it) } } """.trimIndent() diff --git a/runtime/serde/serde-xml/common/src/aws/smithy/kotlin/runtime/serde/xml/XmlSerializer.kt b/runtime/serde/serde-xml/common/src/aws/smithy/kotlin/runtime/serde/xml/XmlSerializer.kt index 35618cb49e..d1356f848c 100644 --- a/runtime/serde/serde-xml/common/src/aws/smithy/kotlin/runtime/serde/xml/XmlSerializer.kt +++ b/runtime/serde/serde-xml/common/src/aws/smithy/kotlin/runtime/serde/xml/XmlSerializer.kt @@ -134,7 +134,7 @@ public class XmlSerializer(private val xmlWriter: XmlStreamWriter = xmlStreamWri field(descriptor, value.format(format)) override fun field(descriptor: SdkFieldDescriptor, value: ByteArray): Unit = - field(descriptor, value) + field(descriptor, value.encodeBase64String()) override fun field(descriptor: SdkFieldDescriptor, value: Document?): Unit = throw SerializationException( "cannot serialize field ${descriptor.serialName}; Document type is not supported by xml encoding", From 48849a1208fe0bb2c42c06c49b54b9c419104378 Mon Sep 17 00:00:00 2001 From: Matas Date: Mon, 6 Jan 2025 16:34:11 -0500 Subject: [PATCH 08/65] fix: correctly serialize subset of shape's members when configured (#1199) --- .../core/QueryHttpBindingProtocolGenerator.kt | 2 +- .../codegen/aws/protocols/RpcV2CborTest.kt | 17 +++++++++++++++++ .../rendering/serde/CborSerializerGenerator.kt | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/QueryHttpBindingProtocolGenerator.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/QueryHttpBindingProtocolGenerator.kt index 62f8f7ebe1..db97349f84 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/QueryHttpBindingProtocolGenerator.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/QueryHttpBindingProtocolGenerator.kt @@ -145,7 +145,7 @@ abstract class AbstractQueryFormUrlSerializerGenerator( return shape.documentSerializer(ctx.settings, symbol, members) { writer -> writer.openBlock("internal fun #identifier.name:L(serializer: #T, input: #T) {", RuntimeTypes.Serde.Serializer, symbol) .call { - renderSerializerBody(ctx, shape, shape.members().toList(), writer) + renderSerializerBody(ctx, shape, members.toList(), writer) } .closeBlock("}") } diff --git a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2CborTest.kt b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2CborTest.kt index 17a7c0f3d1..0114185004 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2CborTest.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2CborTest.kt @@ -4,6 +4,7 @@ */ package software.amazon.smithy.kotlin.codegen.aws.protocols +import io.kotest.matchers.string.shouldNotContain import software.amazon.smithy.kotlin.codegen.test.* import kotlin.test.Test @@ -145,4 +146,20 @@ class RpcV2CborTest { val serializeBody = serializer.lines(" override suspend fun serialize(context: ExecutionContext, input: PutFooStreamingRequest): HttpRequestBuilder {", "}") serializeBody.shouldContainOnlyOnceWithDiff("""builder.headers.setMissing("Content-Type", "application/vnd.amazon.eventstream")""") } + + @Test + fun testEventStreamInitialRequestDoesNotSerializeStreamMember() { + val ctx = model.newTestContext("CborExample") + + val generator = RpcV2Cbor() + generator.generateProtocolClient(ctx.generationCtx) + + ctx.generationCtx.delegator.finalize() + ctx.generationCtx.delegator.flushWriters() + + val documentSerializer = ctx.manifest.expectFileString("/src/main/kotlin/com/test/serde/PutFooStreamingRequestDocumentSerializer.kt") + + val serializeBody = documentSerializer.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", "}") + serializeBody.shouldNotContain("input.messages") // `messages` is the stream member and should not be serialized in the initial request + } } diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/CborSerializerGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/CborSerializerGenerator.kt index 1fdb7850a7..545a484a90 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/CborSerializerGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/CborSerializerGenerator.kt @@ -108,7 +108,7 @@ class CborSerializerGenerator( val symbol = ctx.symbolProvider.toSymbol(shape) return shape.documentSerializer(ctx.settings, symbol, members) { writer -> writer.withBlock("internal fun #identifier.name:L(serializer: #T, input: #T) {", "}", RuntimeTypes.Serde.Serializer, symbol) { - call { renderSerializerBody(ctx, shape, shape.members().toList(), writer) } + call { renderSerializerBody(ctx, shape, members.toList(), writer) } } } } From ded3a4bb03060f28f3ce085fed3a9627f7297ae5 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Mon, 6 Jan 2025 21:45:24 +0000 Subject: [PATCH 09/65] chore: release 1.3.32 --- .changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json | 5 ----- CHANGELOG.md | 5 +++++ gradle.properties | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 .changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json diff --git a/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json b/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json deleted file mode 100644 index 0fad5e0349..0000000000 --- a/.changes/1021e75a-45f3-4f3a-820c-700d9ec6e782.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "1021e75a-45f3-4f3a-820c-700d9ec6e782", - "type": "bugfix", - "description": "Fix serialization of CBOR blobs" -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5473a56d69..a52fe756c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [1.3.32] - 01/06/2025 + +### Fixes +* Fix serialization of CBOR blobs + ## [1.3.31] - 12/18/2024 ### Features diff --git a/gradle.properties b/gradle.properties index f902a36719..eda623b285 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.32-SNAPSHOT +sdkVersion=1.3.32 # codegen -codegenVersion=0.33.32-SNAPSHOT \ No newline at end of file +codegenVersion=0.33.32 \ No newline at end of file From d97e8ba056d5f0c9869226854638dd486e06f1fa Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Mon, 6 Jan 2025 21:45:25 +0000 Subject: [PATCH 10/65] chore: bump snapshot version to 1.3.33-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index eda623b285..b49ffff27f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.32 +sdkVersion=1.3.33-SNAPSHOT # codegen -codegenVersion=0.33.32 \ No newline at end of file +codegenVersion=0.33.33-SNAPSHOT \ No newline at end of file From 78f17f3dcb809e297669c9733e2f440da33985f2 Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Wed, 8 Jan 2025 09:23:33 -0800 Subject: [PATCH 11/65] chore: add *-main to branch workflows (#1209) --- .github/workflows/api-compat-verification.yml | 4 +++- .github/workflows/artifact-size-metrics.yml | 4 +++- .github/workflows/changelog-verification.yml | 4 +++- .github/workflows/continuous-integration.yml | 4 +++- .github/workflows/dependabot.yml | 4 +++- .github/workflows/kat-transform.yml | 4 +++- .github/workflows/lint.yml | 5 ++++- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/api-compat-verification.yml b/.github/workflows/api-compat-verification.yml index 26c7ef3901..2d4a22452a 100644 --- a/.github/workflows/api-compat-verification.yml +++ b/.github/workflows/api-compat-verification.yml @@ -3,7 +3,9 @@ name: API compatibility verification on: pull_request: types: [ opened, synchronize, reopened, labeled, unlabeled ] - branches: [ main ] + branches: + - main + - '*-main' jobs: api-compat-verification: diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index bd1c521e16..0591b2b6aa 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -2,7 +2,9 @@ name: Artifact Size Metrics on: pull_request: types: [ opened, synchronize, reopened, labeled, unlabeled ] - branches: [ main ] + branches: + - main + - '*-main' release: types: [published] diff --git a/.github/workflows/changelog-verification.yml b/.github/workflows/changelog-verification.yml index 547b155abf..ed6efef911 100644 --- a/.github/workflows/changelog-verification.yml +++ b/.github/workflows/changelog-verification.yml @@ -3,7 +3,9 @@ name: Changelog verification on: pull_request: types: [ opened, synchronize, reopened, labeled, unlabeled ] - branches: [ main ] + branches: + - main + - '*-main' jobs: changelog-verification: diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 9b0dc1c880..599293cc06 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -2,7 +2,9 @@ name: CI on: push: - branches: [ main ] + branches: + - main + - '*-main' pull_request: workflow_dispatch: diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index 69fb0c9885..6588de3857 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -2,7 +2,9 @@ name: Dependabot Dependency Submission on: push: - branches: [ main ] + branches: + - main + - '*-main' permissions: contents: write diff --git a/.github/workflows/kat-transform.yml b/.github/workflows/kat-transform.yml index 859a904bc3..938e936ef9 100644 --- a/.github/workflows/kat-transform.yml +++ b/.github/workflows/kat-transform.yml @@ -3,7 +3,9 @@ name: Kat Transform on: pull_request: types: [ opened, synchronize, reopened, labeled, unlabeled ] - branches: [ main ] + branches: + - main + - '*-main' # Allow one instance of this workflow per pull request, and cancel older runs when new changes are pushed concurrency: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6693ed2aae..e95b98aded 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,8 +5,11 @@ on: branches: - '**' - '!main' + - '!*-main' pull_request: - branches: [ main ] + branches: + - main + - '*-main' workflow_dispatch: env: From d06ee0a604dd0750421c6d7dfe7c47dfbcd062bf Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Wed, 8 Jan 2025 09:23:43 -0800 Subject: [PATCH 12/65] chore: add .kotlin/ to .gitignore (#1208) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 225fe6070b..99ff20f122 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ out/ # Compiled class file *.class *.klib +.kotlin/ # Log file *.log From d2e7c918e7fc9ee9892fd6cd7d852db4d5b2f2db Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:16:58 -0500 Subject: [PATCH 13/65] chore: smithy version bump (#1213) --- .../model/error-correction-tests.smithy | 13 ++++++++++--- .../core/AwsHttpBindingProtocolGenerator.kt | 10 +++++++++- gradle/libs.versions.toml | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/codegen/protocol-tests/model/error-correction-tests.smithy b/codegen/protocol-tests/model/error-correction-tests.smithy index 74e614bdc5..201ffc877f 100644 --- a/codegen/protocol-tests/model/error-correction-tests.smithy +++ b/codegen/protocol-tests/model/error-correction-tests.smithy @@ -37,7 +37,12 @@ operation SayHello { output: TestOutputDocument, errors: [Error] } @http(method: "POST", uri: "/") operation SayHelloXml { output: TestOutput, errors: [Error] } -structure TestOutputDocument with [TestStruct] { innerField: Nested, @required document: Document } +structure TestOutputDocument with [TestStruct] { + innerField: Nested, + // FIXME: This trait fails smithy validator + // @required + document: Document +} structure TestOutput with [TestStruct] { innerField: Nested } @mixin @@ -60,7 +65,8 @@ structure TestStruct { @required nestedListValue: NestedList - @required + // FIXME: This trait fails smithy validator + // @required nested: Nested @required @@ -91,7 +97,8 @@ union MyUnion { } structure Nested { - @required + // FIXME: This trait fails smithy validator + // @required a: String } diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt index 864c2a6c3c..6e5834f7d1 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt @@ -39,7 +39,15 @@ abstract class AwsHttpBindingProtocolGenerator : HttpBindingProtocolGenerator() // The following can be used to generate only a specific test by name. // val targetedTest = TestMemberDelta(setOf("RestJsonComplexErrorWithNoMessage"), TestContainmentMode.RUN_TESTS) - val ignoredTests = TestMemberDelta(setOf()) + val ignoredTests = TestMemberDelta( + setOf( + "AwsJson10ClientErrorCorrectsWithDefaultValuesWhenServerFailsToSerializeRequiredValues", + "RestJsonNullAndEmptyHeaders", + "NullAndEmptyHeaders", + "RpcV2CborClientPopulatesDefaultsValuesWhenMissingInResponse", + "RpcV2CborClientPopulatesDefaultValuesInInput", + ), + ) val requestTestBuilder = HttpProtocolUnitTestRequestGenerator.Builder() val responseTestBuilder = HttpProtocolUnitTestResponseGenerator.Builder() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0683bfc2e1..14232f4241 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,7 +17,7 @@ crt-kotlin-version = "0.8.10" micrometer-version = "1.13.6" # codegen -smithy-version = "1.51.0" +smithy-version = "1.53.0" smithy-gradle-version = "0.9.0" # testing From 5a2df8f171250e150c685c9389f80e2a6b0778eb Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Fri, 10 Jan 2025 14:36:46 +0000 Subject: [PATCH 14/65] chore: release 1.3.33 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a52fe756c1..2c327d4f40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## [1.3.33] - 01/10/2025 + ## [1.3.32] - 01/06/2025 ### Fixes diff --git a/gradle.properties b/gradle.properties index b49ffff27f..b6869a974b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.33-SNAPSHOT +sdkVersion=1.3.33 # codegen -codegenVersion=0.33.33-SNAPSHOT \ No newline at end of file +codegenVersion=0.33.33 \ No newline at end of file From 003633bad25b5b3e75112da2d1de5f2eeffd1471 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Fri, 10 Jan 2025 14:36:47 +0000 Subject: [PATCH 15/65] chore: bump snapshot version to 1.3.34-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b6869a974b..6c237cf8df 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.33 +sdkVersion=1.3.34-SNAPSHOT # codegen -codegenVersion=0.33.33 \ No newline at end of file +codegenVersion=0.33.34-SNAPSHOT \ No newline at end of file From 5f5ec8f16b4db571bb9c83f520e26f9927d8ecf2 Mon Sep 17 00:00:00 2001 From: Matas Date: Fri, 10 Jan 2025 11:13:29 -0500 Subject: [PATCH 16/65] feat: add `AuthTokenGenerator` (#1212) --- .../api/aws-signing-common.api | 10 +++ .../auth/awssigning/AuthTokenGenerator.kt | 44 ++++++++++++ .../auth/awssigning/AuthTokenGeneratorTest.kt | 71 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt create mode 100644 runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt diff --git a/runtime/auth/aws-signing-common/api/aws-signing-common.api b/runtime/auth/aws-signing-common/api/aws-signing-common.api index 0c96486679..d128b0bd6f 100644 --- a/runtime/auth/aws-signing-common/api/aws-signing-common.api +++ b/runtime/auth/aws-signing-common/api/aws-signing-common.api @@ -1,3 +1,13 @@ +public final class aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator { + public fun (Ljava/lang/String;Laws/smithy/kotlin/runtime/auth/awscredentials/CredentialsProvider;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner;Laws/smithy/kotlin/runtime/time/Clock;)V + public synthetic fun (Ljava/lang/String;Laws/smithy/kotlin/runtime/auth/awscredentials/CredentialsProvider;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner;Laws/smithy/kotlin/runtime/time/Clock;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun generateAuthToken-exY8QGI (Laws/smithy/kotlin/runtime/net/url/Url;Ljava/lang/String;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getClock ()Laws/smithy/kotlin/runtime/time/Clock; + public final fun getCredentialsProvider ()Laws/smithy/kotlin/runtime/auth/awscredentials/CredentialsProvider; + public final fun getService ()Ljava/lang/String; + public final fun getSigner ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; +} + public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsChunkedByteReadChannel : aws/smithy/kotlin/runtime/io/SdkByteReadChannel { public fun (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;[BLaws/smithy/kotlin/runtime/http/DeferredHeaders;)V public synthetic fun (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;[BLaws/smithy/kotlin/runtime/http/DeferredHeaders;ILkotlin/jvm/internal/DefaultConstructorMarker;)V diff --git a/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt new file mode 100644 index 0000000000..e92ac1f72c --- /dev/null +++ b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt @@ -0,0 +1,44 @@ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* SPDX-License-Identifier: Apache-2.0 +*/ +package aws.smithy.kotlin.runtime.auth.awssigning + +import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider +import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningConfig.Companion.invoke +import aws.smithy.kotlin.runtime.http.HttpMethod +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.net.url.Url +import aws.smithy.kotlin.runtime.time.Clock +import kotlin.time.Duration + +/** + * Generates an authentication token, which is a SigV4-signed URL with the HTTP scheme removed. + * @param service The name of the service the token is being generated for + * @param credentialsProvider The [CredentialsProvider] which will provide credentials to use when generating the auth token + * @param signer The [AwsSigner] implementation to use when creating the authentication token + * @param clock The [Clock] implementation to use + */ +public class AuthTokenGenerator( + public val service: String, + public val credentialsProvider: CredentialsProvider, + public val signer: AwsSigner, + public val clock: Clock = Clock.System, +) { + private fun Url.trimScheme(): String = toString().removePrefix(scheme.protocolName).removePrefix("://") + + public suspend fun generateAuthToken(endpoint: Url, region: String, expiration: Duration): String { + val req = HttpRequest(HttpMethod.GET, endpoint) + + val config = AwsSigningConfig { + credentials = credentialsProvider.resolve() + this.region = region + service = this@AuthTokenGenerator.service + signingDate = clock.now() + expiresAfter = expiration + signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS + } + + return signer.sign(req, config).output.url.trimScheme() + } +} diff --git a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt new file mode 100644 index 0000000000..87fec1a74e --- /dev/null +++ b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt @@ -0,0 +1,71 @@ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* SPDX-License-Identifier: Apache-2.0 +*/ +package aws.smithy.kotlin.runtime.auth.awssigning + +import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials +import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider +import aws.smithy.kotlin.runtime.collections.Attributes +import aws.smithy.kotlin.runtime.http.Headers +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.request.toBuilder +import aws.smithy.kotlin.runtime.net.Host +import aws.smithy.kotlin.runtime.net.url.Url +import aws.smithy.kotlin.runtime.time.Instant +import aws.smithy.kotlin.runtime.time.ManualClock +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertContains +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.seconds +import kotlin.time.DurationUnit + +class AuthTokenGeneratorTest { + @Test + fun testGenerateAuthToken() = runTest { + val credentials = Credentials("akid", "secret") + + val credentialsProvider = object : CredentialsProvider { + var credentialsResolved = false + override suspend fun resolve(attributes: Attributes): Credentials { + credentialsResolved = true + return credentials + } + } + + val clock = ManualClock(Instant.fromEpochSeconds(0)) + + val generator = AuthTokenGenerator("foo", credentialsProvider, TEST_SIGNER, clock = clock) + + val endpoint = Url { host = Host.parse("foo.bar.us-east-1.baz") } + val token = generator.generateAuthToken(endpoint, "us-east-1", 333.seconds) + + assertContains(token, "foo.bar.us-east-1.baz") + assertContains(token, "X-Amz-Credential=signature") // test custom signer was invoked + assertContains(token, "X-Amz-Expires=333") // expiration + assertContains(token, "X-Amz-SigningDate=0") // clock + + assertTrue(credentialsProvider.credentialsResolved) + } +} + +private val TEST_SIGNER = object : AwsSigner { + override suspend fun sign( + request: HttpRequest, + config: AwsSigningConfig, + ): AwsSigningResult { + val builder = request.toBuilder() + builder.url.parameters.decodedParameters.apply { + put("X-Amz-Credential", "signature") + put("X-Amz-Expires", (config.expiresAfter?.toLong(DurationUnit.SECONDS) ?: 900).toString()) + put("X-Amz-SigningDate", config.signingDate.epochSeconds.toString()) + } + + return AwsSigningResult(builder.build(), "signature".encodeToByteArray()) + } + + override suspend fun signChunk(chunkBody: ByteArray, prevSignature: ByteArray, config: AwsSigningConfig): AwsSigningResult = throw IllegalStateException("signChunk unexpectedly invoked") + + override suspend fun signChunkTrailer(trailingHeaders: Headers, prevSignature: ByteArray, config: AwsSigningConfig): AwsSigningResult = throw IllegalStateException("signChunkTrailer unexpectedly invoked") +} From 3fe1b5e7763bd4ed386f30d3f4bfcbb0ad4aa352 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Fri, 10 Jan 2025 16:45:39 +0000 Subject: [PATCH 17/65] chore: release 1.3.34 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c327d4f40..c1758b4332 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## [1.3.34] - 01/10/2025 + ## [1.3.33] - 01/10/2025 ## [1.3.32] - 01/06/2025 diff --git a/gradle.properties b/gradle.properties index 6c237cf8df..193406ed69 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.34-SNAPSHOT +sdkVersion=1.3.34 # codegen -codegenVersion=0.33.34-SNAPSHOT \ No newline at end of file +codegenVersion=0.33.34 \ No newline at end of file From 0bba3084ebb3160abe2a21fc86f4223c7bf37c23 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Fri, 10 Jan 2025 16:45:40 +0000 Subject: [PATCH 18/65] chore: bump snapshot version to 1.3.35-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 193406ed69..d76819491b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.34 +sdkVersion=1.3.35-SNAPSHOT # codegen -codegenVersion=0.33.34 \ No newline at end of file +codegenVersion=0.33.35-SNAPSHOT \ No newline at end of file From 52e4439088b388c5f4d8c9b1e6fec6588d37a1a4 Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Wed, 15 Jan 2025 12:33:57 -0500 Subject: [PATCH 19/65] misc: merge v1.4 into main (#1218) --- .brazil.json | 2 +- .../0857b6f0-0444-479f-be6b-06ef71d482a0.json | 9 ++++ .../1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json | 6 +++ .../3456d00f-1b29-4d88-ab02-045db1b1ebce.json | 8 +++ .../kotlin/codegen/core/KotlinDependency.kt | 2 +- .../rendering/waiters/WaiterGenerator.kt | 15 +++--- .../waiters/ServiceWaitersGeneratorTest.kt | 6 +-- .../rendering/waiters/WaiterGeneratorTest.kt | 4 +- gradle/libs.versions.toml | 17 ++++--- .../tests/SigningSuiteTestBaseJVM.kt | 3 +- runtime/runtime-core/api/runtime-core.api | 15 +++++- .../aws/smithy/kotlin/runtime/Exceptions.kt | 49 +++++++++++++++++- .../kotlin/runtime/collections/Attributes.kt | 11 ++++ .../kotlin/runtime/retries/Exceptions.kt | 23 ++++++++- .../runtime/retries/StandardRetryStrategy.kt | 30 +++++++++-- .../retries/delay/StandardRetryTokenBucket.kt | 2 +- .../smithy/kotlin/runtime/ExceptionsTest.kt | 34 +++++++++++++ .../impl/StandardRetryIntegrationTest.kt | 50 +++++++++++++++---- .../smithy/kotlin/codegen/util/TestUtils.kt | 7 +-- 19 files changed, 250 insertions(+), 43 deletions(-) create mode 100644 .changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json create mode 100644 .changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json create mode 100644 .changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json diff --git a/.brazil.json b/.brazil.json index cb2e43713a..5a1d830abd 100644 --- a/.brazil.json +++ b/.brazil.json @@ -1,6 +1,6 @@ { "dependencies": { - "org.jetbrains.kotlin:kotlin-stdlib:2.0.*": "KotlinStdlib-2.x", + "org.jetbrains.kotlin:kotlin-stdlib:2.*": "KotlinStdlib-2.x", "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.*": "KotlinxCoroutinesCoreJvm-1.x", "com.squareup.okhttp3:okhttp-coroutines:5.*": "OkHttp3Coroutines-5.x", diff --git a/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json b/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json new file mode 100644 index 0000000000..d89da89103 --- /dev/null +++ b/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json @@ -0,0 +1,9 @@ +{ + "id": "0857b6f0-0444-479f-be6b-06ef71d482a0", + "type": "feature", + "description": "⚠️ **IMPORTANT**: Add `retryStrategy` configuration option for waiters", + "issues": [ + "https://github.com/awslabs/aws-sdk-kotlin/issues/1431" + ], + "requiresMinorVersionBump": true +} \ No newline at end of file diff --git a/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json b/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json new file mode 100644 index 0000000000..10ef502204 --- /dev/null +++ b/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json @@ -0,0 +1,6 @@ +{ + "id": "1a68d0b7-00e7-45c0-88f6-95e5c39c9c61", + "type": "misc", + "description": "⚠️ **IMPORTANT**: Upgrade to Kotlin 2.1.0", + "requiresMinorVersionBump": true +} \ No newline at end of file diff --git a/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json b/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json new file mode 100644 index 0000000000..767e48a02e --- /dev/null +++ b/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json @@ -0,0 +1,8 @@ +{ + "id": "3456d00f-1b29-4d88-ab02-045db1b1ebce", + "type": "bugfix", + "description": "Include more information when retry strategy halts early due to token bucket capacity errors", + "issues": [ + "awslabs/aws-sdk-kotlin#1321" + ] +} \ No newline at end of file diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt index 17faf0ad48..b575efae60 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt @@ -37,7 +37,7 @@ private fun getDefaultRuntimeVersion(): String { // publishing info const val RUNTIME_GROUP: String = "aws.smithy.kotlin" val RUNTIME_VERSION: String = System.getProperty("smithy.kotlin.codegen.clientRuntimeVersion", getDefaultRuntimeVersion()) -val KOTLIN_COMPILER_VERSION: String = System.getProperty("smithy.kotlin.codegen.kotlinCompilerVersion", "2.0.10") +val KOTLIN_COMPILER_VERSION: String = System.getProperty("smithy.kotlin.codegen.kotlinCompilerVersion", "2.1.0") enum class SourceSet { CommonMain, diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGenerator.kt index 552a352a1a..f150cbc3d2 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGenerator.kt @@ -17,7 +17,7 @@ import java.text.DecimalFormatSymbols * Renders the top-level retry strategy for a waiter. */ private fun KotlinWriter.renderRetryStrategy(wi: WaiterInfo, asValName: String) { - withBlock("val #L = #T {", "}", asValName, RuntimeTypes.Core.Retries.StandardRetryStrategy) { + withBlock("val #L = retryStrategy ?: #T {", "}", asValName, RuntimeTypes.Core.Retries.StandardRetryStrategy) { write("maxAttempts = 20") write("tokenBucket = #T", RuntimeTypes.Core.Retries.Delay.InfiniteTokenBucket) withBlock("delayProvider {", "}") { @@ -35,18 +35,21 @@ private fun KotlinWriter.renderRetryStrategy(wi: WaiterInfo, asValName: String) internal fun KotlinWriter.renderWaiter(wi: WaiterInfo) { write("") wi.waiter.documentation.ifPresent(::dokka) - val inputParameter = if (wi.input.hasAllOptionalMembers) { - format("request: #1T = #1T { }", wi.inputSymbol) + + val requestType = if (wi.input.hasAllOptionalMembers) { + format("#1T = #1T { }", wi.inputSymbol) } else { - format("request: #T", wi.inputSymbol) + format("#T", wi.inputSymbol) } + withBlock( - "#L suspend fun #T.#L(#L): #T<#T> {", + "#L suspend fun #T.#L(request: #L, retryStrategy: #T? = null): #T<#T> {", "}", wi.ctx.settings.api.visibility, wi.serviceSymbol, wi.methodName, - inputParameter, + requestType, + RuntimeTypes.Core.Retries.RetryStrategy, RuntimeTypes.Core.Retries.Outcome, wi.outputSymbol, ) { diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/ServiceWaitersGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/ServiceWaitersGeneratorTest.kt index c83c29661d..49ee90f484 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/ServiceWaitersGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/ServiceWaitersGeneratorTest.kt @@ -43,7 +43,7 @@ class ServiceWaitersGeneratorTest { /** * Wait until a foo exists with optional input */ - public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }): Outcome { + public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }, retryStrategy: RetryStrategy? = null): Outcome { """.trimIndent() val methodFooter = """ val policy = AcceptorRetryPolicy(request, acceptors) @@ -59,7 +59,7 @@ class ServiceWaitersGeneratorTest { /** * Wait until a foo exists with required input */ - public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest): Outcome { + public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest, retryStrategy: RetryStrategy? = null): Outcome { """.trimIndent() listOf( generateService("simple-service-with-operation-waiter.smithy"), @@ -105,7 +105,7 @@ class ServiceWaitersGeneratorTest { @Test fun testRetryStrategy() { val expected = """ - val strategy = StandardRetryStrategy { + val strategy = retryStrategy ?: StandardRetryStrategy { maxAttempts = 20 tokenBucket = InfiniteTokenBucket delayProvider { diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGeneratorTest.kt index c8f6ae3cfc..705b3b8b16 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGeneratorTest.kt @@ -28,7 +28,7 @@ class WaiterGeneratorTest { @Test fun testDefaultDelays() { val expected = """ - val strategy = StandardRetryStrategy { + val strategy = retryStrategy ?: StandardRetryStrategy { maxAttempts = 20 tokenBucket = InfiniteTokenBucket delayProvider { @@ -45,7 +45,7 @@ class WaiterGeneratorTest { @Test fun testCustomDelays() { val expected = """ - val strategy = StandardRetryStrategy { + val strategy = retryStrategy ?: StandardRetryStrategy { maxAttempts = 20 tokenBucket = InfiniteTokenBucket delayProvider { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 14232f4241..6ef5b35d57 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] -kotlin-version = "2.0.21" +kotlin-version = "2.1.0" dokka-version = "1.9.10" -aws-kotlin-repo-tools-version = "0.4.16" +aws-kotlin-repo-tools-version = "0.4.17" # libs coroutines-version = "1.9.0" @@ -10,11 +10,12 @@ atomicfu-version = "0.25.0" okhttp-version = "5.0.0-alpha.14" okhttp4-version = "4.12.0" okio-version = "3.9.1" -otel-version = "1.43.0" +otel-version = "1.45.0" slf4j-version = "2.0.16" slf4j-v1x-version = "1.7.36" -crt-kotlin-version = "0.8.10" -micrometer-version = "1.13.6" +crt-kotlin-version = "0.9.0" +micrometer-version = "1.14.2" +binary-compatibility-validator-version = "0.16.3" # codegen smithy-version = "1.53.0" @@ -23,7 +24,7 @@ smithy-gradle-version = "0.9.0" # testing junit-version = "5.10.5" kotest-version = "5.9.1" -kotlin-compile-testing-version = "1.6.0" +kotlin-compile-testing-version = "0.7.0" kotlinx-benchmark-version = "0.4.12" kotlinx-serialization-version = "1.7.3" docker-java-version = "3.4.0" @@ -80,7 +81,7 @@ smithy-smoke-test-traits = { module = "software.amazon.smithy:smithy-smoke-test- junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-version" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-version" } -kotlin-compile-testing = {module = "com.github.tschuchortdev:kotlin-compile-testing", version.ref = "kotlin-compile-testing-version" } +kotlin-compile-testing = {module = "dev.zacsweers.kctfork:core", version.ref = "kotlin-compile-testing-version" } kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest-version" } kotest-assertions-core-jvm = { module = "io.kotest:kotest-assertions-core-jvm", version.ref = "kotest-version" } kotlinx-benchmark-runtime = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark-version" } @@ -104,7 +105,7 @@ 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 = "0.13.2" } +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"} aws-kotlin-repo-tools-kmp = { id = "aws.sdk.kotlin.gradle.kmp", version.ref = "aws-kotlin-repo-tools-version" } aws-kotlin-repo-tools-smithybuild = { id = "aws.sdk.kotlin.gradle.smithybuild", version.ref = "aws-kotlin-repo-tools-version" } diff --git a/runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/SigningSuiteTestBaseJVM.kt b/runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/SigningSuiteTestBaseJVM.kt index 904aef564b..b3c4202d26 100644 --- a/runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/SigningSuiteTestBaseJVM.kt +++ b/runtime/auth/aws-signing-tests/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/SigningSuiteTestBaseJVM.kt @@ -28,6 +28,7 @@ import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.runBlocking +import kotlinx.io.readByteArray import kotlinx.serialization.json.* import org.junit.jupiter.api.Assumptions.assumeTrue import org.junit.jupiter.api.Test @@ -383,7 +384,7 @@ public actual abstract class SigningSuiteTestBase : HasSigner { } if (hasBody) { - val bytes = runBlocking { chan.readRemaining().readBytes() } + val bytes = runBlocking { chan.readRemaining().readByteArray() } builder.body = HttpBody.fromBytes(bytes) } diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 942f99e348..8c42034110 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -1,3 +1,13 @@ +public final class aws/smithy/kotlin/runtime/ClientErrorContext { + public fun (Ljava/lang/String;Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getFormatted ()Ljava/lang/String; + public final fun getKey ()Ljava/lang/String; + public final fun getValue ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public class aws/smithy/kotlin/runtime/ClientException : aws/smithy/kotlin/runtime/SdkBaseException { public fun ()V public fun (Ljava/lang/String;)V @@ -9,11 +19,13 @@ public class aws/smithy/kotlin/runtime/ErrorMetadata { public static final field Companion Laws/smithy/kotlin/runtime/ErrorMetadata$Companion; public fun ()V public final fun getAttributes ()Laws/smithy/kotlin/runtime/collections/MutableAttributes; + public final fun getClientContext ()Ljava/util/List; public final fun isRetryable ()Z public final fun isThrottling ()Z } public final class aws/smithy/kotlin/runtime/ErrorMetadata$Companion { + public final fun getClientContext ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getRetryable ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getThrottlingError ()Laws/smithy/kotlin/runtime/collections/AttributeKey; } @@ -62,7 +74,6 @@ public class aws/smithy/kotlin/runtime/ServiceException : aws/smithy/kotlin/runt public fun (Ljava/lang/String;)V public fun (Ljava/lang/String;Ljava/lang/Throwable;)V public fun (Ljava/lang/Throwable;)V - protected fun getDisplayMetadata ()Ljava/util/List; public fun getMessage ()Ljava/lang/String; public synthetic fun getSdkErrorMetadata ()Laws/smithy/kotlin/runtime/ErrorMetadata; public fun getSdkErrorMetadata ()Laws/smithy/kotlin/runtime/ServiceErrorMetadata; @@ -134,6 +145,7 @@ public final class aws/smithy/kotlin/runtime/collections/AttributesBuilder { } public final class aws/smithy/kotlin/runtime/collections/AttributesKt { + public static final fun appendValue (Laws/smithy/kotlin/runtime/collections/MutableAttributes;Laws/smithy/kotlin/runtime/collections/AttributeKey;Ljava/lang/Object;)V public static final fun attributesOf (Lkotlin/jvm/functions/Function1;)Laws/smithy/kotlin/runtime/collections/Attributes; public static final fun emptyAttributes ()Laws/smithy/kotlin/runtime/collections/Attributes; public static final fun get (Laws/smithy/kotlin/runtime/collections/Attributes;Laws/smithy/kotlin/runtime/collections/AttributeKey;)Ljava/lang/Object; @@ -1685,6 +1697,7 @@ public abstract class aws/smithy/kotlin/runtime/retries/RetryException : aws/smi public final fun getAttempts ()I public final fun getLastException ()Ljava/lang/Throwable; public final fun getLastResponse ()Ljava/lang/Object; + public fun toString ()Ljava/lang/String; } public final class aws/smithy/kotlin/runtime/retries/RetryFailureException : aws/smithy/kotlin/runtime/retries/RetryException { diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Exceptions.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Exceptions.kt index 87697ec7d7..661d855a5b 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Exceptions.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/Exceptions.kt @@ -8,6 +8,41 @@ import aws.smithy.kotlin.runtime.collections.AttributeKey import aws.smithy.kotlin.runtime.collections.MutableAttributes import aws.smithy.kotlin.runtime.collections.mutableAttributes +/** + * Describes additional context about an error which may be useful in client-side debugging. This information will be + * included in exception messages. This contrasts with [ErrorMetadata] which is not _necessarily_ included in messages + * and not _necessarily_ client-related. + * @param key A header or key for the information + * @param value A value for the information + */ +public class ClientErrorContext(public val key: String, public val value: String) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ClientErrorContext + + if (key != other.key) return false + if (value != other.value) return false + + return true + } + + /** + * Gets a formatted representation of this error context suitable for inclusion in a message. This format is + * generally `"$key: $value"`. + */ + public val formatted: String = "$key: $value" + + override fun hashCode(): Int { + var result = key.hashCode() + result = 31 * result + value.hashCode() + return result + } + + override fun toString(): String = "ClientErrorContext(key='$key', value='$value')" +} + /** * Additional metadata about an error */ @@ -16,6 +51,12 @@ public open class ErrorMetadata { public val attributes: MutableAttributes = mutableAttributes() public companion object { + /** + * Set if there are additional context elements about the error + */ + public val ClientContext: AttributeKey> = + AttributeKey("aws.smithy.kotlin#ClientContext") + /** * Set if an error is retryable */ @@ -32,6 +73,9 @@ public open class ErrorMetadata { public val isThrottling: Boolean get() = attributes.getOrNull(ThrottlingError) ?: false + + public val clientContext: List + get() = attributes.getOrNull(ClientContext).orEmpty() } /** @@ -156,7 +200,7 @@ public open class ServiceException : SdkBaseException { public constructor(cause: Throwable?) : super(cause) - protected open val displayMetadata: List + private val displayMetadata: List get() = buildList { val serviceProvidedMessage = super.message ?: sdkErrorMetadata.errorMessage if (serviceProvidedMessage == null) { @@ -166,7 +210,10 @@ public open class ServiceException : SdkBaseException { } else { add(serviceProvidedMessage) } + sdkErrorMetadata.requestId?.let { add("Request ID: $it") } + + sdkErrorMetadata.clientContext.mapTo(this@buildList) { it.formatted } } override val message: String diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/Attributes.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/Attributes.kt index 1fffcc82a2..77c2507394 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/Attributes.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/Attributes.kt @@ -115,6 +115,17 @@ public fun MutableAttributes.merge(other: Attributes) { } } +/** + * Appends a value to a list-typed attribute. If the attribute does not exist, it will be created. + * @param key The key for the attribute + * @param element The element to append to the existing (or new) list value of the attribute + */ +public fun MutableAttributes.appendValue(key: AttributeKey>, element: E) { + val existingList = getOrNull(key).orEmpty() + val newList = existingList + element + set(key, newList) +} + private class AttributesImpl constructor(seed: Attributes) : MutableAttributes { private val map: MutableMap, Any> = mutableMapOf() constructor() : this(emptyAttributes()) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/Exceptions.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/Exceptions.kt index dbc2de0ffa..a81c830da2 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/Exceptions.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/Exceptions.kt @@ -22,7 +22,28 @@ public sealed class RetryException( public val attempts: Int, public val lastResponse: Any?, public val lastException: Throwable?, -) : ClientException(message, cause) +) : ClientException(message, cause) { + override fun toString(): String = buildString { + append(this@RetryException::class.simpleName) + append("(") + + append("message=") + append(message) + + append(",attempts=") + append(attempts) + + if (lastException != null) { + append(",lastException=") + append(lastException) + } else if (lastResponse != null) { + append(",lastResponse=") + append(lastResponse) + } + + append(")") + } +} /** * Indicates that retrying has failed because too many attempts have completed unsuccessfully. diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/StandardRetryStrategy.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/StandardRetryStrategy.kt index 95fd16faee..fb223aec68 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/StandardRetryStrategy.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/StandardRetryStrategy.kt @@ -5,6 +5,10 @@ package aws.smithy.kotlin.runtime.retries +import aws.smithy.kotlin.runtime.ClientErrorContext +import aws.smithy.kotlin.runtime.ErrorMetadata +import aws.smithy.kotlin.runtime.ServiceException +import aws.smithy.kotlin.runtime.collections.appendValue import aws.smithy.kotlin.runtime.retries.delay.* import aws.smithy.kotlin.runtime.retries.policy.RetryDirective import aws.smithy.kotlin.runtime.retries.policy.RetryPolicy @@ -129,17 +133,35 @@ public open class StandardRetryStrategy(override val config: Config = Config.def } } - private fun throwCapacityExceeded(cause: Throwable, attempt: Int, result: Result?): Nothing = - when (val ex = result?.exceptionOrNull()) { + private fun throwCapacityExceeded( + cause: RetryCapacityExceededException, + attempt: Int, + result: Result?, + ): Nothing { + val capacityMessage = buildString { + append("Insufficient client capacity to attempt retry, halting on attempt ") + append(attempt) + append(" of ") + append(config.maxAttempts) + } + + throw when (val retryableException = result?.exceptionOrNull()) { null -> throw TooManyAttemptsException( - cause.message!!, + capacityMessage, cause, attempt, result?.getOrNull(), result?.exceptionOrNull(), ) - else -> throw ex + + is ServiceException -> retryableException.apply { + val addCtx = ClientErrorContext("Early retry termination", capacityMessage) + sdkErrorMetadata.attributes.appendValue(ErrorMetadata.ClientContext, addCtx) + } + + else -> retryableException } + } /** * Handles the termination of the retry loop because of a non-retryable failure by throwing a diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/delay/StandardRetryTokenBucket.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/delay/StandardRetryTokenBucket.kt index 4bd2c23766..b2c4c70588 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/delay/StandardRetryTokenBucket.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/retries/delay/StandardRetryTokenBucket.kt @@ -60,7 +60,7 @@ public class StandardRetryTokenBucket internal constructor( capacity -= size } else { if (config.useCircuitBreakerMode) { - throw RetryCapacityExceededException("Insufficient capacity to attempt another retry") + throw RetryCapacityExceededException("Insufficient capacity to attempt retry") } val extraRequiredCapacity = size - capacity diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/ExceptionsTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/ExceptionsTest.kt index 551718c36e..0ba2d1639f 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/ExceptionsTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/ExceptionsTest.kt @@ -5,9 +5,14 @@ package aws.smithy.kotlin.runtime import aws.smithy.kotlin.runtime.collections.MutableAttributes +import aws.smithy.kotlin.runtime.collections.appendValue import kotlin.test.Test import kotlin.test.assertEquals +private const val CTX_KEY_1 = "Color" +private const val CTX_VALUE_1 = "blue" +private const val CTX_KEY_2 = "Shape" +private const val CTX_VALUE_2 = "square" private const val ERROR_CODE = "ErrorWithNoMessage" private const val METADATA_MESSAGE = "This is a message included in metadata but not the regular response" private const val PROTOCOL_RESPONSE_SUMMARY = "HTTP 418 I'm a teapot" @@ -104,6 +109,35 @@ class ExceptionsTest { e.message, ) } + + @Test + fun testNoMessageWithClientContext() { + val e = FooServiceException { + appendValue(ErrorMetadata.ClientContext, ClientErrorContext(CTX_KEY_1, CTX_VALUE_1)) + appendValue(ErrorMetadata.ClientContext, ClientErrorContext(CTX_KEY_2, CTX_VALUE_2)) + } + assertEquals( + buildList { + add("Error type: Unknown") + add("Protocol response: (empty response)") + add("$CTX_KEY_1: $CTX_VALUE_1") + add("$CTX_KEY_2: $CTX_VALUE_2") + }.joinToString(), + e.message, + ) + } + + @Test + fun testMessageWithClientContext() { + val e = FooServiceException(SERVICE_MESSAGE) { + appendValue(ErrorMetadata.ClientContext, ClientErrorContext(CTX_KEY_1, CTX_VALUE_1)) + appendValue(ErrorMetadata.ClientContext, ClientErrorContext(CTX_KEY_2, CTX_VALUE_2)) + } + assertEquals( + "$SERVICE_MESSAGE, $CTX_KEY_1: $CTX_VALUE_1, $CTX_KEY_2: $CTX_VALUE_2", + e.message, + ) + } } private class FooServiceException( diff --git a/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/retries/impl/StandardRetryIntegrationTest.kt b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/retries/impl/StandardRetryIntegrationTest.kt index f2c08e47eb..2bd3bc7e6a 100644 --- a/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/retries/impl/StandardRetryIntegrationTest.kt +++ b/runtime/runtime-core/jvm/test/aws/smithy/kotlin/runtime/retries/impl/StandardRetryIntegrationTest.kt @@ -5,8 +5,8 @@ package aws.smithy.kotlin.runtime.retries.impl +import aws.smithy.kotlin.runtime.ServiceException import aws.smithy.kotlin.runtime.retries.StandardRetryStrategy -import aws.smithy.kotlin.runtime.retries.TooManyAttemptsException import aws.smithy.kotlin.runtime.retries.delay.StandardRetryTokenBucket import aws.smithy.kotlin.runtime.retries.getOrThrow import aws.smithy.kotlin.runtime.retries.policy.RetryDirective @@ -15,6 +15,7 @@ import aws.smithy.kotlin.runtime.retries.policy.RetryPolicy import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.currentTime import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.assertThrows import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds @@ -38,7 +39,7 @@ class StandardRetryIntegrationTest { val block = object { var index = 0 - suspend fun doIt() = tc.responses[index++].response.statusCode + suspend fun doIt() = tc.responses[index++].response.getOrThrow() }::doIt val startTimeMs = currentTime @@ -47,9 +48,29 @@ class StandardRetryIntegrationTest { val finalState = tc.responses.last().expected when (finalState.outcome) { - TestOutcome.Success -> assertEquals(200, result.getOrNull()?.getOrThrow(), "Unexpected outcome for $name") - TestOutcome.MaxAttemptsExceeded -> assertIs(result.exceptionOrNull()) - TestOutcome.RetryQuotaExceeded -> assertIs(result.exceptionOrNull()) + TestOutcome.Success -> + assertEquals(Ok, result.getOrThrow().getOrThrow(), "Unexpected outcome for $name") + + TestOutcome.MaxAttemptsExceeded -> { + val e = assertThrows("Expected exception for $name") { + result.getOrThrow() + } + + assertEquals(tc.responses.last().response.statusCode, e.code, "Unexpected error code for $name") + } + + TestOutcome.RetryQuotaExceeded -> { + val e = assertThrows("Expected exception for $name") { + result.getOrThrow() + } + + assertEquals(tc.responses.last().response.statusCode, e.code, "Unexpected error code for $name") + + assertTrue("Expected retry capacity message in exception for $name") { + "Insufficient client capacity to attempt retry" in e.message + } + } + else -> fail("Unexpected outcome for $name: ${finalState.outcome}") } @@ -72,10 +93,19 @@ class StandardRetryIntegrationTest { } } -object IntegrationTestPolicy : RetryPolicy { - override fun evaluate(result: Result): RetryDirective = when (val code = result.getOrNull()!!) { - 200 -> RetryDirective.TerminateAndSucceed - 500, 502 -> RetryDirective.RetryError(RetryErrorType.ServerSide) - else -> fail("Unexpected status code: $code") +object IntegrationTestPolicy : RetryPolicy { + override fun evaluate(result: Result): RetryDirective = when { + result.isSuccess -> RetryDirective.TerminateAndSucceed + result.isFailure -> RetryDirective.RetryError(RetryErrorType.ServerSide) + else -> fail("Unexpected result condition") } } + +data object Ok + +class HttpCodeException(val code: Int) : ServiceException() + +fun Response.getOrThrow() = when (statusCode) { + 200 -> Ok + else -> throw HttpCodeException(statusCode) +} diff --git a/tests/compile/src/test/kotlin/software/amazon/smithy/kotlin/codegen/util/TestUtils.kt b/tests/compile/src/test/kotlin/software/amazon/smithy/kotlin/codegen/util/TestUtils.kt index 02bf209f3c..2e64c9d4fe 100644 --- a/tests/compile/src/test/kotlin/software/amazon/smithy/kotlin/codegen/util/TestUtils.kt +++ b/tests/compile/src/test/kotlin/software/amazon/smithy/kotlin/codegen/util/TestUtils.kt @@ -6,6 +6,7 @@ package software.amazon.smithy.kotlin.codegen.util +import com.tschuchort.compiletesting.JvmCompilationResult import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -36,8 +37,8 @@ private fun String.slashEscape(char: Char) = this.replace(char.toString(), """\$ * Captures the result of a model transformation test */ data class ModelChangeTestResult( - val originalModelCompilationResult: KotlinCompilation.Result, - val updatedModelCompilationResult: KotlinCompilation.Result, + val originalModelCompilationResult: JvmCompilationResult, + val updatedModelCompilationResult: JvmCompilationResult, val compileSuccess: Boolean, val compileOutput: String, ) @@ -88,7 +89,7 @@ fun compileSdkAndTest( testSource: String? = null, outputSink: OutputStream = System.out, emitSourcesToTmp: Boolean = false, -): KotlinCompilation.Result { +): JvmCompilationResult { val sdkFileManifest = generateSdk(model) if (emitSourcesToTmp) { From e0c25d654adde3124f50733e0bc66fde2ee8d058 Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Wed, 15 Jan 2025 12:35:50 -0500 Subject: [PATCH 20/65] feat: support default checksums (#1191) --- .../kotlin/codegen/core/RuntimeTypes.kt | 7 +- .../HttpChecksumRequiredIntegration.kt | 66 +++++ .../protocol/HttpProtocolClientGenerator.kt | 25 -- ...tlin.codegen.integration.KotlinIntegration | 1 + .../protocol/http-client/api/http-client.api | 20 +- ...eptor.kt => CachingChecksumInterceptor.kt} | 14 +- .../interceptors/ChecksumInterceptorUtils.kt | 44 +++ .../FlexibleChecksumsRequestInterceptor.kt | 277 ++++++++---------- .../FlexibleChecksumsResponseInterceptor.kt | 94 +++--- .../HttpChecksumRequiredInterceptor.kt | 98 +++++++ .../interceptors/Md5ChecksumInterceptor.kt | 54 ---- .../http/operation/HttpOperationContext.kt | 4 +- ...t.kt => CachingChecksumInterceptorTest.kt} | 12 +- ...FlexibleChecksumsRequestInterceptorTest.kt | 115 +++++--- ...lexibleChecksumsResponseInterceptorTest.kt | 84 +++++- ...=> HttpChecksumRequiredInterceptorTest.kt} | 46 ++- runtime/protocol/http/api/http.api | 18 ++ .../smithy/kotlin/runtime/http/HttpBody.kt | 52 ++++ runtime/runtime-core/api/runtime-core.api | 15 + .../businessmetrics/BusinessMetricsUtils.kt | 8 + .../kotlin/runtime/hashing/HashFunction.kt | 55 ++++ .../kotlin/runtime/io/SdkByteReadChannel.kt | 16 + runtime/smithy-client/api/smithy-client.api | 28 ++ .../client/config/HttpChecksumConfig.kt | 63 ++++ 24 files changed, 865 insertions(+), 351 deletions(-) create mode 100644 codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/checksums/HttpChecksumRequiredIntegration.kt rename runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/{AbstractChecksumInterceptor.kt => CachingChecksumInterceptor.kt} (67%) create mode 100644 runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/ChecksumInterceptorUtils.kt create mode 100644 runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptor.kt delete mode 100644 runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptor.kt rename runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/{AbstractChecksumInterceptorTest.kt => CachingChecksumInterceptorTest.kt} (88%) rename runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/{Md5ChecksumInterceptorTest.kt => HttpChecksumRequiredInterceptorTest.kt} (62%) create mode 100644 runtime/smithy-client/common/src/aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig.kt diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt index e42612b0b5..b6341e0443 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt @@ -81,7 +81,7 @@ object RuntimeTypes { object Interceptors : RuntimeTypePackage(KotlinDependency.HTTP, "interceptors") { val ContinueInterceptor = symbol("ContinueInterceptor") val HttpInterceptor = symbol("HttpInterceptor") - val Md5ChecksumInterceptor = symbol("Md5ChecksumInterceptor") + val HttpChecksumRequiredInterceptor = symbol("HttpChecksumRequiredInterceptor") val FlexibleChecksumsRequestInterceptor = symbol("FlexibleChecksumsRequestInterceptor") val FlexibleChecksumsResponseInterceptor = symbol("FlexibleChecksumsResponseInterceptor") val ResponseLengthValidationInterceptor = symbol("ResponseLengthValidationInterceptor") @@ -231,6 +231,9 @@ object RuntimeTypes { object Config : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "config") { val RequestCompressionConfig = symbol("RequestCompressionConfig") val CompressionClientConfig = symbol("CompressionClientConfig") + val HttpChecksumConfig = symbol("HttpChecksumConfig") + val RequestHttpChecksumConfig = symbol("RequestHttpChecksumConfig") + val ResponseHttpChecksumConfig = symbol("ResponseHttpChecksumConfig") } object Endpoints : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "endpoints") { @@ -395,6 +398,7 @@ object RuntimeTypes { val TelemetryContextElement = symbol("TelemetryContextElement", "context") val TraceSpan = symbol("TraceSpan", "trace") val withSpan = symbol("withSpan", "trace") + val warn = symbol("warn", "logging") } object TelemetryDefaults : RuntimeTypePackage(KotlinDependency.TELEMETRY_DEFAULTS) { val Global = symbol("Global") @@ -409,6 +413,7 @@ object RuntimeTypes { val CompletableDeferred = "kotlinx.coroutines.CompletableDeferred".toSymbol() val job = "kotlinx.coroutines.job".toSymbol() + val runBlocking = "kotlinx.coroutines.runBlocking".toSymbol() object Flow { // NOTE: smithy-kotlin core has an API dependency on this already diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/checksums/HttpChecksumRequiredIntegration.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/checksums/HttpChecksumRequiredIntegration.kt new file mode 100644 index 0000000000..61432a7b12 --- /dev/null +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/checksums/HttpChecksumRequiredIntegration.kt @@ -0,0 +1,66 @@ +package software.amazon.smithy.kotlin.codegen.rendering.checksums + +import software.amazon.smithy.aws.traits.HttpChecksumTrait +import software.amazon.smithy.kotlin.codegen.KotlinSettings +import software.amazon.smithy.kotlin.codegen.core.KotlinWriter +import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes +import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +import software.amazon.smithy.kotlin.codegen.model.hasTrait +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolMiddleware +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait + +/** + * Handles the `httpChecksumRequired` trait. + * See: https://smithy.io/2.0/spec/http-bindings.html#httpchecksumrequired-trait + */ +class HttpChecksumRequiredIntegration : KotlinIntegration { + override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = + model.isTraitApplied(HttpChecksumRequiredTrait::class.java) + + override fun customizeMiddleware( + ctx: ProtocolGenerator.GenerationContext, + resolved: List, + ): List = resolved + httpChecksumRequiredDefaultAlgorithmMiddleware + httpChecksumRequiredMiddleware +} + +/** + * Adds default checksum algorithm to the execution context + */ +private val httpChecksumRequiredDefaultAlgorithmMiddleware = object : ProtocolMiddleware { + override val name: String = "httpChecksumRequiredDefaultAlgorithmMiddleware" + override val order: Byte = -2 // Before S3 Express (possibly) changes the default (-1) and before calculating checksum (0) + + override fun isEnabledFor(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): Boolean = + op.hasTrait() && !op.hasTrait() + + override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) { + writer.write( + "op.context[#T.DefaultChecksumAlgorithm] = #S", + RuntimeTypes.HttpClient.Operation.HttpOperationContext, + "MD5", + ) + } +} + +/** + * Adds interceptor to calculate request checksums. + * The `httpChecksum` trait supersedes the `httpChecksumRequired` trait. If both are applied to an operation use `httpChecksum`. + * + * See: https://smithy.io/2.0/aws/aws-core.html#behavior-with-httpchecksumrequired + */ +private val httpChecksumRequiredMiddleware = object : ProtocolMiddleware { + override val name: String = "httpChecksumRequiredMiddleware" + + override fun isEnabledFor(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): Boolean = + op.hasTrait() && !op.hasTrait() + + override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) { + writer.write( + "op.interceptors.add(#T())", + RuntimeTypes.HttpClient.Interceptors.HttpChecksumRequiredInterceptor, + ) + } +} diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt index 519957cbed..f12ab07a26 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt @@ -4,7 +4,6 @@ */ package software.amazon.smithy.kotlin.codegen.rendering.protocol -import software.amazon.smithy.aws.traits.HttpChecksumTrait import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.kotlin.codegen.core.* import software.amazon.smithy.kotlin.codegen.integration.SectionId @@ -22,7 +21,6 @@ import software.amazon.smithy.model.knowledge.OperationIndex import software.amazon.smithy.model.knowledge.TopDownIndex import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.traits.EndpointTrait -import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait /** * Renders an implementation of a service interface for HTTP protocol @@ -318,8 +316,6 @@ open class HttpProtocolClientGenerator( .forEach { middleware -> middleware.render(ctx, op, writer) } - - op.renderIsMd5ChecksumRequired(writer) } /** @@ -336,27 +332,6 @@ open class HttpProtocolClientGenerator( */ protected open fun renderAdditionalMethods(writer: KotlinWriter) { } - /** - * Render optionally installing Md5ChecksumMiddleware. - * The Md5 middleware will only be installed if the operation requires a checksum and the user has not opted-in to flexible checksums. - */ - private fun OperationShape.renderIsMd5ChecksumRequired(writer: KotlinWriter) { - val httpChecksumTrait = getTrait() - - // the checksum requirement can be modeled in either HttpChecksumTrait's `requestChecksumRequired` or the HttpChecksumRequired trait - if (!hasTrait() && httpChecksumTrait == null) { - return - } - - if (hasTrait() || httpChecksumTrait?.isRequestChecksumRequired == true) { - val interceptorSymbol = RuntimeTypes.HttpClient.Interceptors.Md5ChecksumInterceptor - val inputSymbol = ctx.symbolProvider.toSymbol(ctx.model.expectShape(inputShape)) - writer.withBlock("op.interceptors.add(#T<#T> {", "})", interceptorSymbol, inputSymbol) { - writer.write("op.context.getOrNull(#T.ChecksumAlgorithm) == null", RuntimeTypes.HttpClient.Operation.HttpOperationContext) - } - } - } - /** * render a utility function to populate an operation's ExecutionContext with defaults from service config, environment, etc */ diff --git a/codegen/smithy-kotlin-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration b/codegen/smithy-kotlin-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration index 0d02b51187..2ab7fe506a 100644 --- a/codegen/smithy-kotlin-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +++ b/codegen/smithy-kotlin-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration @@ -13,3 +13,4 @@ software.amazon.smithy.kotlin.codegen.rendering.endpoints.SdkEndpointBuiltinInte software.amazon.smithy.kotlin.codegen.rendering.compression.RequestCompressionIntegration software.amazon.smithy.kotlin.codegen.rendering.auth.SigV4AsymmetricAuthSchemeIntegration software.amazon.smithy.kotlin.codegen.rendering.smoketests.SmokeTestsIntegration +software.amazon.smithy.kotlin.codegen.rendering.checksums.HttpChecksumRequiredIntegration \ No newline at end of file diff --git a/runtime/protocol/http-client/api/http-client.api b/runtime/protocol/http-client/api/http-client.api index 6e91f528f2..e8527c2c2b 100644 --- a/runtime/protocol/http-client/api/http-client.api +++ b/runtime/protocol/http-client/api/http-client.api @@ -255,7 +255,7 @@ public final class aws/smithy/kotlin/runtime/http/engine/internal/ManagedHttpCli public static final fun manage (Laws/smithy/kotlin/runtime/http/engine/HttpClientEngine;)Laws/smithy/kotlin/runtime/http/engine/HttpClientEngine; } -public abstract class aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor : aws/smithy/kotlin/runtime/client/Interceptor { +public abstract class aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor : aws/smithy/kotlin/runtime/client/Interceptor { public fun ()V public abstract fun applyChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Ljava/lang/String;)Laws/smithy/kotlin/runtime/http/request/HttpRequest; public abstract fun calculateChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -331,19 +331,17 @@ public final class aws/smithy/kotlin/runtime/http/interceptors/DiscoveredEndpoin public fun readBeforeTransmit (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;)V } -public final class aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor : aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor { - public fun ()V - public fun (Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +public final class aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor : aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor { + public fun (ZLaws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig;Ljava/lang/String;)V public fun applyChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Ljava/lang/String;)Laws/smithy/kotlin/runtime/http/request/HttpRequest; public fun calculateChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun modifyBeforeSigning (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public fun readAfterSerialization (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;)V } -public final class aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor : aws/smithy/kotlin/runtime/client/Interceptor { +public class aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor : aws/smithy/kotlin/runtime/client/Interceptor { public static final field Companion Laws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor$Companion; - public fun (Lkotlin/jvm/functions/Function1;)V + public fun (ZLaws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig;)V + public fun ignoreChecksum (Ljava/lang/String;Laws/smithy/kotlin/runtime/client/ProtocolResponseInterceptorContext;)Z public fun modifyBeforeAttemptCompletion-gIAlu-s (Laws/smithy/kotlin/runtime/client/ResponseInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun modifyBeforeCompletion-gIAlu-s (Laws/smithy/kotlin/runtime/client/ResponseInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun modifyBeforeDeserialization (Laws/smithy/kotlin/runtime/client/ProtocolResponseInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -369,10 +367,8 @@ public final class aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksums public final fun getChecksumHeaderValidated ()Laws/smithy/kotlin/runtime/collections/AttributeKey; } -public final class aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptor : aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor { +public final class aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptor : aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor { public fun ()V - public fun (Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun applyChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Ljava/lang/String;)Laws/smithy/kotlin/runtime/http/request/HttpRequest; public fun calculateChecksum (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun modifyBeforeSigning (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -516,9 +512,9 @@ public abstract interface class aws/smithy/kotlin/runtime/http/operation/HttpDes public final class aws/smithy/kotlin/runtime/http/operation/HttpOperationContext { public static final field INSTANCE Laws/smithy/kotlin/runtime/http/operation/HttpOperationContext; - public final fun getChecksumAlgorithm ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getClockSkew ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getClockSkewApproximateSigningTime ()Laws/smithy/kotlin/runtime/collections/AttributeKey; + public final fun getDefaultChecksumAlgorithm ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getHostPrefix ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getHttpCallList ()Laws/smithy/kotlin/runtime/collections/AttributeKey; public final fun getOperationAttributes ()Laws/smithy/kotlin/runtime/collections/AttributeKey; diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor.kt similarity index 67% rename from runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor.kt rename to runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor.kt index 3fa8406bf5..adad89f259 100644 --- a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptor.kt +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptor.kt @@ -9,13 +9,21 @@ import aws.smithy.kotlin.runtime.InternalApi import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext import aws.smithy.kotlin.runtime.http.request.HttpRequest +/** + * Enables inheriting [HttpInterceptor]s to use checksums caching + */ @InternalApi -public abstract class AbstractChecksumInterceptor : HttpInterceptor { +public abstract class CachingChecksumInterceptor : HttpInterceptor { private var cachedChecksum: String? = null override suspend fun modifyBeforeSigning(context: ProtocolRequestInterceptorContext): HttpRequest { - cachedChecksum ?: calculateChecksum(context).also { cachedChecksum = it } - return cachedChecksum?.let { applyChecksum(context, it) } ?: context.protocolRequest + cachedChecksum = cachedChecksum ?: calculateChecksum(context) + + return if (cachedChecksum != null) { + applyChecksum(context, cachedChecksum!!) + } else { + context.protocolRequest + } } public abstract suspend fun calculateChecksum(context: ProtocolRequestInterceptorContext): String? diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/ChecksumInterceptorUtils.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/ChecksumInterceptorUtils.kt new file mode 100644 index 0000000000..b510ab14e5 --- /dev/null +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/ChecksumInterceptorUtils.kt @@ -0,0 +1,44 @@ +package aws.smithy.kotlin.runtime.http.interceptors + +import aws.smithy.kotlin.runtime.businessmetrics.emitBusinessMetric +import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext +import aws.smithy.kotlin.runtime.hashing.HashFunction +import aws.smithy.kotlin.runtime.hashing.resolveChecksumAlgorithmHeaderName +import aws.smithy.kotlin.runtime.hashing.toBusinessMetric +import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.request.toBuilder +import aws.smithy.kotlin.runtime.http.toCompletingBody +import aws.smithy.kotlin.runtime.http.toHashingBody +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.job + +/** + * Configures [HttpRequest] with AWS chunked streaming to calculate checksum during transmission + * @return [HttpRequest] + */ +internal fun calculateAwsChunkedStreamingChecksum( + context: ProtocolRequestInterceptorContext, + checksumAlgorithm: HashFunction, +): HttpRequest { + val request = context.protocolRequest.toBuilder() + val deferredChecksum = CompletableDeferred(context.executionContext.coroutineContext.job) + val checksumHeader = checksumAlgorithm.resolveChecksumAlgorithmHeaderName() + + request.body = request.body + .toHashingBody(checksumAlgorithm, request.body.contentLength) + .toCompletingBody(deferredChecksum) + + request.headers.append("x-amz-trailer", checksumHeader) + request.trailingHeaders.append(checksumHeader, deferredChecksum) + + context.executionContext.emitBusinessMetric(checksumAlgorithm.toBusinessMetric()) + + return request.build() +} + +/** + * @return The default checksum algorithm name in the execution context, null if default checksums are disabled. + */ +internal val ProtocolRequestInterceptorContext.defaultChecksumAlgorithmName: String? + get() = executionContext.getOrNull(HttpOperationContext.DefaultChecksumAlgorithm) diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor.kt index b29ede017f..936dead520 100644 --- a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor.kt +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptor.kt @@ -5,104 +5,117 @@ package aws.smithy.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.ClientException import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.businessmetrics.emitBusinessMetric import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext +import aws.smithy.kotlin.runtime.client.config.RequestHttpChecksumConfig import aws.smithy.kotlin.runtime.hashing.* import aws.smithy.kotlin.runtime.http.* -import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.http.request.header import aws.smithy.kotlin.runtime.http.request.toBuilder import aws.smithy.kotlin.runtime.io.* +import aws.smithy.kotlin.runtime.telemetry.logging.Logger import aws.smithy.kotlin.runtime.telemetry.logging.logger import aws.smithy.kotlin.runtime.text.encoding.encodeBase64String -import aws.smithy.kotlin.runtime.util.LazyAsyncValue -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.job import kotlin.coroutines.coroutineContext /** - * Mutate a request to enable flexible checksums. + * Handles request checksums for operations with the [HttpChecksumTrait] applied. * - * If the checksum will be sent as a header, calculate the checksum. + * If a user supplies a checksum via an HTTP header no calculation will be done. The exception is MD5, if a user + * supplies an MD5 checksum header it will be ignored. * - * Otherwise, if it will be sent as a trailing header, calculate the checksum as asynchronously as the body is streamed. - * In this case, a [LazyAsyncValue] will be added to the execution context which allows the trailing checksum to be sent - * after the entire body has been streamed. + * If the request configuration and model requires checksum calculation: + * - Check if the user configured a checksum algorithm for the request and attempt to use that. + * - If no checksum is configured for the request then use the default checksum algorithm to calculate a checksum. * - * @param checksumAlgorithmNameInitializer an optional function which parses the input [I] to return the checksum algorithm name. - * if not set, then the [HttpOperationContext.ChecksumAlgorithm] execution context attribute will be used. + * If the request will be streamed: + * - The checksum calculation is done during transmission using a hashing & completing body. + * - The checksum will be sent in a trailing header, once the request is consumed. + * + * If the request will not be streamed: + * - The checksum calculation is done before transmission + * - The checksum will be sent in a header + * + * Business metrics MUST be emitted for the checksum algorithm used. + * + * @param requestChecksumRequired Model sourced flag indicating if checksum calculation is mandatory. + * @param requestChecksumCalculation Configuration option that determines when checksum calculation should be done. + * @param requestChecksumAlgorithm The checksum algorithm that the user selected for the request, may be null. */ @InternalApi -public class FlexibleChecksumsRequestInterceptor( - private val checksumAlgorithmNameInitializer: ((I) -> String?)? = null, -) : AbstractChecksumInterceptor() { - private var checksumAlgorithmName: String? = null - - @Deprecated("readAfterSerialization is no longer used") - override fun readAfterSerialization(context: ProtocolRequestInterceptorContext) { } - +public class FlexibleChecksumsRequestInterceptor( + private val requestChecksumRequired: Boolean, + private val requestChecksumCalculation: RequestHttpChecksumConfig?, + private val requestChecksumAlgorithm: String?, +) : CachingChecksumInterceptor() { override suspend fun modifyBeforeSigning(context: ProtocolRequestInterceptorContext): HttpRequest { - val logger = coroutineContext.logger>() + val logger = coroutineContext.logger() - @Suppress("UNCHECKED_CAST") - val input = context.request as I - checksumAlgorithmName = checksumAlgorithmNameInitializer?.invoke(input) ?: context.executionContext.getOrNull(HttpOperationContext.ChecksumAlgorithm) + context.protocolRequest.userProvidedChecksumHeader(logger)?.let { + logger.debug { "Checksum was supplied via header: skipping checksum calculation" } - checksumAlgorithmName ?: run { - logger.debug { "no checksum algorithm specified, skipping flexible checksums processing" } + val request = context.protocolRequest.toBuilder() + request.headers.removeAllChecksumHeadersExcept(it) return context.protocolRequest } - val req = context.protocolRequest.toBuilder() - - check(context.protocolRequest.body !is HttpBody.Empty) { - "Can't calculate the checksum of an empty body" - } - - val headerName = "x-amz-checksum-$checksumAlgorithmName".lowercase() - logger.debug { "Resolved checksum header name: $headerName" } - - // remove all checksum headers except for $headerName - // this handles the case where a user inputs a precalculated checksum, but it doesn't match the input checksum algorithm - req.headers.removeAllChecksumHeadersExcept(headerName) - - val checksumAlgorithm = checksumAlgorithmName?.toHashFunction() ?: throw ClientException("Could not parse checksum algorithm $checksumAlgorithmName") - - if (!checksumAlgorithm.isSupported) { - throw ClientException("Checksum algorithm $checksumAlgorithmName is not supported for flexible checksums") - } - - if (req.body.isEligibleForAwsChunkedStreaming) { - req.header("x-amz-trailer", headerName) - - val deferredChecksum = CompletableDeferred(context.executionContext.coroutineContext.job) - - if (req.headers[headerName] != null) { - logger.debug { "User supplied a checksum, skipping asynchronous calculation" } - - val checksum = req.headers[headerName]!! - req.headers.remove(headerName) // remove the checksum header because it will be sent as a trailing header - - deferredChecksum.complete(checksum) + resolveChecksumAlgorithm( + requestChecksumRequired, + requestChecksumCalculation, + requestChecksumAlgorithm, + context, + )?.let { checksumAlgorithm -> + return if (context.protocolRequest.body.isEligibleForAwsChunkedStreaming) { + logger.debug { "Calculating checksum during transmission using: ${checksumAlgorithm::class.simpleName}" } + calculateAwsChunkedStreamingChecksum(context, checksumAlgorithm) } else { - logger.debug { "Calculating checksum asynchronously" } - req.body = req.body - .toHashingBody(checksumAlgorithm, req.body.contentLength) - .toCompletingBody(deferredChecksum) + if (context.protocolRequest.body is HttpBody.Bytes) { + // Cache checksum + super.modifyBeforeSigning(context) + } else { + val checksum = calculateFlexibleChecksumsChecksum(context) + applyFlexibleChecksumsChecksum(context, checksum) + } } - - req.trailingHeaders.append(headerName, deferredChecksum) - return req.build() - } else { - return super.modifyBeforeSigning(context) } + + logger.debug { "Checksum wasn't provided, selected, or isn't required: skipping checksum calculation" } + return context.protocolRequest } - override suspend fun calculateChecksum(context: ProtocolRequestInterceptorContext): String? { + /** + * Determines what checksum algorithm to use, null if none is required + */ + private fun resolveChecksumAlgorithm( + requestChecksumRequired: Boolean, + requestChecksumCalculation: RequestHttpChecksumConfig?, + requestChecksumAlgorithm: String?, + context: ProtocolRequestInterceptorContext, + ): HashFunction? = + requestChecksumAlgorithm + ?.toHashFunctionOrThrow() + ?.takeIf { it.isSupportedForFlexibleChecksums } + ?: context.defaultChecksumAlgorithmName + ?.toHashFunctionOrThrow() + ?.takeIf { + (requestChecksumRequired || requestChecksumCalculation == RequestHttpChecksumConfig.WHEN_SUPPORTED) && + it.isSupportedForFlexibleChecksums + } + + /** + * Calculates a checksum based on the requirements and limitations of [FlexibleChecksumsRequestInterceptor] + */ + private suspend fun calculateFlexibleChecksumsChecksum( + context: ProtocolRequestInterceptorContext, + ): String { val req = context.protocolRequest.toBuilder() - val checksumAlgorithm = checksumAlgorithmName?.toHashFunction() ?: return null + val checksumAlgorithm = resolveChecksumAlgorithm( + requestChecksumRequired, + requestChecksumCalculation, + requestChecksumAlgorithm, + context, + )!! return when { req.body.contentLength == null && !req.body.isOneShot -> { @@ -110,104 +123,66 @@ public class FlexibleChecksumsRequestInterceptor( channel.rollingHash(checksumAlgorithm).encodeBase64String() } else -> { - val bodyBytes = req.body.readAll()!! - req.body = bodyBytes.toHttpBody() + val bodyBytes = req.body.readAll() ?: byteArrayOf() + if (req.body.isOneShot) req.body = bodyBytes.toHttpBody() bodyBytes.hash(checksumAlgorithm).encodeBase64String() } } } - override fun applyChecksum( + override suspend fun calculateChecksum(context: ProtocolRequestInterceptorContext): String? = + calculateFlexibleChecksumsChecksum(context) + + /** + * Applies a checksum based on the requirements and limitations of [FlexibleChecksumsRequestInterceptor] + */ + private fun applyFlexibleChecksumsChecksum( context: ProtocolRequestInterceptorContext, checksum: String, ): HttpRequest { - val headerName = "x-amz-checksum-$checksumAlgorithmName".lowercase() - - val req = context.protocolRequest.toBuilder() - - if (!req.headers.contains(headerName)) { - req.header(headerName, checksum) - } - - return req.build() + val request = context.protocolRequest.toBuilder() + val checksumAlgorithm = resolveChecksumAlgorithm( + requestChecksumRequired, + requestChecksumCalculation, + requestChecksumAlgorithm, + context, + )!! + val checksumHeader = checksumAlgorithm.resolveChecksumAlgorithmHeaderName() + + request.headers[checksumHeader] = checksum + request.headers.removeAllChecksumHeadersExcept(checksumHeader) + context.executionContext.emitBusinessMetric(checksumAlgorithm.toBusinessMetric()) + + return request.build() } - // FIXME this duplicates the logic from aws-signing-common, but can't import from there due to circular import. - private val HttpBody.isEligibleForAwsChunkedStreaming: Boolean - get() = (this is HttpBody.SourceContent || this is HttpBody.ChannelContent) && - contentLength != null && - (isOneShot || contentLength!! > 65536 * 16) + override fun applyChecksum( + context: ProtocolRequestInterceptorContext, + checksum: String, + ): HttpRequest = applyFlexibleChecksumsChecksum(context, checksum) /** - * @return if the [HashFunction] is supported by flexible checksums + * Checks if a user provided a checksum for a request via an HTTP header. + * The header must start with "x-amz-checksum-" followed by the checksum algorithm's name. + * MD5 is not considered a supported checksum algorithm. */ - private val HashFunction.isSupported: Boolean get() = when (this) { - is Crc32, is Crc32c, is Sha256, is Sha1 -> true - else -> false - } + private fun HttpRequest.userProvidedChecksumHeader(logger: Logger) = headers + .names() + .firstOrNull { + it.startsWith("x-amz-checksum-", ignoreCase = true) && + !it.equals("x-amz-checksum-md5", ignoreCase = true).also { isMd5 -> + if (isMd5) { + logger.debug { "MD5 checksum was supplied via header, MD5 is not a supported algorithm, ignoring header" } + } + } + } /** * Removes all checksum headers except [headerName] * @param headerName the checksum header name to keep */ - private fun HeadersBuilder.removeAllChecksumHeadersExcept(headerName: String) { - names().forEach { name -> - if (name.startsWith("x-amz-checksum-") && name != headerName) { - remove(name) - } - } - } - - /** - * Convert an [HttpBody] with an underlying [HashingSource] or [HashingByteReadChannel] - * to a [CompletingSource] or [CompletingByteReadChannel], respectively. - */ - private fun HttpBody.toCompletingBody(deferred: CompletableDeferred) = when (this) { - is HttpBody.SourceContent -> CompletingSource(deferred, (readFrom() as HashingSource)).toHttpBody(contentLength) - is HttpBody.ChannelContent -> CompletingByteReadChannel(deferred, (readFrom() as HashingByteReadChannel)).toHttpBody(contentLength) - else -> throw ClientException("HttpBody type is not supported") - } - - /** - * An [SdkSource] which uses the underlying [hashingSource]'s checksum to complete a [CompletableDeferred] value. - */ - internal class CompletingSource( - private val deferred: CompletableDeferred, - private val hashingSource: HashingSource, - ) : SdkSource by hashingSource { - override fun read(sink: SdkBuffer, limit: Long): Long = hashingSource.read(sink, limit) - .also { - if (it == -1L) { - deferred.complete(hashingSource.digest().encodeBase64String()) - } - } - } - - /** - * An [SdkByteReadChannel] which uses the underlying [hashingChannel]'s checksum to complete a [CompletableDeferred] value. - */ - internal class CompletingByteReadChannel( - private val deferred: CompletableDeferred, - private val hashingChannel: HashingByteReadChannel, - ) : SdkByteReadChannel by hashingChannel { - override suspend fun read(sink: SdkBuffer, limit: Long): Long = hashingChannel.read(sink, limit) - .also { - if (it == -1L) { - deferred.complete(hashingChannel.digest().encodeBase64String()) - } - } - } - - /** - * Compute the rolling hash of an [SdkByteReadChannel] using [hashFunction], reading up-to [bufferSize] bytes into memory - * @return a ByteArray of the hash function's digest - */ - private suspend fun SdkByteReadChannel.rollingHash(hashFunction: HashFunction, bufferSize: Long = 8192): ByteArray { - val buffer = SdkBuffer() - while (!isClosedForRead) { - read(buffer, bufferSize) - hashFunction.update(buffer.readToByteArray()) - } - return hashFunction.digest() - } + private fun HeadersBuilder.removeAllChecksumHeadersExcept(headerName: String) = + names() + .filter { it.startsWith("x-amz-checksum-", ignoreCase = true) && !it.equals(headerName, ignoreCase = true) } + .forEach { remove(it) } } diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor.kt index 2e43fe1469..eceb19e739 100644 --- a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor.kt +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptor.kt @@ -8,10 +8,11 @@ package aws.smithy.kotlin.runtime.http.interceptors import aws.smithy.kotlin.runtime.ClientException import aws.smithy.kotlin.runtime.InternalApi import aws.smithy.kotlin.runtime.client.ProtocolResponseInterceptorContext -import aws.smithy.kotlin.runtime.client.RequestInterceptorContext +import aws.smithy.kotlin.runtime.client.config.ResponseHttpChecksumConfig import aws.smithy.kotlin.runtime.collections.AttributeKey -import aws.smithy.kotlin.runtime.hashing.toHashFunction +import aws.smithy.kotlin.runtime.hashing.toHashFunctionOrThrow import aws.smithy.kotlin.runtime.http.HttpBody +import aws.smithy.kotlin.runtime.http.readAll import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.response.HttpResponse import aws.smithy.kotlin.runtime.http.response.copy @@ -31,60 +32,87 @@ internal val CHECKSUM_HEADER_VALIDATION_PRIORITY_LIST: List = listOf( ) /** - * Validate a response's checksum. + * Handles response checksums. + * + * If it's a streaming response, it wraps the response in a hashing body, calculating the checksum as the response is + * streamed to the user. The checksum is validated after the user has consumed the entire body using a checksum validating body. + * Otherwise, the checksum if calculated all at once. * - * Wraps the response in a hashing body, calculating the checksum as the response is streamed to the user. - * The checksum is validated after the user has consumed the entire body using a checksum validating body. * Users can check which checksum was validated by referencing the `ResponseChecksumValidated` execution context variable. * - * @param shouldValidateResponseChecksumInitializer A function which uses the input [I] to return whether response checksum validation should occur + * @param responseValidationRequired Model sourced flag indicating if the checksum validation is mandatory. + * @param responseChecksumValidation Configuration option that determines when checksum validation should be done. */ - @InternalApi -public class FlexibleChecksumsResponseInterceptor( - private val shouldValidateResponseChecksumInitializer: (input: I) -> Boolean, +public open class FlexibleChecksumsResponseInterceptor( + private val responseValidationRequired: Boolean, + private val responseChecksumValidation: ResponseHttpChecksumConfig?, ) : HttpInterceptor { - - private var shouldValidateResponseChecksum: Boolean = false - @InternalApi public companion object { // The name of the checksum header which was validated. If `null`, validation was not performed. public val ChecksumHeaderValidated: AttributeKey = AttributeKey("ChecksumHeaderValidated") } - override fun readBeforeSerialization(context: RequestInterceptorContext) { - @Suppress("UNCHECKED_CAST") - val input = context.request as I - shouldValidateResponseChecksum = shouldValidateResponseChecksumInitializer(input) - } - override suspend fun modifyBeforeDeserialization(context: ProtocolResponseInterceptorContext): HttpResponse { - if (!shouldValidateResponseChecksum) { - return context.protocolResponse - } + val configuredToVerifyChecksum = responseValidationRequired || responseChecksumValidation == ResponseHttpChecksumConfig.WHEN_SUPPORTED + if (!configuredToVerifyChecksum) return context.protocolResponse - val logger = coroutineContext.logger>() + val logger = coroutineContext.logger() val checksumHeader = CHECKSUM_HEADER_VALIDATION_PRIORITY_LIST .firstOrNull { context.protocolResponse.headers.contains(it) } ?: run { - logger.warn { "User requested checksum validation, but the response headers did not contain any valid checksums" } + logger.warn { "Checksum validation was requested but the response headers didn't contain a valid checksum." } return context.protocolResponse } - // let the user know which checksum will be validated - logger.debug { "Validating checksum from $checksumHeader" } - context.executionContext[ChecksumHeaderValidated] = checksumHeader + val serviceChecksumValue = context.protocolResponse.headers[checksumHeader]!! + if (ignoreChecksum(serviceChecksumValue, context)) { + return context.protocolResponse + } - val checksumAlgorithm = checksumHeader.removePrefix("x-amz-checksum-").toHashFunction() ?: throw ClientException("could not parse checksum algorithm from header $checksumHeader") + context.executionContext[ChecksumHeaderValidated] = checksumHeader - // Wrap the response body in a hashing body - return context.protocolResponse.copy( - body = context.protocolResponse.body - .toHashingBody(checksumAlgorithm, context.protocolResponse.body.contentLength) - .toChecksumValidatingBody(context.protocolResponse.headers[checksumHeader]!!), - ) + val checksumAlgorithm = checksumHeader + .removePrefix("x-amz-checksum-") + .toHashFunctionOrThrow() + + when (val bodyType = context.protocolResponse.body) { + is HttpBody.Bytes -> { + logger.debug { "Validating checksum before deserialization from $checksumHeader" } + + checksumAlgorithm.update( + context.protocolResponse.body.readAll() ?: byteArrayOf(), + ) + val sdkChecksumValue = checksumAlgorithm.digest().encodeBase64String() + + validateAndThrow( + serviceChecksumValue, + sdkChecksumValue, + ) + + return context.protocolResponse + } + is HttpBody.SourceContent, is HttpBody.ChannelContent -> { + logger.debug { "Validating checksum after deserialization from $checksumHeader" } + + return context.protocolResponse.copy( + body = context.protocolResponse.body + .toHashingBody(checksumAlgorithm, context.protocolResponse.body.contentLength) + .toChecksumValidatingBody(serviceChecksumValue), + ) + } + else -> throw IllegalStateException("HTTP body type '$bodyType' is not supported for flexible checksums.") + } } + + /** + * Additional check on the checksum itself to see if it should be validated + */ + public open fun ignoreChecksum( + checksum: String, + context: ProtocolResponseInterceptorContext, + ): Boolean = false } public class ChecksumMismatchException(message: String?) : ClientException(message) diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptor.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptor.kt new file mode 100644 index 0000000000..f422de7fa7 --- /dev/null +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptor.kt @@ -0,0 +1,98 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.smithy.kotlin.runtime.http.interceptors + +import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext +import aws.smithy.kotlin.runtime.hashing.* +import aws.smithy.kotlin.runtime.http.* +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.request.header +import aws.smithy.kotlin.runtime.http.request.toBuilder +import aws.smithy.kotlin.runtime.io.rollingHash +import aws.smithy.kotlin.runtime.telemetry.logging.logger +import aws.smithy.kotlin.runtime.text.encoding.encodeBase64String +import kotlin.coroutines.coroutineContext + +/** + * Handles checksum request calculation from the `httpChecksumRequired` trait. + */ +@InternalApi +public class HttpChecksumRequiredInterceptor : CachingChecksumInterceptor() { + override suspend fun modifyBeforeSigning(context: ProtocolRequestInterceptorContext): HttpRequest { + if (context.defaultChecksumAlgorithmName == null) { + // Don't calculate checksum + return context.protocolRequest + } + + val checksumAlgorithmName = context.defaultChecksumAlgorithmName!! + val checksumAlgorithm = checksumAlgorithmName.toHashFunctionOrThrow() + + return if (context.protocolRequest.body.isEligibleForAwsChunkedStreaming) { + coroutineContext.logger().debug { + "Calculating checksum during transmission using: ${checksumAlgorithm::class.simpleName}" + } + calculateAwsChunkedStreamingChecksum(context, checksumAlgorithm) + } else { + if (context.protocolRequest.body is HttpBody.Bytes) { + // Cache checksum + super.modifyBeforeSigning(context) + } else { + val checksum = calculateHttpChecksumRequiredChecksum(context) + applyHttpChecksumRequiredChecksum(context, checksum) + } + } + } + + /** + * Calculates a checksum based on the requirements and limitations of [HttpChecksumRequiredInterceptor] + */ + private suspend fun calculateHttpChecksumRequiredChecksum( + context: ProtocolRequestInterceptorContext, + ): String { + val req = context.protocolRequest.toBuilder() + val checksumAlgorithmName = context.defaultChecksumAlgorithmName!! + val checksumAlgorithm = checksumAlgorithmName.toHashFunctionOrThrow() + + return when { + req.body.contentLength == null && !req.body.isOneShot -> { + val channel = req.body.toSdkByteReadChannel()!! + channel.rollingHash(checksumAlgorithm).encodeBase64String() + } + else -> { + val bodyBytes = req.body.readAll() ?: byteArrayOf() + if (req.body.isOneShot) req.body = bodyBytes.toHttpBody() + bodyBytes.hash(checksumAlgorithm).encodeBase64String() + } + } + } + + public override suspend fun calculateChecksum( + context: ProtocolRequestInterceptorContext, + ): String? = + calculateHttpChecksumRequiredChecksum(context) + + /** + * Applies a checksum based on the requirements and limitations of [HttpChecksumRequiredInterceptor] + */ + private fun applyHttpChecksumRequiredChecksum( + context: ProtocolRequestInterceptorContext, + checksum: String, + ): HttpRequest { + val checksumAlgorithmName = context.defaultChecksumAlgorithmName!! + val checksumHeader = checksumAlgorithmName.resolveChecksumAlgorithmHeaderName() + val request = context.protocolRequest.toBuilder() + + request.header(checksumHeader, checksum) + return request.build() + } + + public override fun applyChecksum( + context: ProtocolRequestInterceptorContext, + checksum: String, + ): HttpRequest = + applyHttpChecksumRequiredChecksum(context, checksum) +} diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptor.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptor.kt deleted file mode 100644 index cbe6bcabe2..0000000000 --- a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptor.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.http.interceptors - -import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext -import aws.smithy.kotlin.runtime.hashing.md5 -import aws.smithy.kotlin.runtime.http.HttpBody -import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.http.request.header -import aws.smithy.kotlin.runtime.http.request.toBuilder -import aws.smithy.kotlin.runtime.text.encoding.encodeBase64String - -/** - * Set the `Content-MD5` header based on the current payload - * See: - * - https://awslabs.github.io/smithy/1.0/spec/core/behavior-traits.html#httpchecksumrequired-trait - * - https://datatracker.ietf.org/doc/html/rfc1864.html - * @param block An optional function which parses the input [I] to determine if the `Content-MD5` header should be set. - * If not provided, the default behavior will set the header. - */ -@InternalApi -public class Md5ChecksumInterceptor( - private val block: ((input: I) -> Boolean)? = null, -) : AbstractChecksumInterceptor() { - override suspend fun modifyBeforeSigning(context: ProtocolRequestInterceptorContext): HttpRequest { - @Suppress("UNCHECKED_CAST") - val input = context.request as I - - val injectMd5Header = block?.invoke(input) ?: true - if (!injectMd5Header) { - return context.protocolRequest - } - - return super.modifyBeforeSigning(context) - } - - public override suspend fun calculateChecksum(context: ProtocolRequestInterceptorContext): String? = - when (val body = context.protocolRequest.body) { - is HttpBody.Bytes -> body.bytes().md5().encodeBase64String() - else -> null - } - - public override fun applyChecksum(context: ProtocolRequestInterceptorContext, checksum: String): HttpRequest { - val req = context.protocolRequest.toBuilder() - if (!req.headers.contains("Content-MD5")) { - req.header("Content-MD5", checksum) - } - return req.build() - } -} diff --git a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/operation/HttpOperationContext.kt b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/operation/HttpOperationContext.kt index 524614a667..56444dca98 100644 --- a/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/operation/HttpOperationContext.kt +++ b/runtime/protocol/http-client/common/src/aws/smithy/kotlin/runtime/http/operation/HttpOperationContext.kt @@ -66,9 +66,9 @@ public object HttpOperationContext { public val ClockSkewApproximateSigningTime: AttributeKey = AttributeKey("aws.smithy.kotlin#ClockSkewApproximateSigningTime") /** - * The name of the algorithm to be used for computing a checksum of the request. + * The name of the default algorithm to be used for computing a checksum of the request. */ - public val ChecksumAlgorithm: AttributeKey = AttributeKey("aws.smithy.kotlin#ChecksumAlgorithm") + public val DefaultChecksumAlgorithm: AttributeKey = AttributeKey("aws.smithy.kotlin#DefaultChecksumAlgorithm") } internal val ExecutionContext.operationMetrics: OperationMetrics diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt similarity index 88% rename from runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptorTest.kt rename to runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt index 3de8e557c2..cee1db7766 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/AbstractChecksumInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt @@ -6,7 +6,7 @@ import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.SdkHttpClient -import aws.smithy.kotlin.runtime.http.interceptors.AbstractChecksumInterceptor +import aws.smithy.kotlin.runtime.http.interceptors.CachingChecksumInterceptor import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext import aws.smithy.kotlin.runtime.http.operation.newTestOperation import aws.smithy.kotlin.runtime.http.operation.roundTrip @@ -21,7 +21,7 @@ import kotlin.test.assertEquals private val CHECKSUM_TEST_HEADER = "x-amz-kotlin-sdk-test-checksum-header" -class AbstractChecksumInterceptorTest { +class CachingChecksumInterceptorTest { private val client = SdkHttpClient(TestEngine()) @Test @@ -33,7 +33,7 @@ class AbstractChecksumInterceptorTest { val op = newTestOperation(req, Unit) - op.interceptors.add(TestAbstractChecksumInterceptor(expectedChecksumValue)) + op.interceptors.add(TestCachingChecksumInterceptor(expectedChecksumValue)) op.roundTrip(client, Unit) val call = op.context.attributes[HttpOperationContext.HttpCallList].first() @@ -49,16 +49,16 @@ class AbstractChecksumInterceptorTest { val op = newTestOperation(req, Unit) - op.interceptors.add(TestAbstractChecksumInterceptor(expectedChecksumValue)) + op.interceptors.add(TestCachingChecksumInterceptor(expectedChecksumValue)) // the TestAbstractChecksumInterceptor will throw an exception if calculateChecksum is called more than once. op.roundTrip(client, Unit) op.roundTrip(client, Unit) } - inner class TestAbstractChecksumInterceptor( + inner class TestCachingChecksumInterceptor( private val expectedChecksum: String?, - ) : AbstractChecksumInterceptor() { + ) : CachingChecksumInterceptor() { private var alreadyCalculatedChecksum = false override suspend fun calculateChecksum(context: ProtocolRequestInterceptorContext): String? { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt index c4c85de66b..37e5054865 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt @@ -6,6 +6,7 @@ package aws.smithy.kotlin.runtime.http.interceptors import aws.smithy.kotlin.runtime.ClientException +import aws.smithy.kotlin.runtime.client.config.RequestHttpChecksumConfig import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.hashing.toHashFunction import aws.smithy.kotlin.runtime.http.* @@ -41,9 +42,11 @@ class FlexibleChecksumsRequestInterceptorTest { val op = newTestOperation(req, Unit) op.interceptors.add( - FlexibleChecksumsRequestInterceptor { - checksumAlgorithmName - }, + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = checksumAlgorithmName, + requestChecksumRequired = true, + requestChecksumCalculation = RequestHttpChecksumConfig.WHEN_SUPPORTED, + ), ) op.roundTrip(client, Unit) @@ -65,10 +68,13 @@ class FlexibleChecksumsRequestInterceptorTest { val op = newTestOperation(req, Unit) + op.context.attributes[HttpOperationContext.DefaultChecksumAlgorithm] = "CRC32" op.interceptors.add( - FlexibleChecksumsRequestInterceptor { - checksumAlgorithmName - }, + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = checksumAlgorithmName, + requestChecksumRequired = true, + requestChecksumCalculation = RequestHttpChecksumConfig.WHEN_SUPPORTED, + ), ) op.roundTrip(client, Unit) @@ -87,13 +93,14 @@ class FlexibleChecksumsRequestInterceptorTest { val op = newTestOperation(req, Unit) - op.interceptors.add( - FlexibleChecksumsRequestInterceptor { - unsupportedChecksumAlgorithmName - }, - ) - assertFailsWith { + op.interceptors.add( + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = unsupportedChecksumAlgorithmName, + requestChecksumRequired = true, + requestChecksumCalculation = RequestHttpChecksumConfig.WHEN_SUPPORTED, + ), + ) op.roundTrip(client, Unit) } } @@ -115,9 +122,11 @@ class FlexibleChecksumsRequestInterceptorTest { val op = newTestOperation(req, Unit) op.interceptors.add( - FlexibleChecksumsRequestInterceptor { - checksumAlgorithmName - }, + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = checksumAlgorithmName, + requestChecksumRequired = true, + requestChecksumCalculation = RequestHttpChecksumConfig.WHEN_SUPPORTED, + ), ) op.roundTrip(client, Unit) @@ -126,23 +135,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(0, call.request.headers.getNumChecksumHeaders()) } - @Test - fun itSetsChecksumHeaderViaExecutionContext() = runTest { - checksums.forEach { (checksumAlgorithmName, expectedChecksumValue) -> - val req = HttpRequestBuilder().apply { - body = HttpBody.fromBytes("bar".encodeToByteArray()) - } - - val op = newTestOperation(req, Unit) - op.context[HttpOperationContext.ChecksumAlgorithm] = checksumAlgorithmName - op.interceptors.add(FlexibleChecksumsRequestInterceptor()) - - op.roundTrip(client, Unit) - val call = op.context.attributes[HttpOperationContext.HttpCallList].first() - assertEquals(expectedChecksumValue, call.request.headers["x-amz-checksum-$checksumAlgorithmName"]) - } - } - @Test fun testCompletingSource() = runTest { val hashFunctionName = "crc32" @@ -151,7 +143,7 @@ class FlexibleChecksumsRequestInterceptorTest { val source = byteArray.source() val completableDeferred = CompletableDeferred() val hashingSource = HashingSource(hashFunctionName.toHashFunction()!!, source) - val completingSource = FlexibleChecksumsRequestInterceptor.CompletingSource(completableDeferred, hashingSource) + val completingSource = CompletingSource(completableDeferred, hashingSource) completingSource.read(SdkBuffer(), 1L) assertFalse(completableDeferred.isCompleted) // deferred value should not be completed because the source is not exhausted @@ -172,7 +164,8 @@ class FlexibleChecksumsRequestInterceptorTest { val channel = SdkByteReadChannel(byteArray) val completableDeferred = CompletableDeferred() val hashingChannel = HashingByteReadChannel(hashFunctionName.toHashFunction()!!, channel) - val completingChannel = FlexibleChecksumsRequestInterceptor.CompletingByteReadChannel(completableDeferred, hashingChannel) + val completingChannel = + CompletingByteReadChannel(completableDeferred, hashingChannel) completingChannel.read(SdkBuffer(), 1L) assertFalse(completableDeferred.isCompleted) @@ -198,9 +191,11 @@ class FlexibleChecksumsRequestInterceptorTest { val op = newTestOperation(req, Unit) op.interceptors.add( - FlexibleChecksumsRequestInterceptor { - checksumAlgorithmName - }, + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = checksumAlgorithmName, + requestChecksumRequired = true, + requestChecksumCalculation = RequestHttpChecksumConfig.WHEN_SUPPORTED, + ), ) op.roundTrip(client, Unit) @@ -210,5 +205,51 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(precalculatedChecksumValue, call.request.headers["x-amz-checksum-sha256"]) } + @Test + fun testDefaultChecksumConfiguration() = runTest { + setOf( + DefaultChecksumTest(true, RequestHttpChecksumConfig.WHEN_SUPPORTED, true), + DefaultChecksumTest(true, RequestHttpChecksumConfig.WHEN_REQUIRED, true), + DefaultChecksumTest(false, RequestHttpChecksumConfig.WHEN_SUPPORTED, true), + DefaultChecksumTest(false, RequestHttpChecksumConfig.WHEN_REQUIRED, false), + ).forEach { runDefaultChecksumTest(it) } + } + private fun Headers.getNumChecksumHeaders(): Int = entries().count { (name, _) -> name.startsWith("x-amz-checksum-") } + + private data class DefaultChecksumTest( + val requestChecksumRequired: Boolean, + val requestChecksumCalculation: RequestHttpChecksumConfig, + val defaultChecksumExpected: Boolean, + ) + + private fun runDefaultChecksumTest( + testCase: DefaultChecksumTest, + ) = runTest { + val defaultChecksumAlgorithmName = "crc32" + val expectedChecksumValue = "WdqXHQ==" + + val req = HttpRequestBuilder().apply { + body = HttpBody.fromBytes("bar".encodeToByteArray()) + } + + val op = newTestOperation(req, Unit) + + op.context.attributes[HttpOperationContext.DefaultChecksumAlgorithm] = "CRC32" + op.interceptors.add( + FlexibleChecksumsRequestInterceptor( + requestChecksumAlgorithm = null, // See if default checksum is applied + requestChecksumRequired = testCase.requestChecksumRequired, + requestChecksumCalculation = testCase.requestChecksumCalculation, + ), + ) + + op.roundTrip(client, Unit) + val call = op.context.attributes[HttpOperationContext.HttpCallList].first() + + when (testCase.defaultChecksumExpected) { + true -> assertEquals(expectedChecksumValue, call.request.headers["x-amz-checksum-$defaultChecksumAlgorithmName"]) + false -> assertFalse { call.request.headers.contains("x-amz-checksum-$defaultChecksumAlgorithmName") } + } + } } diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt index 2c04ee680d..e465499ad1 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.http.interceptors +import aws.smithy.kotlin.runtime.client.config.ResponseHttpChecksumConfig import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.HttpCall @@ -73,9 +74,10 @@ class FlexibleChecksumsResponseInterceptorTest { val op = newTestOperation(req) op.interceptors.add( - FlexibleChecksumsResponseInterceptor { - true - }, + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = true, + responseChecksumValidation = ResponseHttpChecksumConfig.WHEN_SUPPORTED, + ), ) val responseChecksumHeaderName = "x-amz-checksum-$checksumAlgorithmName" @@ -99,9 +101,10 @@ class FlexibleChecksumsResponseInterceptorTest { val op = newTestOperation(req) op.interceptors.add( - FlexibleChecksumsResponseInterceptor { - true - }, + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = true, + responseChecksumValidation = ResponseHttpChecksumConfig.WHEN_SUPPORTED, + ), ) val responseChecksumHeaderName = "x-amz-checksum-$checksumAlgorithmName" @@ -126,9 +129,10 @@ class FlexibleChecksumsResponseInterceptorTest { val op = newTestOperation(req) op.interceptors.add( - FlexibleChecksumsResponseInterceptor { - true - }, + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = true, + responseChecksumValidation = ResponseHttpChecksumConfig.WHEN_SUPPORTED, + ), ) val responseHeaders = Headers { @@ -150,9 +154,10 @@ class FlexibleChecksumsResponseInterceptorTest { val op = newTestOperation(req) op.interceptors.add( - FlexibleChecksumsResponseInterceptor { - true - }, + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = true, + responseChecksumValidation = ResponseHttpChecksumConfig.WHEN_SUPPORTED, + ), ) val responseHeaders = Headers { @@ -170,9 +175,10 @@ class FlexibleChecksumsResponseInterceptorTest { val op = newTestOperation(req) op.interceptors.add( - FlexibleChecksumsResponseInterceptor { - false - }, + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = false, + responseChecksumValidation = ResponseHttpChecksumConfig.WHEN_REQUIRED, + ), ) val responseChecksumHeaderName = "x-amz-checksum-crc32" @@ -188,4 +194,52 @@ class FlexibleChecksumsResponseInterceptorTest { assertNull(op.context.getOrNull(ChecksumHeaderValidated)) } + + @Test + fun testResponseValidationConfiguration() = runTest { + setOf( + ResponseChecksumValidationTest(true, ResponseHttpChecksumConfig.WHEN_SUPPORTED, true), + ResponseChecksumValidationTest(true, ResponseHttpChecksumConfig.WHEN_REQUIRED, true), + ResponseChecksumValidationTest(false, ResponseHttpChecksumConfig.WHEN_SUPPORTED, true), + ResponseChecksumValidationTest(false, ResponseHttpChecksumConfig.WHEN_REQUIRED, false), + ).forEach { runResponseChecksumValidationTest(it) } + } + + private data class ResponseChecksumValidationTest( + val responseValidationRequired: Boolean, + val responseChecksumValidation: ResponseHttpChecksumConfig, + val checksumValidationExpected: Boolean, + ) + + private fun runResponseChecksumValidationTest( + testCase: ResponseChecksumValidationTest, + ) = runTest { + checksums.forEach { (checksumAlgorithmName, expectedChecksum) -> + val req = HttpRequestBuilder() + val op = newTestOperation(req) + + op.interceptors.add( + FlexibleChecksumsResponseInterceptor( + responseValidationRequired = testCase.responseValidationRequired, + responseChecksumValidation = testCase.responseChecksumValidation, + ), + ) + + val responseChecksumHeaderName = "x-amz-checksum-$checksumAlgorithmName" + + val responseHeaders = Headers { + append(responseChecksumHeaderName, expectedChecksum) + } + + val client = getMockClient(response, responseHeaders) + + val output = op.roundTrip(client, TestInput("input")) + output.body.readAll() + + when (testCase.checksumValidationExpected) { + true -> assertEquals(responseChecksumHeaderName, op.context[ChecksumHeaderValidated]) + false -> assertNull(op.context.getOrNull(ChecksumHeaderValidated)) + } + } + } } diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt similarity index 62% rename from runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptorTest.kt rename to runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt index 109d2e3e8d..df2cf49f0e 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/Md5ChecksumInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt @@ -6,6 +6,7 @@ package aws.smithy.kotlin.runtime.http.interceptors import aws.smithy.kotlin.runtime.collections.get +import aws.smithy.kotlin.runtime.hashing.Crc32 import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext @@ -14,12 +15,13 @@ import aws.smithy.kotlin.runtime.http.operation.roundTrip import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.httptest.TestEngine import aws.smithy.kotlin.runtime.io.SdkByteReadChannel +import aws.smithy.kotlin.runtime.text.encoding.encodeBase64String import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull -class Md5ChecksumInterceptorTest { +class HttpChecksumRequiredInterceptorTest { private val client = SdkHttpClient(TestEngine()) @Test @@ -29,10 +31,9 @@ class Md5ChecksumInterceptorTest { } val op = newTestOperation(req, Unit) + op.context.attributes[HttpOperationContext.DefaultChecksumAlgorithm] = "MD5" op.interceptors.add( - Md5ChecksumInterceptor { - true - }, + HttpChecksumRequiredInterceptor(), ) val expected = "RG22oBSZFmabBbkzVGRi4w==" @@ -42,7 +43,30 @@ class Md5ChecksumInterceptorTest { } @Test - fun itOnlySetsHeaderForBytesContent() = runTest { + fun itSetsContentCrc32Header() = runTest { + val testBody = "bar".encodeToByteArray() + + val req = HttpRequestBuilder().apply { + body = HttpBody.fromBytes(testBody) + } + val op = newTestOperation(req, Unit) + + op.context.attributes[HttpOperationContext.DefaultChecksumAlgorithm] = "CRC32" + op.interceptors.add( + HttpChecksumRequiredInterceptor(), + ) + + val crc32 = Crc32() + crc32.update(testBody) + val expected = crc32.digest().encodeBase64String() + + op.roundTrip(client, Unit) + val call = op.context.attributes[HttpOperationContext.HttpCallList].first() + assertEquals(expected, call.request.headers["x-amz-checksum-crc32"]) + } + + @Test + fun itSetsHeaderForNonBytesContent() = runTest { val req = HttpRequestBuilder().apply { body = object : HttpBody.ChannelContent() { override fun readFrom(): SdkByteReadChannel = SdkByteReadChannel("fooey".encodeToByteArray()) @@ -50,15 +74,15 @@ class Md5ChecksumInterceptorTest { } val op = newTestOperation(req, Unit) + op.context.attributes[HttpOperationContext.DefaultChecksumAlgorithm] = "MD5" op.interceptors.add( - Md5ChecksumInterceptor { - true - }, + HttpChecksumRequiredInterceptor(), ) + val expected = "vJLiaOiNxaxdWfYAYzdzFQ==" op.roundTrip(client, Unit) val call = op.context.attributes[HttpOperationContext.HttpCallList].first() - assertNull(call.request.headers["Content-MD5"]) + assertEquals(expected, call.request.headers["Content-MD5"]) } @Test @@ -69,9 +93,7 @@ class Md5ChecksumInterceptorTest { val op = newTestOperation(req, Unit) op.interceptors.add( - Md5ChecksumInterceptor { - false // interceptor disabled - }, + HttpChecksumRequiredInterceptor(), ) op.roundTrip(client, Unit) diff --git a/runtime/protocol/http/api/http.api b/runtime/protocol/http/api/http.api index 3f4c29414f..fb338e64d9 100644 --- a/runtime/protocol/http/api/http.api +++ b/runtime/protocol/http/api/http.api @@ -1,3 +1,19 @@ +public final class aws/smithy/kotlin/runtime/http/CompletingByteReadChannel : aws/smithy/kotlin/runtime/io/SdkByteReadChannel { + public fun (Lkotlinx/coroutines/CompletableDeferred;Laws/smithy/kotlin/runtime/io/HashingByteReadChannel;)V + public fun cancel (Ljava/lang/Throwable;)Z + public fun getAvailableForRead ()I + public fun getClosedCause ()Ljava/lang/Throwable; + public fun isClosedForRead ()Z + public fun isClosedForWrite ()Z + public fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class aws/smithy/kotlin/runtime/http/CompletingSource : aws/smithy/kotlin/runtime/io/SdkSource { + public fun (Lkotlinx/coroutines/CompletableDeferred;Laws/smithy/kotlin/runtime/io/HashingSource;)V + public fun close ()V + public fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;J)J +} + public abstract interface class aws/smithy/kotlin/runtime/http/DeferredHeaders : aws/smithy/kotlin/runtime/collections/ValuesMap { public static final field Companion Laws/smithy/kotlin/runtime/http/DeferredHeaders$Companion; } @@ -86,8 +102,10 @@ public abstract class aws/smithy/kotlin/runtime/http/HttpBody$SourceContent : aw } public final class aws/smithy/kotlin/runtime/http/HttpBodyKt { + public static final fun isEligibleForAwsChunkedStreaming (Laws/smithy/kotlin/runtime/http/HttpBody;)Z public static final fun readAll (Laws/smithy/kotlin/runtime/http/HttpBody;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun toByteStream (Laws/smithy/kotlin/runtime/http/HttpBody;)Laws/smithy/kotlin/runtime/content/ByteStream; + public static final fun toCompletingBody (Laws/smithy/kotlin/runtime/http/HttpBody;Lkotlinx/coroutines/CompletableDeferred;)Laws/smithy/kotlin/runtime/http/HttpBody; public static final fun toHashingBody (Laws/smithy/kotlin/runtime/http/HttpBody;Laws/smithy/kotlin/runtime/hashing/HashFunction;Ljava/lang/Long;)Laws/smithy/kotlin/runtime/http/HttpBody; public static final fun toHttpBody (Laws/smithy/kotlin/runtime/content/ByteStream;)Laws/smithy/kotlin/runtime/http/HttpBody; public static final fun toHttpBody (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Ljava/lang/Long;)Laws/smithy/kotlin/runtime/http/HttpBody; diff --git a/runtime/protocol/http/common/src/aws/smithy/kotlin/runtime/http/HttpBody.kt b/runtime/protocol/http/common/src/aws/smithy/kotlin/runtime/http/HttpBody.kt index b86c5c2199..a12626a656 100644 --- a/runtime/protocol/http/common/src/aws/smithy/kotlin/runtime/http/HttpBody.kt +++ b/runtime/protocol/http/common/src/aws/smithy/kotlin/runtime/http/HttpBody.kt @@ -10,6 +10,8 @@ import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.hashing.HashFunction import aws.smithy.kotlin.runtime.http.content.ByteArrayContent import aws.smithy.kotlin.runtime.io.* +import aws.smithy.kotlin.runtime.text.encoding.encodeBase64String +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope /** @@ -191,6 +193,49 @@ public fun HttpBody.toHashingBody( else -> throw ClientException("HttpBody type is not supported") } +/** + * Convert an [HttpBody] with an underlying [HashingSource] or [HashingByteReadChannel] + * to a [CompletingSource] or [CompletingByteReadChannel], respectively. + */ +@InternalApi +public fun HttpBody.toCompletingBody(deferred: CompletableDeferred): HttpBody = when (this) { + is HttpBody.SourceContent -> CompletingSource(deferred, (readFrom() as HashingSource)).toHttpBody(contentLength) + is HttpBody.ChannelContent -> CompletingByteReadChannel(deferred, (readFrom() as HashingByteReadChannel)).toHttpBody(contentLength) + else -> throw ClientException("HttpBody type is not supported") +} + +/** + * An [SdkSource] which uses the underlying [hashingSource]'s checksum to complete a [CompletableDeferred] value. + */ +@InternalApi +public class CompletingSource( + private val deferred: CompletableDeferred, + private val hashingSource: HashingSource, +) : SdkSource by hashingSource { + override fun read(sink: SdkBuffer, limit: Long): Long = hashingSource.read(sink, limit) + .also { + if (it == -1L) { + deferred.complete(hashingSource.digest().encodeBase64String()) + } + } +} + +/** + * An [SdkByteReadChannel] which uses the underlying [hashingChannel]'s checksum to complete a [CompletableDeferred] value. + */ +@InternalApi +public class CompletingByteReadChannel( + private val deferred: CompletableDeferred, + private val hashingChannel: HashingByteReadChannel, +) : SdkByteReadChannel by hashingChannel { + override suspend fun read(sink: SdkBuffer, limit: Long): Long = hashingChannel.read(sink, limit) + .also { + if (it == -1L) { + deferred.complete(hashingChannel.digest().encodeBase64String()) + } + } +} + // FIXME - replace/move to reading to SdkBuffer instead /** * Consume the [HttpBody] and pull the entire contents into memory as a [ByteArray]. @@ -244,3 +289,10 @@ public fun HttpBody.toSdkByteReadChannel(scope: CoroutineScope? = null): SdkByte is HttpBody.ChannelContent -> body.readFrom() is HttpBody.SourceContent -> body.readFrom().toSdkByteReadChannel(scope) } + +// FIXME this duplicates the logic from aws-signing-common +@InternalApi +public val HttpBody.isEligibleForAwsChunkedStreaming: Boolean + get() = (this is HttpBody.SourceContent || this is HttpBody.ChannelContent) && + contentLength != null && + (isOneShot || contentLength!! > 65536 * 16) diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 8c42034110..6d39c3b417 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -104,6 +104,14 @@ public final class aws/smithy/kotlin/runtime/businessmetrics/BusinessMetricsUtil public final class aws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric : java/lang/Enum, aws/smithy/kotlin/runtime/businessmetrics/BusinessMetric { public static final field ACCOUNT_ID_BASED_ENDPOINT Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_CRC32 Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_CRC32C Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_SHA1 Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_SHA256 Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; + public static final field FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; public static final field GZIP_REQUEST_COMPRESSION Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; public static final field PAGINATOR Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; public static final field PROTOCOL_RPC_V2_CBOR Laws/smithy/kotlin/runtime/businessmetrics/SmithyBusinessMetric; @@ -699,7 +707,12 @@ public final class aws/smithy/kotlin/runtime/hashing/HashFunction$DefaultImpls { public final class aws/smithy/kotlin/runtime/hashing/HashFunctionKt { public static final fun hash ([BLaws/smithy/kotlin/runtime/hashing/HashFunction;)[B public static final fun hash ([BLkotlin/jvm/functions/Function0;)[B + public static final fun isSupportedForFlexibleChecksums (Laws/smithy/kotlin/runtime/hashing/HashFunction;)Z + public static final fun resolveChecksumAlgorithmHeaderName (Laws/smithy/kotlin/runtime/hashing/HashFunction;)Ljava/lang/String; + public static final fun resolveChecksumAlgorithmHeaderName (Ljava/lang/String;)Ljava/lang/String; + public static final fun toBusinessMetric (Laws/smithy/kotlin/runtime/hashing/HashFunction;)Laws/smithy/kotlin/runtime/businessmetrics/BusinessMetric; public static final fun toHashFunction (Ljava/lang/String;)Laws/smithy/kotlin/runtime/hashing/HashFunction; + public static final fun toHashFunctionOrThrow (Ljava/lang/String;)Laws/smithy/kotlin/runtime/hashing/HashFunction; } public final class aws/smithy/kotlin/runtime/hashing/HmacKt { @@ -958,6 +971,8 @@ public final class aws/smithy/kotlin/runtime/io/SdkByteReadChannelKt { public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/io/SdkBuffer;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun readRemaining (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/io/SdkBuffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun readToBuffer (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun rollingHash (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/hashing/HashFunction;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun rollingHash$default (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;Laws/smithy/kotlin/runtime/hashing/HashFunction;JLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun writeAll (Laws/smithy/kotlin/runtime/io/SdkByteWriteChannel;Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/businessmetrics/BusinessMetricsUtils.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/businessmetrics/BusinessMetricsUtils.kt index fa9c41652a..0600752a6e 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/businessmetrics/BusinessMetricsUtils.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/businessmetrics/BusinessMetricsUtils.kt @@ -90,6 +90,14 @@ public enum class SmithyBusinessMetric(public override val identifier: String) : SERVICE_ENDPOINT_OVERRIDE("N"), ACCOUNT_ID_BASED_ENDPOINT("O"), SIGV4A_SIGNING("S"), + FLEXIBLE_CHECKSUMS_REQ_CRC32("U"), + FLEXIBLE_CHECKSUMS_REQ_CRC32C("V"), + FLEXIBLE_CHECKSUMS_REQ_SHA1("X"), + FLEXIBLE_CHECKSUMS_REQ_SHA256("Y"), + FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED("Z"), + FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED("a"), + FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED("b"), + FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED("c"), ; override fun toString(): String = identifier diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/HashFunction.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/HashFunction.kt index 50684d61d8..2ad5b6785f 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/HashFunction.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/hashing/HashFunction.kt @@ -4,7 +4,10 @@ */ package aws.smithy.kotlin.runtime.hashing +import aws.smithy.kotlin.runtime.ClientException import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.businessmetrics.BusinessMetric +import aws.smithy.kotlin.runtime.businessmetrics.SmithyBusinessMetric /** * A cryptographic hash function (algorithm) @@ -70,3 +73,55 @@ public fun String.toHashFunction(): HashFunction? = when (this.lowercase()) { "md5" -> Md5() else -> null } + +/** + * @return The [HashFunction] which is represented by this string, or an exception if none match. + */ +@InternalApi +public fun String.toHashFunctionOrThrow(): HashFunction = + toHashFunction() ?: throw ClientException("Checksum algorithm is not supported: $this") + +/** + * @return If the [HashFunction] is supported by flexible checksums + */ +@InternalApi +public val HashFunction.isSupportedForFlexibleChecksums: Boolean + get() = when (this) { + is Crc32, is Crc32c, is Sha1, is Sha256 -> true + else -> false + } + +/** + * @return The checksum algorithm header used depending on the checksum algorithm name + */ +@InternalApi +public fun String.resolveChecksumAlgorithmHeaderName(): String = + this.toHashFunctionOrThrow().resolveChecksumAlgorithmHeaderName() + +/** + * @return The checksum algorithm header used depending on the checksum algorithm + */ +@InternalApi +public fun HashFunction.resolveChecksumAlgorithmHeaderName(): String { + val prefix = "x-amz-checksum-" + return when (this) { + is Crc32 -> prefix + "crc32" + is Crc32c -> prefix + "crc32c" + is Sha1 -> prefix + "sha1" + is Sha256 -> prefix + "sha256" + is Md5 -> "Content-MD5" + else -> throw ClientException("Checksum algorithm is not supported: ${this::class.simpleName}") + } +} + +/** + * Maps supported hash functions to business metrics. + */ +@InternalApi +public fun HashFunction.toBusinessMetric(): BusinessMetric = when (this) { + is Crc32 -> SmithyBusinessMetric.FLEXIBLE_CHECKSUMS_REQ_CRC32 + is Crc32c -> SmithyBusinessMetric.FLEXIBLE_CHECKSUMS_REQ_CRC32C + is Sha1 -> SmithyBusinessMetric.FLEXIBLE_CHECKSUMS_REQ_SHA1 + is Sha256 -> SmithyBusinessMetric.FLEXIBLE_CHECKSUMS_REQ_SHA256 + else -> throw IllegalStateException("Checksum was calculated using an unsupported hash function: ${this::class.simpleName}") +} diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index 87d5a531da..a50259e240 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt @@ -4,6 +4,8 @@ */ package aws.smithy.kotlin.runtime.io +import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.hashing.HashFunction import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.withContext @@ -131,3 +133,17 @@ public suspend fun SdkByteWriteChannel.writeAll(source: SdkSource): Long = withC } totalRead } + +/** + * Compute the rolling hash of an [SdkByteReadChannel] using [hashFunction], reading up-to [bufferSize] bytes into memory + * @return a ByteArray of the hash function's digest + */ +@InternalApi +public suspend fun SdkByteReadChannel.rollingHash(hashFunction: HashFunction, bufferSize: Long = 8192): ByteArray { + val buffer = SdkBuffer() + while (!isClosedForRead) { + read(buffer, bufferSize) + hashFunction.update(buffer.readToByteArray()) + } + return hashFunction.digest() +} diff --git a/runtime/smithy-client/api/smithy-client.api b/runtime/smithy-client/api/smithy-client.api index c2a9190009..b6132b26b8 100644 --- a/runtime/smithy-client/api/smithy-client.api +++ b/runtime/smithy-client/api/smithy-client.api @@ -235,6 +235,18 @@ public final class aws/smithy/kotlin/runtime/client/config/CompressionClientConf public abstract interface annotation class aws/smithy/kotlin/runtime/client/config/CompressionClientConfigDsl : java/lang/annotation/Annotation { } +public abstract interface class aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig { + public abstract fun getRequestChecksumCalculation ()Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; + public abstract fun getResponseChecksumValidation ()Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; +} + +public abstract interface class aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig$Builder { + public abstract fun getRequestChecksumCalculation ()Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; + public abstract fun getResponseChecksumValidation ()Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; + public abstract fun setRequestChecksumCalculation (Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig;)V + public abstract fun setResponseChecksumValidation (Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig;)V +} + public final class aws/smithy/kotlin/runtime/client/config/RequestCompressionConfig { public static final field Companion Laws/smithy/kotlin/runtime/client/config/RequestCompressionConfig$Companion; public fun (Laws/smithy/kotlin/runtime/client/config/RequestCompressionConfig$Builder;)V @@ -258,6 +270,22 @@ public final class aws/smithy/kotlin/runtime/client/config/RequestCompressionCon public final fun invoke (Lkotlin/jvm/functions/Function1;)Laws/smithy/kotlin/runtime/client/config/RequestCompressionConfig; } +public final class aws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig : java/lang/Enum { + public static final field WHEN_REQUIRED Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; + public static final field WHEN_SUPPORTED Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; + public static fun values ()[Laws/smithy/kotlin/runtime/client/config/RequestHttpChecksumConfig; +} + +public final class aws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig : java/lang/Enum { + public static final field WHEN_REQUIRED Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; + public static final field WHEN_SUPPORTED Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; + public static fun values ()[Laws/smithy/kotlin/runtime/client/config/ResponseHttpChecksumConfig; +} + public final class aws/smithy/kotlin/runtime/client/config/RetryMode : java/lang/Enum { public static final field ADAPTIVE Laws/smithy/kotlin/runtime/client/config/RetryMode; public static final field LEGACY Laws/smithy/kotlin/runtime/client/config/RetryMode; diff --git a/runtime/smithy-client/common/src/aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig.kt b/runtime/smithy-client/common/src/aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig.kt new file mode 100644 index 0000000000..fbe73b860e --- /dev/null +++ b/runtime/smithy-client/common/src/aws/smithy/kotlin/runtime/client/config/HttpChecksumConfig.kt @@ -0,0 +1,63 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.smithy.kotlin.runtime.client.config + +/** + * Client config for HTTP checksums + */ +public interface HttpChecksumConfig { + /** + * Configures request checksum calculation + */ + public val requestChecksumCalculation: RequestHttpChecksumConfig? + + /** + * Configures response checksum validation + */ + public val responseChecksumValidation: ResponseHttpChecksumConfig? + + public interface Builder { + /** + * Configures request checksum calculation + */ + public var requestChecksumCalculation: RequestHttpChecksumConfig? + + /** + * Configures response checksum validation + */ + public var responseChecksumValidation: ResponseHttpChecksumConfig? + } +} + +/** + * Configuration options for enabling and managing HTTP request checksums + */ +public enum class RequestHttpChecksumConfig { + /** + * SDK will calculate checksums if the service marks them as required or if the service offers optional checksums. + */ + WHEN_SUPPORTED, + + /** + * SDK will only calculate checksums if the service marks them as required. + */ + WHEN_REQUIRED, +} + +/** + * Configuration options for enabling and managing HTTP response checksums + */ +public enum class ResponseHttpChecksumConfig { + /** + * SDK will validate checksums if the service marks them as required or if the service offers optional checksums. + */ + WHEN_SUPPORTED, + + /** + * SDK will only validate checksums if the service marks them as required. + */ + WHEN_REQUIRED, +} From 14e0958a95a86016d1845c89019a06bc9a0f879c Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Wed, 15 Jan 2025 17:58:12 +0000 Subject: [PATCH 21/65] chore: release 1.4.0 --- .changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json | 9 --------- .changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json | 6 ------ .changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json | 8 -------- CHANGELOG.md | 11 +++++++++++ gradle.properties | 4 ++-- 5 files changed, 13 insertions(+), 25 deletions(-) delete mode 100644 .changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json delete mode 100644 .changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json delete mode 100644 .changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json diff --git a/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json b/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json deleted file mode 100644 index d89da89103..0000000000 --- a/.changes/0857b6f0-0444-479f-be6b-06ef71d482a0.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "0857b6f0-0444-479f-be6b-06ef71d482a0", - "type": "feature", - "description": "⚠️ **IMPORTANT**: Add `retryStrategy` configuration option for waiters", - "issues": [ - "https://github.com/awslabs/aws-sdk-kotlin/issues/1431" - ], - "requiresMinorVersionBump": true -} \ No newline at end of file diff --git a/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json b/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json deleted file mode 100644 index 10ef502204..0000000000 --- a/.changes/1a68d0b7-00e7-45c0-88f6-95e5c39c9c61.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": "1a68d0b7-00e7-45c0-88f6-95e5c39c9c61", - "type": "misc", - "description": "⚠️ **IMPORTANT**: Upgrade to Kotlin 2.1.0", - "requiresMinorVersionBump": true -} \ No newline at end of file diff --git a/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json b/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json deleted file mode 100644 index 767e48a02e..0000000000 --- a/.changes/3456d00f-1b29-4d88-ab02-045db1b1ebce.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "3456d00f-1b29-4d88-ab02-045db1b1ebce", - "type": "bugfix", - "description": "Include more information when retry strategy halts early due to token bucket capacity errors", - "issues": [ - "awslabs/aws-sdk-kotlin#1321" - ] -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c1758b4332..c324c5e681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [1.4.0] - 01/15/2025 + +### Features +* [#1431](https://github.com/awslabs/aws-sdk-kotlin/issues/1431) ⚠️ **IMPORTANT**: Add `retryStrategy` configuration option for waiters + +### Fixes +* [#1321](https://github.com/awslabs/aws-sdk-kotlin/issues/1321) Include more information when retry strategy halts early due to token bucket capacity errors + +### Miscellaneous +* ⚠️ **IMPORTANT**: Upgrade to Kotlin 2.1.0 + ## [1.3.34] - 01/10/2025 ## [1.3.33] - 01/10/2025 diff --git a/gradle.properties b/gradle.properties index d76819491b..d0e2da8b41 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.3.35-SNAPSHOT +sdkVersion=1.4.0 # codegen -codegenVersion=0.33.35-SNAPSHOT \ No newline at end of file +codegenVersion=0.34.0 \ No newline at end of file From ed95d7b5014ba9311d4a3fff16671971fc026e36 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Wed, 15 Jan 2025 17:58:13 +0000 Subject: [PATCH 22/65] chore: bump snapshot version to 1.4.1-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index d0e2da8b41..dbe31b2197 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.4.0 +sdkVersion=1.4.1-SNAPSHOT # codegen -codegenVersion=0.34.0 \ No newline at end of file +codegenVersion=0.34.1-SNAPSHOT \ No newline at end of file From a4ace353ca9dc1517c00de345a833691c444841d Mon Sep 17 00:00:00 2001 From: Matas Date: Thu, 16 Jan 2025 11:50:34 -0500 Subject: [PATCH 23/65] fix: add 0.9.x aws-crt-kotlin transform (#1220) --- .brazil.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.brazil.json b/.brazil.json index 5a1d830abd..dbb2135d1b 100644 --- a/.brazil.json +++ b/.brazil.json @@ -8,6 +8,7 @@ "com.squareup.okio:okio-jvm:3.*": "OkioJvm-3.x", "io.opentelemetry:opentelemetry-api:1.*": "Maven-io-opentelemetry_opentelemetry-api-1.x", "org.slf4j:slf4j-api:2.*": "Maven-org-slf4j_slf4j-api-2.x", + "aws.sdk.kotlin.crt:aws-crt-kotlin:0.9.*": "AwsCrtKotlin-0.9.x", "aws.sdk.kotlin.crt:aws-crt-kotlin:0.8.*": "AwsCrtKotlin-0.8.x", "com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x" }, From 15e5f0ce2c713f3e81f75a28e90b4175891e0575 Mon Sep 17 00:00:00 2001 From: Matas Date: Thu, 16 Jan 2025 14:57:24 -0500 Subject: [PATCH 24/65] fix: Ensure `Host` header is included when signing auth tokens (#1222) --- .github/workflows/continuous-integration.yml | 2 +- gradle/libs.versions.toml | 2 +- .../kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt | 9 ++++++++- .../runtime/auth/awssigning/AuthTokenGeneratorTest.kt | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 599293cc06..ef2cc9db42 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -68,7 +68,7 @@ jobs: ./gradlew test jvmTest - name: Save Test Reports if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-reports-${{ matrix.os }} path: '**/build/reports' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6ef5b35d57..6d8724016e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ kotlin-version = "2.1.0" dokka-version = "1.9.10" -aws-kotlin-repo-tools-version = "0.4.17" +aws-kotlin-repo-tools-version = "0.4.18" # libs coroutines-version = "1.9.0" diff --git a/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt index e92ac1f72c..f80ee4fe7e 100644 --- a/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt +++ b/runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGenerator.kt @@ -6,6 +6,7 @@ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningConfig.Companion.invoke +import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.net.url.Url @@ -28,7 +29,13 @@ public class AuthTokenGenerator( private fun Url.trimScheme(): String = toString().removePrefix(scheme.protocolName).removePrefix("://") public suspend fun generateAuthToken(endpoint: Url, region: String, expiration: Duration): String { - val req = HttpRequest(HttpMethod.GET, endpoint) + val req = HttpRequest( + HttpMethod.GET, + endpoint, + headers = Headers { + append("Host", endpoint.hostAndPort) + }, + ) val config = AwsSigningConfig { credentials = credentialsProvider.resolve() diff --git a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt index 87fec1a74e..75b17fbab9 100644 --- a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt +++ b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/AuthTokenGeneratorTest.kt @@ -45,6 +45,7 @@ class AuthTokenGeneratorTest { assertContains(token, "X-Amz-Credential=signature") // test custom signer was invoked assertContains(token, "X-Amz-Expires=333") // expiration assertContains(token, "X-Amz-SigningDate=0") // clock + assertContains(token, "X-Amz-SignedHeaders=host") assertTrue(credentialsProvider.credentialsResolved) } @@ -60,6 +61,7 @@ private val TEST_SIGNER = object : AwsSigner { put("X-Amz-Credential", "signature") put("X-Amz-Expires", (config.expiresAfter?.toLong(DurationUnit.SECONDS) ?: 900).toString()) put("X-Amz-SigningDate", config.signingDate.epochSeconds.toString()) + put("X-Amz-SignedHeaders", request.headers.names().map { it.lowercase() }.joinToString()) } return AwsSigningResult(builder.build(), "signature".encodeToByteArray()) From 447ac10880ebe778471d9ad4bce97a424139550d Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Thu, 16 Jan 2025 19:59:39 +0000 Subject: [PATCH 25/65] chore: release 1.4.1 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c324c5e681..a4c4a65548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## [1.4.1] - 01/16/2025 + ## [1.4.0] - 01/15/2025 ### Features diff --git a/gradle.properties b/gradle.properties index dbe31b2197..e005c08ee2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.4.1-SNAPSHOT +sdkVersion=1.4.1 # codegen -codegenVersion=0.34.1-SNAPSHOT \ No newline at end of file +codegenVersion=0.34.1 \ No newline at end of file From 0f8db4452966822949bbe6616e3642b2063cfb63 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Thu, 16 Jan 2025 19:59:40 +0000 Subject: [PATCH 26/65] chore: bump snapshot version to 1.4.2-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e005c08ee2..df0e651ce1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.4.1 +sdkVersion=1.4.2-SNAPSHOT # codegen -codegenVersion=0.34.1 \ No newline at end of file +codegenVersion=0.34.2-SNAPSHOT \ No newline at end of file From 8b336937bb028bc3d0fcb1beafeabcf4c25fc51e Mon Sep 17 00:00:00 2001 From: Matas Date: Thu, 23 Jan 2025 14:03:54 -0500 Subject: [PATCH 27/65] fix: address various failing protocol tests (#1223) --- .../model/error-correction-tests.smithy | 12 ++++---- .../core/AwsHttpBindingProtocolGenerator.kt | 8 +---- .../codegen/core/KotlinSymbolProvider.kt | 30 ++++++++++++------- .../codegen/rendering/StructureGenerator.kt | 1 + .../protocol/HttpStringValuesMapSerializer.kt | 19 ++---------- .../kotlin/codegen/core/SymbolProviderTest.kt | 2 +- .../HttpBindingProtocolGeneratorTest.kt | 8 ++--- .../HttpStringValuesMapSerializerTest.kt | 16 +++++----- gradle/libs.versions.toml | 2 +- .../kotlin/runtime/text/encoding/Base64.kt | 11 +++++-- .../runtime/text/encoding/Base64Test.kt | 28 ++++++++++++----- 11 files changed, 74 insertions(+), 63 deletions(-) diff --git a/codegen/protocol-tests/model/error-correction-tests.smithy b/codegen/protocol-tests/model/error-correction-tests.smithy index 201ffc877f..4f246e1b99 100644 --- a/codegen/protocol-tests/model/error-correction-tests.smithy +++ b/codegen/protocol-tests/model/error-correction-tests.smithy @@ -39,8 +39,9 @@ operation SayHelloXml { output: TestOutput, errors: [Error] } structure TestOutputDocument with [TestStruct] { innerField: Nested, - // FIXME: This trait fails smithy validator - // @required + + // Note: This shape _should_ be @required, but causes Smithy httpResponseTests validation to fail. + // We expect `document` to be deserialized as `null` and enforce @required using a runtime check, but Smithy validator doesn't recognize / allow this. document: Document } structure TestOutput with [TestStruct] { innerField: Nested } @@ -65,8 +66,8 @@ structure TestStruct { @required nestedListValue: NestedList - // FIXME: This trait fails smithy validator - // @required + // Note: This shape _should_ be @required, but causes Smithy httpResponseTests validation to fail. + // We expect `nested` to be deserialized as `null` and enforce @required using a runtime check, but Smithy validator doesn't recognize / allow this. nested: Nested @required @@ -97,8 +98,7 @@ union MyUnion { } structure Nested { - // FIXME: This trait fails smithy validator - // @required + @required a: String } diff --git a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt index 6e5834f7d1..bd41afcade 100644 --- a/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt +++ b/codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/core/AwsHttpBindingProtocolGenerator.kt @@ -40,13 +40,7 @@ abstract class AwsHttpBindingProtocolGenerator : HttpBindingProtocolGenerator() // val targetedTest = TestMemberDelta(setOf("RestJsonComplexErrorWithNoMessage"), TestContainmentMode.RUN_TESTS) val ignoredTests = TestMemberDelta( - setOf( - "AwsJson10ClientErrorCorrectsWithDefaultValuesWhenServerFailsToSerializeRequiredValues", - "RestJsonNullAndEmptyHeaders", - "NullAndEmptyHeaders", - "RpcV2CborClientPopulatesDefaultsValuesWhenMissingInResponse", - "RpcV2CborClientPopulatesDefaultValuesInInput", - ), + setOf(), ) val requestTestBuilder = HttpProtocolUnitTestRequestGenerator.Builder() diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinSymbolProvider.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinSymbolProvider.kt index e6dbd0dca1..f35570dfeb 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinSymbolProvider.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinSymbolProvider.kt @@ -193,7 +193,7 @@ class KotlinSymbolProvider(private val model: Model, private val settings: Kotli } else { // only use @default if type is `T` shape.getTrait()?.let { - defaultValue(it.getDefaultValue(targetShape)) + setDefaultValue(it, targetShape) } } } @@ -219,9 +219,10 @@ class KotlinSymbolProvider(private val model: Model, private val settings: Kotli } } - private fun DefaultTrait.getDefaultValue(targetShape: Shape): String? { - val node = toNode() - return when { + private fun Symbol.Builder.setDefaultValue(defaultTrait: DefaultTrait, targetShape: Shape) { + val node = defaultTrait.toNode() + + val defaultValue = when { node.toString() == "null" -> null // Check if target is an enum before treating the default like a regular number/string @@ -235,13 +236,20 @@ class KotlinSymbolProvider(private val model: Model, private val settings: Kotli "${enumSymbol.fullName}.fromValue($arg)" } - targetShape.isBlobShape && targetShape.isStreaming -> - node - .toString() - .takeUnless { it.isEmpty() } - ?.let { "ByteStream.fromString(${it.dq()})" } + targetShape.isBlobShape -> { + addReferences(RuntimeTypes.Core.Text.Encoding.decodeBase64) - targetShape.isBlobShape -> "${node.toString().dq()}.encodeToByteArray()" + if (targetShape.isStreaming) { + node.toString() + .takeUnless { it.isEmpty() } + ?.let { + addReferences(RuntimeTypes.Core.Content.ByteStream) + "ByteStream.fromString(${it.dq()}.decodeBase64())" + } + } else { + "${node.toString().dq()}.decodeBase64().encodeToByteArray()" + } + } targetShape.isDocumentShape -> getDefaultValueForDocument(node) targetShape.isTimestampShape -> getDefaultValueForTimestamp(node.asNumberNode().get()) @@ -252,6 +260,8 @@ class KotlinSymbolProvider(private val model: Model, private val settings: Kotli node.isStringNode -> node.toString().dq() else -> node.toString() } + + defaultValue(defaultValue) } private fun getDefaultValueForTimestamp(node: NumberNode): String { diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/StructureGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/StructureGenerator.kt index c34eb5ab9d..5d90f376d2 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/StructureGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/StructureGenerator.kt @@ -248,6 +248,7 @@ class StructureGenerator( } else { memberSymbol } + write("public var #L: #E", memberName, builderMemberSymbol) } write("") diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializer.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializer.kt index 932b2a796a..5dfc519962 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializer.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializer.kt @@ -157,9 +157,8 @@ class HttpStringValuesMapSerializer( val paramName = binding.locationName // addAll collection parameter 2 val param2 = if (mapFnContents.isEmpty()) "input.$memberName" else "input.$memberName.map { $mapFnContents }" - val nullCheck = if (memberSymbol.isNullable) "?" else "" writer.write( - "if (input.#L$nullCheck.isNotEmpty() == true) #L(#S, #L)", + "if (input.#L != null) #L(#S, #L)", memberName, binding.location.addAllFnName, paramName, @@ -174,8 +173,7 @@ class HttpStringValuesMapSerializer( val paramName = binding.locationName val memberSymbol = symbolProvider.toSymbol(binding.member) - // NOTE: query parameters are allowed to be empty, whereas headers should omit empty string - // values from serde + // NOTE: query parameters are allowed to be empty if ((location == HttpBinding.Location.QUERY || location == HttpBinding.Location.HEADER) && binding.member.hasTrait()) { // Call the idempotency token function if no supplied value. writer.addImport(RuntimeTypes.SmithyClient.IdempotencyTokenProviderExt) @@ -185,18 +183,7 @@ class HttpStringValuesMapSerializer( paramName, ) } else { - val nullCheck = - if (location == HttpBinding.Location.QUERY || - memberTarget.hasTrait< - @Suppress("DEPRECATION") - software.amazon.smithy.model.traits.EnumTrait, - >() - ) { - if (memberSymbol.isNullable) "input.$memberName != null" else "" - } else { - val nullCheck = if (memberSymbol.isNullable) "?" else "" - "input.$memberName$nullCheck.isNotEmpty() == true" - } + val nullCheck = if (memberSymbol.isNullable) "input.$memberName != null" else "" val cond = defaultCheck(binding.member) ?: nullCheck diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/core/SymbolProviderTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/core/SymbolProviderTest.kt index 0cc4d2cb14..bb90fbc0fb 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/core/SymbolProviderTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/core/SymbolProviderTest.kt @@ -182,7 +182,7 @@ class SymbolProviderTest { "double,2.71828,2.71828", "byte,10,10.toByte()", "string,\"hello\",\"hello\"", - "blob,\"abcdefg\",\"abcdefg\".encodeToByteArray()", + "blob,\"abcdefg\",\"abcdefg\".decodeBase64().encodeToByteArray()", "boolean,true,true", "bigInteger,5,5", "bigDecimal,9.0123456789,9.0123456789", diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGeneratorTest.kt index 3c15579dab..6f8040e7dc 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGeneratorTest.kt @@ -57,8 +57,8 @@ internal class SmokeTestOperationSerializer: HttpSerializer.NonStreaming( + "YQ" to "a", + "Yg" to "b", + "YWI" to "ab", + "YWJj" to "abc", + "SGVsbG8gd29ybGQ" to "Hello world", + ) + + inputs.forEach { (encoded, expected) -> + val actual = encoded.decodeBase64() + assertEquals(expected, actual) + } + } } From 03badf913813df5481b330e9eeff80bcea5586ec Mon Sep 17 00:00:00 2001 From: Matas Date: Thu, 23 Jan 2025 14:04:09 -0500 Subject: [PATCH 28/65] misc: re-enable `kotlinWarningsAsErrors=true` (#1224) --- .github/workflows/continuous-integration.yml | 3 +-- .../kotlin/runtime/http/engine/okhttp/MetricsInterceptor.kt | 2 +- .../smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt | 2 ++ .../smithy/kotlin/runtime/http/engine/okhttp/OkHttpUtils.kt | 2 +- .../smithy/kotlin/runtime/http/engine/okhttp4/OkHttp4Engine.kt | 2 +- .../common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt | 3 +-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index ef2cc9db42..d47020ea5d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -62,8 +62,7 @@ jobs: - name: Test shell: bash run: | - # FIXME K2. Re-enable warnings as errors after this warning is removed: https://youtrack.jetbrains.com/issue/KT-68532 - # echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties + echo "kotlinWarningsAsErrors=true" >> $GITHUB_WORKSPACE/local.properties ./gradlew apiCheck ./gradlew test jvmTest - name: Save Test Reports diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/MetricsInterceptor.kt b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/MetricsInterceptor.kt index 0ea8ae5e66..8047b870c3 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/MetricsInterceptor.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/MetricsInterceptor.kt @@ -30,7 +30,7 @@ public object MetricsInterceptor : Interceptor { } val originalResponse = chain.proceed(request) - val response = if (originalResponse.body == null || originalResponse.body?.contentLength() == 0L) { + val response = if (originalResponse.body.contentLength() == 0L) { originalResponse } else { originalResponse.newBuilder() diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt index 061c22a13d..a20387d0a0 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt @@ -15,6 +15,7 @@ import aws.smithy.kotlin.runtime.net.TlsVersion import aws.smithy.kotlin.runtime.operation.ExecutionContext import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.time.fromEpochMilliseconds +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.job import okhttp3.* import okhttp3.ConnectionPool @@ -47,6 +48,7 @@ public class OkHttpEngine( private val connectionIdleMonitor = config.connectionIdlePollingInterval?.let { ConnectionIdleMonitor(it) } private val client = config.buildClientWithConnectionListener(metrics, connectionIdleMonitor) + @OptIn(ExperimentalCoroutinesApi::class) override suspend fun roundTrip(context: ExecutionContext, request: HttpRequest): HttpCall { val callContext = callContext() diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpUtils.kt b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpUtils.kt index c287228fdf..181ed400c3 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpUtils.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpUtils.kt @@ -104,7 +104,7 @@ public fun Headers.toOkHttpHeaders(): OkHttpHeaders = OkHttpHeaders.Builder().al @InternalApi public fun OkHttpResponse.toSdkResponse(): HttpResponse { val sdkHeaders = OkHttpHeadersAdapter(headers) - val httpBody = if (body == null || body!!.contentLength() == 0L) { + val httpBody = if (body.contentLength() == 0L) { HttpBody.Empty } else { object : HttpBody.SourceContent() { diff --git a/runtime/protocol/http-client-engines/http-client-engine-okhttp4/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp4/OkHttp4Engine.kt b/runtime/protocol/http-client-engines/http-client-engine-okhttp4/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp4/OkHttp4Engine.kt index ff59823201..026bbd942c 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-okhttp4/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp4/OkHttp4Engine.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-okhttp4/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp4/OkHttp4Engine.kt @@ -99,7 +99,7 @@ private suspend fun Call.executeAsync(): Response = call: Call, response: Response, ) { - continuation.resume(response) { + continuation.resume(response) { cause, _, _ -> response.closeQuietly() } } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt index 9b691a79a2..c8437b2b33 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/JMESPath.kt @@ -62,8 +62,7 @@ public fun Any?.type(): String = when (this) { is List<*>, is Array<*> -> "array" is Number -> "number" is Any -> "object" - null -> "null" - else -> throw Exception("Undetected type for: $this") + else -> "null" } // Collection `flattenIfPossible` functions From 9f44cdbd82adc1dd30eaf4bc4290b61eee09bbd4 Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:33:23 -0800 Subject: [PATCH 29/65] fix: ignore hop-by-hop headers when signing requests (#1227) --- .../b0646077-397d-48a8-94f2-ea2db40b1dea.json | 5 +++++ gradle/libs.versions.toml | 2 +- .../runtime/auth/awssigning/Canonicalizer.kt | 17 ++++++++++++++--- .../auth/awssigning/DefaultCanonicalizerTest.kt | 9 +++++++-- .../runtime/http/auth/AwsHttpSignerTestBase.kt | 16 +++++++++------- 5 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 .changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json diff --git a/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json b/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json new file mode 100644 index 0000000000..96e13a4a82 --- /dev/null +++ b/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json @@ -0,0 +1,5 @@ +{ + "id": "b0646077-397d-48a8-94f2-ea2db40b1dea", + "type": "bugfix", + "description": "Ignore hop-by-hop headers when signing requests" +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31f5d17afa..bdc0c8e98b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ okio-version = "3.9.1" otel-version = "1.45.0" slf4j-version = "2.0.16" slf4j-v1x-version = "1.7.36" -crt-kotlin-version = "0.9.0" +crt-kotlin-version = "0.9.1" micrometer-version = "1.14.2" binary-compatibility-validator-version = "0.16.3" diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt index 69d742de79..c7c47fe5a2 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt @@ -58,16 +58,27 @@ internal interface Canonicalizer { ): CanonicalRequest } -// Taken from https://github.com/awslabs/aws-c-auth/blob/dd505b55fd46222834f35c6e54165d8cbebbfaaa/source/aws_signing.c#L118-L156 private val skipHeaders = setOf( - "connection", "expect", // https://github.com/awslabs/aws-sdk-kotlin/issues/862 + + // Taken from https://github.com/awslabs/aws-c-auth/blob/274a1d21330731cc51bb742794adc70ada5f4380/source/aws_signing.c#L121-L164 "sec-websocket-key", "sec-websocket-protocol", "sec-websocket-version", - "upgrade", "user-agent", "x-amzn-trace-id", + + // Taken from https://datatracker.ietf.org/doc/html/rfc2616#section-13.5.1. These are "hop-by-hop" headers which may + // be modified/removed by intervening proxies or caches. These are unsafe to sign because if they change they render + // the signature invalid. + "connection", + "keep-alive", + "proxy-authenticate", + "proxy-authorization", + "te", + "trailers", + "transfer-encoding", + "upgrade", ) internal class DefaultCanonicalizer(private val sha256Supplier: HashSupplier = ::Sha256) : Canonicalizer { diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt index 7fc20ddb83..2dfbdf48e1 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt @@ -6,8 +6,12 @@ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.tests.DEFAULT_TEST_CREDENTIALS -import aws.smithy.kotlin.runtime.http.* -import aws.smithy.kotlin.runtime.http.request.* +import aws.smithy.kotlin.runtime.http.Headers +import aws.smithy.kotlin.runtime.http.HttpBody +import aws.smithy.kotlin.runtime.http.HttpMethod +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.request.headers +import aws.smithy.kotlin.runtime.http.request.url import aws.smithy.kotlin.runtime.net.Host import aws.smithy.kotlin.runtime.net.url.Url import aws.smithy.kotlin.runtime.time.Instant @@ -136,6 +140,7 @@ class DefaultCanonicalizerTest { // These should not be signed set("Expect", "100-continue") set("X-Amzn-Trace-Id", "qux") + set("Transfer-Encoding", "chunked") } body = HttpBody.Empty } diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 2ce308df8f..7d10b35e14 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -12,7 +12,9 @@ import aws.smithy.kotlin.runtime.auth.awssigning.DefaultAwsSigner import aws.smithy.kotlin.runtime.auth.awssigning.internal.AWS_CHUNKED_THRESHOLD import aws.smithy.kotlin.runtime.collections.Attributes import aws.smithy.kotlin.runtime.collections.get -import aws.smithy.kotlin.runtime.http.* +import aws.smithy.kotlin.runtime.http.HttpBody +import aws.smithy.kotlin.runtime.http.HttpMethod +import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.operation.* import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder @@ -149,8 +151,8 @@ public abstract class AwsHttpSignerTestBase( val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) val expectedDate = "20201016T195600Z" val expectedSig = "AWS4-HMAC-SHA256 Credential=AKID/20201016/us-east-1/demo/aws4_request, " + - "SignedHeaders=content-encoding;host;transfer-encoding;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + - "Signature=ac341b9b248a0b23d2fcd9f7e805f4eb0b8a1b789bb23a8ec6adc6c48dd084ad" + "SignedHeaders=content-encoding;host;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + + "Signature=ef06c95647c4d2daa6c89ac90274f1c780777cba8eaab772df6d8009def3eb8f" val signed = getSignedRequest(op) assertEquals(expectedDate, signed.headers["X-Amz-Date"]) @@ -162,8 +164,8 @@ public abstract class AwsHttpSignerTestBase( val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) val expectedDate = "20201016T195600Z" val expectedSig = "AWS4-HMAC-SHA256 Credential=AKID/20201016/us-east-1/demo/aws4_request, " + - "SignedHeaders=content-encoding;host;transfer-encoding;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + - "Signature=ac341b9b248a0b23d2fcd9f7e805f4eb0b8a1b789bb23a8ec6adc6c48dd084ad" + "SignedHeaders=content-encoding;host;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + + "Signature=ef06c95647c4d2daa6c89ac90274f1c780777cba8eaab772df6d8009def3eb8f" val signed = getSignedRequest(op) assertEquals(expectedDate, signed.headers["X-Amz-Date"]) @@ -176,8 +178,8 @@ public abstract class AwsHttpSignerTestBase( val expectedDate = "20201016T195600Z" // should have same signature as testSignAwsChunkedStreamNonReplayable(), except for the hash, since the body is different val expectedSig = "AWS4-HMAC-SHA256 Credential=AKID/20201016/us-east-1/demo/aws4_request, " + - "SignedHeaders=content-encoding;host;transfer-encoding;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + - "Signature=3f0277123c9ed8a8858f793886a0ac0fcb457bc54401ffc22d470f373397cff0" + "SignedHeaders=content-encoding;host;x-amz-archive-description;x-amz-date;x-amz-decoded-content-length;x-amz-security-token, " + + "Signature=a902702b57057a864bf41cc22ee846a1b7bd047e22784367ec6a459f6791330e" val signed = getSignedRequest(op) assertEquals(expectedDate, signed.headers["X-Amz-Date"]) From 97ac44792df8016d27988bcde1d112c69b46ab29 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Tue, 28 Jan 2025 18:35:54 +0000 Subject: [PATCH 30/65] chore: release 1.4.2 --- .changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json | 5 ----- CHANGELOG.md | 5 +++++ gradle.properties | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 .changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json diff --git a/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json b/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json deleted file mode 100644 index 96e13a4a82..0000000000 --- a/.changes/b0646077-397d-48a8-94f2-ea2db40b1dea.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "b0646077-397d-48a8-94f2-ea2db40b1dea", - "type": "bugfix", - "description": "Ignore hop-by-hop headers when signing requests" -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c4a65548..2e925d0943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [1.4.2] - 01/28/2025 + +### Fixes +* Ignore hop-by-hop headers when signing requests + ## [1.4.1] - 01/16/2025 ## [1.4.0] - 01/15/2025 diff --git a/gradle.properties b/gradle.properties index df0e651ce1..1b11779bb6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.4.2-SNAPSHOT +sdkVersion=1.4.2 # codegen -codegenVersion=0.34.2-SNAPSHOT \ No newline at end of file +codegenVersion=0.34.2 \ No newline at end of file From b7e50e3c66a073e5696b363aae29823284beef09 Mon Sep 17 00:00:00 2001 From: aws-sdk-kotlin-ci Date: Tue, 28 Jan 2025 18:35:55 +0000 Subject: [PATCH 31/65] chore: bump snapshot version to 1.4.3-SNAPSHOT --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1b11779bb6..9e53dbcaf0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ kotlinx.atomicfu.enableNativeIrTransformation=false org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G # SDK -sdkVersion=1.4.2 +sdkVersion=1.4.3-SNAPSHOT # codegen -codegenVersion=0.34.2 \ No newline at end of file +codegenVersion=0.34.3-SNAPSHOT \ No newline at end of file From e6357f92abd84dd2276a0f9ba27204be610d0068 Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Thu, 30 Jan 2025 16:34:10 -0500 Subject: [PATCH 32/65] misc: add telemetry configuration to DefaultAwsSigner (#1226) * add telemetry provider configuration * lint * address pr reviews * add changelog --- .../d3ce7511-6fb2-4435-8f46-db724551b384.json | 5 ++++ .../api/aws-signing-default.api | 8 ++++++ .../auth/awssigning/DefaultAwsSigner.kt | 27 ++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 .changes/d3ce7511-6fb2-4435-8f46-db724551b384.json diff --git a/.changes/d3ce7511-6fb2-4435-8f46-db724551b384.json b/.changes/d3ce7511-6fb2-4435-8f46-db724551b384.json new file mode 100644 index 0000000000..aa89d9167e --- /dev/null +++ b/.changes/d3ce7511-6fb2-4435-8f46-db724551b384.json @@ -0,0 +1,5 @@ +{ + "id": "d3ce7511-6fb2-4435-8f46-db724551b384", + "type": "misc", + "description": "Add telemetry provider configuration to `DefaultAwsSigner`" +} \ No newline at end of file diff --git a/runtime/auth/aws-signing-default/api/aws-signing-default.api b/runtime/auth/aws-signing-default/api/aws-signing-default.api index 3b9535c403..e00e6d829a 100644 --- a/runtime/auth/aws-signing-default/api/aws-signing-default.api +++ b/runtime/auth/aws-signing-default/api/aws-signing-default.api @@ -1,4 +1,12 @@ +public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerBuilder { + public fun ()V + public final fun build ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; + public final fun getTelemetryProvider ()Laws/smithy/kotlin/runtime/telemetry/TelemetryProvider; + public final fun setTelemetryProvider (Laws/smithy/kotlin/runtime/telemetry/TelemetryProvider;)V +} + public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerKt { + public static final fun DefaultAwsSigner (Lkotlin/jvm/functions/Function1;)Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; public static final fun getDefaultAwsSigner ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; } diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt index df613d31b0..791d8fce0a 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt @@ -4,8 +4,10 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning +import aws.smithy.kotlin.runtime.ExperimentalApi import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider import aws.smithy.kotlin.runtime.telemetry.logging.logger import aws.smithy.kotlin.runtime.time.TimestampFormat import kotlin.coroutines.coroutineContext @@ -13,13 +15,30 @@ import kotlin.coroutines.coroutineContext /** The default implementation of [AwsSigner] */ public val DefaultAwsSigner: AwsSigner = DefaultAwsSignerImpl() +/** Creates a customized instance of [AwsSigner] */ +@Suppress("ktlint:standard:function-naming") +public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = + DefaultAwsSignerBuilder().apply(block).build() + +/** A builder class for creating instances of [AwsSigner] using the default implementation */ +public class DefaultAwsSignerBuilder { + public var telemetryProvider: TelemetryProvider? = null + + public fun build(): AwsSigner = DefaultAwsSignerImpl( + telemetryProvider = telemetryProvider, + ) +} + +@OptIn(ExperimentalApi::class) internal class DefaultAwsSignerImpl( private val canonicalizer: Canonicalizer = Canonicalizer.Default, private val signatureCalculator: SignatureCalculator = SignatureCalculator.Default, private val requestMutator: RequestMutator = RequestMutator.Default, + private val telemetryProvider: TelemetryProvider? = null, ) : AwsSigner { override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { - val logger = coroutineContext.logger() + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() // TODO: implement SigV4a if (config.algorithm != AwsSigningAlgorithm.SIGV4) { @@ -52,7 +71,8 @@ internal class DefaultAwsSignerImpl( prevSignature: ByteArray, config: AwsSigningConfig, ): AwsSigningResult { - val logger = coroutineContext.logger() + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() val stringToSign = signatureCalculator.chunkStringToSign(chunkBody, prevSignature, config) logger.trace { "Chunk string to sign:\n$stringToSign" } @@ -70,7 +90,8 @@ internal class DefaultAwsSignerImpl( prevSignature: ByteArray, config: AwsSigningConfig, ): AwsSigningResult { - val logger = coroutineContext.logger() + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() // FIXME - can we share canonicalization code more than we are..., also this reduce is inefficient. // canonicalize the headers From 6d4f3b9ffd0fbf8b78fc04a40b267a857f1eeb8a Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 13:37:20 -0500 Subject: [PATCH 33/65] Unignore tests which pass now --- .../kotlin/runtime/collections/ReadThroughCacheTest.kt | 3 --- .../aws/smithy/kotlin/runtime/content/BigDecimalTest.kt | 4 ---- .../aws/smithy/kotlin/runtime/content/BigIntegerTest.kt | 7 ------- .../smithy/kotlin/runtime/content/ByteStreamFlowTest.kt | 4 ---- .../test/aws/smithy/kotlin/runtime/time/ManualClockTest.kt | 2 -- .../test/aws/smithy/kotlin/runtime/time/ParseEpochTest.kt | 2 -- .../test/aws/smithy/kotlin/runtime/util/CachedValueTest.kt | 7 ------- 7 files changed, 29 deletions(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/ReadThroughCacheTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/ReadThroughCacheTest.kt index 0769c3049b..4d85ece15f 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/ReadThroughCacheTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/ReadThroughCacheTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.collections -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.time.ManualClock import aws.smithy.kotlin.runtime.util.ExpiringValue import kotlinx.coroutines.test.runTest @@ -14,7 +13,6 @@ import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds class ReadThroughCacheTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadThrough() = runTest { val clock = ManualClock() @@ -38,7 +36,6 @@ class ReadThroughCacheTest { assertEquals(3, cache.get("b") { uncachedValue() }) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSweep() = runTest { val clock = ManualClock() diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigDecimalTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigDecimalTest.kt index d5d1fbbcca..dcb828146c 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigDecimalTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigDecimalTest.kt @@ -4,13 +4,11 @@ */ package aws.smithy.kotlin.runtime.content -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFails class BigDecimalTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBigDecimal() { val reallyPreciseNumberString = "0.340282366920938463463374607431768211456" // 128 bits of magnitude @@ -18,13 +16,11 @@ class BigDecimalTest { assertEquals(reallyPreciseNumberString, reallyPreciseNumber.toPlainString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBadBigDecimal() { assertFails { BigDecimal("1234567890.1234567890foo") } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEquals() { val value = "0.340282366920938463463374607431768211456" diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt index 8991a60ca8..be78e6c3d8 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/BigIntegerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.content -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.text.encoding.decodeHexBytes import kotlin.test.Test import kotlin.test.assertContentEquals @@ -12,7 +11,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFails class BigIntegerTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBigInteger() { val reallyBigNumberString = "340282366920938463463374607431768211456" // 128-bit number @@ -20,20 +18,17 @@ class BigIntegerTest { assertEquals(reallyBigNumberString, reallyBigNumber.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBadBigInteger() { assertFails { BigInteger("1234567890foo1234567890") } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEquals() { val value = "340282366920938463463374607431768211456" assertEquals(BigInteger(value), BigInteger(value)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testPlusOperator() { // Map of an expected value to a pair of two values that should sum to get that expected value @@ -52,7 +47,6 @@ class BigIntegerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testMinusOperator() { // Map of an expected value to a pair of two values that should subtract to get that expected value @@ -71,7 +65,6 @@ class BigIntegerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testByteOperations() { // Map of hexadecimal encoding of a big integer to the expected string representation of that big integer diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/ByteStreamFlowTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/ByteStreamFlowTest.kt index 1ddbc8e195..d4568a882c 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/ByteStreamFlowTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/content/ByteStreamFlowTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.content -import aws.smithy.kotlin.runtime.IgnoreNative import io.kotest.matchers.string.shouldContain import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel @@ -19,7 +18,6 @@ class ByteStreamChannelSourceFlowTest : ByteStreamFlowTest(ByteStreamFactory.SDK abstract class ByteStreamFlowTest( private val factory: ByteStreamFactory, ) { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testToFlowWithSizeHint() = runTest { val data = "a korf is a tiger".repeat(1024).encodeToByteArray() @@ -59,7 +57,6 @@ abstract class ByteStreamFlowTest( testByteArray(3278), ) - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testFlowToByteStreamReadAll() = runTest { val flow = data.asFlow() @@ -140,7 +137,6 @@ abstract class ByteStreamFlowTest( ch.closedCause?.message.shouldContain("scope cancelled") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testChannelCancellation() = runTest { // cancelling the channel should cancel the scope (via write failing) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ManualClockTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ManualClockTest.kt index d9430b9284..0a4f50d4a7 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ManualClockTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ManualClockTest.kt @@ -5,14 +5,12 @@ package aws.smithy.kotlin.runtime.time -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertEquals import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds class ManualClockTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testAdvance() { val epoch = 1634413920L diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ParseEpochTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ParseEpochTest.kt index 736ae2a60a..8aba9c6b36 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ParseEpochTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/ParseEpochTest.kt @@ -4,12 +4,10 @@ */ package aws.smithy.kotlin.runtime.time -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertEquals class ParseEpochTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itParsesEpochTimestamps() { val tests = listOf( diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/CachedValueTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/CachedValueTest.kt index 6a4f7fa07e..5a9897bb55 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/CachedValueTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/CachedValueTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.util -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.time.ManualClock import kotlinx.coroutines.* @@ -16,7 +15,6 @@ import kotlin.test.* import kotlin.time.Duration.Companion.seconds class CachedValueTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNull() = runTest { val epoch = Instant.fromEpochSeconds(0) @@ -27,7 +25,6 @@ class CachedValueTest { assertNull(value.get()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testExpiration() = runTest { val epoch = Instant.fromEpochSeconds(0) @@ -44,7 +41,6 @@ class CachedValueTest { assertNull(value.get()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testExpirationBuffer() = runTest { val epoch = Instant.fromEpochSeconds(0) @@ -61,7 +57,6 @@ class CachedValueTest { assertNull(value.get()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testGetOrLoad() = runTest { val epoch = Instant.fromEpochSeconds(0) @@ -98,7 +93,6 @@ class CachedValueTest { assertEquals(2, count) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClose() = runTest { val epoch = Instant.fromEpochSeconds(0) @@ -113,7 +107,6 @@ class CachedValueTest { assertFailsWith { value.get() } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun throwsAfterCloseDuringGetOrLoad() = runTest { val epoch = Instant.fromEpochSeconds(0) From 9d6857be261d650c1ce1b8145f42881d8054747d Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:22:57 -0500 Subject: [PATCH 34/65] misc: gradle mirror (#1204) --- .github/workflows/artifact-size-metrics.yml | 4 ++++ .github/workflows/continuous-integration.yml | 14 ++++++++++++++ .github/workflows/kat-transform.yml | 5 +++++ .github/workflows/lint.yml | 2 ++ gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index 0591b2b6aa..d1216099ae 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -31,6 +31,8 @@ jobs: with: role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} aws-region: us-west-2 + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Generate Artifact Size Metrics run: ./gradlew artifactSizeMetrics - name: Save Artifact Size Metrics @@ -54,6 +56,8 @@ jobs: with: role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} aws-region: us-west-2 + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Generate Artifact Size Metrics run: ./gradlew artifactSizeMetrics - name: Analyze Artifact Size Metrics diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d47020ea5d..5536a141bc 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -39,6 +39,8 @@ jobs: distribution: 'corretto' java-version: 17 cache: 'gradle' + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Test shell: bash run: | @@ -59,6 +61,8 @@ jobs: distribution: 'corretto' java-version: 17 cache: 'gradle' + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Test shell: bash run: | @@ -83,6 +87,8 @@ jobs: distribution: 'corretto' java-version: 17 cache: 'gradle' + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Test shell: bash run: | @@ -110,6 +116,14 @@ jobs: # smithy-kotlin is checked out as a sibling dir which will automatically make it an included build path: 'aws-sdk-kotlin' repository: 'awslabs/aws-sdk-kotlin' + - name: Configure Gradle - smithy-kotlin + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: ./smithy-kotlin + - name: Configure Gradle - aws-sdk-kotlin + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: ./aws-sdk-kotlin - name: Configure JDK uses: actions/setup-java@v3 with: diff --git a/.github/workflows/kat-transform.yml b/.github/workflows/kat-transform.yml index 938e936ef9..bcf6c933c1 100644 --- a/.github/workflows/kat-transform.yml +++ b/.github/workflows/kat-transform.yml @@ -35,6 +35,11 @@ jobs: role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} aws-region: us-west-2 + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: ./smithy-kotlin + - name: Setup kat uses: awslabs/aws-kotlin-repo-tools/.github/actions/setup-kat@main diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e95b98aded..809b2bc451 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,6 +21,8 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v2 + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - name: Lint ${{ env.PACKAGE_NAME }} run: | ./gradlew ktlint diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3499ded5c1..dace2bff9b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From ab66141bff70c094b7505537cb0f881fb95c673c Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 16:34:20 -0500 Subject: [PATCH 35/65] Ignore flaky test --- .../test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt b/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt index 63faeb120c..99cd58b75c 100644 --- a/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt @@ -16,6 +16,7 @@ import kotlin.time.Duration.Companion.milliseconds class AsyncStressTest : AbstractEngineTest() { + @Ignore // FIXME Flaky test on JVM: aws.smithy.kotlin.runtime.http.HttpException: java.io.IOException: unexpected end of stream on http://127.0.0.1:8082/...; HttpErrorCode(CONNECTION_CLOSED) @Test fun testConcurrentRequests() = testEngines { // https://github.com/awslabs/aws-sdk-kotlin/issues/170 From c082cde2cf3a4599e0bd4d04aec01f316da6aab3 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 16:40:50 -0500 Subject: [PATCH 36/65] Unignore more tests --- .../awscredentials/CachedCredentialsProviderTest.kt | 8 -------- .../kotlin/runtime/auth/awssigning/PresignerTest.kt | 3 --- .../auth/awssigning/DefaultCanonicalizerTest.kt | 7 ------- .../auth/awssigning/DefaultRequestMutatorTest.kt | 2 -- .../auth/awssigning/DefaultSignatureCalculatorTest.kt | 5 ----- .../tests/AwsChunkedByteReadChannelTestBase.kt | 2 -- .../auth/awssigning/tests/AwsChunkedTestBase.kt | 10 ---------- .../auth/awssigning/tests/BasicSigningTestBase.kt | 5 ----- .../awsprotocol/eventstream/EventStreamSigningTest.kt | 3 --- 9 files changed, 45 deletions(-) diff --git a/runtime/auth/aws-credentials/common/test/aws/smithy/kotlin/runtime/auth/awscredentials/CachedCredentialsProviderTest.kt b/runtime/auth/aws-credentials/common/test/aws/smithy/kotlin/runtime/auth/awscredentials/CachedCredentialsProviderTest.kt index 15a5ba1adf..6eb9b0d034 100644 --- a/runtime/auth/aws-credentials/common/test/aws/smithy/kotlin/runtime/auth/awscredentials/CachedCredentialsProviderTest.kt +++ b/runtime/auth/aws-credentials/common/test/aws/smithy/kotlin/runtime/auth/awscredentials/CachedCredentialsProviderTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awscredentials -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.Attributes import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.time.ManualClock @@ -37,7 +36,6 @@ class CachedCredentialsProviderTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testLoadFirstCall() = runTest { // explicit expiration @@ -52,7 +50,6 @@ class CachedCredentialsProviderTest { assertEquals(1, source.callCount) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testDefaultExpiration() = runTest { // expiration should come from the cached provider @@ -65,7 +62,6 @@ class CachedCredentialsProviderTest { assertEquals(1, source.callCount) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReloadExpiredCredentials() = runTest { val source = TestCredentialsProvider(expiration = testExpiration) @@ -81,7 +77,6 @@ class CachedCredentialsProviderTest { assertEquals(2, source.callCount) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRefreshBufferWindow() = runTest { val source = TestCredentialsProvider(expiration = testExpiration) @@ -103,7 +98,6 @@ class CachedCredentialsProviderTest { assertEquals(2, source.callCount) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testLoadFailed() = runTest { val source = object : CredentialsProvider { @@ -126,7 +120,6 @@ class CachedCredentialsProviderTest { provider.resolve() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testItThrowsOnGetCredentialsAfterClose() = runTest { val source = TestCredentialsProvider(expiration = testExpiration) @@ -144,7 +137,6 @@ class CachedCredentialsProviderTest { assertEquals(1, source.callCount) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testCachedConvenienceFunction() = runTest { val source = TestCredentialsProvider(expiration = testExpiration) diff --git a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/PresignerTest.kt b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/PresignerTest.kt index 3f6e4eb5de..ec7a9d4ec7 100644 --- a/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/PresignerTest.kt +++ b/runtime/auth/aws-signing-common/common/test/aws/smithy/kotlin/runtime/auth/awssigning/PresignerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.client.endpoints.Endpoint @@ -25,14 +24,12 @@ import kotlin.test.assertTrue class PresignerTest { // Verify that custom endpoint URL schemes aren't changed. // See https://github.com/awslabs/aws-sdk-kotlin/issues/938 - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSignedUrlAllowsHttp() = testSigningUrl("http://localhost:8080/path/to/resource?foo=bar") // Verify that custom endpoint URL schemes aren't changed. // See https://github.com/awslabs/aws-sdk-kotlin/issues/938 @Test - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation fun testSignedUrlAllowsHttps() = testSigningUrl("https://localhost:8088/path/to/resource?bar=foo") private fun testSigningUrl(url: String) = runTest { diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt index 734371cb10..2dfbdf48e1 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultCanonicalizerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.tests.DEFAULT_TEST_CREDENTIALS import aws.smithy.kotlin.runtime.http.Headers @@ -23,7 +22,6 @@ import kotlin.test.assertEquals class DefaultCanonicalizerTest { // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCanonicalize() = runTest { val request = HttpRequest { @@ -84,7 +82,6 @@ class DefaultCanonicalizerTest { } // Targeted test for proper URI path escaping. See https://github.com/smithy-lang/smithy-kotlin/issues/657 - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testEscapablePath() { val uri = Url.Builder() @@ -101,7 +98,6 @@ class DefaultCanonicalizerTest { assertEquals("/2013-04-01/healthcheck/foo%253Cbar%253Ebaz%253C%252Fbar%253E", uri.canonicalPath(config)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCanonicalPath() { val config = AwsSigningConfig { @@ -117,7 +113,6 @@ class DefaultCanonicalizerTest { assertEquals("/foo/%40bar/baz%253Cqux%253Aquux", uri.canonicalPath(config)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCanonicalQueryParams() { Url.Builder().apply { @@ -132,7 +127,6 @@ class DefaultCanonicalizerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testUnsignedHeaders() = runTest { val request = HttpRequest { @@ -166,7 +160,6 @@ class DefaultCanonicalizerTest { assertEquals(expectedSignedHeaders, actual.signedHeaders) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCustomPort() = runTest { val request = HttpRequest { diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultRequestMutatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultRequestMutatorTest.kt index 7f84e8658a..7eb10ab692 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultRequestMutatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultRequestMutatorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.HttpBody @@ -16,7 +15,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class DefaultRequestMutatorTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testAppendAuthHeader() { val canonical = CanonicalRequest(baseRequest.toBuilder(), "", "action;host;x-amz-date", "") diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt index 60264a43ac..fc5c23304c 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.tests.DEFAULT_TEST_CREDENTIALS import aws.smithy.kotlin.runtime.hashing.sha256 @@ -17,7 +16,6 @@ import kotlin.test.assertEquals class DefaultSignatureCalculatorTest { // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCalculate() { val signingKey = "c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9".decodeHexBytes() @@ -34,7 +32,6 @@ class DefaultSignatureCalculatorTest { } // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSigningKey() = runTest { val config = AwsSigningConfig { @@ -50,7 +47,6 @@ class DefaultSignatureCalculatorTest { } // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testStringToSign() { val canonicalRequest = """ @@ -84,7 +80,6 @@ class DefaultSignatureCalculatorTest { private data class ChunkStringToSignTest(val signatureType: AwsSignatureType, val expectedNonSignatureHeaderHash: String) - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testChunkStringToSign() { // Test event stream signing diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt index 3374dedc42..f86ef5ba3a 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.io.* @@ -18,7 +17,6 @@ import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds abstract class AwsChunkedByteReadChannelTestBase : AwsChunkedTestBase(AwsChunkedReaderFactory.Channel) { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSlowProducerMultipleChunksPartialLast(): TestResult = runTest { val numChunks = 6 diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt index be05b88eb9..10247109ae 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.http.DeferredHeaders @@ -172,7 +171,6 @@ abstract class AwsChunkedTestBase( return length } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadNegativeOffset(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -186,7 +184,6 @@ abstract class AwsChunkedTestBase( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExactBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -220,7 +217,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExcessiveBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -250,7 +246,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadFewerBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -277,7 +272,6 @@ abstract class AwsChunkedTestBase( assertFalse(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleFullChunks(): TestResult = runTest { val numChunks = 5 @@ -325,7 +319,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleChunksLastChunkNotFull(): TestResult = runTest { val numChunks = 6 @@ -391,7 +384,6 @@ abstract class AwsChunkedTestBase( assertEquals(0, chunkSizes.last()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -442,7 +434,6 @@ abstract class AwsChunkedTestBase( assertEquals(expectedTrailerSignature.decodeToString(), trailerSignature) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunk(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -474,7 +465,6 @@ abstract class AwsChunkedTestBase( assertEquals(chunkSizes[1], 0) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunkWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index 3f4e1e1d17..2a517fc090 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.http.HttpBody @@ -56,7 +55,6 @@ public abstract class BasicSigningTestBase : HasSigner { credentials = DEFAULT_TEST_CREDENTIALS } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignRequestSigV4(): TestResult = runTest { // sanity test @@ -85,7 +83,6 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(expectedSig, result.signature.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public open fun testSignRequestSigV4Asymmetric(): TestResult = runTest { // sanity test @@ -168,7 +165,6 @@ public abstract class BasicSigningTestBase : HasSigner { return chunk } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignChunks(): TestResult = runTest { val request = createChunkedTestRequest() @@ -192,7 +188,6 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(EXPECTED_FINAL_CHUNK_SIGNATURE, finalChunkResult.signature.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSigningCopiesInput(): TestResult = runTest { // sanity test the signer doesn't mutate the input and instead copies to a new request diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/EventStreamSigningTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/EventStreamSigningTest.kt index f9333af4a9..b672571184 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/EventStreamSigningTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/EventStreamSigningTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.eventstream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.auth.awssigning.* @@ -29,7 +28,6 @@ class EventStreamSigningTest { override suspend fun resolve(attributes: Attributes) = testCredentials } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSignPayload() = runTest { val messageToSign = buildMessage { @@ -68,7 +66,6 @@ class EventStreamSigningTest { assertEquals(expected, actualSignature) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEmptyEndFrameSent() = runTest { val messageToSign = buildMessage { From 6f51c2cc49297cbd4dae75e5f44c71da0cb46949 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:19:05 -0500 Subject: [PATCH 37/65] Allow unpadded day of month --- .../src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt index 6ca75c5f87..3585a2efde 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt @@ -10,6 +10,7 @@ import kotlinx.datetime.UtcOffset import kotlinx.datetime.format.DateTimeComponents import kotlinx.datetime.format.DayOfWeekNames import kotlinx.datetime.format.MonthNames +import kotlinx.datetime.format.Padding import kotlinx.datetime.format.alternativeParsing import kotlinx.datetime.format.char import kotlinx.datetime.format.optional @@ -106,7 +107,7 @@ internal object DateTimeFormats { dayOfWeek(DayOfWeekNames.ENGLISH_ABBREVIATED) chars(", ") - dayOfMonth() + dayOfMonth(padding = Padding.NONE) char(' ') monthName(MonthNames.ENGLISH_ABBREVIATED) char(' ') From 7918a4d1af92e95bd5fa90b0efd5e08a19511688 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:19:22 -0500 Subject: [PATCH 38/65] Oct 6 2023 was a FRIDAY! --- .../common/test/ClockSkewInterceptorTest.kt | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt index 67bd5c90a4..17d33bf82a 100644 --- a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt +++ b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.awsprotocol -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.SdkBaseException import aws.smithy.kotlin.runtime.ServiceErrorMetadata import aws.smithy.kotlin.runtime.awsprotocol.ClockSkewInterceptor.Companion.CLOCK_SKEW_THRESHOLD @@ -32,50 +31,45 @@ private val POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION = "InvalidSignatureExcepti private val NOT_SKEWED_RESPONSE_CODE_DESCRIPTION = "RequestThrottled" class ClockSkewInterceptorTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testNotSkewed() { - val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") assertEquals(clientTime, serverTime) assertFalse(clientTime.isSkewed(serverTime, NOT_SKEWED_RESPONSE_CODE_DESCRIPTION)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkewedByResponseCode() { // clocks are exactly the same, but service returned skew error - val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(0.days, clientTime.until(serverTime)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkewedByTime() { - val clientTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Wed, 7 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Sat, 7 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(1.days, clientTime.until(serverTime)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNegativeSkewedByTime() { - val clientTime = Instant.fromRfc5322("Wed, 7 Oct 2023 16:20:50 -0400") - val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:20:50 -0400") + val clientTime = Instant.fromRfc5322("Sat, 7 Oct 2023 16:20:50 -0400") + val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:20:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(-1.days, clientTime.until(serverTime)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkewThreshold() { val minute = 20 var clientTime = - Instant.fromRfc5322("Wed, 6 Oct 2023 16:${minute - CLOCK_SKEW_THRESHOLD.inWholeMinutes}:50 -0400") - val serverTime = Instant.fromRfc5322("Wed, 6 Oct 2023 16:$minute:50 -0400") + Instant.fromRfc5322("Fri, 6 Oct 2023 16:${minute - CLOCK_SKEW_THRESHOLD.inWholeMinutes}:50 -0400") + val serverTime = Instant.fromRfc5322("Fri, 6 Oct 2023 16:$minute:50 -0400") assertTrue(clientTime.isSkewed(serverTime, POSSIBLE_SKEWED_RESPONSE_CODE_DESCRIPTION)) assertEquals(CLOCK_SKEW_THRESHOLD, clientTime.until(serverTime)) @@ -114,7 +108,7 @@ class ClockSkewInterceptorTest { op.interceptors.add(ClockSkewInterceptor()) if (expectException) { - assertFailsWith { + assertFails { op.roundTrip(client, Unit) } @@ -131,18 +125,16 @@ class ClockSkewInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClockSkewApplied() = runTest { testRoundTrip( - serverTimeString = "Wed, 14 Sep 2023 16:20:50 -0400", // Big skew + serverTimeString = "Thu, 14 Sep 2023 16:20:50 -0400", // Big skew clientTimeString = "20231006T131604Z", httpStatusCode = HttpStatusCode.Forbidden, expectException = false, ) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClockSkewNotApplied_NoSkew() = runTest { testRoundTrip( @@ -153,7 +145,6 @@ class ClockSkewInterceptorTest { ) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClockSkewNotApplied_BadDate() = runTest { testRoundTrip( From ba7bfa447d13b5b8d7ca96600d6b3524393ee715 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:19:32 -0500 Subject: [PATCH 39/65] Re-enable more tests --- .../kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 6 ------ .../awsprotocol/eventstream/FrameEncoderTest.kt | 2 -- .../awsprotocol/eventstream/HeaderValueTest.kt | 1 - .../runtime/awsprotocol/eventstream/MessageTest.kt | 11 ----------- 4 files changed, 20 deletions(-) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 51be65b92a..e8b1b6feae 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -108,7 +108,6 @@ public abstract class AwsHttpSignerTestBase( return operation.context[HttpOperationContext.HttpCallList].last().request } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignRequest(): TestResult = runTest { val op = buildOperation() @@ -122,7 +121,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testUnsignedRequest(): TestResult = runTest { val op = buildOperation(unsigned = true) @@ -136,7 +134,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignReplayableStreamingRequest(): TestResult = runTest { val op = buildOperation(streaming = true) @@ -150,7 +147,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignAwsChunkedStreamNonReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -164,7 +160,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test public fun testSignAwsChunkedStreamReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -178,7 +173,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test public fun testSignOneShotStream(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false) diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt index ae82292eec..6bfba22f36 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt @@ -17,7 +17,6 @@ import kotlin.test.assertContentEquals import kotlin.test.assertEquals class FrameEncoderTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEncode() = runTest { val expected = listOf( @@ -44,7 +43,6 @@ class FrameEncoderTest { assertContentEquals(expected[2], actual[2].readByteArray()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testAsEventStreamHttpBody() = runTest { val messages = flowOf( diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt index 8478472b32..1a8689397c 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt @@ -16,7 +16,6 @@ import kotlin.test.assertFails class HeaderValueTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testExpectAs() { assertEquals(true, HeaderValue.Bool(true).expectBool()) diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt index 95ec4e8dbd..5ba8e9af14 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt @@ -53,7 +53,6 @@ fun validMessageNoHeaders(): ByteArray = byteArrayFrom( class MessageTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testMessageNoHeaders() { // Test message taken from the CRT: @@ -70,7 +69,6 @@ class MessageTest { assertEquals(expectedPayload, actual.payload.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testMessageOneHeader() { // Test message taken from the CRT: @@ -92,7 +90,6 @@ class MessageTest { assertEquals(expectedHeaders, actual.headers) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRoundTripAllHeadersPayload() { val encoded = validMessageWithAllHeaders() @@ -122,7 +119,6 @@ class MessageTest { assertContentEquals(message.payload, result.payload) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeaderStringValueLength() { // header length = -1 @@ -144,7 +140,6 @@ class MessageTest { }.message.shouldContain("Invalid HeaderValue; type=STRING, len=65535") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeaderStringLengthCutoff() { val encoded = byteArrayFrom( @@ -161,7 +156,6 @@ class MessageTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeaderValueType() { val encoded = byteArrayFrom( @@ -182,7 +176,6 @@ class MessageTest { }.message.shouldContain("Unknown HeaderType: 96") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeaderNameLength() { val encoded = byteArrayFrom( @@ -203,7 +196,6 @@ class MessageTest { }.message.shouldContain("Invalid header name length") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeadersLength() { val encoded = byteArrayFrom( @@ -220,7 +212,6 @@ class MessageTest { }.message.shouldContain("Not enough bytes to read header name; needed: 3; remaining: 1") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidPreludeChecksum() { val encoded = byteArrayFrom( @@ -241,7 +232,6 @@ class MessageTest { }.message.shouldContain("Prelude checksum mismatch; expected=0xdeadbeef; calculated=0x8bb495fb") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidMessageChecksum() { val encoded = byteArrayFrom( @@ -262,7 +252,6 @@ class MessageTest { }.message.shouldContain("Message checksum mismatch; expected=0xdeadbeef; calculated=0x01a05860") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidHeaderNameLengthTooLong() { val encoded = byteArrayFrom( From 1f271bfdcf330a28077881988013a1a7e7f449ec Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:41:59 -0500 Subject: [PATCH 40/65] Re-enable way more tests --- .../runtime/crt/SdkSourceBodyStreamTest.kt | 3 - .../eventstream/FrameDecoderTest.kt | 3 - .../awsprotocol/json/AwsJsonProtocolTest.kt | 3 - .../http/engine/crt/AsyncStressTest.kt | 2 +- .../http/engine/crt/RequestConversionTest.kt | 2 - .../crt/SdkStreamResponseHandlerTest.kt | 2 - .../http/engine/crt/SendChunkedBodyTest.kt | 4 - .../http/engine/HttpCallContextTest.kt | 1 - .../http/engine/HttpClientEngineTest.kt | 6 - .../CachingChecksumInterceptorTest.kt | 2 - ...FlexibleChecksumsRequestInterceptorTest.kt | 8 - ...lexibleChecksumsResponseInterceptorTest.kt | 6 - .../HttpChecksumRequiredInterceptorTest.kt | 4 - .../RequestCompressionInterceptorTest.kt | 7 - ...ResponseLengthValidationInterceptorTest.kt | 5 - .../middleware/DefaultValidateResponseTest.kt | 2 - .../http/middleware/MutateHeadersTest.kt | 3 - .../http/middleware/RetryMiddlewareTest.kt | 1 - .../operation/HttpInterceptorOrderTest.kt | 19 -- .../http/operation/HttpInterceptorTest.kt | 4 - .../HttpInterceptorTypeValidationTest.kt | 3 - .../http/operation/SdkHttpOperationTest.kt | 2 - .../operation/SdkOperationExecutionTest.kt | 1 - .../runtime/httptest/TestConnectionTest.kt | 6 - .../smithy/kotlin/runtime/http/HeadersTest.kt | 5 +- .../kotlin/runtime/http/HttpBodyTest.kt | 2 - .../runtime/http/HttpRequestBuilderTest.kt | 2 - .../runtime/http/response/HttpResponseTest.kt | 1 - ...hyProtocolResponseHeaderInterceptorTest.kt | 2 - .../cbor/Rpcv2CborErrorDeserializerTest.kt | 1 - .../serde/cbor/CborDeserializerErrorTest.kt | 59 ------- .../serde/cbor/CborDeserializerSuccessTest.kt | 167 ------------------ .../serde/cbor/CborDeserializerTest.kt | 1 - .../runtime/serde/cbor/CborSerializerTest.kt | 20 +-- .../serde/formurl/FormUrlSerializerTest.kt | 17 -- .../serde/json/JsonDeserializerTest.kt | 2 - .../smithy/test/HttpRequestTestBuilderTest.kt | 12 -- .../test/HttpResponseTestBuilderTest.kt | 1 - 38 files changed, 4 insertions(+), 387 deletions(-) diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt index eb4209c74a..3f0e089c09 100644 --- a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt +++ b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt @@ -22,7 +22,6 @@ class SdkSourceBodyStreamTest { return MutableBuffer.of(dest) to dest } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFully() = runTest { val data = byteArrayOf(1, 2, 3, 4, 5) @@ -37,7 +36,6 @@ class SdkSourceBodyStreamTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testPartialRead() = runTest { val source = "123456".encodeToByteArray().source() @@ -55,7 +53,6 @@ class SdkSourceBodyStreamTest { assertEquals("456", sent2.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testLargeTransfer() = runTest { val data = "foobar" diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt index a9214f46e4..6be7591c00 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt @@ -15,7 +15,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class FrameDecoderTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testFrameStreamSingleMessage() = runTest { val encoded = validMessageWithAllHeaders() @@ -29,7 +28,6 @@ class FrameDecoderTest { assertEquals(expected, actual.first()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testFrameStreamMultipleMessagesChunked() = runTest { val encoded = SdkBuffer().apply { @@ -53,7 +51,6 @@ class FrameDecoderTest { assertEquals(expected3, actual[2]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testChannelClosed() = runTest { // contents don't matter diff --git a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt index 41cbabfe8f..168589c041 100644 --- a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt +++ b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt @@ -18,7 +18,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class AwsJsonProtocolTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSetJsonProtocolHeaders() = runTest { @Suppress("DEPRECATION") @@ -41,7 +40,6 @@ class AwsJsonProtocolTest { assertEquals("FooService_blah.Bar", request.headers["X-Amz-Target"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEmptyBody() = runTest { @Suppress("DEPRECATION") @@ -61,7 +59,6 @@ class AwsJsonProtocolTest { assertEquals("{}", actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDoesNotOverride() = runTest { @Suppress("DEPRECATION") diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index 7d0b0def83..589e8d674e 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -37,7 +37,7 @@ class AsyncStressTest : TestWithLocalServer() { } }.start() - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation +// @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testStreamNotConsumed() = runBlocking { // test that filling the stream window and not consuming the body stream still cleans up resources diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt index 531a253127..7180c10c9d 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt @@ -54,7 +54,6 @@ class RequestConversionTest { assertFalse(crtRequest.body is ReadChannelBodyStream) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkToCrtRequestStreamingBody() { val stream = byteStreamFromContents("foobar") @@ -73,7 +72,6 @@ class RequestConversionTest { crtBody.cancel() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEngineAddsContentLengthHeader() { val stream = byteStreamFromContents("foobar") diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index e5fc0259c9..286ac61cad 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -125,7 +125,6 @@ class SdkStreamResponseHandlerTest { assertTrue(respChan.isClosedForWrite) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRespBody() = runTest { val handler = SdkStreamResponseHandler(mockConn, coroutineContext) @@ -154,7 +153,6 @@ class SdkStreamResponseHandlerTest { assertEquals(data, respChan.readToBuffer().readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testStreamError() = runTest { val handler = SdkStreamResponseHandler(mockConn, coroutineContext) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt index f456817161..86cb5d57bf 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt @@ -28,7 +28,6 @@ class SendChunkedBodyTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSourceContent() = runTest { val stream = MockHttpStream(200) @@ -46,7 +45,6 @@ class SendChunkedBodyTest { assertEquals(1, stream.numChunksWritten) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testChannelContentMultipleChunks() = runTest { val stream = MockHttpStream(200) @@ -68,7 +66,6 @@ class SendChunkedBodyTest { assertTrue(stream.numChunksWritten > 1) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testChannelContent() = runTest { val stream = MockHttpStream(200) @@ -87,7 +84,6 @@ class SendChunkedBodyTest { assertEquals(1, stream.numChunksWritten) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSourceContentMultipleChunks() = runTest { val stream = MockHttpStream(200) diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt index e6183f8ece..61fab9962b 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt @@ -25,7 +25,6 @@ import kotlin.test.assertTrue import kotlin.coroutines.coroutineContext as currentCoroutineContext class HttpCallContextTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @OptIn(ExperimentalCoroutinesApi::class) @Test fun testStructuredConcurrency() = runTest { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt index 0fbaa6cb04..2b330a1ec3 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt @@ -61,7 +61,6 @@ class HttpClientEngineTest { private val HttpCall.job: Job get() = coroutineContext.job - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCallComplete() = runTest { val call = client.call(HttpRequestBuilder()) @@ -71,7 +70,6 @@ class HttpClientEngineTest { assertTrue(call.job.isCompleted) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testUserContextCancelsRequestJob() = runTest { val job = launch { @@ -88,7 +86,6 @@ class HttpClientEngineTest { assertTrue(callJob.isCancelled) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testInFlightRequestJobsAreIndependent() = runTest { val job1 = launch { @@ -113,7 +110,6 @@ class HttpClientEngineTest { job2.cancel() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testEngineJobNotCancelledByRequestJobs() = runTest { launch { @@ -131,7 +127,6 @@ class HttpClientEngineTest { assertTrue(engine.coroutineContext.job.isActive) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testShutdownOnlyAfterInFlightDone() = runTest { val waiter = Channel(1) @@ -166,7 +161,6 @@ class HttpClientEngineTest { assertTrue(engine.shutdownCalled) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testRequestAfterClose() = runTest { engine.close() diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt index c464e99994..06aa9c8dfd 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt @@ -25,7 +25,6 @@ private val CHECKSUM_TEST_HEADER = "x-amz-kotlin-sdk-test-checksum-header" class CachingChecksumInterceptorTest { private val client = SdkHttpClient(TestEngine()) - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testChecksumIsCalculatedAndApplied() = runTest { val req = HttpRequestBuilder().apply { @@ -42,7 +41,6 @@ class CachingChecksumInterceptorTest { assertEquals(expectedChecksumValue, call.request.headers[CHECKSUM_TEST_HEADER]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCachedChecksumIsUsed() = runTest { val req = HttpRequestBuilder().apply { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt index f95349752e..347a7b130a 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt @@ -33,7 +33,6 @@ class FlexibleChecksumsRequestInterceptorTest { "sha256" to "1dXchshIKqXiaKCqueqR7AOz1qLpiqayo7gbnaxzaQo=", ) - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSetsChecksumHeader() = runTest { checksums.forEach { (checksumAlgorithmName, expectedChecksumValue) -> @@ -57,7 +56,6 @@ class FlexibleChecksumsRequestInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itAllowsOnlyOneChecksumHeader() = runTest { val req = HttpRequestBuilder().apply { @@ -86,7 +84,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(1, call.request.headers.getNumChecksumHeaders()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itThrowsOnUnsupportedChecksumAlgorithm() = runTest { val req = HttpRequestBuilder().apply { @@ -109,7 +106,6 @@ class FlexibleChecksumsRequestInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itRemovesChecksumHeadersForAwsChunked() = runTest { val data = ByteArray(65536 * 32) { 'a'.code.toByte() } @@ -140,7 +136,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(0, call.request.headers.getNumChecksumHeaders()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCompletingSource() = runTest { val hashFunctionName = "crc32" @@ -162,7 +157,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(expectedHash.digest().encodeBase64String(), completableDeferred.await()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCompletingByteReadChannel() = runTest { val hashFunctionName = "sha256" @@ -186,7 +180,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(expectedHash.digest().encodeBase64String(), completableDeferred.await()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itUsesPrecalculatedChecksum() = runTest { val req = HttpRequestBuilder().apply { @@ -213,7 +206,6 @@ class FlexibleChecksumsRequestInterceptorTest { assertEquals(precalculatedChecksumValue, call.request.headers["x-amz-checksum-sha256"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testDefaultChecksumConfiguration() = runTest { setOf( diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt index 48501c89ef..e11fdd18a5 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt @@ -68,7 +68,6 @@ class FlexibleChecksumsResponseInterceptorTest { return SdkHttpClient(mockEngine) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testResponseChecksumValid() = runTest { checksums.forEach { (checksumAlgorithmName, expectedChecksum) -> @@ -96,7 +95,6 @@ class FlexibleChecksumsResponseInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testResponseServiceChecksumInvalid() = runTest { checksums.forEach { (checksumAlgorithmName, _) -> @@ -126,7 +124,6 @@ class FlexibleChecksumsResponseInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testMultipleChecksumsReturned() = runTest { val req = HttpRequestBuilder() @@ -152,7 +149,6 @@ class FlexibleChecksumsResponseInterceptorTest { assertEquals("x-amz-checksum-crc32c", op.context[ChecksumHeaderValidated]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSkipsValidationOfMultipartChecksum() = runTest { val req = HttpRequestBuilder() @@ -174,7 +170,6 @@ class FlexibleChecksumsResponseInterceptorTest { op.roundTrip(client, TestInput("input")) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSkipsValidationWhenDisabled() = runTest { val req = HttpRequestBuilder() @@ -201,7 +196,6 @@ class FlexibleChecksumsResponseInterceptorTest { assertNull(op.context.getOrNull(ChecksumHeaderValidated)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testResponseValidationConfiguration() = runTest { setOf( diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt index 8634c0735a..eb06bb633b 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt @@ -25,7 +25,6 @@ import kotlin.test.assertNull class HttpChecksumRequiredInterceptorTest { private val client = SdkHttpClient(TestEngine()) - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSetsContentMd5Header() = runTest { val req = HttpRequestBuilder().apply { @@ -44,7 +43,6 @@ class HttpChecksumRequiredInterceptorTest { assertEquals(expected, call.request.headers["Content-MD5"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSetsContentCrc32Header() = runTest { val testBody = "bar".encodeToByteArray() @@ -68,7 +66,6 @@ class HttpChecksumRequiredInterceptorTest { assertEquals(expected, call.request.headers["x-amz-checksum-crc32"]) } - @IgnoreNative @Test fun itSetsHeaderForNonBytesContent() = runTest { val req = HttpRequestBuilder().apply { @@ -89,7 +86,6 @@ class HttpChecksumRequiredInterceptorTest { assertEquals(expected, call.request.headers["Content-MD5"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itDoesNotSetContentMd5Header() = runTest { val req = HttpRequestBuilder().apply { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt index 725989fe98..3f6666d0c2 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt @@ -59,7 +59,6 @@ class RequestCompressionInterceptorTest { return op.context.attributes[HttpOperationContext.HttpCallList].first() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCompressionThresholdTooHigh() = runTest { val payload = "bar" @@ -79,7 +78,6 @@ class RequestCompressionInterceptorTest { assertEquals(bytes, sentBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCompression() = runTest { val payload = "bar" @@ -100,7 +98,6 @@ class RequestCompressionInterceptorTest { assertContentEquals(bytes, decompressedBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkSource() = runTest { val payload = "bar" @@ -121,7 +118,6 @@ class RequestCompressionInterceptorTest { assertContentEquals(bytes, decompressedBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkByteReadChannel() = runTest { val payload = "bar" @@ -142,7 +138,6 @@ class RequestCompressionInterceptorTest { assertContentEquals(bytes, decompressedBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testHeaderAlreadySet() = runTest { val payload = "bar" @@ -164,7 +159,6 @@ class RequestCompressionInterceptorTest { assertContentEquals(bytes, decompressedBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNoSupportedAlgorithms() = runTest { val payload = "bar" @@ -184,7 +178,6 @@ class RequestCompressionInterceptorTest { assertEquals(bytes, sentBytes) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidCompressionThreshold() = runTest { val payload = "bar" diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt index 4fa184459d..cbcb01f452 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt @@ -78,7 +78,6 @@ class ResponseLengthValidationInterceptorTest { private fun allBodies() = nonEmptyBodies() + HttpBody.Empty - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testCorrectLengthReturned() = runTest { nonEmptyBodies().forEach { body -> @@ -88,7 +87,6 @@ class ResponseLengthValidationInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNotEnoughBytesReturned() = runTest { nonEmptyBodies().forEach { body -> @@ -100,7 +98,6 @@ class ResponseLengthValidationInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testTooManyBytesReturned() = runTest { allBodies().forEach { body -> @@ -112,7 +109,6 @@ class ResponseLengthValidationInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNoContentLengthSkipsValidation() = runTest { allBodies().forEach { body -> @@ -122,7 +118,6 @@ class ResponseLengthValidationInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testEmptyBodyCorrectLengthReturned() = runTest { val client = client(HttpBody.Empty, 0) // expect correct content length diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt index d8667ae65f..c1c10e8ffa 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt @@ -22,7 +22,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class DefaultValidateResponseTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itThrowsExceptionOnNon200Response() = runTest { val mockEngine = TestEngine { _, request -> @@ -46,7 +45,6 @@ class DefaultValidateResponseTest { return@runTest } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itPassesSuccessResponses() = runTest { val mockEngine = TestEngine { _, request -> diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt index 7d2632749d..eae995dded 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt @@ -21,7 +21,6 @@ import kotlin.test.assertEquals class MutateHeadersTest { private val client = SdkHttpClient(TestEngine()) - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itOverridesHeaders() = runTest { val req = HttpRequestBuilder().apply { @@ -52,7 +51,6 @@ class MutateHeadersTest { assertEquals("qux", call.request.headers["baz"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itAppendsHeaders() = runTest { val req = HttpRequestBuilder().apply { @@ -83,7 +81,6 @@ class MutateHeadersTest { assertEquals("qux", call.request.headers["baz"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSetsMissing() = runTest { val req = HttpRequestBuilder().apply { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt index b2bb1bc816..4c7bd7e5ed 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt @@ -35,7 +35,6 @@ class RetryMiddlewareTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testRetryMiddleware() = runTest { val req = HttpRequestBuilder() diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt index 0a64190951..03510423f9 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt @@ -136,7 +136,6 @@ class HttpInterceptorOrderTest { hooksFired.shouldContainInOrder(expected) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testInterceptorOrderSuccess() = runTest { // sanity test all hooks fire in order @@ -153,109 +152,91 @@ class HttpInterceptorOrderTest { assertEquals(expected, hooksFired) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadBeforeExecutionErrors() = runTest { simpleFailOrderTest("readBeforeExecution") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeSerializationErrors() = runTest { simpleFailOrderTest("modifyBeforeSerialization") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadBeforeSerializationErrors() = runTest { simpleFailOrderTest("readBeforeSerialization") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadAfterSerializationErrors() = runTest { simpleFailOrderTest("readAfterSerialization") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeRetryLoopErrors() = runTest { simpleFailOrderTest("modifyBeforeRetryLoop") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadBeforeAttemptErrors() = runTest { simpleFailOrderTest("readBeforeAttempt") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeSigningErrors() = runTest { simpleFailOrderTest("modifyBeforeSigning") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadBeforeSigningErrors() = runTest { simpleFailOrderTest("readBeforeSigning") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadAfterSigningErrors() = runTest { simpleFailOrderTest("readAfterSigning") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeTransmitErrors() = runTest { simpleFailOrderTest("modifyBeforeTransmit") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadBeforeTransmitErrors() = runTest { simpleFailOrderTest("readBeforeTransmit") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterTransmitErrors() = runTest { simpleFailOrderTest("readAfterTransmit") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadBeforeDeserializationErrors() = runTest { simpleFailOrderTest("readBeforeDeserialization") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterDeserializationErrors() = runTest { simpleFailOrderTest("readAfterDeserialization") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterAttemptErrors() = runTest { simpleFailOrderTest("readAfterAttempt") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testModifyBeforeAttemptCompletionErrors() = runTest { simpleFailOrderTest("modifyBeforeAttemptCompletion") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testModifyBeforeCompletionErrors() = runTest { simpleFailOrderTest("modifyBeforeCompletion") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterExecutionErrors() = runTest { simpleFailOrderTest("readAfterExecution") diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt index b2830268da..ffa4a4d894 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt @@ -152,7 +152,6 @@ class HttpInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testInterceptorModifications() = runTest { val serialized = HttpRequestBuilder().apply { @@ -175,7 +174,6 @@ class HttpInterceptorTest { assertEquals("final", output.value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testInterceptorModificationsWithRetries() = runTest { val serialized = HttpRequestBuilder().apply { @@ -214,7 +212,6 @@ class HttpInterceptorTest { assertEquals("ignore-failure", output.value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testMapFailureOnAttempt() = runTest { val interceptor = object : HttpInterceptor { @@ -227,7 +224,6 @@ class HttpInterceptorTest { testMapFailure(interceptor) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testMapFailureOnCompletion() = runTest { val interceptor = object : HttpInterceptor { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt index e7847ff8fa..e1582ece99 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt @@ -17,7 +17,6 @@ import kotlin.IllegalStateException import kotlin.test.* class HttpInterceptorTypeValidationTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeSerializationTypeFailure() = runTest { val i1 = object : HttpInterceptor { @@ -46,7 +45,6 @@ class HttpInterceptorTypeValidationTest { ex.message.shouldContain("modifyBeforeSerialization invalid type conversion: found class aws.smithy.kotlin.runtime.http.operation.TestOutput; expected class aws.smithy.kotlin.runtime.http.operation.TestInput") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeAttemptCompletionTypeFailure() = runTest { val i1 = object : HttpInterceptor { @@ -74,7 +72,6 @@ class HttpInterceptorTypeValidationTest { ex.message.shouldContain("modifyBeforeAttemptCompletion invalid type conversion: found class kotlin.String; expected class aws.smithy.kotlin.runtime.http.operation.TestOutput") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testModifyBeforeCompletionTypeFailure() = runTest { val i1 = object : HttpInterceptor { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt index 59bbc66974..766b1e13dd 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt @@ -19,7 +19,6 @@ import kotlin.test.assertFailsWith import kotlin.test.assertNotNull class SdkHttpOperationTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testTelemetryInstrumentation() = runTest { val op = newTestOperation(HttpRequestBuilder(), Unit) @@ -33,7 +32,6 @@ class SdkHttpOperationTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testMissingRequiredProperties() = runTest { val ex = assertFailsWith { diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt index 33c394f8a5..a6f2dc53a8 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt @@ -28,7 +28,6 @@ import kotlin.test.assertFalse import kotlin.test.assertTrue class SdkOperationExecutionTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testOperationMiddlewareOrder() = runTest { // sanity test middleware flows the way we expect diff --git a/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt b/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt index c1cfa8ec28..b7b2f9e9af 100644 --- a/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt +++ b/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt @@ -16,7 +16,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFails class TestConnectionTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testAssertRequestsSuccess() = runTest { val engine = buildTestConnection { @@ -44,7 +43,6 @@ class TestConnectionTest { engine.assertRequests() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testAssertRequestsUrlDifferent() = runTest { val engine = buildTestConnection { @@ -72,7 +70,6 @@ class TestConnectionTest { }.message.shouldContain("URL mismatch") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testAssertRequestsMissingHeader() = runTest { val engine = buildTestConnection { @@ -100,7 +97,6 @@ class TestConnectionTest { }.message.shouldContain("header `x-baz` missing value `qux`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testAssertRequestsBodyDifferent() = runTest { val engine = buildTestConnection { @@ -129,7 +125,6 @@ class TestConnectionTest { }.message.shouldContain("body mismatch") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testAssertRequestsAny() = runTest { val engine = buildTestConnection { @@ -164,7 +159,6 @@ class TestConnectionTest { engine.assertRequests() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testFromJson() = runTest { // language=JSON diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt index 04cea1b3e6..f2022359e7 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt @@ -29,7 +29,6 @@ class HeadersTest { assertEquals("Headers [key=[value]]", "$actual2") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSubsequentModificationsDontAffectOriginal() { val builder = HeadersBuilder() @@ -53,8 +52,8 @@ class HeadersTest { "c" to listOf("crocodile"), ) - assertEquals(firstExpected.entries, first.entries()) - assertEquals(secondExpected.entries, second.entries()) + assertEquals(firstExpected.entries.toList(), first.entries().toList()) + assertEquals(secondExpected.entries.toList(), second.entries().toList()) } @Test diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt index a76f8ddc9e..9667b9284e 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt @@ -50,7 +50,6 @@ class HttpBodyTest { assertTrue(body.isOneShot) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testStreamingReadAllClosedForRead() = runTest { val expected = "foobar" @@ -63,7 +62,6 @@ class HttpBodyTest { assertEquals(expected, body.readAll()!!.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testStreamingReadAllClosedForWrite() = runTest { val expected = "foobar" diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt index 9954de1d6e..fe713d42e8 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt @@ -42,7 +42,6 @@ class HttpRequestBuilderTest { assertEquals(HttpBody.Empty, request.body) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDumpRequest() = runTest { val content = "Mom!...Dad!...Bingo!...Bluey!" @@ -81,7 +80,6 @@ class HttpRequestBuilderTest { assertEquals(content, actualReplacedContent) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRequestToBuilder() = runTest { val req = HttpRequest( diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt index 32c420fef3..9e8fe42c52 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt @@ -37,7 +37,6 @@ class HttpResponseTest { assertEquals(HttpStatusCode.BadRequest, resp.statusCode()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDumpResponse() = runTest { val content = "Mom!...Dad!...Bingo!...Bluey!" diff --git a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt index 02a330f5f3..54b6e28805 100644 --- a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt +++ b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt @@ -56,7 +56,6 @@ internal fun getMockClient(response: ByteArray, responseHeaders: Headers = Heade internal val RESPONSE = "abc".repeat(1024).encodeToByteArray() class RpcV2CborSmithyProtocolResponseHeaderInterceptorTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testThrowsOnMissingHeader() = runTest { val req = HttpRequestBuilder() @@ -71,7 +70,6 @@ class RpcV2CborSmithyProtocolResponseHeaderInterceptorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSucceedsOnPresentHeader() = runTest { val req = HttpRequestBuilder() diff --git a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt index 6357e782f0..a3f45cb545 100644 --- a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt +++ b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt @@ -15,7 +15,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class RpcV2CborErrorDeserializerTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDeserializeErrorType() = runTest { val tests = listOf( diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt index 1ace81d9ef..d869b409a6 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt @@ -15,7 +15,6 @@ import kotlin.test.Test import kotlin.test.assertFails class CborDeserializerErrorTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - major7 - float64 - incomplete float64 at end of buf`() { val payload = "0xfb00000000000000".toByteArray() @@ -28,7 +27,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - uint - 2 - arg len 2 greater than remaining buf len`() { val payload = "0x1900".toByteArray() @@ -41,7 +39,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - uint - 4 - arg len 4 greater than remaining buf len`() { val payload = "0x1a000000".toByteArray() @@ -54,7 +51,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - negint - 2 - arg len 2 greater than remaining buf len`() { val payload = "0x3900".toByteArray() @@ -67,7 +63,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - slice - 2 - arg len 2 greater than remaining buf len`() { val payload = "0x5900".toByteArray() @@ -80,7 +75,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - slice - 8 - arg len 8 greater than remaining buf len`() { val payload = "0x5b00000000000000".toByteArray() @@ -93,7 +87,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - tag - 2 - arg len 2 greater than remaining buf len`() { val payload = "0xd900".toByteArray() @@ -105,7 +98,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - tag - 4 - arg len 4 greater than remaining buf len`() { val payload = "0xda000000".toByteArray() @@ -117,7 +109,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - uint - unexpected minor value 31`() { val payload = "0x1f".toByteArray() @@ -130,7 +121,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - list - 1 - arg len 1 greater than remaining buf len`() { val payload = "0x98".toByteArray() @@ -145,7 +135,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - list - 4 - arg len 4 greater than remaining buf len`() { val payload = "0x9a000000".toByteArray() @@ -160,7 +149,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - list - 8 - arg len 8 greater than remaining buf len`() { val payload = "0x9b00000000000000".toByteArray() @@ -175,7 +163,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - map - 1 - arg len 1 greater than remaining buf len`() { val payload = "0xb8".toByteArray() @@ -191,7 +178,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - map - 4 - arg len 4 greater than remaining buf len`() { val payload = "0xba000000".toByteArray() @@ -207,7 +193,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - major7 - float32 - incomplete float32 at end of buf`() { val payload = "0xfa000000".toByteArray() @@ -220,7 +205,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - string - 2 - arg len 2 greater than remaining buf len`() { val payload = "0x7900".toByteArray() @@ -233,7 +217,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - list - 2 - arg len 2 greater than remaining buf len`() { val payload = "0x9900".toByteArray() @@ -248,7 +231,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - negint - unexpected minor value 31`() { val payload = "0x3f".toByteArray() @@ -261,7 +243,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - string - 8 - arg len 8 greater than remaining buf len`() { val payload = "0x7b00000000000000".toByteArray() @@ -274,7 +255,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - major7 - unexpected minor value 31`() { val payload = "0xff".toByteArray() @@ -287,7 +267,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - string - 1 - arg len 1 greater than remaining buf len`() { val payload = "0x78".toByteArray() @@ -300,7 +279,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - tag - unexpected minor value 31`() { val payload = "0xdf".toByteArray() @@ -312,7 +290,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - slice - 1 - arg len 1 greater than remaining buf len`() { val payload = "0x58".toByteArray() @@ -325,7 +302,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - slice - 4 - arg len 4 greater than remaining buf len`() { val payload = "0x5a000000".toByteArray() @@ -338,7 +314,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - map - 2 - arg len 2 greater than remaining buf len`() { val payload = "0xb900".toByteArray() @@ -354,7 +329,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - map - 8 - arg len 8 greater than remaining buf len`() { val payload = "0xbb00000000000000".toByteArray() @@ -370,7 +344,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - tag - 8 - arg len 8 greater than remaining buf len`() { val payload = "0xdb00000000000000".toByteArray() @@ -382,7 +355,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - uint - 1 - arg len 1 greater than remaining buf len`() { val payload = "0x18".toByteArray() @@ -395,7 +367,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - major7 - float16 - incomplete float16 at end of buf`() { val payload = "0xf900".toByteArray() @@ -408,7 +379,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - uint - 8 - arg len 8 greater than remaining buf len`() { val payload = "0x1b00000000000000".toByteArray() @@ -421,7 +391,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - negint - 1 - arg len 1 greater than remaining buf len`() { val payload = "0x38".toByteArray() @@ -434,7 +403,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - negint - 4 - arg len 4 greater than remaining buf len`() { val payload = "0x3a000000".toByteArray() @@ -447,7 +415,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - negint - 8 - arg len 8 greater than remaining buf len`() { val payload = "0x3b00000000000000".toByteArray() @@ -460,7 +427,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - string - 4 - arg len 4 greater than remaining buf len`() { val payload = "0x7a000000".toByteArray() @@ -473,7 +439,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidArgument - tag - 1 - arg len 1 greater than remaining buf len`() { val payload = "0xd8".toByteArray() @@ -485,7 +450,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidList - indefinite list - invalid item - arg len 1 greater than remaining buf len`() { val payload = "0x9f18".toByteArray() @@ -500,7 +464,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidList - list - eof after head - unexpected end of payload`() { val payload = "0x81".toByteArray() @@ -515,7 +478,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidList - list - invalid item - arg len 1 greater than remaining buf len`() { val payload = "0x8118".toByteArray() @@ -530,7 +492,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidList - indefinite list - no break - expected break marker`() { val payload = "0x9f".toByteArray() @@ -545,7 +506,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - map - non-string key - unexpected major type 0 for map key`() { val payload = "0xa100".toByteArray() @@ -561,7 +521,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - map - invalid key - slice len 1 greater than remaining buf len`() { val payload = "0xa17801".toByteArray() @@ -577,7 +536,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - map - invalid value - arg len 1 greater than remaining buf len`() { val payload = "0xa163666f6f18".toByteArray() @@ -593,7 +551,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - indefinite map - no break - expected break marker`() { val payload = "0xbf".toByteArray() @@ -609,7 +566,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - indefinite map - non-string key - unexpected major type 0 for map key`() { val payload = "0xbf00".toByteArray() @@ -625,7 +581,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - indefinite map - invalid key - slice len 1 greater than remaining buf len`() { val payload = "0xbf7801".toByteArray() @@ -641,7 +596,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - indefinite map - invalid value - arg len 1 greater than remaining buf len`() { val payload = "0xbf63666f6f18".toByteArray() @@ -657,7 +611,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidMap - map - eof after head - unexpected end of payload`() { val payload = "0xa1".toByteArray() @@ -673,7 +626,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - slice - invalid nested definite - decode subslice slice len 1 greater than remaining buf len`() { val payload = "0x5f5801".toByteArray() @@ -686,7 +638,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - string - no break - expected break marker`() { val payload = "0x7f".toByteArray() @@ -699,7 +650,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - string - invalid nested major - unexpected major type 2 in indefinite slice`() { val payload = "0x7f40".toByteArray() @@ -712,7 +662,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - string - nested indefinite - nested indefinite slice`() { val payload = "0x7f7f".toByteArray() @@ -725,7 +674,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - string - invalid nested definite - decode subslice - slice len 1 greater than remaining buf len`() { val payload = "0x7f7801".toByteArray() @@ -738,7 +686,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - slice - invalid nested major - unexpected major type 3 in indefinite slice`() { val payload = "0x5f60".toByteArray() @@ -751,7 +698,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - slice - no break - expected break marker`() { val payload = "0x5f".toByteArray() @@ -764,7 +710,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - slice - nested indefinite - nested indefinite slice`() { val payload = "0x5f5f".toByteArray() @@ -777,7 +722,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - string - 1 - not enough bytes - slice len 1 greater than remaining buf len`() { val payload = "0x7801".toByteArray() @@ -790,7 +734,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidSlice - slice - 1 - not enough bytes - slice len 1 greater than remaining buf len`() { val payload = "0x5801".toByteArray() @@ -803,7 +746,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidTag - invalid value - arg len 1 greater than remaining buf len`() { val payload = "0xc118".toByteArray() @@ -815,7 +757,6 @@ class CborDeserializerErrorTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `TestDecode_InvalidTag - eof - unexpected end of payload`() { val payload = "0xc1".toByteArray() diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt index 03f52f0936..a2b16fffaa 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt @@ -25,7 +25,6 @@ internal fun String.toByteArray(): ByteArray = this .toByteArray() class CborDeserializerSuccessTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - undefined`() { val payload = "0xf7".toByteArray() @@ -37,7 +36,6 @@ class CborDeserializerSuccessTest { assertEquals(null, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float64 - 1dot625`() { val payload = "0xfb3ffa000000000000".toByteArray() @@ -49,7 +47,6 @@ class CborDeserializerSuccessTest { assertEquals(1.625, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 0 - max`() { val payload = "0x17".toByteArray() @@ -61,7 +58,6 @@ class CborDeserializerSuccessTest { assertEquals(23, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 8 - min`() { val payload = "0x1b0000000000000000".toByteArray() @@ -73,7 +69,6 @@ class CborDeserializerSuccessTest { assertEquals(0uL, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 8 - max`() { val payload = "0x1bffffffffffffffff".toByteArray() @@ -82,7 +77,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, aws.smithy.kotlin.runtime.serde.cbor.encoding.UInt.decode(buffer).value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 8 - min`() { val payload = "0x3b0000000000000000".toByteArray() @@ -94,7 +88,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - true`() { val payload = "0xf5".toByteArray() @@ -106,7 +99,6 @@ class CborDeserializerSuccessTest { assertEquals(true, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 4 - min`() { val payload = "0x1a00000000".toByteArray() @@ -118,7 +110,6 @@ class CborDeserializerSuccessTest { assertEquals(0, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 4 - max`() { val payload = "0x1affffffff".toByteArray() @@ -128,7 +119,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MAX_VALUE, aws.smithy.kotlin.runtime.serde.cbor.encoding.UInt.decode(buffer).value.toUInt()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 1 - min`() { val payload = "0x3800".toByteArray() @@ -140,7 +130,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float16 - subnormal`() { val payload = "0xf90050".toByteArray() @@ -152,7 +141,6 @@ class CborDeserializerSuccessTest { assertEquals(4.7683716E-6f, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float16 - NaN - LSB`() { val payload = "0xf97c01".toByteArray() @@ -164,7 +152,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 1 - min`() { val payload = "0x1800".toByteArray() @@ -176,7 +163,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MIN_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 0 - min`() { val payload = "0x20".toByteArray() @@ -188,7 +174,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float16 - -Inf`() { val payload = "0xf9fc00".toByteArray() @@ -200,7 +185,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NEGATIVE_INFINITY, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 8 - max`() { val payload = "0x3bfffffffffffffffe".toByteArray() @@ -209,7 +193,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 0 - min`() { val payload = "0x00".toByteArray() @@ -221,7 +204,6 @@ class CborDeserializerSuccessTest { assertEquals(0u, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 1 - max`() { val payload = "0x18ff".toByteArray() @@ -230,7 +212,6 @@ class CborDeserializerSuccessTest { assertEquals(255u, aws.smithy.kotlin.runtime.serde.cbor.encoding.UInt.decode(buffer).value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 2 - min`() { val payload = "0x190000".toByteArray() @@ -242,7 +223,6 @@ class CborDeserializerSuccessTest { assertEquals(0u, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 1 - max`() { val payload = "0x38ff".toByteArray() @@ -254,7 +234,6 @@ class CborDeserializerSuccessTest { assertEquals(-256, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 2 - min`() { val payload = "0x390000".toByteArray() @@ -266,7 +245,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float64 - +Inf`() { val payload = "0xfb7ff0000000000000".toByteArray() @@ -278,7 +256,6 @@ class CborDeserializerSuccessTest { assertEquals(Double.fromBits(9218868437227405312), result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 4 - min`() { val payload = "0x3a00000000".toByteArray() @@ -290,7 +267,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 4 - max`() { val payload = "0x3affffffff".toByteArray() @@ -303,7 +279,6 @@ class CborDeserializerSuccessTest { assertEquals(res, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float16 - NaN - MSB`() { val payload = "0xf97e00".toByteArray() @@ -315,7 +290,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float32 - +Inf`() { val payload = "0xfa7f800000".toByteArray() @@ -327,7 +301,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - uint - 2 - max`() { val payload = "0x19ffff".toByteArray() @@ -336,7 +309,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MAX_VALUE, aws.smithy.kotlin.runtime.serde.cbor.encoding.UInt.decode(buffer).value.toUShort()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 2 - max`() { val payload = "0x39ffff".toByteArray() @@ -345,7 +317,6 @@ class CborDeserializerSuccessTest { assertEquals(65536u, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - false`() { val payload = "0xf4".toByteArray() @@ -357,7 +328,6 @@ class CborDeserializerSuccessTest { assertEquals(false, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - null`() { val payload = "0xf6".toByteArray() @@ -369,7 +339,6 @@ class CborDeserializerSuccessTest { assertEquals(null, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - negint - 0 - max`() { val payload = "0x37".toByteArray() @@ -381,7 +350,6 @@ class CborDeserializerSuccessTest { assertEquals(-24, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float16 - +Inf`() { val payload = "0xf97c00".toByteArray() @@ -393,7 +361,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `atomic - float32 - 1dot625`() { val payload = "0xfa3fd00000".toByteArray() @@ -405,7 +372,6 @@ class CborDeserializerSuccessTest { assertEquals(1.625f, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `definite slice - len = 0`() { val payload = "0x40".toByteArray() @@ -417,7 +383,6 @@ class CborDeserializerSuccessTest { assertEquals(0, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `definite slice - len greater than 0`() { val payload = "0x43666f6f".toByteArray() @@ -434,7 +399,6 @@ class CborDeserializerSuccessTest { assertEquals(3, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `definite string - len = 0`() { val payload = "0x60".toByteArray() @@ -446,7 +410,6 @@ class CborDeserializerSuccessTest { assertEquals("", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `definite string - len greater than 0`() { val payload = "0x63666f6f".toByteArray() @@ -458,7 +421,6 @@ class CborDeserializerSuccessTest { assertEquals("foo", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite slice - len greater than 0`() { val payload = "0x5f43666f6f40ff".toByteArray() @@ -475,7 +437,6 @@ class CborDeserializerSuccessTest { assertEquals(3, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite slice - len greater than 0 - len greater than 0`() { val payload = "0x5f43666f6f43666f6fff".toByteArray() @@ -490,7 +451,6 @@ class CborDeserializerSuccessTest { assertEquals(expected.size, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite slice - len = 0`() { val payload = "0x5fff".toByteArray() @@ -502,7 +462,6 @@ class CborDeserializerSuccessTest { assertEquals(0, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite slice - len = 0 explicit`() { val payload = "0x5f40ff".toByteArray() @@ -514,7 +473,6 @@ class CborDeserializerSuccessTest { assertEquals(0, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite slice - len = 0 - len greater than 0`() { val payload = "0x5f4043666f6fff".toByteArray() @@ -529,7 +487,6 @@ class CborDeserializerSuccessTest { assertEquals(expected.size, result.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite string - len = 0`() { val payload = "0x7fff".toByteArray() @@ -541,7 +498,6 @@ class CborDeserializerSuccessTest { assertEquals("", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite string - len = 0 - explicit`() { val payload = "0x7f60ff".toByteArray() @@ -553,7 +509,6 @@ class CborDeserializerSuccessTest { assertEquals("", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite string - len = 0 - len greater than 0`() { val payload = "0x7f6063666f6fff".toByteArray() @@ -565,7 +520,6 @@ class CborDeserializerSuccessTest { assertEquals("foo", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite string - len greater than 0 - len = 0`() { val payload = "0x7f63666f6f60ff".toByteArray() @@ -577,7 +531,6 @@ class CborDeserializerSuccessTest { assertEquals("foo", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite string - len greater than 0 - len greater than 0`() { val payload = "0x7f63666f6f63666f6fff".toByteArray() @@ -589,7 +542,6 @@ class CborDeserializerSuccessTest { assertEquals("foofoo", result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of one uint - 1 - max`() { val payload = "0x8118ff".toByteArray() @@ -607,7 +559,6 @@ class CborDeserializerSuccessTest { assertEquals(255u, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of one uint - 8 - min`() { val payload = "0x811b0000000000000000".toByteArray() @@ -625,7 +576,6 @@ class CborDeserializerSuccessTest { assertEquals(0, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 1 - min`() { val payload = "0x9f1800ff".toByteArray() @@ -643,7 +593,6 @@ class CborDeserializerSuccessTest { assertEquals(0u, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 2 - max`() { val payload = "0x9f19ffffff".toByteArray() @@ -661,7 +610,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MAX_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 2 - min`() { val payload = "0x9f390000ff".toByteArray() @@ -679,7 +627,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 4 - max`() { val payload = "0x811affffffff".toByteArray() @@ -697,7 +644,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MAX_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 8 - min`() { val payload = "0x9f1b0000000000000000ff".toByteArray() @@ -715,7 +661,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 2 - max`() { val payload = "0x9f39ffffff".toByteArray() @@ -733,7 +678,6 @@ class CborDeserializerSuccessTest { assertEquals(-65536, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float16 - NaN - LSB`() { val payload = "0x9ff97c01ff".toByteArray() @@ -751,7 +695,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 1 - max`() { val payload = "0x8138ff".toByteArray() @@ -769,7 +712,6 @@ class CborDeserializerSuccessTest { assertEquals(-256, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 2 - min`() { val payload = "0x81390000".toByteArray() @@ -787,7 +729,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of null`() { val payload = "0x81f6".toByteArray() @@ -801,7 +742,6 @@ class CborDeserializerSuccessTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float16 -Inf`() { val payload = "0x81f9fc00".toByteArray() @@ -819,7 +759,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NEGATIVE_INFINITY, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 4 - min`() { val payload = "0x9f1a00000000ff".toByteArray() @@ -837,7 +776,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 1 - min`() { val payload = "0x811800".toByteArray() @@ -855,7 +793,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 0 - max`() { val payload = "0x9f17ff".toByteArray() @@ -873,7 +810,6 @@ class CborDeserializerSuccessTest { assertEquals(23u, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 0 - min`() { val payload = "0x9f20ff".toByteArray() @@ -891,7 +827,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 1 - max`() { val payload = "0x9f38ffff".toByteArray() @@ -909,7 +844,6 @@ class CborDeserializerSuccessTest { assertEquals(-256, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of null`() { val payload = "0x9ff6ff".toByteArray() @@ -923,7 +857,6 @@ class CborDeserializerSuccessTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 1 - max`() { val payload = "0x9f18ffff".toByteArray() @@ -941,7 +874,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MAX_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 4 - max`() { val payload = "0x9f1affffffffff".toByteArray() @@ -959,7 +891,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MAX_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of _ uint - 8 - max`() { val payload = "0x9f1bffffffffffffffffff".toByteArray() @@ -982,7 +913,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of boolean true`() { val payload = "0x9ff5ff".toByteArray() @@ -1000,7 +930,6 @@ class CborDeserializerSuccessTest { assertEquals(true, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of undefined`() { val payload = "0x9ff7ff".toByteArray() @@ -1018,7 +947,6 @@ class CborDeserializerSuccessTest { assertEquals(0, actual.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 0 - max`() { val payload = "0x8117".toByteArray() @@ -1036,7 +964,6 @@ class CborDeserializerSuccessTest { assertEquals(23u, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 8 - max`() { val payload = "0x811bffffffffffffffff".toByteArray() @@ -1057,7 +984,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 0 - min`() { val payload = "0x8120".toByteArray() @@ -1075,7 +1001,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 0 - max`() { val payload = "0x8137".toByteArray() @@ -1093,7 +1018,6 @@ class CborDeserializerSuccessTest { assertEquals(-24, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 4 - min`() { val payload = "0x813a00000000".toByteArray() @@ -1111,7 +1035,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of boolean true`() { val payload = "0x81f5".toByteArray() @@ -1129,7 +1052,6 @@ class CborDeserializerSuccessTest { assertEquals(true, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float32`() { val payload = "0x81fa7f800000".toByteArray() @@ -1147,7 +1069,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.fromBits(2139095040), actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float64`() { val payload = "0x81fb7ff0000000000000".toByteArray() @@ -1165,7 +1086,6 @@ class CborDeserializerSuccessTest { assertEquals(Double.fromBits(9218868437227405312), actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 2 - min`() { val payload = "0x9f190000ff".toByteArray() @@ -1183,7 +1103,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float16 - NaN - MSB`() { val payload = "0x9ff97e00ff".toByteArray() @@ -1201,7 +1120,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 0 - max`() { val payload = "0x9f37ff".toByteArray() @@ -1219,7 +1137,6 @@ class CborDeserializerSuccessTest { assertEquals(-24, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 1 - min`() { val payload = "0x9f3800ff".toByteArray() @@ -1237,7 +1154,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 8 - min`() { val payload = "0x9f3b0000000000000000ff".toByteArray() @@ -1255,7 +1171,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 8 - max`() { val payload = "0x9f3bfffffffffffffffeff".toByteArray() @@ -1277,7 +1192,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of boolean false`() { val payload = "0x81f4".toByteArray() @@ -1295,7 +1209,6 @@ class CborDeserializerSuccessTest { assertEquals(false, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of uint - 0 - min`() { val payload = "0x9f00ff".toByteArray() @@ -1313,7 +1226,6 @@ class CborDeserializerSuccessTest { assertEquals(0, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 4 - min`() { val payload = "0x9f3a00000000ff".toByteArray() @@ -1331,7 +1243,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of negint - 4 - max`() { val payload = "0x9f3affffffffff".toByteArray() @@ -1349,7 +1260,6 @@ class CborDeserializerSuccessTest { assertEquals(-4294967296, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float16 - +Inf`() { val payload = "0x9ff97c00ff".toByteArray() @@ -1367,7 +1277,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 0 - min`() { val payload = "0x8100".toByteArray() @@ -1385,7 +1294,6 @@ class CborDeserializerSuccessTest { assertEquals(0u, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 1 - min`() { val payload = "0x813800".toByteArray() @@ -1403,7 +1311,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float16 - -Inf`() { val payload = "0x9ff9fc00ff".toByteArray() @@ -1421,7 +1328,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NEGATIVE_INFINITY, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float32`() { val payload = "0x9ffa7f800000ff".toByteArray() @@ -1439,7 +1345,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.fromBits(2139095040), actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 2 - min`() { val payload = "0x81190000".toByteArray() @@ -1457,7 +1362,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 4 - min`() { val payload = "0x811a00000000".toByteArray() @@ -1475,7 +1379,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MIN_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float16 - +Inf`() { val payload = "0x81f97c00".toByteArray() @@ -1493,7 +1396,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of float64`() { val payload = "0x9ffb7ff0000000000000ff".toByteArray() @@ -1511,7 +1413,6 @@ class CborDeserializerSuccessTest { assertEquals(Double.fromBits(9218868437227405312), actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float16 - NaN - MSB`() { val payload = "0x81f97e00".toByteArray() @@ -1529,7 +1430,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of float16 - NaN - LSB`() { val payload = "0x81f97c01".toByteArray() @@ -1547,7 +1447,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite list of boolean false`() { val payload = "0x9ff4ff".toByteArray() @@ -1565,7 +1464,6 @@ class CborDeserializerSuccessTest { assertEquals(false, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 8 - min`() { val payload = "0x813b0000000000000000".toByteArray() @@ -1583,7 +1481,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 8 - max`() { val payload = "0x813bfffffffffffffffe".toByteArray() @@ -1605,7 +1502,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of undefined`() { val payload = "0x81f7".toByteArray() @@ -1619,7 +1515,6 @@ class CborDeserializerSuccessTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of uint - 2 - max`() { val payload = "0x8119ffff".toByteArray() @@ -1637,7 +1532,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MAX_VALUE, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 2 - max`() { val payload = "0x8139ffff".toByteArray() @@ -1655,7 +1549,6 @@ class CborDeserializerSuccessTest { assertEquals(-65536, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `list of negint - 4 - max`() { val payload = "0x813affffffff".toByteArray() @@ -1673,7 +1566,6 @@ class CborDeserializerSuccessTest { assertEquals(-4294967296, actual[0]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - _ uint - 8 - max`() { val payload = "0xbf63666f6f1bffffffffffffffffff".toByteArray() @@ -1697,7 +1589,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of null`() { val payload = "0xa163666f6ff6".toByteArray() @@ -1716,7 +1607,6 @@ class CborDeserializerSuccessTest { assertEquals(null, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - _ negint - 4 - max`() { val payload = "0xbf63666f6f3affffffffff".toByteArray() @@ -1735,7 +1625,6 @@ class CborDeserializerSuccessTest { assertEquals(-4294967296, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - _ float16 - -Inf`() { val payload = "0xbf63666f6ff9fc00ff".toByteArray() @@ -1754,7 +1643,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NEGATIVE_INFINITY, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 2 - max`() { val payload = "0xa163666f6f19ffff".toByteArray() @@ -1773,7 +1661,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - negint - 1 - min`() { val payload = "0xa163666f6f3800".toByteArray() @@ -1792,7 +1679,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of undefined`() { val payload = "0xbf63666f6ff7ff".toByteArray() @@ -1811,7 +1697,6 @@ class CborDeserializerSuccessTest { assertEquals(null, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 0 - max`() { val payload = "0xa163666f6f17".toByteArray() @@ -1830,7 +1715,6 @@ class CborDeserializerSuccessTest { assertEquals(23, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 0 - max`() { val payload = "0xbf63666f6f17ff".toByteArray() @@ -1849,7 +1733,6 @@ class CborDeserializerSuccessTest { assertEquals(23, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 1 - min`() { val payload = "0xbf63666f6f1800ff".toByteArray() @@ -1868,7 +1751,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 8 - min`() { val payload = "0xbf63666f6f1b0000000000000000ff".toByteArray() @@ -1887,7 +1769,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 8 - max`() { val payload = "0xbf63666f6f3bfffffffffffffffeff".toByteArray() @@ -1911,7 +1792,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 2 - min`() { val payload = "0xa163666f6f190000".toByteArray() @@ -1930,7 +1810,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of float16 - NaN - MSB`() { val payload = "0xbf63666f6ff97e00ff".toByteArray() @@ -1949,7 +1828,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - negint - 0 - min`() { val payload = "0xa163666f6f20".toByteArray() @@ -1968,7 +1846,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - float16 - -Inf`() { val payload = "0xa163666f6ff9fc00".toByteArray() @@ -1987,7 +1864,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NEGATIVE_INFINITY, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 1 - max`() { val payload = "0xbf63666f6f38ffff".toByteArray() @@ -2006,7 +1882,6 @@ class CborDeserializerSuccessTest { assertEquals(-256, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 8 - min`() { val payload = "0xbf63666f6f3b0000000000000000ff".toByteArray() @@ -2025,7 +1900,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 1 - min`() { val payload = "0xa163666f6f1800".toByteArray() @@ -2044,7 +1918,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 2 - min`() { val payload = "0xbf63666f6f190000ff".toByteArray() @@ -2063,7 +1936,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 2 - max`() { val payload = "0xbf63666f6f19ffffff".toByteArray() @@ -2082,7 +1954,6 @@ class CborDeserializerSuccessTest { assertEquals(UShort.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 0 - max`() { val payload = "0xbf63666f6f37ff".toByteArray() @@ -2101,7 +1972,6 @@ class CborDeserializerSuccessTest { assertEquals(-24, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 2 - max`() { val payload = "0xbf63666f6f39ffffff".toByteArray() @@ -2120,7 +1990,6 @@ class CborDeserializerSuccessTest { assertEquals(-65536, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of boolean true`() { val payload = "0xa163666f6ff5".toByteArray() @@ -2139,7 +2008,6 @@ class CborDeserializerSuccessTest { assertEquals(true, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of boolean true`() { val payload = "0xbf63666f6ff5ff".toByteArray() @@ -2158,7 +2026,6 @@ class CborDeserializerSuccessTest { assertEquals(true, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of boolean false`() { val payload = "0xbf63666f6ff4ff".toByteArray() @@ -2177,7 +2044,6 @@ class CborDeserializerSuccessTest { assertEquals(false, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 8 - max`() { val payload = "0xa163666f6f1bffffffffffffffff".toByteArray() @@ -2201,7 +2067,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - float16 - NaN - LSB`() { val payload = "0xa163666f6ff97c01".toByteArray() @@ -2220,7 +2085,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 0 - min`() { val payload = "0xbf63666f6f00ff".toByteArray() @@ -2239,7 +2103,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 4 - min`() { val payload = "0xbf63666f6f3a00000000ff".toByteArray() @@ -2258,7 +2121,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of float32`() { val payload = "0xbf63666f6ffa7f800000ff".toByteArray() @@ -2277,7 +2139,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.fromBits(2139095040), actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of uint - 0 - min`() { val payload = "0xa163666f6f00".toByteArray() @@ -2296,7 +2157,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - negint - 1 - max`() { val payload = "0xa163666f6f38ff".toByteArray() @@ -2315,7 +2175,6 @@ class CborDeserializerSuccessTest { assertEquals(-256, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - float64`() { val payload = "0xa163666f6ffb7ff0000000000000".toByteArray() @@ -2334,7 +2193,6 @@ class CborDeserializerSuccessTest { assertEquals(Double.fromBits(9218868437227405312), actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of float16 - NaN - LSB`() { val payload = "0xbf63666f6ff97c01ff".toByteArray() @@ -2353,7 +2211,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 8 - min`() { val payload = "0xa163666f6f1b0000000000000000".toByteArray() @@ -2372,7 +2229,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - negint - 8 - max`() { val payload = "0xa163666f6f3bfffffffffffffffe".toByteArray() @@ -2396,7 +2252,6 @@ class CborDeserializerSuccessTest { assertEquals(ULong.MAX_VALUE, result) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of undefined`() { val payload = "0xa163666f6ff7".toByteArray() @@ -2415,7 +2270,6 @@ class CborDeserializerSuccessTest { assertEquals(null, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of float16 - NaN - MSB`() { val payload = "0xa163666f6ff97e00".toByteArray() @@ -2434,7 +2288,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.NaN, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of negint - 8 - min`() { val payload = "0xa163666f6f3b0000000000000000".toByteArray() @@ -2453,7 +2306,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 4 - max`() { val payload = "0xbf63666f6f1affffffffff".toByteArray() @@ -2472,7 +2324,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 1 - min`() { val payload = "0xbf63666f6f3800ff".toByteArray() @@ -2491,7 +2342,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of float16 - +Inf`() { val payload = "0xbf63666f6ff97c00ff".toByteArray() @@ -2510,7 +2360,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - negint - 2 - min`() { val payload = "0xa163666f6f390000".toByteArray() @@ -2529,7 +2378,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of false`() { val payload = "0xa163666f6ff4".toByteArray() @@ -2548,7 +2396,6 @@ class CborDeserializerSuccessTest { assertEquals(false, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of float32`() { val payload = "0xa163666f6ffa7f800000".toByteArray() @@ -2567,7 +2414,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.fromBits(2139095040), actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 1 - max`() { val payload = "0xbf63666f6f18ffff".toByteArray() @@ -2586,7 +2432,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of negint - 0 - max`() { val payload = "0xa163666f6f37".toByteArray() @@ -2605,7 +2450,6 @@ class CborDeserializerSuccessTest { assertEquals(-24, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of negint - 4 - max`() { val payload = "0xa163666f6f3affffffff".toByteArray() @@ -2624,7 +2468,6 @@ class CborDeserializerSuccessTest { assertEquals(-4294967296, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of float16 - +Inf`() { val payload = "0xa163666f6ff97c00".toByteArray() @@ -2643,7 +2486,6 @@ class CborDeserializerSuccessTest { assertEquals(Float.POSITIVE_INFINITY, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of float64`() { val payload = "0xbf63666f6ffb7ff0000000000000ff".toByteArray() @@ -2662,7 +2504,6 @@ class CborDeserializerSuccessTest { assertEquals(Double.fromBits(9218868437227405312), actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of uint - 1 - max`() { val payload = "0xa163666f6f18ff".toByteArray() @@ -2681,7 +2522,6 @@ class CborDeserializerSuccessTest { assertEquals(UByte.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map - uint - 4 - max`() { val payload = "0xa163666f6f1affffffff".toByteArray() @@ -2700,7 +2540,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MAX_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of negint - 2 - max`() { val payload = "0xa163666f6f39ffff".toByteArray() @@ -2719,7 +2558,6 @@ class CborDeserializerSuccessTest { assertEquals(-65536, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of uint - 4 - min`() { val payload = "0xbf63666f6f1a00000000ff".toByteArray() @@ -2738,7 +2576,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 0 - min`() { val payload = "0xbf63666f6f20ff".toByteArray() @@ -2757,7 +2594,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of null`() { val payload = "0xbf63666f6ff6ff".toByteArray() @@ -2776,7 +2612,6 @@ class CborDeserializerSuccessTest { assertEquals(null, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of uint - 4 - min`() { val payload = "0xa163666f6f1a00000000".toByteArray() @@ -2795,7 +2630,6 @@ class CborDeserializerSuccessTest { assertEquals(UInt.MIN_VALUE, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `map of negint - 4 - min`() { val payload = "0xa163666f6f3a00000000".toByteArray() @@ -2814,7 +2648,6 @@ class CborDeserializerSuccessTest { assertEquals(-1, actual.entries.first().value) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun `indefinite map of negint - 2 - min`() { val payload = "0xbf63666f6f390000ff".toByteArray() diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt index 93a5b10806..47b04a590d 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt @@ -11,7 +11,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFails class CborDeserializerTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNumberDeserializationThrowsOnOutOfRange() { val serializer = CborSerializer() diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt index b8c45af823..cbe338df1a 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt @@ -18,7 +18,6 @@ import kotlin.time.Duration.Companion.seconds @OptIn(ExperimentalStdlibApi::class) class CborSerializerTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBoolean() { val tests = listOf(true, false, true, false, false) @@ -37,7 +36,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testByte() { val tests = listOf(Byte.MIN_VALUE, -34, 0, 39, Byte.MAX_VALUE) @@ -55,7 +53,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testChar() { val tests = listOf( @@ -80,7 +77,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInt() { val tests = listOf(Int.MIN_VALUE, -34, 0, 39, 402, Int.MAX_VALUE) @@ -98,7 +94,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testLong() { val tests = listOf(Long.MIN_VALUE, -34, 0, 39, 402, Long.MAX_VALUE) @@ -116,7 +111,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testFloat() { val tests = listOf( @@ -148,7 +142,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDouble() { val tests = listOf( @@ -176,7 +169,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBigInteger() { val tests = listOf( @@ -208,7 +200,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testBigDecimal() { val tests = listOf( @@ -248,7 +239,6 @@ class CborSerializerTest { assertEquals("c48221196ab3", serializer.toByteArray().toHexString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testString() { val tests = listOf( @@ -275,7 +265,6 @@ class CborSerializerTest { assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInstant() { val tests = listOf( @@ -290,7 +279,6 @@ class CborSerializerTest { Instant.now() + 10.days, Instant.now() + 365.days, Instant.now() + 1825.days, - Instant.MAX_VALUE, ) val serializer = CborSerializer() @@ -302,16 +290,13 @@ class CborSerializerTest { val buffer = SdkBuffer().apply { write(serializer.toByteArray()) } val deserializer = CborPrimitiveDeserializer(buffer) - tests.dropLast(1).forEach { + tests.forEach { assertEquals(it.epochMilliseconds, deserializer.deserializeInstant(TimestampFormat.EPOCH_SECONDS).epochMilliseconds) } - // FIXME Serializing -> deserializing Instant.MAX_VALUE results in a one millisecond offset... - assertEquals(Instant.MAX_VALUE.epochMilliseconds, deserializer.deserializeInstant(TimestampFormat.EPOCH_SECONDS).epochMilliseconds - 1) assertEquals(0, buffer.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testNull() { val serializer = CborSerializer() @@ -323,7 +308,6 @@ class CborSerializerTest { assertNull(deserializer.deserializeNull()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testDocument() { val serializer = CborSerializer() @@ -332,7 +316,6 @@ class CborSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testList() { val serializer = CborSerializer() @@ -369,7 +352,6 @@ class CborSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testMap() { val serializer = CborSerializer() diff --git a/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt b/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt index 9874dbafa4..20e6747616 100644 --- a/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt +++ b/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt @@ -100,7 +100,6 @@ class FormUrlSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesStructs() { val struct = PrimitiveStructTest() @@ -125,7 +124,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesEmptyStrings() { // see `string` from https://awslabs.github.io/smithy/1.0/spec/aws/aws-query-protocol.html#x-www-form-urlencoded-shape-serialization @@ -188,7 +186,6 @@ class FormUrlSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesLists() { val input = ListInput( @@ -210,7 +207,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesFlattenedLists() { // xmlFlattened() lists @@ -235,7 +231,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesListsWithRenamedMember() { // xmlName() trait on list member @@ -257,7 +252,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesClassWithNestedClassField() { val a = A( @@ -317,7 +311,6 @@ class FormUrlSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesMaps() { val input = MapInput( @@ -351,7 +344,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itSerializesMapOfLists() { val input = MapInput( @@ -400,7 +392,6 @@ class FormUrlSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesMapOfMapOfPrimitive() { val expected = """ @@ -422,7 +413,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesFlattenedMaps() { val input = MapInput( @@ -491,7 +481,6 @@ class FormUrlSerializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesNestedMaps() { val input = NestedStructureInput( @@ -511,7 +500,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesNestedLists() { val input = NestedStructureInput( @@ -529,7 +517,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesRenamedMaps() { // map with xmlName key/value overrides @@ -567,7 +554,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesQueryLiterals() { // test SdkObjectDescriptor with query literals trait @@ -599,7 +585,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itEncodesWhitespace() { val input = MapInput( @@ -624,7 +609,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesEmptyList() { val input = ListInput( @@ -642,7 +626,6 @@ class FormUrlSerializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itSerializesEmptyListInMap() { val input = MapInput( diff --git a/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt b/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt index fd12b97a95..54a5a19c1b 100644 --- a/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt +++ b/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt @@ -100,7 +100,6 @@ class JsonDeserializerTest { assertEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun itHandlesBigInteger() { val tests = listOf( @@ -118,7 +117,6 @@ class JsonDeserializerTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itHandlesBigDecimal() { val tests = listOf( diff --git a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt index 6798ed3d0b..1bae6d2fa9 100644 --- a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt +++ b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt @@ -20,7 +20,6 @@ class HttpRequestTestBuilderTest { private val execContext = ExecutionContext() - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsHttpMethod() { val ex = assertFails { @@ -39,7 +38,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("expected method: `POST`; got: `GET`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsUri() { val ex = assertFails { @@ -60,7 +58,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("expected path: `/foo`; got: `/bar`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsQueryParameters() { val ex = assertFails { @@ -89,7 +86,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("Query parameter `Hi` does not contain expected value `Hello%20there`. Actual values: [Hello]") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsForbiddenQueryParameters() { val ex = assertFails { @@ -120,7 +116,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("forbidden query parameter found: `foobar`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsRequiredQueryParameters() { val ex = assertFails { @@ -152,7 +147,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("required query parameter not found: `requiredQuery`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsHeaders() { val ex = assertFails { @@ -193,7 +187,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("expected header `k2` has no actual values") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsListsOfHeaders() { val ex = assertFails { @@ -222,7 +215,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("expected header name value pair not equal: `k2:v3, v4, v5`; found: `k2:v3, v4") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsForbiddenHeaders() { val ex = assertFails { @@ -266,7 +258,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("forbidden header found: `forbiddenHeader`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsRequiredHeaders() { val ex = assertFails { @@ -311,7 +302,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("expected required header not found: `requiredHeader`") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itFailsWhenBodyAssertFunctionIsMissing() { val ex = assertFails { @@ -331,7 +321,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("body assertion function is required if an expected body is defined") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itCallsBodyAssertFunction() { val ex = assertFails { @@ -352,7 +341,6 @@ class HttpRequestTestBuilderTest { ex.message.shouldContain("actual bytes read does not match expected") } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itAssertsHostWhenSet() { val ex = assertFails { diff --git a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt index 8571acdb17..02e725c093 100644 --- a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt +++ b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt @@ -15,7 +15,6 @@ import kotlin.test.Test class HttpResponseTestBuilderTest { private data class Foo(val bar: Int, val baz: String) - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun itBuildsResponses() { httpResponseTest { From 617aa4c71247d7bc4b89e454f73f0795e8a4ae56 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:42:18 -0500 Subject: [PATCH 41/65] ktlint --- .../aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 1 - .../aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt | 1 - .../kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt | 1 - .../kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt | 1 - .../kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt | 1 - .../smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt | 1 - .../kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt | 1 - .../aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt | 1 - .../kotlin/runtime/http/engine/crt/RequestConversionTest.kt | 1 - .../runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt | 1 - .../smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt | 1 - .../aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt | 1 - .../smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt | 1 - .../runtime/http/interceptors/CachingChecksumInterceptorTest.kt | 1 - .../http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt | 1 - .../interceptors/FlexibleChecksumsResponseInterceptorTest.kt | 1 - .../http/interceptors/HttpChecksumRequiredInterceptorTest.kt | 1 - .../http/interceptors/RequestCompressionInterceptorTest.kt | 1 - .../http/interceptors/ResponseLengthValidationInterceptorTest.kt | 1 - .../runtime/http/middleware/DefaultValidateResponseTest.kt | 1 - .../smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt | 1 - .../smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt | 1 - .../kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt | 1 - .../runtime/http/operation/HttpInterceptorTypeValidationTest.kt | 1 - .../smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt | 1 - .../kotlin/runtime/http/operation/SdkOperationExecutionTest.kt | 1 - .../aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt | 1 - .../common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt | 1 - .../common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt | 1 - .../aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt | 1 - .../aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt | 1 - .../cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt | 1 - .../awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt | 1 - .../kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt | 1 - .../kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt | 1 - .../aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt | 1 - .../aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt | 1 - .../smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt | 1 - .../aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt | 1 - .../kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt | 1 - .../kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt | 1 - 41 files changed, 41 deletions(-) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index e8b1b6feae..7d10b35e14 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http.auth -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigner diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt index 3f0e089c09..4c8ee5c3ba 100644 --- a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt +++ b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/SdkSourceBodyStreamTest.kt @@ -6,7 +6,6 @@ package aws.smithy.kotlin.runtime.crt import aws.sdk.kotlin.crt.io.MutableBuffer -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.io.SdkSource import aws.smithy.kotlin.runtime.io.source diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt index 6be7591c00..4e35cb58dc 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameDecoderTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.eventstream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.* import io.kotest.matchers.string.shouldContain import kotlinx.coroutines.flow.* diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt index 6bfba22f36..ccc80102ed 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/FrameEncoderTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.eventstream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.readAll import aws.smithy.kotlin.runtime.io.SdkBuffer import kotlinx.coroutines.flow.flowOf diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt index 1a8689397c..16602572ea 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/HeaderValueTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.eventstream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.util.Uuid import io.kotest.matchers.string.shouldContain diff --git a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt index 5ba8e9af14..4b37771253 100644 --- a/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt +++ b/runtime/protocol/aws-event-stream/common/test/aws/smithy/kotlin/runtime/awsprotocol/eventstream/MessageTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.eventstream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.EOFException import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.time.Instant diff --git a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt index 168589c041..b26ed992af 100644 --- a/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt +++ b/runtime/protocol/aws-json-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/json/AwsJsonProtocolTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.awsprotocol.json -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.operation.* diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index 589e8d674e..f948ea7dc9 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.complete diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt index 7180c10c9d..88e88561e7 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/RequestConversionTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.crt.ReadChannelBodyStream import aws.smithy.kotlin.runtime.http.* diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index 286ac61cad..005d577f74 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -7,7 +7,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt import aws.sdk.kotlin.crt.http.* import aws.sdk.kotlin.crt.io.byteArrayBuffer -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.HttpErrorCode import aws.smithy.kotlin.runtime.http.HttpException diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt index 86cb5d57bf..88366c41f0 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SendChunkedBodyTest.kt @@ -6,7 +6,6 @@ package aws.smithy.kotlin.runtime.http.engine.crt import aws.sdk.kotlin.crt.http.HttpStream -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.toHttpBody import aws.smithy.kotlin.runtime.io.SdkByteReadChannel import aws.smithy.kotlin.runtime.io.readToByteArray diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt index 61fab9962b..cb41cff0d4 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpCallContextTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http.engine -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.HttpCall diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt index 2b330a1ec3..4468534cb8 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/engine/HttpClientEngineTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.engine -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.HttpCall import aws.smithy.kotlin.runtime.http.complete diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt index 06aa9c8dfd..cee1db7766 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/CachingChecksumInterceptorTest.kt @@ -2,7 +2,6 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.HttpBody diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt index 347a7b130a..37e5054865 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsRequestInterceptorTest.kt @@ -6,7 +6,6 @@ package aws.smithy.kotlin.runtime.http.interceptors import aws.smithy.kotlin.runtime.ClientException -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.client.config.RequestHttpChecksumConfig import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.hashing.toHashFunction diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt index e11fdd18a5..e465499ad1 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/FlexibleChecksumsResponseInterceptorTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.client.config.ResponseHttpChecksumConfig import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.* diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt index eb06bb633b..df2cf49f0e 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/HttpChecksumRequiredInterceptorTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.hashing.Crc32 import aws.smithy.kotlin.runtime.http.HttpBody diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt index 3f6666d0c2..11163c4a61 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/RequestCompressionInterceptorTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.compression.CompressionAlgorithm import aws.smithy.kotlin.runtime.compression.Gzip diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt index cbcb01f452..e9730f726c 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/interceptors/ResponseLengthValidationInterceptorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.HttpCall import aws.smithy.kotlin.runtime.http.operation.* diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt index c1c10e8ffa..71d1d67ce2 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/DefaultValidateResponseTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http.middleware -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.HttpCall diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt index eae995dded..f97a982714 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/MutateHeadersTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.middleware -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt index 4c7bd7e5ed..d80c48ab75 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/middleware/RetryMiddlewareTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.middleware -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.collections.get import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.operation.HttpOperationContext diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt index 03510423f9..297b9db295 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorOrderTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.operation -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt index e1582ece99..7d2cd3d88f 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTypeValidationTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.operation -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.client.* import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor import aws.smithy.kotlin.runtime.http.request.HttpRequest diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt index 766b1e13dd..22e36d1cf1 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkHttpOperationTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.operation -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.httptest.TestEngine diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt index a6f2dc53a8..11657db007 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/SdkOperationExecutionTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.operation -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.AuthSchemeId import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.HttpBody diff --git a/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt b/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt index b7b2f9e9af..b8f0a41f15 100644 --- a/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt +++ b/runtime/protocol/http-test/common/test/aws/smithy/kotlin/runtime/httptest/TestConnectionTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.httptest -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.net.Host diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt index f2022359e7..b7ec3fe6c0 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt index 9667b9284e..844d054166 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpBodyTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.io.SdkByteChannel diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt index fe713d42e8..79675b689a 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HttpRequestBuilderTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.http -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.http.content.ByteArrayContent import aws.smithy.kotlin.runtime.http.request.HttpRequest diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt index 9e8fe42c52..2f07d3cd5b 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/response/HttpResponseTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.response -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.HttpBody diff --git a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt index 54b6e28805..1a795be3c8 100644 --- a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt +++ b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/RpcV2CborSmithyProtocolResponseHeaderInterceptorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.awsprotocol.rpcv2.cbor -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.ServiceException import aws.smithy.kotlin.runtime.http.* import aws.smithy.kotlin.runtime.http.operation.* diff --git a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt index a3f45cb545..b478925733 100644 --- a/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt +++ b/runtime/protocol/smithy-rpcv2-protocols/common/test/aws/smithy/kotlin/runtime/awsprotocol/rpcv2/cbor/Rpcv2CborErrorDeserializerTest.kt @@ -2,7 +2,6 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.awsprotocol.rpcv2.cbor.RpcV2CborErrorDeserializer import aws.smithy.kotlin.runtime.serde.SdkFieldDescriptor import aws.smithy.kotlin.runtime.serde.SdkObjectDescriptor diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt index d869b409a6..70d11b6792 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerErrorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.serde.cbor -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.serde.SdkFieldDescriptor import aws.smithy.kotlin.runtime.serde.SerialKind diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt index a2b16fffaa..a9d4b0a7d1 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerSuccessTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.serde.cbor -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.serde.SdkFieldDescriptor import aws.smithy.kotlin.runtime.serde.SerialKind diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt index 47b04a590d..a94891c5cb 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborDeserializerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.serde.cbor -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.SdkBuffer import kotlin.test.Test import kotlin.test.assertEquals diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt index cbe338df1a..80d4121393 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.serde.cbor -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.BigDecimal import aws.smithy.kotlin.runtime.content.BigInteger import aws.smithy.kotlin.runtime.io.SdkBuffer diff --git a/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt b/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt index 20e6747616..ea5662dba7 100644 --- a/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt +++ b/runtime/serde/serde-form-url/common/test/aws/smithy/kotlin/runtime/serde/formurl/FormUrlSerializerTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.serde.formurl -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.serde.* import aws.smithy.kotlin.runtime.time.Instant import aws.smithy.kotlin.runtime.time.TimestampFormat diff --git a/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt b/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt index 54a5a19c1b..bd96e92173 100644 --- a/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt +++ b/runtime/serde/serde-json/common/test/aws/smithy/kotlin/runtime/serde/json/JsonDeserializerTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.serde.json -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.content.Document import aws.smithy.kotlin.runtime.content.buildDocument import aws.smithy.kotlin.runtime.serde.* diff --git a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt index 1bae6d2fa9..140fea8d25 100644 --- a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt +++ b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpRequestTestBuilderTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.smithy.test -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.request.HttpRequest diff --git a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt index 02e725c093..5a66bd33be 100644 --- a/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt +++ b/runtime/smithy-test/common/test/aws/smithy/kotlin/runtime/smithy/test/HttpResponseTestBuilderTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.smithy.test -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpStatusCode import aws.smithy.kotlin.runtime.http.readAll import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder From 404f199883f780aeaa6067a002b2b6b942d23cbe Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 17:43:14 -0500 Subject: [PATCH 42/65] re-ignore `testStreamNotConsumed` --- .../smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index f948ea7dc9..7d0b0def83 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.http.engine.crt +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpMethod import aws.smithy.kotlin.runtime.http.SdkHttpClient import aws.smithy.kotlin.runtime.http.complete @@ -36,7 +37,7 @@ class AsyncStressTest : TestWithLocalServer() { } }.start() -// @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation + @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testStreamNotConsumed() = runBlocking { // test that filling the stream window and not consuming the body stream still cleans up resources From cc91c32fad85e8bd8225da4be2bae39c03410aa1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 19:03:34 -0500 Subject: [PATCH 43/65] Fix `testFormatAsRfc5322` --- .../src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt index 3585a2efde..e2130b4e1d 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt @@ -107,7 +107,12 @@ internal object DateTimeFormats { dayOfWeek(DayOfWeekNames.ENGLISH_ABBREVIATED) chars(", ") - dayOfMonth(padding = Padding.NONE) + alternativeParsing({ + dayOfMonth(padding = Padding.NONE) + }) { + dayOfMonth() + } + char(' ') monthName(MonthNames.ENGLISH_ABBREVIATED) char(' ') From 2c6a5871ed808b324bfc91acd7650326521a4093 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 21:03:00 -0500 Subject: [PATCH 44/65] Disable signing tests --- .../runtime/auth/awssigning/tests/BasicSigningTestBase.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index 2a517fc090..3f4e1e1d17 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.tests +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.http.HttpBody @@ -55,6 +56,7 @@ public abstract class BasicSigningTestBase : HasSigner { credentials = DEFAULT_TEST_CREDENTIALS } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignRequestSigV4(): TestResult = runTest { // sanity test @@ -83,6 +85,7 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(expectedSig, result.signature.decodeToString()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public open fun testSignRequestSigV4Asymmetric(): TestResult = runTest { // sanity test @@ -165,6 +168,7 @@ public abstract class BasicSigningTestBase : HasSigner { return chunk } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignChunks(): TestResult = runTest { val request = createChunkedTestRequest() @@ -188,6 +192,7 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(EXPECTED_FINAL_CHUNK_SIGNATURE, finalChunkResult.signature.decodeToString()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSigningCopiesInput(): TestResult = runTest { // sanity test the signer doesn't mutate the input and instead copies to a new request From c64d203ad3b61dc36b4c34a5f48a8c33e45bca02 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 21:19:49 -0500 Subject: [PATCH 45/65] Catch kotlinx.datetime.DateTimeFormatException, throw aws.smithy.kotlin.runtime.time.ParseException --- .../common/test/ClockSkewInterceptorTest.kt | 2 +- .../kotlin/runtime/time/InstantNative.kt | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt index 17d33bf82a..71afea0700 100644 --- a/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt +++ b/runtime/protocol/aws-protocol-core/common/test/ClockSkewInterceptorTest.kt @@ -108,7 +108,7 @@ class ClockSkewInterceptorTest { op.interceptors.add(ClockSkewInterceptor()) if (expectException) { - assertFails { + assertFailsWith { op.roundTrip(client, Unit) } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 899419245a..1dce706775 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.time +import aws.smithy.kotlin.runtime.SdkBaseException import kotlinx.datetime.Clock import kotlinx.datetime.format import kotlin.time.Duration @@ -62,7 +63,7 @@ public actual class Instant(internal val delegate: KtInstant) : Comparable Date: Tue, 4 Feb 2025 21:40:49 -0500 Subject: [PATCH 46/65] re-ignore AwsChunkedByteReadChannelTestBase --- .../auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt index f86ef5ba3a..3374dedc42 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.io.* @@ -17,6 +18,7 @@ import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds abstract class AwsChunkedByteReadChannelTestBase : AwsChunkedTestBase(AwsChunkedReaderFactory.Channel) { + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSlowProducerMultipleChunksPartialLast(): TestResult = runTest { val numChunks = 6 From 49f44bfe55d363e58bdae5cceee714c50c6f55a7 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 22:13:53 -0500 Subject: [PATCH 47/65] ktlint --- .../native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 1dce706775..5e47dbc93c 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.time -import aws.smithy.kotlin.runtime.SdkBaseException import kotlinx.datetime.Clock import kotlinx.datetime.format import kotlin.time.Duration From 2942895cc6e67488054db81213327f016cc70b2d Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 22:14:41 -0500 Subject: [PATCH 48/65] Disable more tests --- .../auth/awssigning/tests/AwsChunkedTestBase.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt index 10247109ae..be05b88eb9 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.http.DeferredHeaders @@ -171,6 +172,7 @@ abstract class AwsChunkedTestBase( return length } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadNegativeOffset(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -184,6 +186,7 @@ abstract class AwsChunkedTestBase( } } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExactBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -217,6 +220,7 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExcessiveBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -246,6 +250,7 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadFewerBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -272,6 +277,7 @@ abstract class AwsChunkedTestBase( assertFalse(awsChunked.isClosedForRead()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleFullChunks(): TestResult = runTest { val numChunks = 5 @@ -319,6 +325,7 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleChunksLastChunkNotFull(): TestResult = runTest { val numChunks = 6 @@ -384,6 +391,7 @@ abstract class AwsChunkedTestBase( assertEquals(0, chunkSizes.last()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -434,6 +442,7 @@ abstract class AwsChunkedTestBase( assertEquals(expectedTrailerSignature.decodeToString(), trailerSignature) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunk(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -465,6 +474,7 @@ abstract class AwsChunkedTestBase( assertEquals(chunkSizes[1], 0) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunkWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES From 49663c0d9715e58832dc69ee54f0f66d4abd9a46 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 22:32:37 -0500 Subject: [PATCH 49/65] Ignore signingKey test --- .../runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt index fc5c23304c..a16ceee175 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.tests.DEFAULT_TEST_CREDENTIALS import aws.smithy.kotlin.runtime.hashing.sha256 @@ -32,6 +33,7 @@ class DefaultSignatureCalculatorTest { } // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. Need to fix parsing ISO 8601 to try all possible formats @Test fun testSigningKey() = runTest { val config = AwsSigningConfig { From 5daf945edbcd8eca421e585e9d4cd039254b80f2 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 4 Feb 2025 23:38:30 -0500 Subject: [PATCH 50/65] Ignore AwsHttpSignerTestBase --- .../smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 7d10b35e14..1786744b01 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.http.auth +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigner @@ -133,6 +134,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test public fun testSignReplayableStreamingRequest(): TestResult = runTest { val op = buildOperation(streaming = true) @@ -146,6 +148,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test public fun testSignAwsChunkedStreamNonReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -159,6 +162,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test public fun testSignAwsChunkedStreamReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -172,6 +176,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test public fun testSignOneShotStream(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false) From 5e3d785008fa02f98a0564bf1e96a94437df073f Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 09:13:24 -0500 Subject: [PATCH 51/65] testStreamError --- .../runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index 005d577f74..7382adcca4 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -7,6 +7,7 @@ package aws.smithy.kotlin.runtime.http.engine.crt import aws.sdk.kotlin.crt.http.* import aws.sdk.kotlin.crt.io.byteArrayBuffer +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.HttpErrorCode import aws.smithy.kotlin.runtime.http.HttpException @@ -152,6 +153,7 @@ class SdkStreamResponseHandlerTest { assertEquals(data, respChan.readToBuffer().readUtf8()) } + @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test fun testStreamError() = runTest { val handler = SdkStreamResponseHandler(mockConn, coroutineContext) From dc65792d0b288e254f3c280e3e577287abe37ebd Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 15:47:10 -0500 Subject: [PATCH 52/65] Update JVM `Instant` min/max values to be equal to Native's --- runtime/runtime-core/build.gradle.kts | 2 +- .../jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt | 5 +++-- .../smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/runtime-core/build.gradle.kts b/runtime/runtime-core/build.gradle.kts index 7a4bdd17fa..cd9e4e8b3f 100644 --- a/runtime/runtime-core/build.gradle.kts +++ b/runtime/runtime-core/build.gradle.kts @@ -22,13 +22,13 @@ kotlin { implementation(libs.okio) // Coroutines' locking features are used in retry token bucket implementations api(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.datetime) } } nativeMain { dependencies { api(libs.crt.kotlin) - implementation(libs.kotlinx.datetime) } } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt index e1a17cd8c0..3f0f1459fa 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/time/InstantJVM.kt @@ -25,6 +25,7 @@ import kotlin.time.Duration import kotlin.time.toKotlinDuration import java.time.Duration as jtDuration import java.time.Instant as jtInstant +import kotlinx.datetime.Instant as KtInstant // FIXME Consider making this multiplatform (`common`) using kotlinx.datetime public actual class Instant(internal val value: jtInstant) : Comparable { @@ -136,12 +137,12 @@ public actual class Instant(internal val value: jtInstant) : Comparable /** * Create an [Instant] with the minimum possible value */ - public actual val MIN_VALUE: Instant = Instant(jtInstant.MIN) + public actual val MIN_VALUE: Instant = fromEpochMilliseconds(KtInstant.DISTANT_PAST.toEpochMilliseconds()) /** * Create an [Instant] with the maximum possible value */ - public actual val MAX_VALUE: Instant = Instant(jtInstant.MAX) + public actual val MAX_VALUE: Instant = fromEpochMilliseconds(KtInstant.DISTANT_FUTURE.toEpochMilliseconds()) } } diff --git a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt index 80d4121393..63da8441e5 100644 --- a/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt +++ b/runtime/serde/serde-cbor/common/test/aws/smithy/kotlin/runtime/serde/cbor/CborSerializerTest.kt @@ -278,6 +278,7 @@ class CborSerializerTest { Instant.now() + 10.days, Instant.now() + 365.days, Instant.now() + 1825.days, + Instant.MAX_VALUE, ) val serializer = CborSerializer() From eb971de9a0be325662b3f9ab86ae140598606a69 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 15:47:53 -0500 Subject: [PATCH 53/65] Re-enable flaky test --- .../test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt b/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt index 99cd58b75c..63faeb120c 100644 --- a/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/test-suite/common/test/aws/smithy/kotlin/runtime/http/test/AsyncStressTest.kt @@ -16,7 +16,6 @@ import kotlin.time.Duration.Companion.milliseconds class AsyncStressTest : AbstractEngineTest() { - @Ignore // FIXME Flaky test on JVM: aws.smithy.kotlin.runtime.http.HttpException: java.io.IOException: unexpected end of stream on http://127.0.0.1:8082/...; HttpErrorCode(CONNECTION_CLOSED) @Test fun testConcurrentRequests() = testEngines { // https://github.com/awslabs/aws-sdk-kotlin/issues/170 From 2197a75b9ad7cc2c8570461f8963dc08d5277ed3 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 16:19:33 -0500 Subject: [PATCH 54/65] Re-enable testSigningKey after fixing Native's fromIso8601 implementation --- .../DefaultSignatureCalculatorTest.kt | 1 - .../smithy/kotlin/runtime/time/InstantTest.kt | 4 +++ .../kotlin/runtime/time/DateTimeFormats.kt | 12 +++++++++ .../kotlin/runtime/time/InstantNative.kt | 27 +++++++++++++------ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt index a16ceee175..a176aea11a 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt @@ -33,7 +33,6 @@ class DefaultSignatureCalculatorTest { } // Test adapted from https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. Need to fix parsing ISO 8601 to try all possible formats @Test fun testSigningKey() = runTest { val config = AwsSigningConfig { diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt index 9659754e4c..c50bbd6d85 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/time/InstantTest.kt @@ -56,6 +56,10 @@ class InstantTest { // leap second - dropped to: 2020-12-31T23:59:59 FromTest("2020-12-31T23:59:60Z", 1609459199, 0), + + // condensed, date only + FromTest("20250205", 1738713600, 0), + FromTest("20231127", 1701043200, 0), ) @Test diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt index e2130b4e1d..7d7ed8261c 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt @@ -8,6 +8,7 @@ package aws.smithy.kotlin.runtime.time import kotlinx.datetime.LocalDate import kotlinx.datetime.UtcOffset import kotlinx.datetime.format.DateTimeComponents +import kotlinx.datetime.format.DateTimeFormat import kotlinx.datetime.format.DayOfWeekNames import kotlinx.datetime.format.MonthNames import kotlinx.datetime.format.Padding @@ -131,3 +132,14 @@ internal object DateTimeFormats { } } } + +/** + * ISO8601 condensed, date only. Corresponds to [TimestampFormat.ISO_8601_CONDENSED_DATE]. + * Used only for _parsing_ ISO8601 condensed strings. Instant.parse() will fail if using [DateTimeFormats.ISO_8601_CONDENSED_DATE] + * because that is a [DateTimeFormat] which requires a time component to be present. + */ +internal val ISO_8601_CONDENSED_DATE_LOCALDATE = LocalDate.Format { + year() + monthNumber() + dayOfMonth() + } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 5e47dbc93c..e3267c796a 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -6,7 +6,13 @@ package aws.smithy.kotlin.runtime.time import kotlinx.datetime.Clock +import kotlinx.datetime.LocalDate +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.LocalTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.format +import kotlinx.datetime.toInstant import kotlin.time.Duration import kotlinx.datetime.Instant as KtInstant @@ -62,17 +68,22 @@ public actual class Instant(internal val delegate: KtInstant) : Comparable + try { + return Instant(parseFn()) + } catch (e: IllegalArgumentException) { + parseException.value.addSuppressed(e) } } - Instant(parsed.toInstantUsingOffset()) - } catch (e: IllegalArgumentException) { - throw ParseException(ts, "Failed to parse $ts into an ISO-8601 timestamp", 0) + throw parseException.value } /** From a50fced479ede53022064018c4e00f8b4b460bba Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 16:20:08 -0500 Subject: [PATCH 55/65] ktlint --- .../auth/awssigning/DefaultSignatureCalculatorTest.kt | 1 - .../src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt | 8 ++++---- .../src/aws/smithy/kotlin/runtime/time/InstantNative.kt | 3 --- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt index a176aea11a..fc5c23304c 100644 --- a/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt +++ b/runtime/auth/aws-signing-default/common/test/aws/smithy/kotlin/runtime/auth/awssigning/DefaultSignatureCalculatorTest.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.tests.DEFAULT_TEST_CREDENTIALS import aws.smithy.kotlin.runtime.hashing.sha256 diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt index 7d7ed8261c..550a95cfe1 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/DateTimeFormats.kt @@ -139,7 +139,7 @@ internal object DateTimeFormats { * because that is a [DateTimeFormat] which requires a time component to be present. */ internal val ISO_8601_CONDENSED_DATE_LOCALDATE = LocalDate.Format { - year() - monthNumber() - dayOfMonth() - } + year() + monthNumber() + dayOfMonth() +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index e3267c796a..1da4e870a7 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -7,12 +7,9 @@ package aws.smithy.kotlin.runtime.time import kotlinx.datetime.Clock import kotlinx.datetime.LocalDate -import kotlinx.datetime.LocalDateTime -import kotlinx.datetime.LocalTime import kotlinx.datetime.TimeZone import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.format -import kotlinx.datetime.toInstant import kotlin.time.Duration import kotlinx.datetime.Instant as KtInstant From a1e373e2bdce73a0668f9d026e7a74988f130018 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 22:40:55 -0500 Subject: [PATCH 56/65] Add KotlinxDatetimeJvm transform --- .brazil.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.brazil.json b/.brazil.json index dbb2135d1b..0d39c288de 100644 --- a/.brazil.json +++ b/.brazil.json @@ -2,7 +2,6 @@ "dependencies": { "org.jetbrains.kotlin:kotlin-stdlib:2.*": "KotlinStdlib-2.x", "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.*": "KotlinxCoroutinesCoreJvm-1.x", - "com.squareup.okhttp3:okhttp-coroutines:5.*": "OkHttp3Coroutines-5.x", "com.squareup.okhttp3:okhttp:5.*": "OkHttp3-5.x", "com.squareup.okio:okio-jvm:3.*": "OkioJvm-3.x", @@ -10,7 +9,8 @@ "org.slf4j:slf4j-api:2.*": "Maven-org-slf4j_slf4j-api-2.x", "aws.sdk.kotlin.crt:aws-crt-kotlin:0.9.*": "AwsCrtKotlin-0.9.x", "aws.sdk.kotlin.crt:aws-crt-kotlin:0.8.*": "AwsCrtKotlin-0.8.x", - "com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x" + "com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x", + "org.jetbrains.kotlinx:kotlinx-datetime:0.*": "KotlinxDatetimeJvm-0.x" }, "packageHandlingRules": { "versioning": { From 75db9e6aa0e3014c3a8778201bf11e30ce4a692d Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 23:21:23 -0500 Subject: [PATCH 57/65] Add -jvm --- .brazil.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.brazil.json b/.brazil.json index 0d39c288de..1b1a908eb0 100644 --- a/.brazil.json +++ b/.brazil.json @@ -10,7 +10,7 @@ "aws.sdk.kotlin.crt:aws-crt-kotlin:0.9.*": "AwsCrtKotlin-0.9.x", "aws.sdk.kotlin.crt:aws-crt-kotlin:0.8.*": "AwsCrtKotlin-0.8.x", "com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x", - "org.jetbrains.kotlinx:kotlinx-datetime:0.*": "KotlinxDatetimeJvm-0.x" + "org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.*": "KotlinxDatetimeJvm-0.x" }, "packageHandlingRules": { "versioning": { From 6ca94cc7b5f9d15cf2e61a73320cd03f6fb1d786 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 5 Feb 2025 23:28:20 -0500 Subject: [PATCH 58/65] Remove `lazy` --- .../src/aws/smithy/kotlin/runtime/time/InstantNative.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 1da4e870a7..9ac7639ff8 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -66,7 +66,7 @@ public actual class Instant(internal val delegate: KtInstant) : Comparable Date: Wed, 5 Feb 2025 23:39:05 -0500 Subject: [PATCH 59/65] kt --- .../native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt index 9ac7639ff8..01edcaf1af 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/time/InstantNative.kt @@ -66,7 +66,7 @@ public actual class Instant(internal val delegate: KtInstant) : Comparable Date: Thu, 6 Feb 2025 10:26:36 -0800 Subject: [PATCH 60/65] fix: correctly check equality for CaseInsensitiveMap (#1235) --- .../4820850c-8916-47f5-a7e1-8880e6a00d22.json | 5 + runtime/runtime-core/api/runtime-core.api | 1 + .../runtime/collections/CaseInsensitiveMap.kt | 22 ++- .../CaseInsensitiveMutableStringSet.kt | 40 ++++++ .../collections/CaseInsensitiveString.kt | 11 ++ .../kotlin/runtime/collections/ValuesMap.kt | 16 +-- .../collections/CaseInsensitiveMapTest.kt | 66 +++++++++ .../CaseInsensitiveMutableStringSetTest.kt | 125 ++++++++++++++++++ .../collections/CaseInsensitiveStringTest.kt | 27 ++++ 9 files changed, 291 insertions(+), 22 deletions(-) create mode 100644 .changes/4820850c-8916-47f5-a7e1-8880e6a00d22.json create mode 100644 runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSet.kt create mode 100644 runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveString.kt create mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSetTest.kt create mode 100644 runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveStringTest.kt diff --git a/.changes/4820850c-8916-47f5-a7e1-8880e6a00d22.json b/.changes/4820850c-8916-47f5-a7e1-8880e6a00d22.json new file mode 100644 index 0000000000..297f7e603f --- /dev/null +++ b/.changes/4820850c-8916-47f5-a7e1-8880e6a00d22.json @@ -0,0 +1,5 @@ +{ + "id": "4820850c-8916-47f5-a7e1-8880e6a00d22", + "type": "bugfix", + "description": "Fix errors in equality checks for `CaseInsensitiveMap` which affect `Headers` and `ValuesMap` implementations" +} \ No newline at end of file diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 6d39c3b417..0d5399d430 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -306,6 +306,7 @@ public class aws/smithy/kotlin/runtime/collections/ValuesMapImpl : aws/smithy/ko public fun getAll (Ljava/lang/String;)Ljava/util/List; public fun getCaseInsensitiveName ()Z protected final fun getValues ()Ljava/util/Map; + public fun hashCode ()I public fun isEmpty ()Z public fun names ()Ljava/util/Set; } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt index 096e1b6d3d..7e6d6751f9 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt @@ -6,16 +6,6 @@ package aws.smithy.kotlin.runtime.collections import aws.smithy.kotlin.runtime.InternalApi -private class CaseInsensitiveString(val s: String) { - val hash: Int = s.lowercase().hashCode() - override fun hashCode(): Int = hash - override fun equals(other: Any?): Boolean = other is CaseInsensitiveString && other.s.equals(s, ignoreCase = true) - override fun toString(): String = s -} - -private fun String.toInsensitive(): CaseInsensitiveString = - CaseInsensitiveString(this) - /** * Map of case-insensitive [String] to [Value] */ @@ -30,17 +20,17 @@ internal class CaseInsensitiveMap : MutableMap { override fun containsValue(value: Value): Boolean = impl.containsValue(value) - override fun get(key: String): Value? = impl.get(key.toInsensitive()) + override fun get(key: String): Value? = impl[key.toInsensitive()] override fun isEmpty(): Boolean = impl.isEmpty() override val entries: MutableSet> get() = impl.entries.map { - Entry(it.key.s, it.value) + Entry(it.key.normalized, it.value) }.toMutableSet() override val keys: MutableSet - get() = impl.keys.map { it.s }.toMutableSet() + get() = CaseInsensitiveMutableStringSet(impl.keys) override val values: MutableCollection get() = impl.values @@ -57,6 +47,12 @@ internal class CaseInsensitiveMap : MutableMap { override fun remove(key: String): Value? = impl.remove(key.toInsensitive()) + override fun hashCode() = impl.hashCode() + + override fun equals(other: Any?) = other is CaseInsensitiveMap<*> && impl == other.impl + + override fun toString() = impl.toString() + private class Entry( override val key: Key, override var value: Value, diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSet.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSet.kt new file mode 100644 index 0000000000..63924013c9 --- /dev/null +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSet.kt @@ -0,0 +1,40 @@ +package aws.smithy.kotlin.runtime.collections + +internal class CaseInsensitiveMutableStringSet( + initialValues: Iterable = setOf(), +) : MutableSet { + private val delegate = initialValues.toMutableSet() + + override fun add(element: String) = delegate.add(element.toInsensitive()) + override fun clear() = delegate.clear() + override fun contains(element: String) = delegate.contains(element.toInsensitive()) + override fun containsAll(elements: Collection) = elements.all { it in this } + override fun equals(other: Any?) = other is CaseInsensitiveMutableStringSet && delegate == other.delegate + override fun hashCode() = delegate.hashCode() + override fun isEmpty() = delegate.isEmpty() + override fun remove(element: String) = delegate.remove(element.toInsensitive()) + override val size: Int get() = delegate.size + override fun toString() = delegate.toString() + + override fun addAll(elements: Collection) = + elements.fold(false) { modified, item -> add(item) || modified } + + override fun iterator() = object : MutableIterator { + val delegate = this@CaseInsensitiveMutableStringSet.delegate.iterator() + override fun hasNext() = delegate.hasNext() + override fun next() = delegate.next().normalized + override fun remove() = delegate.remove() + } + + override fun removeAll(elements: Collection) = + elements.fold(false) { modified, item -> remove(item) || modified } + + override fun retainAll(elements: Collection): Boolean { + val insensitiveElements = elements.map { it.toInsensitive() }.toSet() + val toRemove = delegate.filterNot { it in insensitiveElements } + return toRemove.fold(false) { modified, item -> delegate.remove(item) || modified } + } +} + +internal fun CaseInsensitiveMutableStringSet(initialValues: Iterable) = + CaseInsensitiveMutableStringSet(initialValues.map { it.toInsensitive() }) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveString.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveString.kt new file mode 100644 index 0000000000..e182ca813d --- /dev/null +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveString.kt @@ -0,0 +1,11 @@ +package aws.smithy.kotlin.runtime.collections + +internal class CaseInsensitiveString(val original: String) { + val normalized = original.lowercase() + override fun hashCode() = normalized.hashCode() + override fun equals(other: Any?) = other is CaseInsensitiveString && normalized == other.normalized + override fun toString() = original +} + +internal fun String.toInsensitive(): CaseInsensitiveString = + CaseInsensitiveString(this) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/ValuesMap.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/ValuesMap.kt index 763fa21ece..efa7a70af3 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/ValuesMap.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/ValuesMap.kt @@ -89,15 +89,13 @@ public open class ValuesMapImpl( override fun isEmpty(): Boolean = values.isEmpty() - override fun equals(other: Any?): Boolean = - other is ValuesMap<*> && - caseInsensitiveName == other.caseInsensitiveName && - names().let { names -> - if (names.size != other.names().size) { - return false - } - names.all { getAll(it) == other.getAll(it) } - } + override fun equals(other: Any?): Boolean = when (other) { + is ValuesMapImpl<*> -> caseInsensitiveName == other.caseInsensitiveName && values == other.values + is ValuesMap<*> -> caseInsensitiveName == other.caseInsensitiveName && entries() == other.entries() + else -> false + } + + override fun hashCode(): Int = values.hashCode() private fun Map>.deepCopyValues(): Map> = mapValues { (_, v) -> v.toList() } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt index dcf919d52d..a36d8ebc31 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt @@ -6,6 +6,8 @@ package aws.smithy.kotlin.runtime.collections import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class CaseInsensitiveMapTest { @Test @@ -18,4 +20,68 @@ class CaseInsensitiveMapTest { assertEquals("json", map["content-type"]) assertEquals("json", map["CONTENT-TYPE"]) } + + @Test + fun testContains() { + val map = CaseInsensitiveMap() + map["A"] = "apple" + map["B"] = "banana" + map["C"] = "cherry" + + assertTrue("C" in map) + assertTrue("c" in map) + assertFalse("D" in map) + } + + @Test + fun testKeysContains() { + val map = CaseInsensitiveMap() + map["A"] = "apple" + map["B"] = "banana" + map["C"] = "cherry" + val keys = map.keys + + assertTrue("C" in keys) + assertTrue("c" in keys) + assertFalse("D" in keys) + } + + @Test + fun testEquality() { + val left = CaseInsensitiveMap() + left["A"] = "apple" + left["B"] = "banana" + left["C"] = "cherry" + + val right = CaseInsensitiveMap() + right["c"] = "cherry" + right["b"] = "banana" + right["a"] = "apple" + + assertEquals(left, right) + } + + @Test + fun testEntriesEquality() { + val left = CaseInsensitiveMap() + left["A"] = "apple" + left["B"] = "banana" + left["C"] = "cherry" + + val right = CaseInsensitiveMap() + right["c"] = "cherry" + right["b"] = "banana" + right["a"] = "apple" + + assertEquals(left.entries, right.entries) + } + + @Test + fun testToString() { + val map = CaseInsensitiveMap() + map["A"] = "apple" + map["B"] = "banana" + map["C"] = "cherry" + assertEquals("{A=apple, B=banana, C=cherry}", map.toString()) + } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSetTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSetTest.kt new file mode 100644 index 0000000000..258ef4c7f3 --- /dev/null +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMutableStringSetTest.kt @@ -0,0 +1,125 @@ +package aws.smithy.kotlin.runtime.collections + +import kotlin.test.* + +private val input = setOf("APPLE", "banana", "cHeRrY") +private val variations = (input + input.map { it.lowercase() } + input.map { it.uppercase() }) +private val disjoint = setOf("durIAN", "ELdeRBerRY", "FiG") +private val subset = input - "APPLE" +private val intersecting = subset + disjoint + +class CaseInsensitiveMutableStringSetTest { + private fun assertSize(size: Int, set: CaseInsensitiveMutableStringSet) { + assertEquals(size, set.size) + val emptyAsserter: (Boolean) -> Unit = if (size == 0) ::assertTrue else ::assertFalse + emptyAsserter(set.isEmpty()) + } + + @Test + fun testInitialization() { + val set = CaseInsensitiveMutableStringSet(input) + assertSize(3, set) + } + + @Test + fun testAdd() { + val set = CaseInsensitiveMutableStringSet(input) + set += "durIAN" + assertSize(4, set) + } + + @Test + fun testAddAll() { + val set = CaseInsensitiveMutableStringSet(input) + assertFalse(set.addAll(set)) + + val intersecting = input + "durian" + assertTrue(set.addAll(intersecting)) + assertSize(4, set) + } + + @Test + fun testClear() { + val set = CaseInsensitiveMutableStringSet(input) + set.clear() + assertSize(0, set) + } + + @Test + fun testContains() { + val set = CaseInsensitiveMutableStringSet(input) + variations.forEach { assertTrue("Set should contain element $it") { it in set } } + + assertFalse("durian" in set) + } + + @Test + fun testContainsAll() { + val set = CaseInsensitiveMutableStringSet(input) + assertTrue(set.containsAll(variations)) + + val intersecting = input + "durian" + assertFalse(set.containsAll(intersecting)) + } + + @Test + fun testEquality() { + val left = CaseInsensitiveMutableStringSet(input) + val right = CaseInsensitiveMutableStringSet(input) + assertEquals(left, right) + + left -= "apple" + assertNotEquals(left, right) + + right -= "ApPlE" + assertEquals(left, right) + } + + @Test + fun testIterator() { + val set = CaseInsensitiveMutableStringSet(input) + val iterator = set.iterator() + + assertTrue(iterator.hasNext()) + assertEquals("apple", iterator.next()) + + assertTrue(iterator.hasNext()) + assertEquals("banana", iterator.next()) + iterator.remove() + assertSize(2, set) + + assertTrue(iterator.hasNext()) + assertEquals("cherry", iterator.next()) + + assertFalse(iterator.hasNext()) + assertTrue(set.containsAll(input - "banana")) + } + + @Test + fun testRemove() { + val set = CaseInsensitiveMutableStringSet(input) + set -= "BANANA" + assertSize(2, set) + } + + @Test + fun testRemoveAll() { + val set = CaseInsensitiveMutableStringSet(input) + assertFalse(set.removeAll(disjoint)) + + assertTrue(set.removeAll(intersecting)) + assertSize(1, set) + assertTrue("apple" in set) + } + + @Test + fun testRetainAll() { + val set = CaseInsensitiveMutableStringSet(input) + assertFalse(set.retainAll(set)) + assertSize(3, set) + + assertTrue(set.retainAll(intersecting)) + assertSize(2, set) + assertTrue(set.containsAll(subset)) + } +} diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveStringTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveStringTest.kt new file mode 100644 index 0000000000..f3a0c7b600 --- /dev/null +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveStringTest.kt @@ -0,0 +1,27 @@ +package aws.smithy.kotlin.runtime.collections + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +class CaseInsensitiveStringTest { + @Test + fun testEquality() { + val left = "Banana".toInsensitive() + val right = "baNAna".toInsensitive() + assertEquals(left, right) + assertNotEquals("Banana", left) + assertNotEquals("baNAna", right) + + val nonMatching = "apple".toInsensitive() + assertNotEquals(nonMatching, left) + assertNotEquals(nonMatching, right) + } + + @Test + fun testProperties() { + val s = "BANANA".toInsensitive() + assertEquals("BANANA", s.original) + assertEquals("banana", s.normalized) + } +} From eceec2ead7d66b2c43f2f26f28271dddc582e7d2 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 6 Feb 2025 14:45:46 -0500 Subject: [PATCH 61/65] CI From 1dc4a45999461ab1c62458d349df6062073bc551 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 6 Feb 2025 14:52:40 -0500 Subject: [PATCH 62/65] Configure Gradle with working directory --- .github/workflows/continuous-integration.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 4dd76543de..b09ce9173d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -91,6 +91,8 @@ jobs: - name: Configure Gradle uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: 'smithy-kotlin' - name: Setup build uses: ./smithy-kotlin/.github/actions/setup-build @@ -157,6 +159,8 @@ jobs: - name: Configure Gradle uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: 'smithy-kotlin' - name: Test working-directory: ./smithy-kotlin @@ -187,6 +191,8 @@ jobs: - name: Configure Gradle uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + with: + working-directory: 'smithy-kotlin' - name: Test working-directory: ./smithy-kotlin From 1af0e8200c3f78949be02d1ef68dd5f120e73aa1 Mon Sep 17 00:00:00 2001 From: 0marperez <60363173+0marperez@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:01:47 -0500 Subject: [PATCH 63/65] misc: gradle version bump (#1236) --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index dace2bff9b..b136486be8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 120768c37101a25fdfddb3504df048cb25045b8e Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:01:31 -0800 Subject: [PATCH 64/65] fix: correct hash code calculation for case-insensitive map entries (#1238) * fix: correct hash code calculation for case-insensitive map entries * remove commented-out code --- .../c0040355-ffdc-4813-80e9-baf859ef02b9.json | 5 +++++ .../runtime/collections/CaseInsensitiveMap.kt | 2 +- .../collections/CaseInsensitiveMapTest.kt | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .changes/c0040355-ffdc-4813-80e9-baf859ef02b9.json diff --git a/.changes/c0040355-ffdc-4813-80e9-baf859ef02b9.json b/.changes/c0040355-ffdc-4813-80e9-baf859ef02b9.json new file mode 100644 index 0000000000..42302b920d --- /dev/null +++ b/.changes/c0040355-ffdc-4813-80e9-baf859ef02b9.json @@ -0,0 +1,5 @@ +{ + "id": "c0040355-ffdc-4813-80e9-baf859ef02b9", + "type": "bugfix", + "description": "fix: correct hash code calculation for case-insensitive map entries" +} \ No newline at end of file diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt index 7e6d6751f9..e888ad72bc 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMap.kt @@ -63,7 +63,7 @@ internal class CaseInsensitiveMap : MutableMap { return value } - override fun hashCode(): Int = 17 * 31 + key!!.hashCode() + value!!.hashCode() + override fun hashCode(): Int = key.hashCode() xor value.hashCode() // Match JVM & K/N stdlib implementations override fun equals(other: Any?): Boolean { if (other == null || other !is Map.Entry<*, *>) return false diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt index a36d8ebc31..96fd83612b 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/collections/CaseInsensitiveMapTest.kt @@ -76,6 +76,22 @@ class CaseInsensitiveMapTest { assertEquals(left.entries, right.entries) } + @Test + fun testEntriesEqualityWithNormalMap() { + val left = CaseInsensitiveMap() + left["A"] = "apple" + left["B"] = "banana" + left["C"] = "cherry" + + val right = mutableMapOf( + "c" to "cherry", + "b" to "banana", + "a" to "apple", + ) + + assertEquals(left.entries, right.entries) + } + @Test fun testToString() { val map = CaseInsensitiveMap() From ab3e7e7e3ec15cb885dfed3cdb4e0cb443b674c6 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 10 Feb 2025 12:29:13 -0500 Subject: [PATCH 65/65] Revert `.toList()` workaround --- .../common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt index b7ec3fe6c0..7bd34fe5ae 100644 --- a/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt +++ b/runtime/protocol/http/common/test/aws/smithy/kotlin/runtime/http/HeadersTest.kt @@ -51,8 +51,8 @@ class HeadersTest { "c" to listOf("crocodile"), ) - assertEquals(firstExpected.entries.toList(), first.entries().toList()) - assertEquals(secondExpected.entries.toList(), second.entries().toList()) + assertEquals(firstExpected.entries, first.entries()) + assertEquals(secondExpected.entries, second.entries()) } @Test