GDTCORLifecycleTest.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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/GDTCORStorage_Private.h"
  21. #import "GDTCORLibrary/Private/GDTCORTransformer_Private.h"
  22. #import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
  23. #import "GDTCORTests/Lifecycle/Helpers/GDTCORLifecycleTestPrioritizer.h"
  24. #import "GDTCORTests/Lifecycle/Helpers/GDTCORLifecycleTestUploader.h"
  25. #import "GDTCORTests/Common/Categories/GDTCORStorage+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:[[NSObject alloc] init] \
  41. handler:^BOOL { \
  42. return YES; \
  43. }]; \
  44. [self waitForExpectations:@[ expectation ] timeout:timeInterval]; \
  45. }
  46. /** A test-only event data object used in this integration test. */
  47. @interface GDTCORLifecycleTestEvent : NSObject <GDTCOREventDataObject>
  48. @end
  49. @implementation GDTCORLifecycleTestEvent
  50. - (NSData *)transportBytes {
  51. // In real usage, protobuf's -data method or a custom implementation using nanopb are used.
  52. return [[NSString stringWithFormat:@"%@", [NSDate date]] dataUsingEncoding:NSUTF8StringEncoding];
  53. }
  54. @end
  55. @interface GDTCORLifecycleTest : XCTestCase
  56. /** The test prioritizer. */
  57. @property(nonatomic) GDTCORLifecycleTestPrioritizer *prioritizer;
  58. /** The test uploader. */
  59. @property(nonatomic) GDTCORLifecycleTestUploader *uploader;
  60. @end
  61. @implementation GDTCORLifecycleTest
  62. - (void)setUp {
  63. [super setUp];
  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:[GDTCORStorage archivePath] error:&error];
  67. self.uploader = [[GDTCORLifecycleTestUploader alloc] init];
  68. [[GDTCORRegistrar sharedInstance] registerUploader:self.uploader target:kGDTCORTargetTest];
  69. self.prioritizer = [[GDTCORLifecycleTestPrioritizer alloc] init];
  70. [[GDTCORRegistrar sharedInstance] registerPrioritizer:self.prioritizer target:kGDTCORTargetTest];
  71. [[GDTCORStorage sharedInstance] reset];
  72. [[GDTCORUploadCoordinator sharedInstance] reset];
  73. }
  74. // Backgrounding and foregrounding are only applicable for iOS and tvOS.
  75. #if TARGET_OS_IOS || TARGET_OS_TV
  76. /** Tests that the library serializes itself to disk when the app backgrounds. */
  77. - (void)testBackgrounding {
  78. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  79. transformers:nil
  80. target:kGDTCORTargetTest];
  81. GDTCOREvent *event = [transport eventForTransport];
  82. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  83. XCTAssertEqual([GDTCORStorage sharedInstance].storedEvents.count, 0);
  84. [transport sendDataEvent:event];
  85. GDTCORWaitForBlock(
  86. ^BOOL {
  87. return [GDTCORStorage sharedInstance].storedEvents.count > 0;
  88. },
  89. 5.0);
  90. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  91. [notifCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
  92. XCTAssertTrue([GDTCORApplication sharedApplication].isRunningInBackground);
  93. GDTCORWaitForBlock(
  94. ^BOOL {
  95. NSFileManager *fm = [NSFileManager defaultManager];
  96. return [fm fileExistsAtPath:[GDTCORStorage archivePath] isDirectory:NULL];
  97. },
  98. 5.0);
  99. }
  100. /** Tests that the library deserializes itself from disk when the app foregrounds. */
  101. - (void)testForegrounding {
  102. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  103. transformers:nil
  104. target:kGDTCORTargetTest];
  105. GDTCOREvent *event = [transport eventForTransport];
  106. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  107. XCTAssertEqual([GDTCORStorage sharedInstance].storedEvents.count, 0);
  108. [transport sendDataEvent:event];
  109. GDTCORWaitForBlock(
  110. ^BOOL {
  111. return [GDTCORStorage sharedInstance].storedEvents.count > 0;
  112. },
  113. 5.0);
  114. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  115. [notifCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
  116. GDTCORWaitForBlock(
  117. ^BOOL {
  118. NSFileManager *fm = [NSFileManager defaultManager];
  119. return [fm fileExistsAtPath:[GDTCORStorage archivePath] isDirectory:NULL];
  120. },
  121. 5.0);
  122. [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
  123. [notifCenter postNotificationName:UIApplicationWillEnterForegroundNotification object:nil];
  124. XCTAssertFalse([GDTCORApplication sharedApplication].isRunningInBackground);
  125. GDTCORWaitForBlock(
  126. ^BOOL {
  127. return [GDTCORStorage sharedInstance].storedEvents.count > 0;
  128. },
  129. 5.0);
  130. }
  131. #endif // #if TARGET_OS_IOS || TARGET_OS_TV
  132. /** Tests that the library gracefully stops doing stuff when terminating. */
  133. - (void)testTermination {
  134. GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"test"
  135. transformers:nil
  136. target:kGDTCORTargetTest];
  137. GDTCOREvent *event = [transport eventForTransport];
  138. event.dataObject = [[GDTCORLifecycleTestEvent alloc] init];
  139. XCTAssertEqual([GDTCORStorage sharedInstance].storedEvents.count, 0);
  140. [transport sendDataEvent:event];
  141. GDTCORWaitForBlock(
  142. ^BOOL {
  143. return [GDTCORStorage sharedInstance].storedEvents.count > 0;
  144. },
  145. 5.0);
  146. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  147. [notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];
  148. GDTCORWaitForBlock(
  149. ^BOOL {
  150. NSFileManager *fm = [NSFileManager defaultManager];
  151. return [fm fileExistsAtPath:[GDTCORStorage archivePath] isDirectory:NULL];
  152. },
  153. 5.0);
  154. }
  155. @end