FPRAppActivityTrackerTest.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import <XCTest/XCTest.h>
  15. #import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
  16. #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
  17. #import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
  18. #import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
  19. #import "FirebaseCore/Sources/Private/FIRAppInternal.h"
  20. #import <OCMock/OCMock.h>
  21. @interface FPRAppActivityTrackerTest : FPRTestCase
  22. @end
  23. @interface FPRAppActivityTracker (Tests)
  24. @property(nonatomic) FPRConfigurations *configurations;
  25. + (BOOL)isPrewarmAvailable;
  26. - (BOOL)isAppStartEnabled;
  27. - (BOOL)isActivePrewarmEnabled;
  28. - (BOOL)isDoubleDispatchEnabled;
  29. - (BOOL)isApplicationPreWarmed;
  30. @end
  31. @implementation FPRAppActivityTrackerTest
  32. - (void)setUp {
  33. [super setUp];
  34. FIRPerformance *performance = [FIRPerformance sharedInstance];
  35. [performance setDataCollectionEnabled:YES];
  36. }
  37. - (void)tearDown {
  38. [super tearDown];
  39. FIRPerformance *performance = [FIRPerformance sharedInstance];
  40. [performance setDataCollectionEnabled:NO];
  41. }
  42. /** Validates if the instance was successfully created. */
  43. - (void)testInstanceCreation {
  44. XCTAssertNotNil([FPRAppActivityTracker sharedInstance]);
  45. XCTAssertEqualObjects([FPRAppActivityTracker sharedInstance],
  46. [FPRAppActivityTracker sharedInstance]);
  47. }
  48. /** Validates if an active trace is available when the app is active. */
  49. - (void)testActiveTrace {
  50. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  51. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  52. object:[UIApplication sharedApplication]];
  53. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  54. object:[UIApplication sharedApplication]];
  55. XCTAssertNotNil([FPRAppActivityTracker sharedInstance].activeTrace);
  56. }
  57. /** Validates no active trace is available when data collection is disabled. */
  58. - (void)testActiveTraceWhenDataCollectionDisabled {
  59. BOOL dataCollectionEnabled = [FIRPerformance sharedInstance].dataCollectionEnabled;
  60. [[FIRPerformance sharedInstance] setDataCollectionEnabled:NO];
  61. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  62. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  63. object:[UIApplication sharedApplication]];
  64. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  65. object:[UIApplication sharedApplication]];
  66. XCTAssertNil([FPRAppActivityTracker sharedInstance].activeTrace);
  67. [[FIRPerformance sharedInstance] setDataCollectionEnabled:dataCollectionEnabled];
  68. }
  69. /** Validates if the active trace changes across launch of application from foreground to background
  70. * and then background to foreground.
  71. */
  72. - (void)testActiveTraceChanging {
  73. FIRTrace *activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  74. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  75. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  76. object:[UIApplication sharedApplication]];
  77. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  78. object:[UIApplication sharedApplication]];
  79. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  80. object:[UIApplication sharedApplication]];
  81. FIRTrace *newActiveTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  82. XCTAssertNotEqual(activeTrace, newActiveTrace);
  83. }
  84. /** Validates if the active trace changes across launch of application from foreground to
  85. * background.
  86. */
  87. - (void)testActiveTraceWhenAppChangesStates {
  88. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  89. FIRTrace *activeTrace = nil;
  90. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  91. object:[UIApplication sharedApplication]];
  92. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  93. object:[UIApplication sharedApplication]];
  94. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  95. XCTAssertEqual(activeTrace.name, kFPRAppTraceNameBackgroundSession);
  96. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  97. object:[UIApplication sharedApplication]];
  98. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  99. XCTAssertEqual(activeTrace.name, kFPRAppTraceNameForegroundSession);
  100. }
  101. /** Validates if the active trace is nil when data collection is toggled.
  102. */
  103. - (void)testActiveTraceIsNilWhenAppChangesStatesAndDataCollectionToggledFromEnabled {
  104. BOOL dataCollectionEnabled = [FIRPerformance sharedInstance].dataCollectionEnabled;
  105. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  106. FIRTrace *activeTrace = nil;
  107. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  108. object:[UIApplication sharedApplication]];
  109. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  110. object:[UIApplication sharedApplication]];
  111. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  112. XCTAssertEqual(activeTrace.name, kFPRAppTraceNameBackgroundSession);
  113. [[FIRPerformance sharedInstance] setDataCollectionEnabled:NO];
  114. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  115. object:[UIApplication sharedApplication]];
  116. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  117. XCTAssertNil(activeTrace);
  118. [[FIRPerformance sharedInstance] setDataCollectionEnabled:YES];
  119. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  120. object:[UIApplication sharedApplication]];
  121. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  122. XCTAssertEqual(activeTrace.name, kFPRAppTraceNameBackgroundSession);
  123. [FIRPerformance sharedInstance].dataCollectionEnabled = dataCollectionEnabled;
  124. }
  125. /** Validates if the active trace is nil when data collection is toggled.
  126. */
  127. - (void)testActiveTraceIsNilWhenAppChangesStatesAndDataCollectionToggledFromDisabled {
  128. BOOL dataCollectionEnabled = [FIRPerformance sharedInstance].dataCollectionEnabled;
  129. [[FIRPerformance sharedInstance] setDataCollectionEnabled:NO];
  130. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  131. FIRTrace *activeTrace = nil;
  132. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  133. object:[UIApplication sharedApplication]];
  134. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  135. object:[UIApplication sharedApplication]];
  136. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  137. XCTAssertNil(activeTrace);
  138. [[FIRPerformance sharedInstance] setDataCollectionEnabled:YES];
  139. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  140. object:[UIApplication sharedApplication]];
  141. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  142. XCTAssertNotNil(activeTrace);
  143. [[FIRPerformance sharedInstance] setDataCollectionEnabled:NO];
  144. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  145. object:[UIApplication sharedApplication]];
  146. activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
  147. XCTAssertNil(activeTrace);
  148. [FIRPerformance sharedInstance].dataCollectionEnabled = dataCollectionEnabled;
  149. }
  150. /** Validates if the application state is managed correctly. */
  151. - (void)testApplicationStateManagement {
  152. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  153. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  154. [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
  155. object:[UIApplication sharedApplication]];
  156. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  157. object:[UIApplication sharedApplication]];
  158. XCTAssertEqual(appTracker.applicationState, FPRApplicationStateBackground);
  159. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  160. object:[UIApplication sharedApplication]];
  161. XCTAssertEqual(appTracker.applicationState, FPRApplicationStateForeground);
  162. [defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
  163. object:[UIApplication sharedApplication]];
  164. XCTAssertEqual(appTracker.applicationState, FPRApplicationStateBackground);
  165. }
  166. /** Validates double dispatch returns true when +load occurs before didFinishLaunching
  167. */
  168. - (void)test_isApplicationPrewarmed_doubleDispatch_returnsYes {
  169. id mockAppTracker = OCMPartialMock([FPRAppActivityTracker sharedInstance]);
  170. OCMStub([mockAppTracker isPrewarmAvailable]).andReturn(YES);
  171. OCMStub([mockAppTracker isDoubleDispatchEnabled]).andReturn(YES);
  172. OCMStub([mockAppTracker isActivePrewarmEnabled]).andReturn(NO);
  173. [FPRAppActivityTracker load];
  174. [[NSNotificationCenter defaultCenter]
  175. postNotificationName:UIApplicationDidFinishLaunchingNotification
  176. object:[UIApplication sharedApplication]];
  177. XCTAssertTrue([mockAppTracker isApplicationPreWarmed]);
  178. }
  179. /** Validates ActivePrewarm environment variable set to true is detected by prewarm-detection
  180. */
  181. - (void)test_isApplicationPrewarmed_activePrewarm_returnsYes {
  182. id mockAppTracker = OCMPartialMock([FPRAppActivityTracker sharedInstance]);
  183. OCMStub([mockAppTracker isPrewarmAvailable]).andReturn(YES);
  184. OCMStub([mockAppTracker isDoubleDispatchEnabled]).andReturn(NO);
  185. OCMStub([mockAppTracker isActivePrewarmEnabled]).andReturn(YES);
  186. setenv("ActivePrewarm", "1", 1);
  187. XCTAssertTrue([mockAppTracker isApplicationPreWarmed]);
  188. }
  189. /** Validates when ActivePrewarm environment variable is not set, prewarm-detection returns false
  190. */
  191. - (void)test_isApplicationPrewarmed_activePrewarm_returnsNo {
  192. id mockAppTracker = OCMPartialMock([FPRAppActivityTracker sharedInstance]);
  193. OCMStub([mockAppTracker isPrewarmAvailable]).andReturn(YES);
  194. OCMStub([mockAppTracker isDoubleDispatchEnabled]).andReturn(NO);
  195. OCMStub([mockAppTracker isActivePrewarmEnabled]).andReturn(YES);
  196. XCTAssertFalse([mockAppTracker isApplicationPreWarmed]);
  197. }
  198. /** Validates when RC flag fpr_prewarm_detection is PrewarmDetectionModeNone
  199. */
  200. - (void)test_isAppStartEnabled_PrewarmDetectionModeKeepNone_returnsNo {
  201. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  202. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  203. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeKeepNone);
  204. appTracker.configurations = mockConfigurations;
  205. XCTAssertFalse([appTracker isApplicationPreWarmed]);
  206. }
  207. /** Validates when RC flag fpr_prewarm_detection is PrewarmDetectionModeAll
  208. */
  209. - (void)test_isAppStartEnabled_PrewarmDetectionModeKeepAll_returnsYes {
  210. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  211. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  212. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeKeepAll);
  213. appTracker.configurations = mockConfigurations;
  214. XCTAssertTrue([appTracker isAppStartEnabled]);
  215. }
  216. /** Validates ActivePrewarm filtering is enabled when RC flag fpr_prewarm_detection is
  217. * PrewarmDetectionModeActivePrewarm
  218. */
  219. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeActivePrewarm_returnsYes {
  220. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  221. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  222. appTracker.configurations = mockConfigurations;
  223. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeActivePrewarm);
  224. XCTAssertTrue([appTracker isActivePrewarmEnabled]);
  225. }
  226. /** Validates ActivePrewarm filtering is disabled when RC flag fpr_prewarm_detection is
  227. * PrewarmDetectionModeDoubleDispatch
  228. */
  229. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeDoubleDispatch_returnsNo {
  230. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  231. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  232. appTracker.configurations = mockConfigurations;
  233. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeDoubleDispatch);
  234. XCTAssertFalse([appTracker isActivePrewarmEnabled]);
  235. }
  236. /** Validates double dispatch filtering is disabled when RC flag fpr_prewarm_detection is
  237. * PrewarmDetectionModeActivePrewarm
  238. */
  239. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeActivePrewarm_returnsNo {
  240. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  241. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  242. appTracker.configurations = mockConfigurations;
  243. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeActivePrewarm);
  244. XCTAssertFalse([appTracker isDoubleDispatchEnabled]);
  245. }
  246. /** Validates double dispatch filtering is enabled when RC flag fpr_prewarm_detection is
  247. * PrewarmDetectionModeDoubleDispatch
  248. */
  249. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeDoubleDispatch_returnsYes {
  250. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  251. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  252. appTracker.configurations = mockConfigurations;
  253. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeDoubleDispatch);
  254. XCTAssertTrue([appTracker isDoubleDispatchEnabled]);
  255. }
  256. /** Validates ActivePrewarm filtering is enabled when RC flag fpr_prewarm_detection is
  257. * PrewarmDetectionModeActivePrewarmOrDoubleDispatch
  258. */
  259. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeActivePrewarmOrDoubleDispatch_returnsYes {
  260. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  261. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  262. appTracker.configurations = mockConfigurations;
  263. OCMStub([mockConfigurations prewarmDetectionMode])
  264. .andReturn(PrewarmDetectionModeActivePrewarmOrDoubleDispatch);
  265. XCTAssertTrue([appTracker isActivePrewarmEnabled]);
  266. }
  267. /** Validates double dispatch filtering is enabled when RC flag fpr_prewarm_detection is
  268. * PrewarmDetectionModeActivePrewarmOrDoubleDispatch
  269. */
  270. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeActivePrewarmOrDoubleDispatch_returnsYes {
  271. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  272. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  273. appTracker.configurations = mockConfigurations;
  274. OCMStub([mockConfigurations prewarmDetectionMode])
  275. .andReturn(PrewarmDetectionModeActivePrewarmOrDoubleDispatch);
  276. XCTAssertTrue([appTracker isDoubleDispatchEnabled]);
  277. }
  278. @end