@@ -104,6 +104,56 @@ class RotatingCredentialProviderTests: XCTestCase {
104
104
XCTAssertEqual ( count. load ( ordering: . sequentiallyConsistent) , 1 )
105
105
}
106
106
107
+ func testGetCredentialAndGetNewOnesAsAboutToExpire( ) async throws {
108
+ let group = MultiThreadedEventLoopGroup ( numberOfThreads: 1 )
109
+ defer { XCTAssertNoThrow ( try group. syncShutdownGracefully ( ) ) }
110
+ let httpClient = HTTPClient ( eventLoopGroupProvider: . shared( group) )
111
+ defer { XCTAssertNoThrow ( try httpClient. syncShutdown ( ) ) }
112
+
113
+ let creds = [
114
+ TestExpiringCredential (
115
+ accessKeyId: " abc123 " ,
116
+ secretAccessKey: " abc123 " ,
117
+ sessionToken: " abc123 " ,
118
+ expiration: Date ( timeIntervalSinceNow: 10 )
119
+ ) ,
120
+ TestExpiringCredential (
121
+ accessKeyId: " def456 " ,
122
+ secretAccessKey: " def456 " ,
123
+ sessionToken: " def456 " ,
124
+ expiration: Date ( timeIntervalSinceNow: 10 )
125
+ ) ,
126
+ ]
127
+
128
+ let count = ManagedAtomic ( 0 )
129
+ let client = RotatingCredentialTestClient {
130
+ let cred = creds [ count. load ( ordering: . sequentiallyConsistent) ]
131
+ count. wrappingIncrement ( ordering: . sequentiallyConsistent)
132
+ return cred
133
+ }
134
+ let context = CredentialProviderFactory . Context ( httpClient: httpClient, logger: Logger ( label: " soto " ) , options: . init( ) )
135
+ let provider = RotatingCredentialProvider ( context: context, provider: client)
136
+
137
+ // get credentials for first time
138
+ var returned = try await provider. getCredential ( logger: Logger ( label: " soto " ) )
139
+
140
+ XCTAssertEqual ( returned. accessKeyId, creds [ 0 ] . accessKeyId)
141
+ XCTAssertEqual ( returned. secretAccessKey, creds [ 0 ] . secretAccessKey)
142
+ XCTAssertEqual ( returned. sessionToken, creds [ 0 ] . sessionToken)
143
+ XCTAssertEqual ( ( returned as? TestExpiringCredential ) ? . expiration, creds [ 0 ] . expiration)
144
+
145
+ // get credentials a second time, callback must not be hit
146
+ returned = try await provider. getCredential ( logger: Logger ( label: " soto " ) )
147
+
148
+ XCTAssertEqual ( returned. accessKeyId, creds [ 1 ] . accessKeyId)
149
+ XCTAssertEqual ( returned. secretAccessKey, creds [ 1 ] . secretAccessKey)
150
+ XCTAssertEqual ( returned. sessionToken, creds [ 1 ] . sessionToken)
151
+ XCTAssertEqual ( ( returned as? TestExpiringCredential ) ? . expiration, creds [ 1 ] . expiration)
152
+
153
+ // ensure callback was hit twice as we
154
+ XCTAssertEqual ( count. load ( ordering: . sequentiallyConsistent) , 2 )
155
+ }
156
+
107
157
func testGetCredentialHighlyConcurrent( ) async throws {
108
158
let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
109
159
defer { XCTAssertNoThrow ( try group. syncShutdownGracefully ( ) ) }
0 commit comments