From 2bdb8d35a6efbd70bb2f52781d8c5cb766fb5716 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Thu, 18 Dec 2025 17:28:48 -0500 Subject: [PATCH 1/8] fix: flaky FIRCLSSettingsTests.m --- Crashlytics/Crashlytics/Models/FIRCLSSettings.m | 4 ---- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m index 80c70a48953..758772e5b8d 100644 --- a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m +++ b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m @@ -190,9 +190,7 @@ - (NSDictionary *)loadCacheKey { - (void)deleteCachedSettings { __weak FIRCLSSettings *weakSelf = self; -#ifndef FIREBASE_IS_NIGHTLY_TESTING dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ -#endif __strong FIRCLSSettings *strongSelf = weakSelf; if ([strongSelf.fileManager fileExistsAtPath:strongSelf.fileManager.settingsFilePath]) { [strongSelf.fileManager removeItemAtPath:strongSelf.fileManager.settingsFilePath]; @@ -200,9 +198,7 @@ - (void)deleteCachedSettings { if ([strongSelf.fileManager fileExistsAtPath:strongSelf.fileManager.settingsCacheKeyPath]) { [strongSelf.fileManager removeItemAtPath:strongSelf.fileManager.settingsCacheKeyPath]; } -#ifndef FIREBASE_IS_NIGHTLY_TESTING }); -#endif @synchronized(self) { self.isCacheKeyExpired = YES; diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index e2bfb58068f..ff046ef9cf2 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -76,6 +76,11 @@ @implementation FIRCLSSettingsTests - (void)setUp { [super setUp]; + dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + // Drain queue to prevent interference from previous tests. + // This queue is used by `- [FIRCLSSettings deleteCachedSettings]`. + }); + _fileManager = [[FIRCLSMockFileManager alloc] init]; _appIDModel = [[FABMockApplicationIdentifierModel alloc] init]; From 62a820f2f264d574e952a0dc3c48d3b9395bc652 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Fri, 19 Dec 2025 11:01:32 -0500 Subject: [PATCH 2/8] crashlytics --- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index ff046ef9cf2..d50bef59f3e 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -75,12 +75,7 @@ @implementation FIRCLSSettingsTests - (void)setUp { [super setUp]; - - dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - // Drain queue to prevent interference from previous tests. - // This queue is used by `- [FIRCLSSettings deleteCachedSettings]`. - }); - + [self drainBackgroundQueue]; _fileManager = [[FIRCLSMockFileManager alloc] init]; _appIDModel = [[FABMockApplicationIdentifierModel alloc] init]; @@ -139,6 +134,10 @@ - (void)cacheSettingsWithGoogleAppID:(NSString *)googleAppID [self.settings cacheSettingsWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; + if (expectedRemoveCount) { + [self drainBackgroundQueue]; + } + [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:1]; } @@ -152,9 +151,19 @@ - (void)reloadFromCacheWithGoogleAppID:(NSString *)googleAppID [self.settings reloadFromCacheWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; + if (expectedRemoveCount) { + [self drainBackgroundQueue]; + } + [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:5.0]; } +- (void)drainBackgroundQueue { + dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + // This queue is used by `- [FIRCLSSettings deleteCachedSettings]`. + }); +} + - (void)testActivatedSettingsCached { NSError *error = nil; [self writeSettings:FIRCLSTestSettingsActivated error:&error]; From a9654320c16858c5221ffe00af302647c8c95fee Mon Sep 17 00:00:00 2001 From: Nick Cooke <36927374+ncooke3@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:19:37 -0500 Subject: [PATCH 3/8] Update Crashlytics/UnitTests/FIRCLSSettingsTests.m --- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index d50bef59f3e..734c7091a3c 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -134,9 +134,7 @@ - (void)cacheSettingsWithGoogleAppID:(NSString *)googleAppID [self.settings cacheSettingsWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; - if (expectedRemoveCount) { - [self drainBackgroundQueue]; - } + [self drainBackgroundQueue]; [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:1]; } From d987d336fc408f327b41d53fab96d6f923829d63 Mon Sep 17 00:00:00 2001 From: Nick Cooke <36927374+ncooke3@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:19:42 -0500 Subject: [PATCH 4/8] Update Crashlytics/UnitTests/FIRCLSSettingsTests.m --- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index 734c7091a3c..48eb493459f 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -149,9 +149,7 @@ - (void)reloadFromCacheWithGoogleAppID:(NSString *)googleAppID [self.settings reloadFromCacheWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; - if (expectedRemoveCount) { - [self drainBackgroundQueue]; - } + [self drainBackgroundQueue]; [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:5.0]; } From 4a17d79de358d4ccd69263c2053aa72b52e5a592 Mon Sep 17 00:00:00 2001 From: Nick Cooke <36927374+ncooke3@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:48:10 -0500 Subject: [PATCH 5/8] Update Crashlytics/UnitTests/FIRCLSSettingsTests.m --- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index 48eb493459f..61442f28938 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -136,7 +136,7 @@ - (void)cacheSettingsWithGoogleAppID:(NSString *)googleAppID [self drainBackgroundQueue]; - [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:1]; + [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:5.0]; } - (void)reloadFromCacheWithGoogleAppID:(NSString *)googleAppID From 5e5f60990599984af3f8442efdf8867f91efe887 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Fri, 19 Dec 2025 17:19:13 -0500 Subject: [PATCH 6/8] try again --- .../Crashlytics/Models/FIRCLSSettings.h | 3 +-- .../Crashlytics/Models/FIRCLSSettings.m | 13 +++++++++++- Crashlytics/UnitTests/FIRCLSSettingsTests.m | 21 ++++++++----------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Crashlytics/Crashlytics/Models/FIRCLSSettings.h b/Crashlytics/Crashlytics/Models/FIRCLSSettings.h index f122fffd93b..488cc295530 100644 --- a/Crashlytics/Crashlytics/Models/FIRCLSSettings.h +++ b/Crashlytics/Crashlytics/Models/FIRCLSSettings.h @@ -30,8 +30,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; - (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager - appIDModel:(FIRCLSApplicationIdentifierModel *)appIDModel - NS_DESIGNATED_INITIALIZER; + appIDModel:(FIRCLSApplicationIdentifierModel *)appIDModel; /** * Recreates the settings dictionary by re-reading the settings file from persistent storage. This diff --git a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m index 758772e5b8d..5b7b5669267 100644 --- a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m +++ b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m @@ -40,12 +40,23 @@ @interface FIRCLSSettings () @property(nonatomic) BOOL isCacheKeyExpired; +@property(nonatomic) dispatch_queue_t deletionQueue; + @end @implementation FIRCLSSettings - (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager appIDModel:(FIRCLSApplicationIdentifierModel *)appIDModel { + return + [self initWithFileManager:fileManager + appIDModel:appIDModel + deletionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)]; +} + +- (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager + appIDModel:(FIRCLSApplicationIdentifierModel *)appIDModel + deletionQueue:(dispatch_queue_t)deletionQueue { self = [super init]; if (!self) { return nil; @@ -190,7 +201,7 @@ - (NSDictionary *)loadCacheKey { - (void)deleteCachedSettings { __weak FIRCLSSettings *weakSelf = self; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + dispatch_async(_deletionQueue, ^{ __strong FIRCLSSettings *strongSelf = weakSelf; if ([strongSelf.fileManager fileExistsAtPath:strongSelf.fileManager.settingsFilePath]) { [strongSelf.fileManager removeItemAtPath:strongSelf.fileManager.settingsFilePath]; diff --git a/Crashlytics/UnitTests/FIRCLSSettingsTests.m b/Crashlytics/UnitTests/FIRCLSSettingsTests.m index 61442f28938..1ef5a58c890 100644 --- a/Crashlytics/UnitTests/FIRCLSSettingsTests.m +++ b/Crashlytics/UnitTests/FIRCLSSettingsTests.m @@ -60,6 +60,10 @@ @interface FIRCLSSettings (Testing) @property(nonatomic, strong) NSDictionary *settingsDictionary; +- (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager + appIDModel:(FIRCLSApplicationIdentifierModel *)appIDModel + deletionQueue:(dispatch_queue_t)deletionQueue; + @end @interface FIRCLSSettingsTests : XCTestCase @@ -75,7 +79,6 @@ @implementation FIRCLSSettingsTests - (void)setUp { [super setUp]; - [self drainBackgroundQueue]; _fileManager = [[FIRCLSMockFileManager alloc] init]; _appIDModel = [[FABMockApplicationIdentifierModel alloc] init]; @@ -83,7 +86,11 @@ - (void)setUp { _appIDModel.displayVersion = FIRCLSDefaultMockAppDisplayVersion; _appIDModel.buildVersion = FIRCLSDefaultMockAppBuildVersion; - _settings = [[FIRCLSSettings alloc] initWithFileManager:_fileManager appIDModel:_appIDModel]; + // Inject a higher priority queue for deletion operations to reduce flakes. + _settings = [[FIRCLSSettings alloc] + initWithFileManager:_fileManager + appIDModel:_appIDModel + deletionQueue:dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)]; } - (void)testDefaultSettings { @@ -134,8 +141,6 @@ - (void)cacheSettingsWithGoogleAppID:(NSString *)googleAppID [self.settings cacheSettingsWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; - [self drainBackgroundQueue]; - [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:5.0]; } @@ -149,17 +154,9 @@ - (void)reloadFromCacheWithGoogleAppID:(NSString *)googleAppID [self.settings reloadFromCacheWithGoogleAppID:googleAppID currentTimestamp:currentTimestamp]; - [self drainBackgroundQueue]; - [self waitForExpectations:@[ self.fileManager.removeExpectation ] timeout:5.0]; } -- (void)drainBackgroundQueue { - dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - // This queue is used by `- [FIRCLSSettings deleteCachedSettings]`. - }); -} - - (void)testActivatedSettingsCached { NSError *error = nil; [self writeSettings:FIRCLSTestSettingsActivated error:&error]; From 079c1ad76c1160ac8565810dc6cd44a0859ac213 Mon Sep 17 00:00:00 2001 From: Nick Cooke <36927374+ncooke3@users.noreply.github.com> Date: Fri, 19 Dec 2025 18:06:38 -0500 Subject: [PATCH 7/8] Apply suggestion from @ncooke3 --- Crashlytics/Crashlytics/Models/FIRCLSSettings.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m index 5b7b5669267..e55982a4ed8 100644 --- a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m +++ b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m @@ -68,6 +68,8 @@ - (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager _settingsDictionary = nil; _isCacheKeyExpired = NO; +_deletionQueue = deletionQueue; + return self; } From b33da2d7309c25619c85654f77d33c09096f4c15 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Sat, 20 Dec 2025 12:06:59 -0500 Subject: [PATCH 8/8] skip ci: style --- Crashlytics/Crashlytics/Models/FIRCLSSettings.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m index e55982a4ed8..b53c44e38d3 100644 --- a/Crashlytics/Crashlytics/Models/FIRCLSSettings.m +++ b/Crashlytics/Crashlytics/Models/FIRCLSSettings.m @@ -68,7 +68,7 @@ - (instancetype)initWithFileManager:(FIRCLSFileManager *)fileManager _settingsDictionary = nil; _isCacheKeyExpired = NO; -_deletionQueue = deletionQueue; + _deletionQueue = deletionQueue; return self; }