|
41 | 41 | import java.time.Instant;
|
42 | 42 | import java.time.ZoneId;
|
43 | 43 | import java.time.ZoneOffset;
|
| 44 | +import java.time.temporal.ChronoUnit; |
44 | 45 | import org.junit.AfterClass;
|
45 | 46 | import org.junit.Before;
|
46 | 47 | import org.junit.Rule;
|
@@ -377,6 +378,42 @@ public void resolveCredentials_callsImdsIfCredentialsWithin5MinutesOfExpiration(
|
377 | 378 | assertThat(credentials10SecondsAgo.secretAccessKey()).isEqualTo("SECRET_ACCESS_KEY2");
|
378 | 379 | }
|
379 | 380 |
|
| 381 | + @Test |
| 382 | + public void imdsCallFrequencyIsLimited() { |
| 383 | + // Requires running the test multiple times to account for refresh jitter |
| 384 | + for (int i = 0; i < 10; i++) { |
| 385 | + AdjustableClock clock = new AdjustableClock(); |
| 386 | + AwsCredentialsProvider credentialsProvider = credentialsProviderWithClock(clock); |
| 387 | + Instant now = Instant.now(); |
| 388 | + String successfulCredentialsResponse1 = |
| 389 | + "{" |
| 390 | + + "\"AccessKeyId\":\"ACCESS_KEY_ID\"," |
| 391 | + + "\"SecretAccessKey\":\"SECRET_ACCESS_KEY\"," |
| 392 | + + "\"Expiration\":\"" + DateUtils.formatIso8601Date(now) + '"' |
| 393 | + + "}"; |
| 394 | + |
| 395 | + String successfulCredentialsResponse2 = |
| 396 | + "{" |
| 397 | + + "\"AccessKeyId\":\"ACCESS_KEY_ID2\"," |
| 398 | + + "\"SecretAccessKey\":\"SECRET_ACCESS_KEY2\"," |
| 399 | + + "\"Expiration\":\"" + DateUtils.formatIso8601Date(now.plus(6, HOURS)) + '"' |
| 400 | + + "}"; |
| 401 | + |
| 402 | + // Set the time to 5 minutes before expiration and call IMDS |
| 403 | + clock.time = now.minus(5, MINUTES); |
| 404 | + stubCredentialsResponse(aResponse().withBody(successfulCredentialsResponse1)); |
| 405 | + AwsCredentials credentials5MinutesAgo = credentialsProvider.resolveCredentials(); |
| 406 | + |
| 407 | + // Set the time to 1 second before expiration, and verify that do not call IMDS because it hasn't been 5 minutes yet |
| 408 | + clock.time = now.minus(1, SECONDS); |
| 409 | + stubCredentialsResponse(aResponse().withBody(successfulCredentialsResponse2)); |
| 410 | + AwsCredentials credentials1SecondsAgo = credentialsProvider.resolveCredentials(); |
| 411 | + |
| 412 | + assertThat(credentials5MinutesAgo).isEqualTo(credentials1SecondsAgo); |
| 413 | + assertThat(credentials5MinutesAgo.secretAccessKey()).isEqualTo("SECRET_ACCESS_KEY"); |
| 414 | + } |
| 415 | + } |
| 416 | + |
380 | 417 | private AwsCredentialsProvider credentialsProviderWithClock(Clock clock) {
|
381 | 418 | InstanceProfileCredentialsProvider.BuilderImpl builder =
|
382 | 419 | (InstanceProfileCredentialsProvider.BuilderImpl) InstanceProfileCredentialsProvider.builder();
|
|
0 commit comments