From 628f14f63de06ddf27d94e9a8335c3a7b520e679 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 14:56:30 -0800 Subject: [PATCH 1/8] Create fakes that can be used during unit tests --- .../Tests/Fakes/GDLLogStorageFake.h | 26 +++++++++++++++++++ .../Tests/Fakes/GDLLogStorageFake.m | 24 +++++++++++++++++ .../Tests/Fakes/GDLLogWriterFake.h | 26 +++++++++++++++++++ .../Tests/Fakes/GDLLogWriterFake.m | 25 ++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.h create mode 100644 GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.m create mode 100644 GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.h create mode 100644 GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.m diff --git a/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.h b/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.h new file mode 100644 index 00000000000..389c64e6dc9 --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.h @@ -0,0 +1,26 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLLogStorage.h" + +NS_ASSUME_NONNULL_BEGIN + +/** A functionless fake that can be injected into classes that need it. */ +@interface GDLLogStorageFake : GDLLogStorage + +@end + +NS_ASSUME_NONNULL_END diff --git a/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.m b/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.m new file mode 100644 index 00000000000..bed9979dd7c --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLLogStorageFake.m @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLLogStorageFake.h" + +@implementation GDLLogStorageFake + +- (void)storeLog:(GDLLogEvent *)log { +} + +@end diff --git a/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.h b/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.h new file mode 100644 index 00000000000..e7ce6ec0bf5 --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.h @@ -0,0 +1,26 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLLogWriter.h" + +NS_ASSUME_NONNULL_BEGIN + +/** A functionless fake that can be injected into classes that need it. */ +@interface GDLLogWriterFake : GDLLogWriter + +@end + +NS_ASSUME_NONNULL_END diff --git a/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.m b/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.m new file mode 100644 index 00000000000..d30236c44d4 --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLLogWriterFake.m @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLLogWriterFake.h" + +@implementation GDLLogWriterFake + +- (void)writeLog:(GDLLogEvent *)log + afterApplyingTransformers:(NSArray> *)logTransformers { +} + +@end From 4ef7b6b36a0f8e545efcfe077cc0b73674adec83 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 14:56:56 -0800 Subject: [PATCH 2/8] Create a private header for the logger --- .../GoogleDataLogger/Classes/GDLLogger.m | 19 +++------- .../Classes/Private/GDLLogger_Private.h | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogger_Private.h diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogger.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogger.m index a9f9358be35..67924fa3b4c 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogger.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogger.m @@ -15,24 +15,12 @@ */ #import "GDLLogger.h" +#import "GDLLogger_Private.h" #import "GDLAssert.h" #import "GDLLogEvent.h" #import "GDLLogWriter.h" -@interface GDLLogger () - -/** The log mapping identifier that a GDLLogBackend will use to map the extension to proto. */ -@property(nonatomic) NSString *logMapID; - -/** The log transformers that will operate on logs logged by this logger. */ -@property(nonatomic) NSArray> *logTransformers; - -/** The target backend of this logger. */ -@property(nonatomic) NSInteger logTarget; - -@end - @implementation GDLLogger - (instancetype)initWithLogMapID:(NSString *)logMapID @@ -45,6 +33,7 @@ - (instancetype)initWithLogMapID:(NSString *)logMapID _logMapID = logMapID; _logTransformers = logTransformers; _logTarget = logTarget; + _logWriterInstance = [GDLLogWriter sharedInstance]; } return self; } @@ -53,14 +42,14 @@ - (void)logTelemetryEvent:(GDLLogEvent *)logEvent { GDLAssert(logEvent, @"You can't log a nil event"); GDLLogEvent *copiedLog = [logEvent copy]; copiedLog.qosTier = GDLLogQoSTelemetry; - [[GDLLogWriter sharedInstance] writeLog:copiedLog afterApplyingTransformers:_logTransformers]; + [self.logWriterInstance writeLog:copiedLog afterApplyingTransformers:_logTransformers]; } - (void)logDataEvent:(GDLLogEvent *)logEvent { GDLAssert(logEvent, @"You can't log a nil event"); GDLAssert(logEvent.qosTier != GDLLogQoSTelemetry, @"Use -logTelemetryEvent, please."); GDLLogEvent *copiedLog = [logEvent copy]; - [[GDLLogWriter sharedInstance] writeLog:copiedLog afterApplyingTransformers:_logTransformers]; + [self.logWriterInstance writeLog:copiedLog afterApplyingTransformers:_logTransformers]; } - (GDLLogEvent *)newEvent { diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogger_Private.h b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogger_Private.h new file mode 100644 index 00000000000..277434c8e31 --- /dev/null +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogger_Private.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class GDLLogWriter; + +@interface GDLLogger () + +/** The log mapping identifier that a GDLLogBackend will use to map the extension to proto. */ +@property(nonatomic) NSString *logMapID; + +/** The log transformers that will operate on logs logged by this logger. */ +@property(nonatomic) NSArray> *logTransformers; + +/** The target backend of this logger. */ +@property(nonatomic) NSInteger logTarget; + +/** The log writer instance to used to write logs. Allows injecting a fake during testing. */ +@property(nonatomic) GDLLogWriter *logWriterInstance; + +@end From 8818bc411a1779beb271ae9a2c35dfbe645e9e55 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 14:57:54 -0800 Subject: [PATCH 3/8] 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 --- .../GoogleDataLogger/Classes/GDLLogWriter.m | 3 ++- .../Classes/Private/GDLLogWriter_Private.h | 5 +++++ GoogleDataLogger/Tests/GDLLogWriterTest.m | 16 ++++++++++++++++ GoogleDataLogger/Tests/GDLLoggerTest.m | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m index 207725c9a1e..25b3fe00086 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m @@ -41,6 +41,7 @@ - (instancetype)init { self = [super init]; if (self) { _logWritingQueue = dispatch_queue_create("com.google.GDLLogWriter", DISPATCH_QUEUE_SERIAL); + _storageInstance = [GDLLogStorage sharedInstance]; } return self; } @@ -62,7 +63,7 @@ - (void)writeLog:(GDLLogEvent *)log return; } } - // TODO(mikehaney24): [[GDLLogStorage sharedInstance] storeLog:transformedLog]; + [self.storageInstance storeLog:transformedLog]; }); } diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogWriter_Private.h b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogWriter_Private.h index 6d9061222b7..83627959553 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogWriter_Private.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogWriter_Private.h @@ -16,9 +16,14 @@ #import "GDLLogWriter.h" +@class GDLLogStorage; + @interface GDLLogWriter () /** The queue on which all work will occur. */ @property(nonatomic) dispatch_queue_t logWritingQueue; +/** The log storage instance used to store logs. Should only be used to inject a testing fake. */ +@property(nonatomic) GDLLogStorage *storageInstance; + @end diff --git a/GoogleDataLogger/Tests/GDLLogWriterTest.m b/GoogleDataLogger/Tests/GDLLogWriterTest.m index 570d61b0d79..d6815456bc1 100644 --- a/GoogleDataLogger/Tests/GDLLogWriterTest.m +++ b/GoogleDataLogger/Tests/GDLLogWriterTest.m @@ -20,10 +20,12 @@ #import "GDLLogEvent.h" #import "GDLLogExtensionTesterClasses.h" +#import "GDLLogStorage.h" #import "GDLLogWriter.h" #import "GDLLogWriter_Private.h" #import "GDLAssertHelper.h" +#import "GDLLogStorageFake.h" @interface GDLLogWriterTestNilingTransformer : NSObject @@ -55,6 +57,20 @@ @interface GDLLogWriterTest : GDLTestCase @implementation GDLLogWriterTest +- (void)setUp { + [super setUp]; + dispatch_sync([GDLLogWriter sharedInstance].logWritingQueue, ^{ + [GDLLogWriter sharedInstance].storageInstance = [[GDLLogStorageFake alloc] init]; + }); +} + +- (void)tearDown { + [super tearDown]; + dispatch_sync([GDLLogWriter sharedInstance].logWritingQueue, ^{ + [GDLLogWriter sharedInstance].storageInstance = [GDLLogStorage sharedInstance]; + }); +} + /** Tests the default initializer. */ - (void)testInit { XCTAssertNotNil([[GDLLogWriter alloc] init]); diff --git a/GoogleDataLogger/Tests/GDLLoggerTest.m b/GoogleDataLogger/Tests/GDLLoggerTest.m index a0c2551678b..d77757b992d 100644 --- a/GoogleDataLogger/Tests/GDLLoggerTest.m +++ b/GoogleDataLogger/Tests/GDLLoggerTest.m @@ -19,7 +19,10 @@ #import #import +#import "GDLLogger_Private.h" + #import "GDLLogExtensionTesterClasses.h" +#import "GDLLogWriterFake.h" @interface GDLLoggerTest : GDLTestCase @@ -36,6 +39,7 @@ - (void)testInit { /** Tests logging a telemetry event. */ - (void)testLogTelemetryEvent { GDLLogger *logger = [[GDLLogger alloc] initWithLogMapID:@"1" logTransformers:nil logTarget:1]; + logger.logWriterInstance = [[GDLLogWriterFake alloc] init]; GDLLogEvent *event = [logger newEvent]; event.extension = [[GDLLogExtensionTesterSimple alloc] init]; XCTAssertNoThrow([logger logTelemetryEvent:event]); @@ -44,6 +48,7 @@ - (void)testLogTelemetryEvent { /** Tests logging a data event. */ - (void)testLogDataEvent { GDLLogger *logger = [[GDLLogger alloc] initWithLogMapID:@"1" logTransformers:nil logTarget:1]; + logger.logWriterInstance = [[GDLLogWriterFake alloc] init]; GDLLogEvent *event = [logger newEvent]; event.extension = [[GDLLogExtensionTesterSimple alloc] init]; XCTAssertNoThrow([logger logDataEvent:event]); From 89b3588e7122dad6e8abc2e3c8e276a18bb3a9a6 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 14:58:59 -0800 Subject: [PATCH 4/8] Treat all warnings as errors, and warn pedantic --- GoogleDataLogger.podspec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GoogleDataLogger.podspec b/GoogleDataLogger.podspec index 75df8a4899e..f2f04c2be95 100644 --- a/GoogleDataLogger.podspec +++ b/GoogleDataLogger.podspec @@ -30,7 +30,9 @@ Shared library for iOS SDK data logging needs. s.dependency 'GoogleUtilities/Logger' s.pod_target_xcconfig = { - 'GCC_C_LANGUAGE_STANDARD' => 'c99' + 'GCC_C_LANGUAGE_STANDARD' => 'c99', + 'GCC_TREAT_WARNINGS_AS_ERRORS' => 'YES', + 'GCC_WARN_PEDANTIC' => 'YES', } # Test specs From 5c4dea634c7d479525949987292706e146845289 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 15:12:11 -0800 Subject: [PATCH 5/8] Ok nevermind, don't warn_pedantic. --- GoogleDataLogger.podspec | 1 - 1 file changed, 1 deletion(-) diff --git a/GoogleDataLogger.podspec b/GoogleDataLogger.podspec index f2f04c2be95..cd0dd074f61 100644 --- a/GoogleDataLogger.podspec +++ b/GoogleDataLogger.podspec @@ -32,7 +32,6 @@ Shared library for iOS SDK data logging needs. s.pod_target_xcconfig = { 'GCC_C_LANGUAGE_STANDARD' => 'c99', 'GCC_TREAT_WARNINGS_AS_ERRORS' => 'YES', - 'GCC_WARN_PEDANTIC' => 'YES', } # Test specs From 558906509cc79635a8fba725db931299fe218b1a Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 15:12:40 -0800 Subject: [PATCH 6/8] remove trailing comma --- GoogleDataLogger.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GoogleDataLogger.podspec b/GoogleDataLogger.podspec index cd0dd074f61..65fc197ac40 100644 --- a/GoogleDataLogger.podspec +++ b/GoogleDataLogger.podspec @@ -31,7 +31,7 @@ Shared library for iOS SDK data logging needs. s.pod_target_xcconfig = { 'GCC_C_LANGUAGE_STANDARD' => 'c99', - 'GCC_TREAT_WARNINGS_AS_ERRORS' => 'YES', + 'GCC_TREAT_WARNINGS_AS_ERRORS' => 'YES' } # Test specs From e48356e567509bd77c199836c263677edc9ce466 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 15:27:57 -0800 Subject: [PATCH 7/8] Remove obsolete TODOs Not needed, because a fake is being used. --- GoogleDataLogger/Tests/GDLLogWriterTest.m | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/GoogleDataLogger/Tests/GDLLogWriterTest.m b/GoogleDataLogger/Tests/GDLLogWriterTest.m index d6815456bc1..2e173d4d987 100644 --- a/GoogleDataLogger/Tests/GDLLogWriterTest.m +++ b/GoogleDataLogger/Tests/GDLLogWriterTest.m @@ -87,9 +87,6 @@ - (void)testWriteLogWithoutTransformers { GDLLogEvent *log = [[GDLLogEvent alloc] initWithLogMapID:@"1" logTarget:1]; log.extension = [[GDLLogExtensionTesterSimple alloc] init]; XCTAssertNoThrow([writer writeLog:log afterApplyingTransformers:nil]); - dispatch_sync(writer.logWritingQueue, ^{ - // TODO(mikehaney24): Assert that storage contains the log. - }); } /** Tests writing a log with a transformer that nils out the log. */ @@ -100,9 +97,6 @@ - (void)testWriteLogWithTransformersThatNilTheLog { NSArray> *transformers = @[ [[GDLLogWriterTestNilingTransformer alloc] init] ]; XCTAssertNoThrow([writer writeLog:log afterApplyingTransformers:transformers]); - dispatch_sync(writer.logWritingQueue, ^{ - // TODO(mikehaney24): Assert that storage does not contain the log. - }); } /** Tests writing a log with a transformer that creates a new log. */ @@ -113,9 +107,6 @@ - (void)testWriteLogWithTransformersThatCreateANewLog { NSArray> *transformers = @[ [[GDLLogWriterTestNewLogTransformer alloc] init] ]; XCTAssertNoThrow([writer writeLog:log afterApplyingTransformers:transformers]); - dispatch_sync(writer.logWritingQueue, ^{ - // TODO(mikehaney24): Assert that storage contains the new log. - }); } /** Tests that using a transformer without transform: implemented throws. */ @@ -131,9 +122,6 @@ - (void)testWriteLogWithBadTransformer { }]; [writer writeLog:log afterApplyingTransformers:transformers]; [self waitForExpectations:@[ errorExpectation ] timeout:5.0]; - dispatch_sync(writer.logWritingQueue, ^{ - // TODO(mikehaney24): Assert that storage contains the new log. - }); } /** Tests that writing a nil log throws. */ From ed2e45729af30c847ee7d25e011fb0bc645fb4b5 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Thu, 3 Jan 2019 15:56:41 -0800 Subject: [PATCH 8/8] Add fakes and injection to log storage for the uploader, implement a fast qos test --- .../GoogleDataLogger/Classes/GDLLogStorage.m | 3 +- .../Classes/Private/GDLLogStorage_Private.h | 5 ++++ .../Tests/Fakes/GDLUploaderFake.h | 27 +++++++++++++++++ .../Tests/Fakes/GDLUploaderFake.m | 25 ++++++++++++++++ GoogleDataLogger/Tests/GDLLogStorageTest.m | 30 ++++++++++++++++++- 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 GoogleDataLogger/Tests/Fakes/GDLUploaderFake.h create mode 100644 GoogleDataLogger/Tests/Fakes/GDLUploaderFake.m diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogStorage.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogStorage.m index 77c5b997daa..f2752a60f0b 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogStorage.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogStorage.m @@ -57,6 +57,7 @@ - (instancetype)init { _storageQueue = dispatch_queue_create("com.google.GDLLogStorage", DISPATCH_QUEUE_SERIAL); _logHashToLogFile = [[NSMutableDictionary alloc] init]; _logTargetToLogFileSet = [[NSMutableDictionary alloc] init]; + _uploader = [GDLUploader sharedInstance]; } return self; } @@ -90,7 +91,7 @@ - (void)storeLog:(GDLLogEvent *)log { // Check the QoS, if it's high priority, notify the log target that it has a high priority log. if (shortLivedLog.qosTier == GDLLogQoSFast) { NSSet *allLogsForLogTarget = self.logTargetToLogFileSet[@(logTarget)]; - [[GDLUploader sharedInstance] forceUploadLogs:allLogsForLogTarget target:logTarget]; + [self.uploader forceUploadLogs:allLogsForLogTarget target:logTarget]; } // Have the prioritizer prioritize the log, enforcing that they do not retain it. diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogStorage_Private.h b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogStorage_Private.h index c58ee5fc7eb..d6547d329fc 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogStorage_Private.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogStorage_Private.h @@ -16,6 +16,8 @@ #import "GDLLogStorage.h" +@class GDLUploader; + @interface GDLLogStorage () /** The queue on which all storage work will occur. */ @@ -28,4 +30,7 @@ @property(nonatomic) NSMutableDictionary *> *logTargetToLogFileSet; +/** The log uploader instance to use. */ +@property(nonatomic) GDLUploader *uploader; + @end diff --git a/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.h b/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.h new file mode 100644 index 00000000000..da8ed2efd07 --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.h @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLUploader.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GDLUploaderFake : GDLUploader + +@property(nonatomic) BOOL forceUploadCalled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.m b/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.m new file mode 100644 index 00000000000..7f3c2880ab7 --- /dev/null +++ b/GoogleDataLogger/Tests/Fakes/GDLUploaderFake.m @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "GDLUploaderFake.h" + +@implementation GDLUploaderFake + +- (void)forceUploadLogs:(NSSet *)logFiles target:(NSInteger)logTarget { + self.forceUploadCalled = YES; +} + +@end diff --git a/GoogleDataLogger/Tests/GDLLogStorageTest.m b/GoogleDataLogger/Tests/GDLLogStorageTest.m index 055923ceeaf..47df570bbe9 100644 --- a/GoogleDataLogger/Tests/GDLLogStorageTest.m +++ b/GoogleDataLogger/Tests/GDLLogStorageTest.m @@ -30,6 +30,7 @@ #import "GDLAssertHelper.h" #import "GDLLogStorage+Testing.h" #import "GDLRegistrar+Testing.h" +#import "GDLUploaderFake.h" static NSInteger logTarget = 1337; @@ -41,6 +42,8 @@ @interface GDLLogStorageTest : GDLTestCase /** The test prioritizer implementation. */ @property(nullable, nonatomic) GDLTestPrioritizer *testPrioritizer; +@property(nonatomic) GDLUploaderFake *uploaderFake; + @end @implementation GDLLogStorageTest @@ -51,6 +54,8 @@ - (void)setUp { self.testPrioritizer = [[GDLTestPrioritizer alloc] init]; [[GDLRegistrar sharedInstance] registerBackend:_testBackend forLogTarget:logTarget]; [[GDLRegistrar sharedInstance] registerLogPrioritizer:_testPrioritizer forLogTarget:logTarget]; + self.uploaderFake = [[GDLUploaderFake alloc] init]; + [GDLLogStorage sharedInstance].uploader = self.uploaderFake; } - (void)tearDown { @@ -60,6 +65,8 @@ - (void)tearDown { self.testPrioritizer = nil; [[GDLRegistrar sharedInstance] reset]; [[GDLLogStorage sharedInstance] reset]; + [GDLLogStorage sharedInstance].uploader = [GDLUploader sharedInstance]; + self.uploaderFake = nil; } /** Tests the singleton pattern. */ @@ -194,6 +201,7 @@ - (void)testLogEventDeallocationIsEnforced { /** Tests encoding and decoding the storage singleton correctly. */ - (void)testNSSecureCoding { + XCTAssertTrue([GDLLogStorage supportsSecureCoding]); GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"404" logTarget:logTarget]; logEvent.extensionBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger logHash = logEvent.hash; @@ -215,7 +223,27 @@ - (void)testNSSecureCoding { /** Tests logging a fast log causes an upload attempt. */ - (void)testQoSTierFast { - // TODO + NSUInteger logHash; + // logEvent is autoreleased, and the pool needs to drain. + @autoreleasepool { + GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"404" logTarget:logTarget]; + logEvent.extensionBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding]; + logEvent.qosTier = GDLLogQoSFast; + logHash = logEvent.hash; + XCTAssertFalse(self.uploaderFake.forceUploadCalled); + XCTAssertNoThrow([[GDLLogStorage sharedInstance] storeLog:logEvent]); + } + dispatch_sync([GDLLogStorage sharedInstance].storageQueue, ^{ + XCTAssertTrue(self.uploaderFake.forceUploadCalled); + XCTAssertEqual([GDLLogStorage sharedInstance].logHashToLogFile.count, 1); + XCTAssertEqual([GDLLogStorage sharedInstance].logTargetToLogFileSet[@(logTarget)].count, 1); + NSURL *logFile = [GDLLogStorage sharedInstance].logHashToLogFile[@(logHash)]; + XCTAssertNotNil(logFile); + XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:logFile.path]); + NSError *error; + XCTAssertTrue([[NSFileManager defaultManager] removeItemAtURL:logFile error:&error]); + XCTAssertNil(error, @"There was an error deleting the logFile: %@", error); + }); } @end