|
26 | 26 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; |
27 | 27 | import static org.assertj.core.api.Assertions.assertThat; |
28 | 28 | import static org.assertj.core.api.Assertions.assertThatThrownBy; |
| 29 | +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; |
29 | 30 |
|
30 | 31 | import com.github.tomakehurst.wiremock.junit5.WireMockExtension; |
31 | 32 | import com.github.tomakehurst.wiremock.junit5.WireMockTest; |
@@ -212,6 +213,82 @@ void resolveCredentials_withNon404ErrorOnProfileDiscovery_doesNotFallbackToLegac |
212 | 213 | verify(0, getRequestedFor(urlPathEqualTo(CREDENTIALS_RESOURCE_PATH + PROFILE_NAME))); |
213 | 214 | } |
214 | 215 |
|
| 216 | + @Test |
| 217 | + void resolveCredentials_withUnstableProfile_ReturnsCredentials() { |
| 218 | + String initialProfile = "my-profile-0007"; |
| 219 | + String newProfile = "my-profile-0007-b"; |
| 220 | + String credentialsJson = String.format( |
| 221 | + "{\"Code\":\"Success\"," + |
| 222 | + "\"LastUpdated\":\"2025-03-18T20:53:17.832308Z\"," + |
| 223 | + "\"Type\":\"AWS-HMAC\"," + |
| 224 | + "\"AccessKeyId\":\"ASIAIOSFODNN7EXAMPLE\"," + |
| 225 | + "\"SecretAccessKey\":\"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"," + |
| 226 | + "\"Token\":\"AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKw...\"," + |
| 227 | + "\"Expiration\":\"2025-03-18T21:53:17.832308Z\"," + |
| 228 | + "\"UnexpectedElement7\":{\"Name\":\"ignore-me-7\"}}"); |
| 229 | + |
| 230 | + wireMockServer.stubFor(put(urlPathEqualTo(TOKEN_RESOURCE_PATH)) |
| 231 | + .willReturn(aResponse().withBody(TOKEN_STUB))); |
| 232 | + |
| 233 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH)) |
| 234 | + .inScenario("unstable-profile") |
| 235 | + .whenScenarioStateIs("Started") |
| 236 | + .willReturn(aResponse().withBody(initialProfile)) |
| 237 | + .willSetStateTo("initial-profile-discovered")); |
| 238 | + |
| 239 | + |
| 240 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + initialProfile)) |
| 241 | + .inScenario("unstable-profile") |
| 242 | + .whenScenarioStateIs("initial-profile-discovered") |
| 243 | + .willReturn(aResponse().withStatus(404)) |
| 244 | + .willSetStateTo("profile-not-found")); |
| 245 | + |
| 246 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH)) |
| 247 | + .inScenario("unstable-profile") |
| 248 | + .whenScenarioStateIs("profile-not-found") |
| 249 | + .willReturn(aResponse().withBody(newProfile)) |
| 250 | + .willSetStateTo("new-profile-discovered")); |
| 251 | + |
| 252 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + newProfile)) |
| 253 | + .inScenario("unstable-profile") |
| 254 | + .whenScenarioStateIs("new-profile-discovered") |
| 255 | + .willReturn(aResponse().withBody(credentialsJson))); |
| 256 | + |
| 257 | + InstanceProfileCredentialsProvider provider = InstanceProfileCredentialsProvider.builder().build(); |
| 258 | + |
| 259 | + AwsCredentials creds1 = provider.resolveCredentials(); |
| 260 | + assertThat(creds1.accessKeyId()).isEqualTo("ASIAIOSFODNN7EXAMPLE"); |
| 261 | + |
| 262 | + AwsCredentials creds2 = assertDoesNotThrow(() -> provider.resolveCredentials()); |
| 263 | + assertThat(creds2.accessKeyId()).isEqualTo("ASIAIOSFODNN7EXAMPLE"); |
| 264 | + |
| 265 | + verify(1, getRequestedFor(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + initialProfile))); |
| 266 | + verify(1, getRequestedFor(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + newProfile))); |
| 267 | + } |
| 268 | + |
| 269 | + @Test |
| 270 | + void resolveCredentials_withTooManyProfileFailures_throwsException() { |
| 271 | + String profile = "unstable-profile"; |
| 272 | + |
| 273 | + wireMockServer.stubFor(put(urlPathEqualTo(TOKEN_RESOURCE_PATH)) |
| 274 | + .willReturn(aResponse().withBody(TOKEN_STUB))); |
| 275 | + |
| 276 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH)) |
| 277 | + .willReturn(aResponse().withBody(profile))); |
| 278 | + |
| 279 | + wireMockServer.stubFor(get(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + profile)) |
| 280 | + .willReturn(aResponse().withStatus(404))); |
| 281 | + |
| 282 | + InstanceProfileCredentialsProvider provider = InstanceProfileCredentialsProvider.builder().build(); |
| 283 | + |
| 284 | + assertThatThrownBy(() -> provider.resolveCredentials()) |
| 285 | + .isInstanceOf(SdkClientException.class) |
| 286 | + .hasMessageContaining("Failed to load credentials from IMDS."); |
| 287 | + |
| 288 | + verify(4, getRequestedFor(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH))); |
| 289 | + verify(4, getRequestedFor(urlPathEqualTo(CREDENTIALS_EXTENDED_RESOURCE_PATH + profile))); |
| 290 | + } |
| 291 | + |
215 | 292 | private void stubSecureCredentialsResponse(com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder responseDefinitionBuilder, boolean useExtended) { |
216 | 293 | wireMockServer.stubFor(put(urlPathEqualTo(TOKEN_RESOURCE_PATH)).willReturn(aResponse().withBody(TOKEN_STUB))); |
217 | 294 | String path = useExtended ? CREDENTIALS_EXTENDED_RESOURCE_PATH : CREDENTIALS_RESOURCE_PATH; |
|
0 commit comments