@@ -15,13 +15,14 @@ import aws.smithy.kotlin.runtime.http.engine.HttpClientEngineBase
1515import aws.smithy.kotlin.runtime.http.engine.HttpClientEngineConfig
1616import aws.smithy.kotlin.runtime.http.request.HttpRequest
1717import aws.smithy.kotlin.runtime.http.response.HttpResponse
18- import aws.smithy.kotlin.runtime.io.use
1918import aws.smithy.kotlin.runtime.operation.ExecutionContext
2019import aws.smithy.kotlin.runtime.time.Instant
2120import aws.smithy.kotlin.runtime.util.TestPlatformProvider
2221import kotlinx.coroutines.test.runTest
22+ import kotlin.test.Test
2323import kotlin.test.assertEquals
2424import kotlin.test.assertNotNull
25+ import kotlin.test.assertTrue
2526
2627class BedrockEnvironmentBearerTokenTest {
2728 private fun mockHttpClient (handler : (HttpRequest ) -> HttpResponse ): HttpClientEngine {
@@ -39,69 +40,129 @@ class BedrockEnvironmentBearerTokenTest {
3940 env = mapOf (" AWS_BEARER_TOKEN_BEDROCK" to " bedrock-token" ),
4041 )
4142
43+ @Test
4244 fun testAuthSchemePreferenceConfigured () = runTest {
43- val builder = BedrockClient .Builder ()
4445 val expectedAuthSchemePreference = listOf (AuthSchemeId .HttpBearer )
46+ val builder = BedrockClient .Builder ()
47+
4548 finalizeBearerTokenConfig(builder, mockPlatformProvider)
49+
4650 assertEquals(expectedAuthSchemePreference, builder.config.authSchemePreference)
4751 }
4852
53+ @Test
4954 fun testBearerAuthSchemePromotedToFirst () = runTest {
55+ val expectedAuthSchemePreference = listOf (AuthSchemeId .HttpBearer , AuthSchemeId .AwsSigV4 )
5056 val builder = BedrockClient .Builder ()
57+
5158 builder.config.authSchemePreference = listOf (AuthSchemeId .AwsSigV4 )
5259 finalizeBearerTokenConfig(builder, mockPlatformProvider)
53- val expectedAuthSchemePreference = listOf (AuthSchemeId .HttpBearer , AuthSchemeId .AwsSigV4 )
5460 assertEquals(expectedAuthSchemePreference, builder.config.authSchemePreference)
5561
5662 builder.config.authSchemePreference = listOf (AuthSchemeId .AwsSigV4 , AuthSchemeId .HttpBearer )
63+ finalizeBearerTokenConfig(builder, mockPlatformProvider)
5764 assertEquals(expectedAuthSchemePreference, builder.config.authSchemePreference)
5865 }
5966
67+ @Test
6068 fun testBearerTokenProviderConfigured () = runTest {
6169 val builder = BedrockClient .Builder ()
6270 finalizeBearerTokenConfig(builder, mockPlatformProvider)
71+
6372 assertNotNull(builder.config.bearerTokenProvider)
6473 val token = builder.config.bearerTokenProvider!! .resolve()
6574 assertNotNull(token)
6675 assertEquals(" bedrock-token" , token.token)
6776 }
6877
78+ @Test
79+ fun testBearerTokenSourcingPrecedence () = runTest {
80+ val builder = BedrockClient .Builder ()
81+
82+ finalizeBearerTokenConfig(
83+ builder,
84+ TestPlatformProvider (
85+ env = mapOf (" AWS_BEARER_TOKEN_BEDROCK" to " env-bedrock-token" ),
86+ props = mapOf (" aws.bearerTokenBedrock" to " sys-props-bedrock-token" ),
87+ ),
88+ )
89+
90+ val token = builder.config.bearerTokenProvider!! .resolve()
91+ assertEquals(" sys-props-bedrock-token" , token.token)
92+ }
93+
94+ @Test
6995 fun testExplicitProviderTakesPrecedence () = runTest {
7096 val builder = BedrockClient .Builder ()
97+
7198 builder.config.bearerTokenProvider = object : BearerTokenProvider {
7299 override suspend fun resolve (attributes : Attributes ): BearerToken = object : BearerToken {
73100 override val token: String = " different-bedrock-token"
74101 override val attributes: Attributes = emptyAttributes()
75102 override val expiration: Instant ? = null
76103 }
77104 }
105+
78106 finalizeBearerTokenConfig(builder, mockPlatformProvider)
107+
79108 assertNotNull(builder.config.bearerTokenProvider)
80109 val token = builder.config.bearerTokenProvider!! .resolve()
81110 assertNotNull(token)
82111 assertEquals(" different-bedrock-token" , token.token)
83112 }
84113
114+ @Test
85115 fun testBearerTokenProviderFunctionality () = runTest {
86116 var capturedAuthHeader: String? = null
87117
88- BedrockClient .fromEnvironment {
89- region = " us-west-2"
90- httpClient = mockHttpClient { request ->
91- // Capture the Authorization header
118+ val builder = BedrockClient .Builder ().apply {
119+ config.region = " us-west-2"
120+ config.httpClient = mockHttpClient { request ->
92121 capturedAuthHeader = request.headers[" Authorization" ]
93122 HttpResponse (
94123 status = HttpStatusCode .OK ,
95124 headers = Headers .Empty ,
96125 body = HttpBody .Empty ,
97126 )
98127 }
99- }.use { client ->
100- // Make an api call to capture Authorization header
101- client.listFoundationModels( )
128+ }
129+
130+ finalizeBearerTokenConfig(builder, mockPlatformProvider )
102131
103- assertNotNull(capturedAuthHeader)
104- assertEquals(" Bearer bedrock-token" , capturedAuthHeader)
132+ val testClient = builder.build()
133+ // Make an api call to capture Authorization header
134+ testClient.listFoundationModels()
135+
136+ assertNotNull(capturedAuthHeader)
137+ assertEquals(" Bearer bedrock-token" , capturedAuthHeader)
138+ }
139+
140+ @Test
141+ fun testBusinessMetricEmitted () = runTest {
142+ var capturedUserAgent: String? = null
143+
144+ val builder = BedrockClient .Builder ().apply {
145+ config.region = " us-west-2"
146+ config.httpClient = mockHttpClient { request ->
147+ capturedUserAgent = request.headers[" User-Agent" ]
148+ HttpResponse (
149+ status = HttpStatusCode .OK ,
150+ headers = Headers .Empty ,
151+ body = HttpBody .Empty ,
152+ )
153+ }
105154 }
155+
156+ finalizeBearerTokenConfig(builder, mockPlatformProvider)
157+
158+ val testClient = builder.build()
159+ // Make an api call to capture User-Agent header
160+ testClient.listFoundationModels()
161+
162+ assertNotNull(capturedUserAgent)
163+ val capturedBusinessMetrics = Regex (" m/([^\\ s]+)" ).find(capturedUserAgent!! )?.value
164+ assertNotNull(capturedBusinessMetrics)
165+ // Check User-Agent header contains the business metric
166+ assertTrue(capturedBusinessMetrics.contains(" 3" ))
106167 }
107168}
0 commit comments