Skip to content

Commit d92147a

Browse files
authored
Add test-related functionality, make GDLRegistrar thread-safe and tested (#2285)
* Add some functionality to the test prioritizer * Change the registrar's API and make it thread safe. * Add an error message enum for a failed upload * Add more functionality to the log storage fake * Make a property readonly.
1 parent f8fb6f1 commit d92147a

File tree

12 files changed

+116
-15
lines changed

12 files changed

+116
-15
lines changed

GoogleDataLogger/GoogleDataLogger/Classes/GDLRegistrar.m

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818

1919
#import "GDLRegistrar_Private.h"
2020

21-
@implementation GDLRegistrar
21+
@implementation GDLRegistrar {
22+
/** Backing ivar for logTargetToUploader property. */
23+
NSMutableDictionary<NSNumber *, id<GDLLogUploader>> *_logTargetToUploader;
24+
25+
/** Backing ivar for logTargetToPrioritizer property. */
26+
NSMutableDictionary<NSNumber *, id<GDLLogPrioritizer>> *_logTargetToPrioritizer;
27+
}
2228

2329
+ (instancetype)sharedInstance {
2430
static GDLRegistrar *sharedInstance;
@@ -32,19 +38,55 @@ + (instancetype)sharedInstance {
3238
- (instancetype)init {
3339
self = [super init];
3440
if (self) {
41+
_registrarQueue = dispatch_queue_create("com.google.GDLRegistrar", DISPATCH_QUEUE_CONCURRENT);
3542
_logTargetToPrioritizer = [[NSMutableDictionary alloc] init];
3643
_logTargetToUploader = [[NSMutableDictionary alloc] init];
3744
}
3845
return self;
3946
}
4047

41-
- (void)registerBackend:(id<GDLLogUploader>)backend forLogTarget:(GDLLogTarget)logTarget {
42-
self.logTargetToUploader[@(logTarget)] = backend;
48+
- (void)registerUploader:(id<GDLLogUploader>)backend logTarget:(GDLLogTarget)logTarget {
49+
__weak GDLRegistrar *weakSelf = self;
50+
dispatch_barrier_async(_registrarQueue, ^{
51+
GDLRegistrar *strongSelf = weakSelf;
52+
if (strongSelf) {
53+
strongSelf->_logTargetToUploader[@(logTarget)] = backend;
54+
}
55+
});
56+
}
57+
58+
- (void)registerPrioritizer:(id<GDLLogPrioritizer>)prioritizer logTarget:(GDLLogTarget)logTarget {
59+
__weak GDLRegistrar *weakSelf = self;
60+
dispatch_barrier_async(_registrarQueue, ^{
61+
GDLRegistrar *strongSelf = weakSelf;
62+
if (strongSelf) {
63+
strongSelf->_logTargetToPrioritizer[@(logTarget)] = prioritizer;
64+
}
65+
});
4366
}
4467

45-
- (void)registerLogPrioritizer:(id<GDLLogPrioritizer>)prioritizer
46-
forLogTarget:(GDLLogTarget)logTarget {
47-
self.logTargetToPrioritizer[@(logTarget)] = prioritizer;
68+
- (NSMutableDictionary<NSNumber *, id<GDLLogUploader>> *)logTargetToUploader {
69+
__block NSMutableDictionary<NSNumber *, id<GDLLogUploader>> *logTargetToUploader;
70+
__weak GDLRegistrar *weakSelf = self;
71+
dispatch_sync(_registrarQueue, ^{
72+
GDLRegistrar *strongSelf = weakSelf;
73+
if (strongSelf) {
74+
logTargetToUploader = strongSelf->_logTargetToUploader;
75+
}
76+
});
77+
return logTargetToUploader;
78+
}
79+
80+
- (NSMutableDictionary<NSNumber *, id<GDLLogPrioritizer>> *)logTargetToPrioritizer {
81+
__block NSMutableDictionary<NSNumber *, id<GDLLogPrioritizer>> *logTargetToPrioritizer;
82+
__weak GDLRegistrar *weakSelf = self;
83+
dispatch_sync(_registrarQueue, ^{
84+
GDLRegistrar *strongSelf = weakSelf;
85+
if (strongSelf) {
86+
logTargetToPrioritizer = strongSelf->_logTargetToPrioritizer;
87+
}
88+
});
89+
return logTargetToPrioritizer;
4890
}
4991

5092
@end

GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLRegistrar_Private.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818

1919
@interface GDLRegistrar ()
2020

21+
/** The concurrent queue on which all registration occurs. */
22+
@property(nonatomic, readonly) dispatch_queue_t registrarQueue;
23+
2124
/** A map of logTargets to backend implementations. */
22-
@property(nonatomic) NSMutableDictionary<NSNumber *, id<GDLLogUploader>> *logTargetToUploader;
25+
@property(atomic, readonly)
26+
NSMutableDictionary<NSNumber *, id<GDLLogUploader>> *logTargetToUploader;
2327

2428
/** A map of logTargets to prioritizer implementations. */
25-
@property(nonatomic) NSMutableDictionary<NSNumber *, id<GDLLogPrioritizer>> *logTargetToPrioritizer;
29+
@property(atomic, readonly)
30+
NSMutableDictionary<NSNumber *, id<GDLLogPrioritizer>> *logTargetToPrioritizer;
2631

2732
@end

GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLRegistrar.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,14 @@ NS_ASSUME_NONNULL_BEGIN
3636
* @param backend The backend object to register.
3737
* @param logTarget The logTarget this backend object will be responsible for.
3838
*/
39-
- (void)registerBackend:(id<GDLLogUploader>)backend forLogTarget:(GDLLogTarget)logTarget;
39+
- (void)registerUploader:(id<GDLLogUploader>)backend logTarget:(GDLLogTarget)logTarget;
4040

4141
/** Registers a log prioritizer implementation with the GoogleDataLogger infrastructure.
4242
*
4343
* @param prioritizer The prioritizer object to register.
4444
* @param logTarget The logTarget this prioritizer object will be responsible for.
4545
*/
46-
- (void)registerLogPrioritizer:(id<GDLLogPrioritizer>)prioritizer
47-
forLogTarget:(GDLLogTarget)logTarget;
46+
- (void)registerPrioritizer:(id<GDLLogPrioritizer>)prioritizer logTarget:(GDLLogTarget)logTarget;
4847

4948
@end
5049

GoogleDataLogger/GoogleDataLogger/DependencyWrappers/GDLConsoleLogger.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ typedef NS_ENUM(NSInteger, GDLMessageCode) {
3333
/** For warning messages concerning protoBytes: not being implemented by a log extension. */
3434
GDLMCWExtensionMissingBytesImpl = 1,
3535

36+
/** For warning message concerning a failed log upload. */
37+
GDLMCWUploadFailed = 2,
38+
3639
/** For error messages concerning transform: not being implemented by a log transformer. */
3740
GDLMCETransformerDoesntImplementTransform = 1000,
3841

GoogleDataLogger/Tests/Unit/Categories/GDLRegistrar+Testing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#import "GDLRegistrar.h"
18+
#import "GDLRegistrar_Private.h"
1819

1920
NS_ASSUME_NONNULL_BEGIN
2021

GoogleDataLogger/Tests/Unit/Categories/GDLRegistrar+Testing.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
@implementation GDLRegistrar (Testing)
2222

2323
- (void)reset {
24-
[self.logTargetToPrioritizer removeAllObjects];
25-
[self.logTargetToUploader removeAllObjects];
24+
dispatch_sync(self.registrarQueue, ^{
25+
[self.logTargetToPrioritizer removeAllObjects];
26+
[self.logTargetToUploader removeAllObjects];
27+
});
2628
}
2729

2830
@end

GoogleDataLogger/Tests/Unit/Fakes/GDLLogStorageFake.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ NS_ASSUME_NONNULL_BEGIN
2121
/** A functionless fake that can be injected into classes that need it. */
2222
@interface GDLLogStorageFake : GDLLogStorage
2323

24+
/** The logs to return from -logHashesToFiles. */
25+
@property(nonatomic) NSSet<NSURL *> *logsToReturnFromLogHashesToFiles;
26+
2427
@end
2528

2629
NS_ASSUME_NONNULL_END

GoogleDataLogger/Tests/Unit/Fakes/GDLLogStorageFake.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,18 @@ @implementation GDLLogStorageFake
2121
- (void)storeLog:(GDLLogEvent *)log {
2222
}
2323

24+
- (NSSet<NSURL *> *)logHashesToFiles:(NSSet<NSNumber *> *)logHashes {
25+
if (_logsToReturnFromLogHashesToFiles) {
26+
return _logsToReturnFromLogHashesToFiles;
27+
} else {
28+
return [[NSSet alloc] init];
29+
}
30+
}
31+
32+
- (void)removeLog:(NSNumber *)logHash logTarget:(NSNumber *)logTarget {
33+
}
34+
35+
- (void)removeLogs:(NSSet<NSNumber *> *)logHashes logTarget:(NSNumber *)logTarget {
36+
}
37+
2438
@end

GoogleDataLogger/Tests/Unit/GDLLogStorageTest.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ - (void)setUp {
5353
[super setUp];
5454
self.testBackend = [[GDLTestUploader alloc] init];
5555
self.testPrioritizer = [[GDLTestPrioritizer alloc] init];
56-
[[GDLRegistrar sharedInstance] registerBackend:_testBackend forLogTarget:logTarget];
57-
[[GDLRegistrar sharedInstance] registerLogPrioritizer:_testPrioritizer forLogTarget:logTarget];
56+
[[GDLRegistrar sharedInstance] registerUploader:_testBackend logTarget:logTarget];
57+
[[GDLRegistrar sharedInstance] registerPrioritizer:_testPrioritizer logTarget:logTarget];
5858
self.uploaderFake = [[GDLUploadCoordinatorFake alloc] init];
5959
[GDLLogStorage sharedInstance].uploader = self.uploaderFake;
6060
}

GoogleDataLogger/Tests/Unit/GDLRegistrarTest.m

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,41 @@
1818

1919
#import <GoogleDataLogger/GDLRegistrar.h>
2020

21+
#import "GDLRegistrar_Private.h"
22+
#import "GDLTestPrioritizer.h"
23+
#import "GDLTestUploader.h"
24+
2125
@interface GDLRegistrarTest : GDLTestCase
2226

27+
@property(nonatomic) GDLLogTarget logTarget;
28+
2329
@end
2430

2531
@implementation GDLRegistrarTest
2632

33+
- (void)setUp {
34+
_logTarget = 23;
35+
}
36+
2737
/** Tests the default initializer. */
2838
- (void)testInit {
2939
XCTAssertNotNil([[GDLRegistrarTest alloc] init]);
3040
}
3141

42+
/** Test registering an uploader. */
43+
- (void)testRegisterUpload {
44+
GDLRegistrar *registrar = [GDLRegistrar sharedInstance];
45+
GDLTestUploader *uploader = [[GDLTestUploader alloc] init];
46+
XCTAssertNoThrow([registrar registerUploader:uploader logTarget:self.logTarget]);
47+
XCTAssertEqual(uploader, registrar.logTargetToUploader[@(_logTarget)]);
48+
}
49+
50+
/** Test registering a prioritizer. */
51+
- (void)testRegisterPrioritizer {
52+
GDLRegistrar *registrar = [GDLRegistrar sharedInstance];
53+
GDLTestPrioritizer *prioritizer = [[GDLTestPrioritizer alloc] init];
54+
XCTAssertNoThrow([registrar registerPrioritizer:prioritizer logTarget:self.logTarget]);
55+
XCTAssertEqual(prioritizer, registrar.logTargetToPrioritizer[@(_logTarget)]);
56+
}
57+
3258
@end

GoogleDataLogger/Tests/Unit/Helpers/GDLTestPrioritizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ NS_ASSUME_NONNULL_BEGIN
3131
/** Allows the running of a block of code during -prioritizeLog. */
3232
@property(nullable, nonatomic) void (^prioritizeLogBlock)(GDLLogEvent *logEvent);
3333

34+
/** A block that can run before -logsForNextUpload completes. */
35+
@property(nullable, nonatomic) void (^logsForNextUploadBlock)(void);
36+
3437
@end
3538

3639
NS_ASSUME_NONNULL_END

GoogleDataLogger/Tests/Unit/Helpers/GDLTestPrioritizer.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ - (instancetype)init {
2727
}
2828

2929
- (NSSet<NSNumber *> *)logsForNextUpload {
30+
if (_logsForNextUploadBlock) {
31+
_logsForNextUploadBlock();
32+
}
3033
return _logsForNextUploadFake;
3134
}
3235

0 commit comments

Comments
 (0)