From 6ed36b2b1ab8a3442b82abc2eb2feba26b8c4cc7 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Fri, 14 Dec 2018 22:53:11 -0800 Subject: [PATCH 1/3] Implement NSSecureCodingProtocol for GDLLogEvent --- .../GoogleDataLogger/Classes/GDLLogEvent.h | 4 +-- .../GoogleDataLogger/Classes/GDLLogEvent.m | 30 +++++++++++++++++++ GoogleDataLogger/Tests/GDLLogEventTest.m | 23 ++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h index 8f5d0e81e2d..90f3cb27426 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h @@ -39,7 +39,7 @@ typedef NS_ENUM(NSInteger, GDLLogQoS) { GDLLogQoSFast = 4 }; -@interface GDLLogEvent : NSObject +@interface GDLLogEvent : NSObject /** The log map identifier, to allow backends to map the extension property to a proto. */ @property(readonly, nonatomic) NSString *logMapID; @@ -49,7 +49,7 @@ typedef NS_ENUM(NSInteger, GDLLogQoS) { /** The log object itself, encapsulated in the transport of your choice, as long as it implements * the GDLLogProto protocol. */ -@property(nonatomic) id extension; +@property(nonatomic) NSData *extensionData; /** The quality of service tier this log belongs to. */ @property(nonatomic) GDLLogQoS qosTier; diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m index ae7ca6eb586..da639d655a1 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m @@ -29,4 +29,34 @@ - (instancetype)initWithLogMapID:(NSString *)logMapID logTarget:(NSInteger)logTa return self; } +#pragma mark - NSSecureCoding and NSCoding Protocols + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + NSString *logMapID = [aDecoder decodeObjectOfClass:[NSObject class] forKey:@"_logMapID"]; + NSInteger logTarget = [aDecoder decodeIntegerForKey:@"_logTarget"]; + self = [self initWithLogMapID:logMapID logTarget:logTarget]; + if (self) { + _extensionData = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"_extensionData"]; + _qosTier = [aDecoder decodeIntegerForKey:@"_qosTier"]; + _clockSnapshot.timeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotTimeMillis"]; + _clockSnapshot.uptimeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotUpTimeMillis"]; + _clockSnapshot.timezoneOffsetMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotTimezoneOffsetMillis"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_logMapID forKey:@"_logMapID"]; + [aCoder encodeInteger:_logTarget forKey:@"_logTarget"]; + [aCoder encodeObject:_extensionData forKey:@"_extensionData"]; + [aCoder encodeInteger:_qosTier forKey:@"_qosTier"]; + [aCoder encodeInt64:_clockSnapshot.timeMillis forKey:@"clockSnapshotTimeMillis"]; + [aCoder encodeInt64:_clockSnapshot.uptimeMillis forKey:@"clockSnapshotUpTimeMillis"]; + [aCoder encodeInt64:_clockSnapshot.timezoneOffsetMillis forKey:@"clockSnapshotTimezoneOffsetMillis"]; +} + @end diff --git a/GoogleDataLogger/Tests/GDLLogEventTest.m b/GoogleDataLogger/Tests/GDLLogEventTest.m index c96c00907ee..081266edf9e 100644 --- a/GoogleDataLogger/Tests/GDLLogEventTest.m +++ b/GoogleDataLogger/Tests/GDLLogEventTest.m @@ -24,9 +24,32 @@ @interface GDLLogEventTest : XCTestCase @implementation GDLLogEventTest +/** Tests the designated initializer. */ - (void)testInit { XCTAssertNotNil([[GDLLogEvent alloc] initWithLogMapID:@"1" logTarget:1]); XCTAssertThrows([[GDLLogEvent alloc] initWithLogMapID:@"" logTarget:1]); } +/** Tests NSKeyedArchiver encoding and decoding. */ +- (void)testArchiving { + XCTAssertTrue([GDLLogEvent supportsSecureCoding]); + GDLLogClockSnapshot clockSnapshot = {10, 100, 1000}; + GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"testID" logTarget:42]; + logEvent.extensionData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding]; + logEvent.qosTier = GDLLogQoSTelemetry; + logEvent.clockSnapshot = clockSnapshot; + + NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:logEvent]; + logEvent = nil; + + logEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; + XCTAssertEqualObjects(logEvent.logMapID, @"testID"); + XCTAssertEqual(logEvent.logTarget, 42); + XCTAssertEqualObjects(logEvent.extensionData, [@"someData" dataUsingEncoding:NSUTF8StringEncoding]); + XCTAssertEqual(logEvent.qosTier, GDLLogQoSTelemetry); + XCTAssertEqual(logEvent.clockSnapshot.timeMillis, 10); + XCTAssertEqual(logEvent.clockSnapshot.uptimeMillis, 100); + XCTAssertEqual(logEvent.clockSnapshot.timezoneOffsetMillis, 1000); +} + @end From 8c848141c466b9aa55c85ec3d8fd05c9aa8fb3c2 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Fri, 14 Dec 2018 23:07:34 -0800 Subject: [PATCH 2/3] Style changes. --- GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m | 6 ++++-- GoogleDataLogger/Tests/GDLLogEventTest.m | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m index da639d655a1..2b4f42fe8bb 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m @@ -44,7 +44,8 @@ - (id)initWithCoder:(NSCoder *)aDecoder { _qosTier = [aDecoder decodeIntegerForKey:@"_qosTier"]; _clockSnapshot.timeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotTimeMillis"]; _clockSnapshot.uptimeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotUpTimeMillis"]; - _clockSnapshot.timezoneOffsetMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotTimezoneOffsetMillis"]; + _clockSnapshot.timezoneOffsetMillis = + [aDecoder decodeInt64ForKey:@"clockSnapshotTimezoneOffsetMillis"]; } return self; } @@ -56,7 +57,8 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeInteger:_qosTier forKey:@"_qosTier"]; [aCoder encodeInt64:_clockSnapshot.timeMillis forKey:@"clockSnapshotTimeMillis"]; [aCoder encodeInt64:_clockSnapshot.uptimeMillis forKey:@"clockSnapshotUpTimeMillis"]; - [aCoder encodeInt64:_clockSnapshot.timezoneOffsetMillis forKey:@"clockSnapshotTimezoneOffsetMillis"]; + [aCoder encodeInt64:_clockSnapshot.timezoneOffsetMillis + forKey:@"clockSnapshotTimezoneOffsetMillis"]; } @end diff --git a/GoogleDataLogger/Tests/GDLLogEventTest.m b/GoogleDataLogger/Tests/GDLLogEventTest.m index 081266edf9e..00abf39e739 100644 --- a/GoogleDataLogger/Tests/GDLLogEventTest.m +++ b/GoogleDataLogger/Tests/GDLLogEventTest.m @@ -45,7 +45,8 @@ - (void)testArchiving { logEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; XCTAssertEqualObjects(logEvent.logMapID, @"testID"); XCTAssertEqual(logEvent.logTarget, 42); - XCTAssertEqualObjects(logEvent.extensionData, [@"someData" dataUsingEncoding:NSUTF8StringEncoding]); + XCTAssertEqualObjects(logEvent.extensionData, + [@"someData" dataUsingEncoding:NSUTF8StringEncoding]); XCTAssertEqual(logEvent.qosTier, GDLLogQoSTelemetry); XCTAssertEqual(logEvent.clockSnapshot.timeMillis, 10); XCTAssertEqual(logEvent.clockSnapshot.uptimeMillis, 100); From 01e183edfdc7ce920918779d3a0b150d077b2388 Mon Sep 17 00:00:00 2001 From: Michael Haney Date: Mon, 17 Dec 2018 15:30:22 -0800 Subject: [PATCH 3/3] Refactor to address some comments and structure GDLLogEvent and GDLLogProto are moved to the public folder. GDLLogEvent has had some public API moved to a private header. GDLLogWriter now writes the extension object to data after transforming, for serialization purposes. Various headers updated to conform to module header rules. --- .../GoogleDataLogger/Classes/GDLLogEvent.m | 54 +++++++++++++------ .../GoogleDataLogger/Classes/GDLLogWriter.m | 12 +++++ .../Classes/Private/GDLLogEvent_Private.h | 36 +++++++++++++ .../Classes/{ => Public}/GDLLogEvent.h | 9 +--- .../Classes/{ => Public}/GDLLogProto.h | 0 .../Classes/Public/GDLLogger.h | 12 +++-- .../Classes/Public/GoogleDataLogger.h | 2 + .../DependencyWrappers/GDLConsoleLogger.h | 5 +- GoogleDataLogger/Tests/GDLLogEventTest.m | 24 +++++---- GoogleDataLogger/Tests/GDLLogWriterTest.m | 5 ++ GoogleDataLogger/Tests/GDLLoggerTest.m | 5 ++ .../Helpers/GDLLogExtensionTesterClasses.h | 31 +++++++++++ .../Helpers/GDLLogExtensionTesterClasses.m | 33 ++++++++++++ 13 files changed, 189 insertions(+), 39 deletions(-) create mode 100644 GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogEvent_Private.h rename GoogleDataLogger/GoogleDataLogger/Classes/{ => Public}/GDLLogEvent.h (89%) rename GoogleDataLogger/GoogleDataLogger/Classes/{ => Public}/GDLLogProto.h (100%) create mode 100644 GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.h create mode 100644 GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.m diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m index 2b4f42fe8bb..36c3cc78497 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.m @@ -14,7 +14,9 @@ * limitations under the License. */ -#import "GDLLogEvent.h" +#import + +#import "GDLLogEvent_Private.h" @implementation GDLLogEvent @@ -31,34 +33,54 @@ - (instancetype)initWithLogMapID:(NSString *)logMapID logTarget:(NSInteger)logTa #pragma mark - NSSecureCoding and NSCoding Protocols +/** NSCoding key for logMapID property. */ +static NSString *logMapIDKey = @"_logMapID"; + +/** NSCoding key for logTarget property. */ +static NSString *logTargetKey = @"_logTarget"; + +/** NSCoding key for extensionBytes property. */ +static NSString *extensionBytesKey = @"_extensionBytes"; + +/** NSCoding key for qosTier property. */ +static NSString *qosTierKey = @"_qosTier"; + +/** NSCoding key for clockSnapshot.timeMillis property. */ +static NSString *clockSnapshotTimeMillisKey = @"_clockSnapshotTimeMillis"; + +/** NSCoding key for clockSnapshot.uptimeMillis property. */ +static NSString *clockSnapshotUpTimeMillis = @"_clockSnapshotUpTimeMillis"; + +/** NSCoding key for clockSnapshot.timezoneOffsetMillis property. */ +static NSString *clockSnapshotTimezoneOffsetMillis = @"_clockSnapshotTimezoneOffsetMillis"; + + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)aDecoder { - NSString *logMapID = [aDecoder decodeObjectOfClass:[NSObject class] forKey:@"_logMapID"]; - NSInteger logTarget = [aDecoder decodeIntegerForKey:@"_logTarget"]; + NSString *logMapID = [aDecoder decodeObjectOfClass:[NSObject class] forKey:logMapIDKey]; + NSInteger logTarget = [aDecoder decodeIntegerForKey:logTargetKey]; self = [self initWithLogMapID:logMapID logTarget:logTarget]; if (self) { - _extensionData = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"_extensionData"]; - _qosTier = [aDecoder decodeIntegerForKey:@"_qosTier"]; - _clockSnapshot.timeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotTimeMillis"]; - _clockSnapshot.uptimeMillis = [aDecoder decodeInt64ForKey:@"clockSnapshotUpTimeMillis"]; + _extensionBytes = [aDecoder decodeObjectOfClass:[NSData class] forKey:extensionBytesKey]; + _qosTier = [aDecoder decodeIntegerForKey:qosTierKey]; + _clockSnapshot.timeMillis = [aDecoder decodeInt64ForKey:clockSnapshotTimeMillisKey]; + _clockSnapshot.uptimeMillis = [aDecoder decodeInt64ForKey:clockSnapshotUpTimeMillis]; _clockSnapshot.timezoneOffsetMillis = - [aDecoder decodeInt64ForKey:@"clockSnapshotTimezoneOffsetMillis"]; + [aDecoder decodeInt64ForKey:clockSnapshotTimezoneOffsetMillis]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { - [aCoder encodeObject:_logMapID forKey:@"_logMapID"]; - [aCoder encodeInteger:_logTarget forKey:@"_logTarget"]; - [aCoder encodeObject:_extensionData forKey:@"_extensionData"]; - [aCoder encodeInteger:_qosTier forKey:@"_qosTier"]; - [aCoder encodeInt64:_clockSnapshot.timeMillis forKey:@"clockSnapshotTimeMillis"]; - [aCoder encodeInt64:_clockSnapshot.uptimeMillis forKey:@"clockSnapshotUpTimeMillis"]; - [aCoder encodeInt64:_clockSnapshot.timezoneOffsetMillis - forKey:@"clockSnapshotTimezoneOffsetMillis"]; + [aCoder encodeObject:_logMapID forKey:logMapIDKey]; + [aCoder encodeInteger:_logTarget forKey:logTargetKey]; + [aCoder encodeObject:_extensionBytes forKey:extensionBytesKey]; + [aCoder encodeInteger:_qosTier forKey:qosTierKey]; + [aCoder encodeInt64:_clockSnapshot.timeMillis forKey:clockSnapshotTimeMillisKey]; + [aCoder encodeInt64:_clockSnapshot.uptimeMillis forKey:clockSnapshotUpTimeMillis]; + [aCoder encodeInt64:_clockSnapshot.timezoneOffsetMillis forKey:clockSnapshotTimezoneOffsetMillis]; } @end diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m index 71590b480e9..7a9d2cb2fcb 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m +++ b/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogWriter.m @@ -20,6 +20,7 @@ #import #import "GDLConsoleLogger.h" +#import "GDLLogEvent_Private.h" #import "GDLLogStorage.h" @implementation GDLLogWriter @@ -60,6 +61,17 @@ - (void)writeLog:(GDLLogEvent *)log return; } } + + // Convert the extension to bytes after transforming. + NSAssert([log.extension respondsToSelector:@selector(protoBytes)], + @"The log event's extension must respond to -protoBytes."); + if ([log.extension respondsToSelector:@selector(protoBytes)]) { + log.extensionBytes = [log.extension protoBytes]; + log.extension = nil; + } else { + GDLLogWarning(GDLMCWExtensionMissingBytesImpl, @"%@", + @"The log event's extension must respond to -protoBytes."); + } // TODO(mikehaney24): [[GDLLogStorage sharedInstance] storeLog:transformedLog]; }); } diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogEvent_Private.h b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogEvent_Private.h new file mode 100644 index 00000000000..1df364bcb58 --- /dev/null +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Private/GDLLogEvent_Private.h @@ -0,0 +1,36 @@ +/* + * Copyright 2018 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 "GDLLogEvent.h" + +#import "GDLLogClock.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GDLLogEvent () + +/** The serialized bytes of the log object. */ +@property(nonatomic) NSData *extensionBytes; + +/** The quality of service tier this log belongs to. */ +@property(nonatomic) GDLLogQoS qosTier; + +/** The clock snapshot at the time of logging. */ +@property(nonatomic) GDLLogClockSnapshot clockSnapshot; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogEvent.h similarity index 89% rename from GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h rename to GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogEvent.h index 90f3cb27426..f3931b2e076 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogEvent.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogEvent.h @@ -16,7 +16,6 @@ #import -#import "GDLLogClock.h" #import "GDLLogProto.h" NS_ASSUME_NONNULL_BEGIN @@ -49,13 +48,7 @@ typedef NS_ENUM(NSInteger, GDLLogQoS) { /** The log object itself, encapsulated in the transport of your choice, as long as it implements * the GDLLogProto protocol. */ -@property(nonatomic) NSData *extensionData; - -/** The quality of service tier this log belongs to. */ -@property(nonatomic) GDLLogQoS qosTier; - -/** The clock snapshot at the time of logging. */ -@property(nonatomic) GDLLogClockSnapshot clockSnapshot; +@property(nullable, nonatomic) id extension; // Please use the designated initializer. - (instancetype)init NS_UNAVAILABLE; diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/GDLLogProto.h b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogProto.h similarity index 100% rename from GoogleDataLogger/GoogleDataLogger/Classes/GDLLogProto.h rename to GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogProto.h diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogger.h b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogger.h index 1938c36f16d..ea52804dc38 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogger.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GDLLogger.h @@ -38,15 +38,19 @@ NS_ASSUME_NONNULL_BEGIN logTransformers:(nullable NSArray> *)logTransformers logTarget:(NSInteger)logTarget NS_DESIGNATED_INITIALIZER; -/** Logs an internal telemetry event. Logs sent using this API are lower in priority, and sometimes - * won't be sent on their own. +/** Copies and logs an internal telemetry event. Logs sent using this API are lower in priority, and + * sometimes won't be sent on their own. + * + * @note This will convert the log event's extension proto to data and release the original log. * * @param logEvent The log event to log. */ - (void)logTelemetryEvent:(GDLLogEvent *)logEvent; -/** Logs an SDK service data event. Logs send using this API are higher in priority, and will cause - * a network request at some point in the relative near future. +/** Copies and logs an SDK service data event. Logs send using this API are higher in priority, and + * will cause a network request at some point in the relative near future. + * + * @note This will convert the log event's extension proto to data and release the original log. * * @param logEvent The log event to log. */ diff --git a/GoogleDataLogger/GoogleDataLogger/Classes/Public/GoogleDataLogger.h b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GoogleDataLogger.h index 6ba563c5ea5..091625895eb 100644 --- a/GoogleDataLogger/GoogleDataLogger/Classes/Public/GoogleDataLogger.h +++ b/GoogleDataLogger/GoogleDataLogger/Classes/Public/GoogleDataLogger.h @@ -14,4 +14,6 @@ * limitations under the License. */ +#import "GDLLogEvent.h" +#import "GDLLogTransformer.h" #import "GDLLogger.h" diff --git a/GoogleDataLogger/GoogleDataLogger/DependencyWrappers/GDLConsoleLogger.h b/GoogleDataLogger/GoogleDataLogger/DependencyWrappers/GDLConsoleLogger.h index aaaa23c6edd..b1ce4fbe3a1 100644 --- a/GoogleDataLogger/GoogleDataLogger/DependencyWrappers/GDLConsoleLogger.h +++ b/GoogleDataLogger/GoogleDataLogger/DependencyWrappers/GDLConsoleLogger.h @@ -28,7 +28,10 @@ static GULLoggerService kGDLConsoleLogger = @"[GoogleDataLogger]"; typedef NS_ENUM(NSInteger, GDLMessageCode) { /** For warning messages concerning transform: not being implemented by a log transformer. */ - GDLMCWTransformerDoesntImplementTransform = 1 + GDLMCWTransformerDoesntImplementTransform = 1, + + /** For warning messages concerning protoBytes: not being implemented by a log extension. */ + GDLMCWExtensionMissingBytesImpl = 2 }; /** */ diff --git a/GoogleDataLogger/Tests/GDLLogEventTest.m b/GoogleDataLogger/Tests/GDLLogEventTest.m index 00abf39e739..d12468cc593 100644 --- a/GoogleDataLogger/Tests/GDLLogEventTest.m +++ b/GoogleDataLogger/Tests/GDLLogEventTest.m @@ -16,7 +16,9 @@ #import -#import "GDLLogEvent.h" +#import + +#import "GDLLogEvent_Private.h" @interface GDLLogEventTest : XCTestCase @@ -35,22 +37,24 @@ - (void)testArchiving { XCTAssertTrue([GDLLogEvent supportsSecureCoding]); GDLLogClockSnapshot clockSnapshot = {10, 100, 1000}; GDLLogEvent *logEvent = [[GDLLogEvent alloc] initWithLogMapID:@"testID" logTarget:42]; - logEvent.extensionData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding]; + logEvent.extensionBytes = [@"someData" dataUsingEncoding:NSUTF8StringEncoding]; logEvent.qosTier = GDLLogQoSTelemetry; logEvent.clockSnapshot = clockSnapshot; NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:logEvent]; + + // To ensure that all the objects being retained by the original logEvent are dealloc'd. logEvent = nil; - logEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; - XCTAssertEqualObjects(logEvent.logMapID, @"testID"); - XCTAssertEqual(logEvent.logTarget, 42); - XCTAssertEqualObjects(logEvent.extensionData, + GDLLogEvent *decodedLogEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; + XCTAssertEqualObjects(decodedLogEvent.logMapID, @"testID"); + XCTAssertEqual(decodedLogEvent.logTarget, 42); + XCTAssertEqualObjects(decodedLogEvent.extensionBytes, [@"someData" dataUsingEncoding:NSUTF8StringEncoding]); - XCTAssertEqual(logEvent.qosTier, GDLLogQoSTelemetry); - XCTAssertEqual(logEvent.clockSnapshot.timeMillis, 10); - XCTAssertEqual(logEvent.clockSnapshot.uptimeMillis, 100); - XCTAssertEqual(logEvent.clockSnapshot.timezoneOffsetMillis, 1000); + XCTAssertEqual(decodedLogEvent.qosTier, GDLLogQoSTelemetry); + XCTAssertEqual(decodedLogEvent.clockSnapshot.timeMillis, 10); + XCTAssertEqual(decodedLogEvent.clockSnapshot.uptimeMillis, 100); + XCTAssertEqual(decodedLogEvent.clockSnapshot.timezoneOffsetMillis, 1000); } @end diff --git a/GoogleDataLogger/Tests/GDLLogWriterTest.m b/GoogleDataLogger/Tests/GDLLogWriterTest.m index d7e88416915..5a9f80e9302 100644 --- a/GoogleDataLogger/Tests/GDLLogWriterTest.m +++ b/GoogleDataLogger/Tests/GDLLogWriterTest.m @@ -19,6 +19,7 @@ #import #import "GDLLogEvent.h" +#import "GDLLogExtensionTesterClasses.h" #import "GDLLogWriter.h" #import "GDLLogWriter_Private.h" @@ -66,6 +67,7 @@ - (void)testSharedInstance { - (void)testWriteLogWithoutTransformers { GDLLogWriter *writer = [GDLLogWriter sharedInstance]; 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. @@ -76,6 +78,7 @@ - (void)testWriteLogWithoutTransformers { - (void)testWriteLogWithTransformersThatNilTheLog { GDLLogWriter *writer = [GDLLogWriter sharedInstance]; GDLLogEvent *log = [[GDLLogEvent alloc] initWithLogMapID:@"2" logTarget:1]; + log.extension = [[GDLLogExtensionTesterSimple alloc] init]; NSArray> *transformers = @[ [[GDLLogWriterTestNilingTransformer alloc] init] ]; XCTAssertNoThrow([writer writeLog:log afterApplyingTransformers:transformers]); @@ -88,6 +91,7 @@ - (void)testWriteLogWithTransformersThatNilTheLog { - (void)testWriteLogWithTransformersThatCreateANewLog { GDLLogWriter *writer = [GDLLogWriter sharedInstance]; GDLLogEvent *log = [[GDLLogEvent alloc] initWithLogMapID:@"2" logTarget:1]; + log.extension = [[GDLLogExtensionTesterSimple alloc] init]; NSArray> *transformers = @[ [[GDLLogWriterTestNewLogTransformer alloc] init] ]; XCTAssertNoThrow([writer writeLog:log afterApplyingTransformers:transformers]); @@ -100,6 +104,7 @@ - (void)testWriteLogWithTransformersThatCreateANewLog { - (void)testWriteLogWithBadTransformer { GDLLogWriter *writer = [GDLLogWriter sharedInstance]; GDLLogEvent *log = [[GDLLogEvent alloc] initWithLogMapID:@"2" logTarget:1]; + log.extension = [[GDLLogExtensionTesterSimple alloc] init]; NSArray *transformers = @[ [[NSObject alloc] init] ]; @try { dispatch_sync(writer.logWritingQueue, ^{ diff --git a/GoogleDataLogger/Tests/GDLLoggerTest.m b/GoogleDataLogger/Tests/GDLLoggerTest.m index 2c7f5d4cebb..b205400e076 100644 --- a/GoogleDataLogger/Tests/GDLLoggerTest.m +++ b/GoogleDataLogger/Tests/GDLLoggerTest.m @@ -16,8 +16,11 @@ #import +#import #import +#import "GDLLogExtensionTesterClasses.h" + @interface GDLLoggerTest : XCTestCase @end @@ -34,6 +37,7 @@ - (void)testInit { - (void)testLogTelemetryEvent { GDLLogger *logger = [[GDLLogger alloc] initWithLogMapID:@"1" logTransformers:nil logTarget:1]; GDLLogEvent *event = [logger newEvent]; + event.extension = [[GDLLogExtensionTesterSimple alloc] init]; XCTAssertNoThrow([logger logTelemetryEvent:event]); } @@ -41,6 +45,7 @@ - (void)testLogTelemetryEvent { - (void)testLogDataEvent { GDLLogger *logger = [[GDLLogger alloc] initWithLogMapID:@"1" logTransformers:nil logTarget:1]; GDLLogEvent *event = [logger newEvent]; + event.extension = [[GDLLogExtensionTesterSimple alloc] init]; XCTAssertNoThrow([logger logDataEvent:event]); } diff --git a/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.h b/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.h new file mode 100644 index 00000000000..9c476446107 --- /dev/null +++ b/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.h @@ -0,0 +1,31 @@ +/* + * Copyright 2018 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** A class to represent a simple log proto. */ +@interface GDLLogExtensionTesterSimple : NSObject + +/** A string that will be turned into bytes. */ +@property(nonatomic) NSString *aString; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.m b/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.m new file mode 100644 index 00000000000..e071e98658f --- /dev/null +++ b/GoogleDataLogger/Tests/Helpers/GDLLogExtensionTesterClasses.m @@ -0,0 +1,33 @@ +/* + * Copyright 2018 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 "GDLLogExtensionTesterClasses.h" + +@implementation GDLLogExtensionTesterSimple + +- (instancetype)init { + self = [super init]; + if (self) { + _aString = @"test"; + } + return self; +} + +- (NSData *)protoBytes { + return [_aString dataUsingEncoding:NSUTF8StringEncoding]; +} + +@end