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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions services/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import aws.sdk.kotlin.gradle.dsl.configurePublishing
import aws.sdk.kotlin.gradle.kmp.*
import aws.sdk.kotlin.gradle.kmp.kotlin
import aws.sdk.kotlin.gradle.util.typedProp
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.time.LocalDateTime
Expand Down Expand Up @@ -109,13 +109,6 @@ subprojects {
testClassesDirs = output.classesDirs

useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
showStackTraces = true
showExceptions = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}

// model a random input to enable re-running e2e tests back to back without
// up-to-date checks or cache getting in the way
Expand All @@ -135,6 +128,16 @@ subprojects {
}
}

tasks.withType<org.gradle.api.tasks.testing.AbstractTestTask>().configureEach {
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
showStackTraces = true
showExceptions = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}

configurePublishing("aws-sdk-kotlin")
publishing {
publications.all {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CreateClientTest {
@Test
fun testMissingRegion() {
// Should _not_ throw an exception since region is optional
S3Client { }
S3Client { }.use { }
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import aws.smithy.kotlin.runtime.operation.ExecutionContext
import aws.smithy.kotlin.runtime.time.ManualClock
import kotlinx.coroutines.*
import kotlinx.coroutines.test.runTest
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.time.ComparableTimeMark
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
Expand All @@ -38,15 +40,15 @@ class DefaultS3ExpressCredentialsProviderTest {
expiration = clock.now() + 5.minutes
}

val client = TestS3Client(expectedCredentials)

DefaultS3ExpressCredentialsProvider(timeSource, clock).use { provider ->
val credentials = provider.createSessionCredentials(
S3ExpressCredentialsCacheKey("bucket", DEFAULT_BASE_CREDENTIALS),
client,
)
assertFalse(credentials.isExpired)
assertEquals(timeSource.markNow() + 5.minutes, credentials.expiresAt)
TestS3Client(expectedCredentials).use { client ->
DefaultS3ExpressCredentialsProvider(timeSource, clock).use { provider ->
val credentials = provider.createSessionCredentials(
S3ExpressCredentialsCacheKey("bucket", DEFAULT_BASE_CREDENTIALS),
client,
)
assertFalse(credentials.isExpired)
assertEquals(timeSource.markNow() + 5.minutes, credentials.expiresAt)
}
}
}

Expand All @@ -67,16 +69,17 @@ class DefaultS3ExpressCredentialsProviderTest {
expiration = clock.now() + 5.minutes
}

val testClient = TestS3Client(expectedCredentials)
DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes).use { provider ->
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}
TestS3Client(expectedCredentials).use { testClient ->
DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes).use { provider ->
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}

provider.resolve(attributes)
provider.resolve(attributes)
}
assertEquals(1, testClient.numCreateSession)
}
assertEquals(1, testClient.numCreateSession)
}

@Test
Expand All @@ -96,23 +99,23 @@ class DefaultS3ExpressCredentialsProviderTest {
expiration = clock.now() + 5.minutes
}

val testClient = TestS3Client(expectedCredentials)

val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)
TestS3Client(expectedCredentials).use { testClient ->
val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)

val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}
provider.resolve(attributes)
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}
provider.resolve(attributes)

// allow the async refresh to initiate before closing the provider
runBlocking { delay(500.milliseconds) }
// allow the async refresh to initiate before closing the provider
runBlocking { delay(500.milliseconds) }

provider.close()
provider.coroutineContext.job.join()
provider.close()
provider.coroutineContext.job.join()

assertEquals(1, testClient.numCreateSession)
assertEquals(1, testClient.numCreateSession)
}
}

@Test
Expand All @@ -132,26 +135,26 @@ class DefaultS3ExpressCredentialsProviderTest {
expiration = clock.now() + 5.minutes
}

val testClient = TestS3Client(expectedCredentials)

val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)
TestS3Client(expectedCredentials).use { testClient ->
val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)

val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}
val calls = (1..5).map {
async { provider.resolve(attributes) }
}
calls.awaitAll()
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "bucket"
}
val calls = (1..5).map {
async { provider.resolve(attributes) }
}
calls.awaitAll()

// allow the async refresh to initiate before closing the provider
runBlocking { delay(500.milliseconds) }
// allow the async refresh to initiate before closing the provider
runBlocking { delay(500.milliseconds) }

provider.close()
provider.coroutineContext.job.join()
provider.close()
provider.coroutineContext.job.join()

assertEquals(1, testClient.numCreateSession)
assertEquals(1, testClient.numCreateSession)
}
}

@Test
Expand All @@ -174,35 +177,35 @@ class DefaultS3ExpressCredentialsProviderTest {
}

// client should throw an exception when `ExceptionBucket` credentials are fetched, but it should be caught
val testClient = TestS3Client(expectedCredentials, throwExceptionOnBucketNamed = "ExceptionBucket")

val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "ExceptionBucket"
}
provider.resolve(attributes)
TestS3Client(expectedCredentials, throwExceptionOnBucketNamed = "ExceptionBucket").use { testClient ->
val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = testClient
this.attributes[S3Attributes.Bucket] = "ExceptionBucket"
}
provider.resolve(attributes)

withTimeout(5.seconds) {
while (testClient.numCreateSession != 1) {
yield()
withTimeout(5.seconds) {
while (testClient.numCreateSession != 1) {
yield()
}
}
}
assertEquals(1, testClient.numCreateSession)
assertEquals(1, testClient.numCreateSession)

attributes[S3Attributes.Bucket] = "SuccessfulBucket"
provider.resolve(attributes)
attributes[S3Attributes.Bucket] = "SuccessfulBucket"
provider.resolve(attributes)

withTimeout(5.seconds) {
while (testClient.numCreateSession != 2) {
yield()
withTimeout(5.seconds) {
while (testClient.numCreateSession != 2) {
yield()
}
}
}

provider.close()
provider.coroutineContext.job.join()
provider.close()
provider.coroutineContext.job.join()

assertEquals(2, testClient.numCreateSession)
assertEquals(2, testClient.numCreateSession)
}
}

@Test
Expand All @@ -224,24 +227,26 @@ class DefaultS3ExpressCredentialsProviderTest {

val provider = DefaultS3ExpressCredentialsProvider(timeSource, clock, cache, refreshBuffer = 1.minutes)

val blockingTestS3Client = object : TestS3Client(expectedCredentials) {
class BlockingTestS3Client : TestS3Client(expectedCredentials) {
override suspend fun createSession(input: CreateSessionRequest): CreateSessionResponse {
delay(10.seconds)
numCreateSession += 1
return CreateSessionResponse { credentials = expectedCredentials }
}
}

val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = blockingTestS3Client
this.attributes[S3Attributes.Bucket] = "bucket"
}
BlockingTestS3Client().use { blockingTestS3Client ->
val attributes = ExecutionContext.build {
this.attributes[S3Attributes.ExpressClient] = blockingTestS3Client
this.attributes[S3Attributes.Bucket] = "bucket"
}

withTimeout(5.seconds) {
provider.resolve(attributes)
provider.close()
withTimeout(5.seconds) {
provider.resolve(attributes)
provider.close()
}
assertEquals(0, blockingTestS3Client.numCreateSession)
}
assertEquals(0, blockingTestS3Client.numCreateSession)
}

/**
Expand Down Expand Up @@ -281,5 +286,9 @@ class DefaultS3ExpressCredentialsProviderTest {
}
return CreateSessionResponse { credentials = expectedCredentials }
}

override fun close() {
client.close()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import aws.smithy.kotlin.runtime.http.HttpBody
import aws.smithy.kotlin.runtime.http.HttpStatusCode
import aws.smithy.kotlin.runtime.http.response.HttpResponse
import aws.smithy.kotlin.runtime.httptest.buildTestConnection
import aws.smithy.kotlin.runtime.io.use
import aws.smithy.kotlin.runtime.time.Instant
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
Expand Down Expand Up @@ -41,15 +42,16 @@ class ExpiresFieldInterceptorTest {
append("Expires", "Mon, 1 Apr 2024 00:00:00 +0000")
}.build()

val s3 = newTestClient(headers = expectedHeaders)
s3.getObject(
GetObjectRequest {
bucket = "test"
key = "key"
},
) {
assertEquals(Instant.fromEpochSeconds(1711929600), it.expires)
assertEquals("Mon, 1 Apr 2024 00:00:00 +0000", it.expiresString)
newTestClient(headers = expectedHeaders).use { s3 ->
s3.getObject(
GetObjectRequest {
bucket = "test"
key = "key"
},
) {
assertEquals(Instant.fromEpochSeconds(1711929600), it.expires)
assertEquals("Mon, 1 Apr 2024 00:00:00 +0000", it.expiresString)
}
}
}

Expand All @@ -61,15 +63,16 @@ class ExpiresFieldInterceptorTest {
append("Expires", invalidExpiresField)
}.build()

val s3 = newTestClient(headers = expectedHeaders)
s3.getObject(
GetObjectRequest {
bucket = "test"
key = "key"
},
) {
assertNull(it.expires)
assertEquals(invalidExpiresField, it.expiresString)
newTestClient(headers = expectedHeaders).use { s3 ->
s3.getObject(
GetObjectRequest {
bucket = "test"
key = "key"
},
) {
assertNull(it.expires)
assertEquals(invalidExpiresField, it.expiresString)
}
}
}
}
Loading
Loading