Repository navigation
fix(app_check): Reduce flakiness in TestGetTokenForcingRefresh - #1953
AustinBenoit wants to merge 1 commit into
Conversation
Use force_refresh=false for the initial GetAppCheckToken call in TestGetTokenForcingRefresh so it coalesces with any in-flight background auto-refresh triggered during app initialization rather than racing against it on Keychain storage. Also increase the sleep intervals between token fetches from 500ms to 1000ms across all platforms to ensure distinct expiration timestamps even with 1-second fetch_time granularity.
There was a problem hiding this comment.
Code Review
This pull request modifies the TestGetTokenForcingRefresh integration test by changing the first token request to not force a refresh and increasing the sleep durations from 500ms to 1000ms. The review comments suggest updating a misleading comment at line 515 to correctly reflect that the cached token is expected, and adding a clarifying comment at line 525 to explain the purpose of the sleep before forcing a token refresh.
| // Wait a bit to make sure the expire time would be different | ||
| std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
There was a problem hiding this comment.
The comment here states that we wait to make sure the expire time would be different, but the subsequent assertion on line 522 actually expects the expire times to be equal (EXPECT_EQ). This comment is misleading for this specific step and should be updated to reflect that we are verifying the cached token is still returned.
| // Wait a bit to make sure the expire time would be different | |
| std::this_thread::sleep_for(std::chrono::milliseconds(500)); | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | |
| // Wait a bit to verify the cached token is still returned | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
| future2.result()->expire_time_millis); | ||
|
|
||
| std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
There was a problem hiding this comment.
This sleep is where we actually need to ensure that the clock has advanced so that the newly forced token gets a different expiration timestamp (especially on desktop platforms with 1-second granularity). Adding a clarifying comment here would improve readability.
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | |
| // Wait a bit to make sure the new token's expire time will be different | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
Summary
Reduces flakiness in
FirebaseAppCheckTest.TestGetTokenForcingRefresh:GetAppCheckToken(false)for the initial token request (GetToken #1):On Apple platforms (iOS / tvOS),
FIRAppCheckis eagerly instantiated duringApp::Create()withisTokenAutoRefreshEnabled = trueandAppCheckCoreTokenRefresherimmediately schedules an initial backgroundperiodicTokenRefresh(token(forcingRefresh: false)). CallingGetAppCheckToken(true)(forcingRefresh: true) immediately afterward bypassedAppCheckCore'songoingTaskcoalescing and launched a competing token refresh request that raced on Keychain storage, occasionally overwriting the newly fetched token with the slightly older background token beforeGetToken #2(force_refresh=false) ran. CallingGetAppCheckToken(false)forGetToken #1coalesces with any in-flight startup token fetch.500msto1000ms:Ensures distinct expiration timestamps across all platforms (including Desktop where
response.fetch_time()has 1-second granularity).