GDTLifecycleTest.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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/GDTEvent.h>
  18. #import <GoogleDataTransport/GDTEventDataObject.h>
  19. #import <GoogleDataTransport/GDTTransport.h>
  20. #import "GDTLibrary/Private/GDTStorage_Private.h"
  21. #import "GDTLibrary/Private/GDTTransformer_Private.h"
  22. #import "GDTLibrary/Private/GDTUploadCoordinator.h"
  23. #import "GDTTests/Lifecycle/Helpers/GDTLifecycleTestPrioritizer.h"
  24. #import "GDTTests/Lifecycle/Helpers/GDTLifecycleTestUploader.h"
  25. #import "GDTTests/Common/Categories/GDTStorage+Testing.h"
  26. #import "GDTTests/Common/Categories/GDTUploadCoordinator+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 GDTWaitForBlock(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 GDTLifecycleTestEvent : NSObject <GDTEventDataObject>
  48. @end
  49. @implementation GDTLifecycleTestEvent
  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 GDTLifecycleTest : XCTestCase
  56. /** The test prioritizer. */
  57. @property(nonatomic) GDTLifecycleTestPrioritizer *prioritizer;
  58. /** The test uploader. */
  59. @property(nonatomic) GDTLifecycleTestUploader *uploader;
  60. @end
  61. @implementation GDTLifecycleTest
  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:[GDTStorage archivePath] error:&error];
  67. self.uploader = [[GDTLifecycleTestUploader alloc] init];
  68. [[GDTRegistrar sharedInstance] registerUploader:self.uploader target:kGDTTargetTest];
  69. self.prioritizer = [[GDTLifecycleTestPrioritizer alloc] init];
  70. [[GDTRegistrar sharedInstance] registerPrioritizer:self.prioritizer target:kGDTTargetTest];
  71. [[GDTStorage sharedInstance] reset];
  72. [[GDTUploadCoordinator sharedInstance] reset];
  73. }
  74. /** Tests that the library serializes itself to disk when the app backgrounds. */
  75. - (void)testBackgrounding {
  76. GDTTransport *transport = [[GDTTransport alloc] initWithMappingID:@"test"
  77. transformers:nil
  78. target:kGDTTargetTest];
  79. GDTEvent *event = [transport eventForTransport];
  80. event.dataObject = [[GDTLifecycleTestEvent alloc] init];
  81. XCTAssertEqual([GDTStorage sharedInstance].storedEvents.count, 0);
  82. [transport sendDataEvent:event];
  83. GDTWaitForBlock(
  84. ^BOOL {
  85. return [GDTStorage sharedInstance].storedEvents.count > 0;
  86. },
  87. 5.0);
  88. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  89. [notifCenter postNotificationName:kGDTApplicationDidEnterBackgroundNotification object:nil];
  90. XCTAssertTrue([GDTStorage sharedInstance].runningInBackground);
  91. XCTAssertTrue([GDTUploadCoordinator sharedInstance].runningInBackground);
  92. GDTWaitForBlock(
  93. ^BOOL {
  94. NSFileManager *fm = [NSFileManager defaultManager];
  95. return [fm fileExistsAtPath:[GDTStorage archivePath] isDirectory:NULL];
  96. },
  97. 5.0);
  98. }
  99. /** Tests that the library deserializes itself from disk when the app foregrounds. */
  100. - (void)testForegrounding {
  101. GDTTransport *transport = [[GDTTransport alloc] initWithMappingID:@"test"
  102. transformers:nil
  103. target:kGDTTargetTest];
  104. GDTEvent *event = [transport eventForTransport];
  105. event.dataObject = [[GDTLifecycleTestEvent alloc] init];
  106. XCTAssertEqual([GDTStorage sharedInstance].storedEvents.count, 0);
  107. [transport sendDataEvent:event];
  108. GDTWaitForBlock(
  109. ^BOOL {
  110. return [GDTStorage sharedInstance].storedEvents.count > 0;
  111. },
  112. 5.0);
  113. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  114. [notifCenter postNotificationName:kGDTApplicationDidEnterBackgroundNotification object:nil];
  115. GDTWaitForBlock(
  116. ^BOOL {
  117. NSFileManager *fm = [NSFileManager defaultManager];
  118. return [fm fileExistsAtPath:[GDTStorage archivePath] isDirectory:NULL];
  119. },
  120. 5.0);
  121. [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
  122. [notifCenter postNotificationName:kGDTApplicationWillEnterForegroundNotification object:nil];
  123. XCTAssertFalse([GDTStorage sharedInstance].runningInBackground);
  124. XCTAssertFalse([GDTUploadCoordinator sharedInstance].runningInBackground);
  125. GDTWaitForBlock(
  126. ^BOOL {
  127. return [GDTStorage sharedInstance].storedEvents.count > 0;
  128. },
  129. 5.0);
  130. }
  131. /** Tests that the library gracefully stops doing stuff when terminating. */
  132. - (void)testTermination {
  133. GDTTransport *transport = [[GDTTransport alloc] initWithMappingID:@"test"
  134. transformers:nil
  135. target:kGDTTargetTest];
  136. GDTEvent *event = [transport eventForTransport];
  137. event.dataObject = [[GDTLifecycleTestEvent alloc] init];
  138. XCTAssertEqual([GDTStorage sharedInstance].storedEvents.count, 0);
  139. [transport sendDataEvent:event];
  140. GDTWaitForBlock(
  141. ^BOOL {
  142. return [GDTStorage sharedInstance].storedEvents.count > 0;
  143. },
  144. 5.0);
  145. NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
  146. [notifCenter postNotificationName:kGDTApplicationWillTerminateNotification object:nil];
  147. GDTWaitForBlock(
  148. ^BOOL {
  149. NSFileManager *fm = [NSFileManager defaultManager];
  150. return [fm fileExistsAtPath:[GDTStorage archivePath] isDirectory:NULL];
  151. },
  152. 5.0);
  153. }
  154. @end