Skip to content

Commit a24bc6e

Browse files
authored
Add resilience in TokenAuthIntegTests (#64757)
The testExpiredTokensDeletedAfterExpiration method assumed that invalidating a refresh token immediately after the delete task was run would behave as if the token did not exist. However, the Elasticsearch concurrency controls do not guarantee that behaviour. It is possible for the request that searches for the token document the corresponds to the refresh token to find an invalidated but not yet deleted document which is reflected in the API response. This change makes the test resilient to this behaviour by wrapping the assertion in an assertBusy Resolves: #56903
1 parent 0805ff1 commit a24bc6e

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/TokenAuthIntegTests.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,26 @@ public void testExpiredTokensDeletedAfterExpiration() throws Exception {
194194
assertThat(invalidateAccessTokenResponse.getPreviouslyInvalidatedTokens(), equalTo(0));
195195
assertThat(invalidateAccessTokenResponse.getErrors(), empty());
196196

197+
// Weird testing behaviour ahead...
198+
// invalidating by access token (above) is a Get, but invalidating by refresh token (below) is a Search
199+
// In a multi node cluster, in a small % of cases, the search might find a document that has been invalidated but not yet deleted
200+
// from that node's shard.
201+
// Our assertion, therefore, is that an attempt to invalidate the (already invalidated) refresh token must not actually invalidate
202+
// anything (concurrency controls must prevent that), nor may return any errors,
203+
// but it might _temporarily_ find an "already invalidated" token.
204+
final InvalidateTokenRequest invalidateRefreshTokenRequest = InvalidateTokenRequest.refreshToken(refreshToken);
197205
InvalidateTokenResponse invalidateRefreshTokenResponse = restClient.security().invalidateToken(
198-
InvalidateTokenRequest.refreshToken(refreshToken), SECURITY_REQUEST_OPTIONS);
206+
invalidateRefreshTokenRequest, SECURITY_REQUEST_OPTIONS);
199207
assertThat(invalidateRefreshTokenResponse.getInvalidatedTokens(), equalTo(0));
200-
assertThat(invalidateRefreshTokenResponse.getPreviouslyInvalidatedTokens(), equalTo(0));
201208
assertThat(invalidateRefreshTokenResponse.getErrors(), empty());
209+
210+
// 99% of the time, this will already be zero, but if not ensure it goes to zero within the allowed timeframe
211+
if (invalidateRefreshTokenResponse.getPreviouslyInvalidatedTokens() > 0) {
212+
assertBusy(() -> {
213+
var newResponse = restClient.security().invalidateToken(invalidateRefreshTokenRequest, SECURITY_REQUEST_OPTIONS);
214+
assertThat(newResponse.getPreviouslyInvalidatedTokens(), equalTo(0));
215+
});
216+
}
202217
}
203218

204219
public void testInvalidateAllTokensForUser() throws Exception {

0 commit comments

Comments
 (0)