Skip to content

Commit 78d9cad

Browse files
authored
Refactor to allow injection of fakes, and take warnings seriously (#2232)
* Create fakes that can be used during unit tests * Create a private header for the logger * All log storage to be injected into the log writer, and now give logs to log storage. Also changes the tests to use the fakes * Treat all warnings as errors, and warn pedantic * Ok nevermind, don't warn_pedantic. * remove trailing comma * Remove obsolete TODOs Not needed, because a fake is being used. * Add fakes and injection to log storage for the uploader, implement a fast qos test
1 parent e129a30 commit 78d9cad

16 files changed

+258
-31
lines changed

GoogleDataLogger.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Shared library for iOS SDK data logging needs.
3030
s.dependency 'GoogleUtilities/Logger'
3131

3232
s.pod_target_xcconfig = {
33-
'GCC_C_LANGUAGE_STANDARD' => 'c99'
33+
'GCC_C_LANGUAGE_STANDARD' => 'c99',
34+
'GCC_TREAT_WARNINGS_AS_ERRORS' => 'YES'
3435
}
3536

3637
# Test specs

GoogleDataLogger/GoogleDataLogger/Classes/GDLLogStorage.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ - (instancetype)init {
5757
_storageQueue = dispatch_queue_create("com.google.GDLLogStorage", DISPATCH_QUEUE_SERIAL);
5858
_logHashToLogFile = [[NSMutableDictionary alloc] init];
5959
_logTargetToLogFileSet = [[NSMutableDictionary alloc] init];
60+
_uploader = [GDLUploader sharedInstance];
6061
}
6162
return self;
6263
}
@@ -90,7 +91,7 @@ - (void)storeLog:(GDLLogEvent *)log {
9091
// Check the QoS, if it's high priority, notify the log target that it has a high priority log.
9192
if (shortLivedLog.qosTier == GDLLogQoSFast) {
9293
NSSet<NSURL *> *allLogsForLogTarget = self.logTargetToLogFileSet[@(logTarget)];
93-
[[GDLUploader sharedInstance] forceUploadLogs:allLogsForLogTarget target:logTarget];
94+
[self.uploader forceUploadLogs:allLogsForLogTarget target:logTarget];
9495
}
9596

9697
// Have the prioritizer prioritize the log, enforcing that they do not retain it.

GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ - (instancetype)init {
4141
self = [super init];
4242
if (self) {
4343
_logWritingQueue = dispatch_queue_create("com.google.GDLLogWriter", DISPATCH_QUEUE_SERIAL);
44+
_storageInstance = [GDLLogStorage sharedInstance];
4445
}
4546
return self;
4647
}
@@ -62,7 +63,7 @@ - (void)writeLog:(GDLLogEvent *)log
6263
return;
6364
}
6465
}
65-
// TODO(mikehaney24): [[GDLLogStorage sharedInstance] storeLog:transformedLog];
66+
[self.storageInstance storeLog:transformedLog];
6667
});
6768
}
6869

GoogleDataLogger/GoogleDataLogger/Classes/GDLLogger.m

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,12 @@
1515
*/
1616

1717
#import "GDLLogger.h"
18+
#import "GDLLogger_Private.h"
1819

1920
#import "GDLAssert.h"
2021
#import "GDLLogEvent.h"
2122
#import "GDLLogWriter.h"
2223

23-
@interface GDLLogger ()
24-
25-
/** The log mapping identifier that a GDLLogBackend will use to map the extension to proto. */
26-
@property(nonatomic) NSString *logMapID;
27-
28-
/** The log transformers that will operate on logs logged by this logger. */
29-
@property(nonatomic) NSArray<id<GDLLogTransformer>> *logTransformers;
30-
31-
/** The target backend of this logger. */
32-
@property(nonatomic) NSInteger logTarget;
33-
34-
@end
35-
3624
@implementation GDLLogger
3725

3826
- (instancetype)initWithLogMapID:(NSString *)logMapID
@@ -45,6 +33,7 @@ - (instancetype)initWithLogMapID:(NSString *)logMapID
4533
_logMapID = logMapID;
4634
_logTransformers = logTransformers;
4735
_logTarget = logTarget;
36+
_logWriterInstance = [GDLLogWriter sharedInstance];
4837
}
4938
return self;
5039
}
@@ -53,14 +42,14 @@ - (void)logTelemetryEvent:(GDLLogEvent *)logEvent {
5342
GDLAssert(logEvent, @"You can't log a nil event");
5443
GDLLogEvent *copiedLog = [logEvent copy];
5544
copiedLog.qosTier = GDLLogQoSTelemetry;
56-
[[GDLLogWriter sharedInstance] writeLog:copiedLog afterApplyingTransformers:_logTransformers];
45+
[self.logWriterInstance writeLog:copiedLog afterApplyingTransformers:_logTransformers];
5746
}
5847

5948
- (void)logDataEvent:(GDLLogEvent *)logEvent {
6049
GDLAssert(logEvent, @"You can't log a nil event");
6150
GDLAssert(logEvent.qosTier != GDLLogQoSTelemetry, @"Use -logTelemetryEvent, please.");
6251
GDLLogEvent *copiedLog = [logEvent copy];
63-
[[GDLLogWriter sharedInstance] writeLog:copiedLog afterApplyingTransformers:_logTransformers];
52+
[self.logWriterInstance writeLog:copiedLog afterApplyingTransformers:_logTransformers];
6453
}
6554

6655
- (GDLLogEvent *)newEvent {

GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogStorage_Private.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#import "GDLLogStorage.h"
1818

19+
@class GDLUploader;
20+
1921
@interface GDLLogStorage ()
2022

2123
/** The queue on which all storage work will occur. */
@@ -28,4 +30,7 @@
2830
@property(nonatomic)
2931
NSMutableDictionary<NSNumber *, NSMutableSet<NSURL *> *> *logTargetToLogFileSet;
3032

33+
/** The log uploader instance to use. */
34+
@property(nonatomic) GDLUploader *uploader;
35+
3136
@end

GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogWriter_Private.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616

1717
#import "GDLLogWriter.h"
1818

19+
@class GDLLogStorage;
20+
1921
@interface GDLLogWriter ()
2022

2123
/** The queue on which all work will occur. */
2224
@property(nonatomic) dispatch_queue_t logWritingQueue;
2325

26+
/** The log storage instance used to store logs. Should only be used to inject a testing fake. */
27+
@property(nonatomic) GDLLogStorage *storageInstance;
28+
2429
@end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import <GoogleDataLogger/GDLLogger.h>
18+
19+
@class GDLLogWriter;
20+
21+
@interface GDLLogger ()
22+
23+
/** The log mapping identifier that a GDLLogBackend will use to map the extension to proto. */
24+
@property(nonatomic) NSString *logMapID;
25+
26+
/** The log transformers that will operate on logs logged by this logger. */
27+
@property(nonatomic) NSArray<id<GDLLogTransformer>> *logTransformers;
28+
29+
/** The target backend of this logger. */
30+
@property(nonatomic) NSInteger logTarget;
31+
32+
/** The log writer instance to used to write logs. Allows injecting a fake during testing. */
33+
@property(nonatomic) GDLLogWriter *logWriterInstance;
34+
35+
@end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLLogStorage.h"
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
/** A functionless fake that can be injected into classes that need it. */
22+
@interface GDLLogStorageFake : GDLLogStorage
23+
24+
@end
25+
26+
NS_ASSUME_NONNULL_END
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLLogStorageFake.h"
18+
19+
@implementation GDLLogStorageFake
20+
21+
- (void)storeLog:(GDLLogEvent *)log {
22+
}
23+
24+
@end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLLogWriter.h"
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
/** A functionless fake that can be injected into classes that need it. */
22+
@interface GDLLogWriterFake : GDLLogWriter
23+
24+
@end
25+
26+
NS_ASSUME_NONNULL_END
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLLogWriterFake.h"
18+
19+
@implementation GDLLogWriterFake
20+
21+
- (void)writeLog:(GDLLogEvent *)log
22+
afterApplyingTransformers:(NSArray<id<GDLLogTransformer>> *)logTransformers {
23+
}
24+
25+
@end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLUploader.h"
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
@interface GDLUploaderFake : GDLUploader
22+
23+
@property(nonatomic) BOOL forceUploadCalled;
24+
25+
@end
26+
27+
NS_ASSUME_NONNULL_END
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GDLUploaderFake.h"
18+
19+
@implementation GDLUploaderFake
20+
21+
- (void)forceUploadLogs:(NSSet<NSURL *> *)logFiles target:(NSInteger)logTarget {
22+
self.forceUploadCalled = YES;
23+
}
24+
25+
@end

GoogleDataLogger/Tests/GDLLogStorageTest.m

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#import "GDLAssertHelper.h"
3131
#import "GDLLogStorage+Testing.h"
3232
#import "GDLRegistrar+Testing.h"
33+
#import "GDLUploaderFake.h"
3334

3435
static NSInteger logTarget = 1337;
3536

@@ -41,6 +42,8 @@ @interface GDLLogStorageTest : GDLTestCase
4142
/** The test prioritizer implementation. */
4243
@property(nullable, nonatomic) GDLTestPrioritizer *testPrioritizer;
4344

45+
@property(nonatomic) GDLUploaderFake *uploaderFake;
46+
4447
@end
4548

4649
@implementation GDLLogStorageTest
@@ -51,6 +54,8 @@ - (void)setUp {
5154
self.testPrioritizer = [[GDLTestPrioritizer alloc] init];
5255
[[GDLRegistrar sharedInstance] registerBackend:_testBackend forLogTarget:logTarget];
5356
[[GDLRegistrar sharedInstance] registerLogPrioritizer:_testPrioritizer forLogTarget:logTarget];
57+
self.uploaderFake = [[GDLUploaderFake alloc] init];
58+
[GDLLogStorage sharedInstance].uploader = self.uploaderFake;
5459
}
5560

5661
- (void)tearDown {
@@ -60,6 +65,8 @@ - (void)tearDown {
6065
self.testPrioritizer = nil;
6166
[[GDLRegistrar sharedInstance] reset];
6267
[[GDLLogStorage sharedInstance] reset];
68+
[GDLLogStorage sharedInstance].uploader = [GDLUploader sharedInstance];
69+
self.uploaderFake = nil;
6370
}
6471

6572
/** Tests the singleton pattern. */
@@ -194,6 +201,7 @@ - (void)testLogEventDeallocationIsEnforced {
194201

195202
/** Tests encoding and decoding the storage singleton correctly. */
196203
- (void)testNSSecureCoding {
204+
XCTAssertTrue([GDLLogStorage supportsSecureCoding]);
197205
GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"404" logTarget:logTarget];
198206
logEvent.extensionBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
199207
NSUInteger logHash = logEvent.hash;
@@ -215,7 +223,27 @@ - (void)testNSSecureCoding {
215223

216224
/** Tests logging a fast log causes an upload attempt. */
217225
- (void)testQoSTierFast {
218-
// TODO
226+
NSUInteger logHash;
227+
// logEvent is autoreleased, and the pool needs to drain.
228+
@autoreleasepool {
229+
GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"404" logTarget:logTarget];
230+
logEvent.extensionBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
231+
logEvent.qosTier = GDLLogQoSFast;
232+
logHash = logEvent.hash;
233+
XCTAssertFalse(self.uploaderFake.forceUploadCalled);
234+
XCTAssertNoThrow([[GDLLogStorage sharedInstance] storeLog:logEvent]);
235+
}
236+
dispatch_sync([GDLLogStorage sharedInstance].storageQueue, ^{
237+
XCTAssertTrue(self.uploaderFake.forceUploadCalled);
238+
XCTAssertEqual([GDLLogStorage sharedInstance].logHashToLogFile.count, 1);
239+
XCTAssertEqual([GDLLogStorage sharedInstance].logTargetToLogFileSet[@(logTarget)].count, 1);
240+
NSURL *logFile = [GDLLogStorage sharedInstance].logHashToLogFile[@(logHash)];
241+
XCTAssertNotNil(logFile);
242+
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:logFile.path]);
243+
NSError *error;
244+
XCTAssertTrue([[NSFileManager defaultManager] removeItemAtURL:logFile error:&error]);
245+
XCTAssertNil(error, @"There was an error deleting the logFile: %@", error);
246+
});
219247
}
220248

221249
@end

0 commit comments

Comments
 (0)