GDTCORLifecycleTest.m 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright 2018 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. #import <XCTest/XCTest.h>
  17. #import <GoogleDataTransport/GDTCOREvent.h>
  18. #import <GoogleDataTransport/GDTCOREventDataObject.h>
  19. #import <GoogleDataTransport/GDTCORTransport.h>
  20. #import "GDTCORLibrary/Private/GDTCORTransformer_Private.h"
  21. #import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
  22. #import "GDTCORTests/Lifecycle/Helpers/GDTCORLifecycleTestPrioritizer.h"
  23. #import "GDTCORTests/Lifecycle/Helpers/GDTCORLifecycleTestUploader.h"
  24. #import "GDTCORTests/Common/Categories/GDTCORFlatFileStorage+Testing.h"
  25. #import "GDTCORTests/Common/Categories/GDTCORRegistrar+Testing.h"
  26. #import "GDTCORTests/Common/Categories/GDTCORUploadCoordinator+Testing.h"
  27. /** Waits for the result of waitBlock to be YES, or times out and fails.
  28. *
  29. * @param waitBlock The block to periodically execute.
  30. * @param timeInterval The timeout.
  31. */
  32. #define GDTCORWaitForBlock(waitBlock, timeInterval) \
  33. { \
  34. NSPredicate *pred = \
  35. [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, \
  36. NSDictionary<NSString *, id> *_Nullable bindings) { \
  37. return waitBlock(); \
  38. }]; \
  39. XCTestExpectation *expectation = [self expectationForPredicate:pred \
  40. evaluatedWithObject:nil \
  41. handler:nil]; \
  42. [self waitForExpectations:@[ expectation ] timeout:timeInterval]; \
  43. }
  44. /** A test-only event data object used in this integration test. */
  45. @interface GDTCORLifecycleTestEvent : NSObject <GDTCOREventDataObject>
  46. @end
  47. @implementation GDTCORLifecycleTestEvent
  48. - (NSData *)transportBytes {
  49. // In real usage, protobuf's -data method or a custom implementation using nanopb are used.
  50. return [[NSString stringWithFormat:@"%@", [NSDate date]] dataUsingEncoding:NSUTF8StringEncoding];
  51. }
  52. @end
  53. @interface GDTCORLifecycleTest : XCTestCase
  54. /** The test prioritizer. */
  55. @property(nonatomic) GDTCORLifecycleTestPrioritizer *prioritizer;
  56. /** The test uploader. */
  57. @property(nonatomic) GDTCORLifecycleTestUploader *uploader;
  58. @end
  59. @implementation GDTCORLifecycleTest
  60. - (void)setUp {
  61. [super setUp];
  62. [[GDTCORRegistrar sharedInstance] registerStorage:[GDTCORFlatFileStorage sharedInstance]
  63. target:kGDTCORTargetTest];
  64. // Don't check the error, because it'll be populated in cases where the file doesn't exist.
  65. NSError *error;
  66. [[NSFileManager defaultManager] removeItemAtPath:[GDTCORFlatFileStorage archivePath]
  67. error:&error];
  68. self.uploader = [[GDTCORLifecycleTestUploader alloc] init];
  69. [[GDTCORRegistrar sharedInstance] registerUploader:self.uploader target:kGDTCORTargetTest];
  70. self.prioritizer = [[GDTCORLifecycleTestPrioritizer alloc] init];
  71. [[GDTCORRegistrar sharedInstance] registerPrioritizer:self.prioritizer target:kGDTCORTargetTest];
  72. }
  73. - (void)tearDown {
  74. [super tearDown];
  75. self.uploader = nil;
  76. self.prioritizer = nil;
  77. [[GDTCORRegistrar sharedInstance] reset];
  78. [[GDTCORFlatFileStorage sharedInstance] reset];
  79. [[GDTCORUploadCoordinator sharedInstance] reset];
  80. }
  81. // Backgrounding and foregrounding are only applicable for iOS and tvOS.
  82. #if TARGET_OS_IOS || TARGET_OS_TV
  83. /** Tests that the library serializes itself to disk when the app backgrounds. */
  84. - (void)testBackgrounding {
  85. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  86. transformers:nil
  87. target:kGDTCORTargetTest];
  88. GDTCOREvent *event = [transport eventForTransport];
  89. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  90. XCTAssertEqual([GDTCORFlatFileStorage sharedInstance].storedEvents.count, 0);
  91. [transport sendDataEvent:event];
  92. GDTCORWaitForBlock(
  93. ^BOOL {
  94. return [GDTCORFlatFileStorage sharedInstance].storedEvents.count > 0;
  95. },
  96. 5.0);
  97. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  98. [notifCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
  99. XCTAssertTrue([GDTCORApplication sharedApplication].isRunningInBackground);
  100. GDTCORWaitForBlock(
  101. ^BOOL {
  102. NSFileManager *fm = [NSFileManager defaultManager];
  103. return [fm fileExistsAtPath:[GDTCORFlatFileStorage archivePath] isDirectory:NULL];
  104. },
  105. 5.0);
  106. }
  107. /** Tests that the library deserializes itself from disk when the app foregrounds. */
  108. - (void)testForegrounding {
  109. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  110. transformers:nil
  111. target:kGDTCORTargetTest];
  112. GDTCOREvent *event = [transport eventForTransport];
  113. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  114. XCTAssertEqual([GDTCORFlatFileStorage sharedInstance].storedEvents.count, 0);
  115. [transport sendDataEvent:event];
  116. GDTCORWaitForBlock(
  117. ^BOOL {
  118. return [GDTCORFlatFileStorage sharedInstance].storedEvents.count > 0;
  119. },
  120. 5.0);
  121. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  122. [notifCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
  123. GDTCORWaitForBlock(
  124. ^BOOL {
  125. NSFileManager *fm = [NSFileManager defaultManager];
  126. return [fm fileExistsAtPath:[GDTCORFlatFileStorage archivePath] isDirectory:NULL];
  127. },
  128. 5.0);
  129. [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
  130. [notifCenter postNotificationName:UIApplicationWillEnterForegroundNotification object:nil];
  131. XCTAssertFalse([GDTCORApplication sharedApplication].isRunningInBackground);
  132. GDTCORWaitForBlock(
  133. ^BOOL {
  134. return [GDTCORFlatFileStorage sharedInstance].storedEvents.count > 0;
  135. },
  136. 5.0);
  137. }
  138. #endif // #if TARGET_OS_IOS || TARGET_OS_TV
  139. /** Tests that the library gracefully stops doing stuff when terminating. */
  140. - (void)testTermination {
  141. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  142. transformers:nil
  143. target:kGDTCORTargetTest];
  144. GDTCOREvent *event = [transport eventForTransport];
  145. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  146. XCTAssertEqual([GDTCORFlatFileStorage sharedInstance].storedEvents.count, 0);
  147. [transport sendDataEvent:event];
  148. GDTCORWaitForBlock(
  149. ^BOOL {
  150. return [GDTCORFlatFileStorage sharedInstance].storedEvents.count > 0;
  151. },
  152. 5.0);
  153. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  154. [notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];
  155. GDTCORWaitForBlock(
  156. ^BOOL {
  157. NSFileManager *fm = [NSFileManager defaultManager];
  158. return [fm fileExistsAtPath:[GDTCORFlatFileStorage archivePath] isDirectory:NULL];
  159. },
  160. 5.0);
  161. }
  162. @end