FPRAppActivityTrackerTest.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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/Extension/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. [FPRAppActivityTracker load];
  188. XCTAssertTrue([mockAppTracker isApplicationPreWarmed]);
  189. }
  190. /** Validates when ActivePrewarm environment variable is not set, prewarm-detection returns false
  191. */
  192. - (void)test_isApplicationPrewarmed_activePrewarm_returnsNo {
  193. id mockAppTracker = OCMPartialMock([FPRAppActivityTracker sharedInstance]);
  194. OCMStub([mockAppTracker isPrewarmAvailable]).andReturn(YES);
  195. OCMStub([mockAppTracker isDoubleDispatchEnabled]).andReturn(NO);
  196. OCMStub([mockAppTracker isActivePrewarmEnabled]).andReturn(YES);
  197. XCTAssertFalse([mockAppTracker isApplicationPreWarmed]);
  198. }
  199. /** Validates when RC flag fpr_prewarm_detection is PrewarmDetectionModeNone
  200. */
  201. - (void)test_isAppStartEnabled_PrewarmDetectionModeKeepNone_returnsNo {
  202. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  203. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  204. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeKeepNone);
  205. appTracker.configurations = mockConfigurations;
  206. XCTAssertFalse([appTracker isApplicationPreWarmed]);
  207. }
  208. /** Validates when RC flag fpr_prewarm_detection is PrewarmDetectionModeAll
  209. */
  210. - (void)test_isAppStartEnabled_PrewarmDetectionModeKeepAll_returnsYes {
  211. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  212. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  213. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeKeepAll);
  214. appTracker.configurations = mockConfigurations;
  215. XCTAssertTrue([appTracker isAppStartEnabled]);
  216. }
  217. /** Validates ActivePrewarm filtering is enabled when RC flag fpr_prewarm_detection is
  218. * PrewarmDetectionModeActivePrewarm
  219. */
  220. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeActivePrewarm_returnsYes {
  221. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  222. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  223. appTracker.configurations = mockConfigurations;
  224. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeActivePrewarm);
  225. XCTAssertTrue([appTracker isActivePrewarmEnabled]);
  226. }
  227. /** Validates ActivePrewarm filtering is disabled when RC flag fpr_prewarm_detection is
  228. * PrewarmDetectionModeDoubleDispatch
  229. */
  230. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeDoubleDispatch_returnsNo {
  231. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  232. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  233. appTracker.configurations = mockConfigurations;
  234. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeDoubleDispatch);
  235. XCTAssertFalse([appTracker isActivePrewarmEnabled]);
  236. }
  237. /** Validates double dispatch filtering is disabled when RC flag fpr_prewarm_detection is
  238. * PrewarmDetectionModeActivePrewarm
  239. */
  240. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeActivePrewarm_returnsNo {
  241. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  242. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  243. appTracker.configurations = mockConfigurations;
  244. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeActivePrewarm);
  245. XCTAssertFalse([appTracker isDoubleDispatchEnabled]);
  246. }
  247. /** Validates double dispatch filtering is enabled when RC flag fpr_prewarm_detection is
  248. * PrewarmDetectionModeDoubleDispatch
  249. */
  250. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeDoubleDispatch_returnsYes {
  251. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  252. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  253. appTracker.configurations = mockConfigurations;
  254. OCMStub([mockConfigurations prewarmDetectionMode]).andReturn(PrewarmDetectionModeDoubleDispatch);
  255. XCTAssertTrue([appTracker isDoubleDispatchEnabled]);
  256. }
  257. /** Validates ActivePrewarm filtering is enabled when RC flag fpr_prewarm_detection is
  258. * PrewarmDetectionModeActivePrewarmOrDoubleDispatch
  259. */
  260. - (void)test_isActivePrewarmEnabled_PrewarmDetectionModeActivePrewarmOrDoubleDispatch_returnsYes {
  261. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  262. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  263. appTracker.configurations = mockConfigurations;
  264. OCMStub([mockConfigurations prewarmDetectionMode])
  265. .andReturn(PrewarmDetectionModeActivePrewarmOrDoubleDispatch);
  266. XCTAssertTrue([appTracker isActivePrewarmEnabled]);
  267. }
  268. /** Validates double dispatch filtering is enabled when RC flag fpr_prewarm_detection is
  269. * PrewarmDetectionModeActivePrewarmOrDoubleDispatch
  270. */
  271. - (void)test_isDoubleDispatchEnabled_PrewarmDetectionModeActivePrewarmOrDoubleDispatch_returnsYes {
  272. FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
  273. id mockConfigurations = OCMClassMock([FPRConfigurations class]);
  274. appTracker.configurations = mockConfigurations;
  275. OCMStub([mockConfigurations prewarmDetectionMode])
  276. .andReturn(PrewarmDetectionModeActivePrewarmOrDoubleDispatch);
  277. XCTAssertTrue([appTracker isDoubleDispatchEnabled]);
  278. }
  279. @end