Skip to content

Commit da31deb

Browse files
committed
Added ResponseChecksumValidation codegen tests
1 parent 4ce5da7 commit da31deb

File tree

2 files changed

+152
-30
lines changed

2 files changed

+152
-30
lines changed

tests/codegen/checksums/src/commonTest/kotlin/ClientConfigTests.kt

Lines changed: 132 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
22
import aws.sdk.kotlin.test.clientconfig.*
3+
import aws.sdk.kotlin.test.clientconfig.model.ValidationMode
34
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
45
import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
56
import aws.smithy.kotlin.runtime.client.config.ChecksumConfigOption
7+
import aws.smithy.kotlin.runtime.http.*
8+
import aws.smithy.kotlin.runtime.http.interceptors.ChecksumMismatchException
69
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
710
import aws.smithy.kotlin.runtime.http.request.HttpRequest
11+
import aws.smithy.kotlin.runtime.http.response.HttpResponse
812
import aws.smithy.kotlin.runtime.httptest.TestEngine
13+
import aws.smithy.kotlin.runtime.time.Instant
914
import kotlinx.coroutines.runBlocking
1015
import org.junit.jupiter.api.Nested
1116
import kotlin.test.Ignore
@@ -18,12 +23,12 @@ class ClientConfigTests {
1823
inner class RequestChecksumNotRequired {
1924
@Test
2025
@Ignore // todo: un-ignore
21-
fun requestChecksumCalculationWhenSupported(): Unit = runBlocking {
22-
val testInterceptor = TestInterceptor()
26+
fun requestChecksumNotRequiredRequestChecksumCalculationWhenSupported(): Unit = runBlocking {
27+
val requestInterceptor = RequestInterceptor()
2328

2429
ClientConfigTestClient {
2530
requestChecksumCalculation = ChecksumConfigOption.WHEN_SUPPORTED
26-
interceptors = mutableListOf(testInterceptor)
31+
interceptors = mutableListOf(requestInterceptor)
2732
httpClient = TestEngine()
2833
credentialsProvider = StaticCredentialsProvider(
2934
Credentials("accessKeyID", "secretAccessKey"),
@@ -35,16 +40,16 @@ class ClientConfigTests {
3540
}
3641
}
3742

38-
assertTrue(testInterceptor.containsChecksum)
43+
assertTrue(requestInterceptor.containsChecksum)
3944
}
4045

4146
@Test
42-
fun requestChecksumCalculationWhenRequired(): Unit = runBlocking {
43-
val testInterceptor = TestInterceptor()
47+
fun requestChecksumNotRequiredRequestChecksumCalculationWhenRequired(): Unit = runBlocking {
48+
val requestInterceptor = RequestInterceptor()
4449

4550
ClientConfigTestClient {
4651
requestChecksumCalculation = ChecksumConfigOption.WHEN_REQUIRED
47-
interceptors = mutableListOf(testInterceptor)
52+
interceptors = mutableListOf(requestInterceptor)
4853
httpClient = TestEngine()
4954
credentialsProvider = StaticCredentialsProvider(
5055
Credentials("accessKeyID", "secretAccessKey"),
@@ -56,20 +61,20 @@ class ClientConfigTests {
5661
}
5762
}
5863

59-
assertFalse(testInterceptor.containsChecksum)
64+
assertFalse(requestInterceptor.containsChecksum)
6065
}
6166
}
6267

6368
@Nested
6469
inner class RequestChecksumRequired {
6570
@Test
6671
@Ignore // todo: un-ignore
67-
fun requestChecksumCalculationWhenSupported(): Unit = runBlocking {
68-
val testInterceptor = TestInterceptor()
72+
fun requestChecksumRequiredRequestChecksumCalculationWhenSupported(): Unit = runBlocking {
73+
val requestInterceptor = RequestInterceptor()
6974

7075
ClientConfigTestClient {
7176
requestChecksumCalculation = ChecksumConfigOption.WHEN_SUPPORTED
72-
interceptors = mutableListOf(testInterceptor)
77+
interceptors = mutableListOf(requestInterceptor)
7378
httpClient = TestEngine()
7479
credentialsProvider = StaticCredentialsProvider(
7580
Credentials("accessKeyID", "secretAccessKey"),
@@ -81,17 +86,17 @@ class ClientConfigTests {
8186
}
8287
}
8388

84-
assertTrue(testInterceptor.containsChecksum)
89+
assertTrue(requestInterceptor.containsChecksum)
8590
}
8691

8792
@Test
8893
@Ignore // todo: un-ignore
89-
fun requestChecksumCalculationWhenRequired(): Unit = runBlocking {
90-
val testInterceptor = TestInterceptor()
94+
fun requestChecksumRequiredRequestChecksumCalculationWhenRequired(): Unit = runBlocking {
95+
val requestInterceptor = RequestInterceptor()
9196

9297
ClientConfigTestClient {
9398
requestChecksumCalculation = ChecksumConfigOption.WHEN_REQUIRED
94-
interceptors = mutableListOf(testInterceptor)
99+
interceptors = mutableListOf(requestInterceptor)
95100
httpClient = TestEngine()
96101
credentialsProvider = StaticCredentialsProvider(
97102
Credentials("accessKeyID", "secretAccessKey"),
@@ -103,21 +108,129 @@ class ClientConfigTests {
103108
}
104109
}
105110

106-
assertTrue(testInterceptor.containsChecksum)
111+
assertTrue(requestInterceptor.containsChecksum)
107112
}
108113
}
109114

110115
@Nested
111116
inner class ResponseChecksumValidation {
112-
// TODO
117+
@Test
118+
@Ignore // todo - unignore
119+
fun responseChecksumValidationResponseChecksumValidationWhenSupported(): Unit = runBlocking {
120+
var responseChecksumValidated = false
121+
122+
ClientConfigTestClient {
123+
responseChecksumValidation = ChecksumConfigOption.WHEN_SUPPORTED
124+
httpClient = TestEngine(
125+
roundTripImpl = { _, request ->
126+
val resp = HttpResponse(
127+
HttpStatusCode.OK,
128+
Headers {
129+
append("x-amz-checksum-crc32", "bogus")
130+
},
131+
"Goodbye!".toHttpBody(),
132+
)
133+
val now = Instant.now()
134+
HttpCall(request, resp, now, now)
135+
}
136+
)
137+
credentialsProvider = StaticCredentialsProvider(
138+
Credentials("accessKeyID", "secretAccessKey"),
139+
)
140+
region = "us-east-1"
141+
}.use { client ->
142+
try {
143+
client.checksumsRequiredOperation {
144+
body = "Hello World!"
145+
}
146+
} catch (_: ChecksumMismatchException) { // "bogus" is not a matching checksum
147+
responseChecksumValidated = true
148+
}
149+
}
150+
151+
assertTrue(responseChecksumValidated)
152+
}
153+
154+
@Test
155+
fun responseChecksumValidationResponseChecksumValidationWhenRequired(): Unit = runBlocking {
156+
var responseChecksumValidated = false
157+
158+
ClientConfigTestClient {
159+
responseChecksumValidation = ChecksumConfigOption.WHEN_REQUIRED
160+
httpClient = TestEngine(
161+
roundTripImpl = { _, request ->
162+
val resp = HttpResponse(
163+
HttpStatusCode.OK,
164+
Headers {
165+
append("x-amz-checksum-crc32", "bogus")
166+
},
167+
"Goodbye!".toHttpBody(),
168+
)
169+
val now = Instant.now()
170+
HttpCall(request, resp, now, now)
171+
}
172+
)
173+
credentialsProvider = StaticCredentialsProvider(
174+
Credentials("accessKeyID", "secretAccessKey"),
175+
)
176+
region = "us-east-1"
177+
}.use { client ->
178+
try {
179+
client.checksumsRequiredOperation {
180+
body = "Hello World!"
181+
}
182+
} catch (_: ChecksumMismatchException) { // "bogus" is not a matching checksum
183+
responseChecksumValidated = true
184+
}
185+
}
186+
187+
assertFalse(responseChecksumValidated)
188+
}
189+
190+
@Test
191+
@Ignore // todo - unignore
192+
fun responseChecksumValidationResponseChecksumValidationWhenRequiredWithRequestValidationModeMember(): Unit = runBlocking {
193+
var responseChecksumValidated = false
194+
195+
ClientConfigTestClient {
196+
responseChecksumValidation = ChecksumConfigOption.WHEN_REQUIRED
197+
httpClient = TestEngine(
198+
roundTripImpl = { _, request ->
199+
val resp = HttpResponse(
200+
HttpStatusCode.OK,
201+
Headers {
202+
append("x-amz-checksum-crc32", "bogus")
203+
},
204+
"Goodbye!".toHttpBody(),
205+
)
206+
val now = Instant.now()
207+
HttpCall(request, resp, now, now)
208+
}
209+
)
210+
credentialsProvider = StaticCredentialsProvider(
211+
Credentials("accessKeyID", "secretAccessKey"),
212+
)
213+
region = "us-east-1"
214+
}.use { client ->
215+
try {
216+
client.checksumsRequiredOperation {
217+
body = "Hello World!"
218+
}
219+
} catch (_: ChecksumMismatchException) { // "bogus" is not a matching checksum
220+
responseChecksumValidated = true
221+
}
222+
}
223+
224+
assertTrue(responseChecksumValidated)
225+
}
113226
}
114227
}
115228

116-
private class TestInterceptor : HttpInterceptor {
229+
private class RequestInterceptor : HttpInterceptor {
117230
var containsChecksum = false
118231

119232
override suspend fun modifyBeforeTransmit(context: ProtocolRequestInterceptorContext<Any, HttpRequest>): HttpRequest {
120-
containsChecksum = context.protocolRequest.headers.contains("x-amz-checksum-crc32")
233+
containsChecksum = context.protocolRequest.headers.contains("x-amz-checksum-crc32") // default checksum algorithm
121234
return context.protocolRequest
122235
}
123236
}

tests/codegen/checksums/src/commonTest/resources/client-config.smithy

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,6 @@ operation ChecksumsNotRequiredOperation {
3333
output: SomeOutput
3434
}
3535

36-
@httpChecksum(
37-
requestChecksumRequired: true,
38-
requestAlgorithmMember: "checksumAlgorithm",
39-
)
40-
@http(method: "POST", uri: "/test-checksums-2", code: 200)
41-
operation ChecksumsRequiredOperation {
42-
input: AnotherInput,
43-
output: AnotherOutput
44-
}
45-
4636
@input
4737
structure SomeInput {
4838
@httpHeader("x-amz-request-algorithm")
@@ -56,11 +46,26 @@ structure SomeInput {
5646
@output
5747
structure SomeOutput {}
5848

49+
@httpChecksum(
50+
requestChecksumRequired: true,
51+
requestAlgorithmMember: "checksumAlgorithm",
52+
requestValidationModeMember: "validationMode",
53+
responseAlgorithms: ["CRC32"]
54+
)
55+
@http(method: "POST", uri: "/test-checksums-2", code: 200)
56+
operation ChecksumsRequiredOperation {
57+
input: AnotherInput,
58+
output: AnotherOutput
59+
}
60+
5961
@input
6062
structure AnotherInput {
6163
@httpHeader("x-amz-request-algorithm")
6264
checksumAlgorithm: ChecksumAlgorithm
6365

66+
@httpHeader("x-amz-response-validation-mode")
67+
validationMode: ValidationMode
68+
6469
@httpPayload
6570
@required
6671
body: String
@@ -75,4 +80,8 @@ enum ChecksumAlgorithm {
7580
CRC64NVME
7681
SHA1
7782
SHA256
78-
}
83+
}
84+
85+
enum ValidationMode {
86+
ENABLED
87+
}

0 commit comments

Comments
 (0)