FPRClientTest.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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/Configurations/FPRConfigurations+Private.h"
  16. #import "FirebasePerformance/Sources/FPRClient+Private.h"
  17. #import "FirebasePerformance/Sources/FPRClient.h"
  18. #import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
  19. #import "FirebasePerformance/Sources/Loggers/FPRGDTLogger.h"
  20. #import "FirebasePerformance/Sources/Loggers/FPRGDTLogger_Private.h"
  21. #import "FirebasePerformance/Tests/Unit/Configurations/FPRFakeRemoteConfig.h"
  22. #import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
  23. #import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
  24. #import "FirebasePerformance/Tests/Unit/Fakes/FPRFakeConfigurations.h"
  25. #import "FirebasePerformance/Tests/Unit/Fakes/FPRFakeInstallations.h"
  26. #import <OCMock/OCMock.h>
  27. #import "SharedTestUtilities/GDTCORTransportFake.h"
  28. NSString *const kFPRMockInstallationId = @"mockId";
  29. @interface FPRClientTest : FPRTestCase
  30. /** Configuration which can be assigned as a fake object for event dispatch control. */
  31. @property(nonatomic) FPRConfigurations *configurations;
  32. /** Fireperf client object which can be used for fake object injection and assertion . */
  33. @property(nonatomic) FPRClient *client;
  34. @end
  35. @implementation FPRClientTest
  36. - (void)setUp {
  37. [super setUp];
  38. // Arrange installations object.
  39. FPRFakeInstallations *installations = [FPRFakeInstallations installations];
  40. self.client = [[FPRClient alloc] init];
  41. installations.identifier = kFPRMockInstallationId;
  42. self.client.installations = (FIRInstallations *)installations;
  43. // Arrange remote config object.
  44. FPRFakeConfigurations *fakeConfigs =
  45. [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
  46. self.configurations = fakeConfigs;
  47. fakeConfigs.dataCollectionEnabled = YES;
  48. fakeConfigs.sdkEnabled = YES;
  49. self.client.configuration = self.configurations;
  50. // Arrange gdtLogger object for event dispatch.
  51. self.client.gdtLogger = [[FPRGDTLogger alloc] initWithLogSource:1];
  52. GDTCORTransportFake *fakeGdtTransport =
  53. [[GDTCORTransportFake alloc] initWithMappingID:@"1" transformers:nil target:kGDTCORTargetFLL];
  54. self.client.gdtLogger.gdtfllTransport = fakeGdtTransport;
  55. }
  56. /** Validates if the gdtTransport logger has received trace perfMetric. */
  57. - (void)testLogAndProcessEventsForTrace {
  58. // Trace type PerfMetric for event dispatch.
  59. firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
  60. // Act on event logging call.
  61. [self.client processAndLogEvent:perfMetric];
  62. firebase_perf_v1_PerfMetric expectedMetric = perfMetric;
  63. expectedMetric.application_info.app_instance_id = FPREncodeString(kFPRMockInstallationId);
  64. // Wait for async job to execute event logging.
  65. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  66. // Validate the event is received by gdtTransport logger.
  67. dispatch_sync(self.client.gdtLogger.queue, ^{
  68. GDTCORTransportFake *fakeGdtTransport =
  69. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  70. XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
  71. GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
  72. XCTAssertNotNil(
  73. FPRDecodeString([(FPRGDTEvent *)event.dataObject metric].application_info.app_instance_id));
  74. XCTAssertEqualObjects([event.dataObject transportBytes],
  75. [[FPRGDTEvent gdtEventForPerfMetric:expectedMetric] transportBytes]);
  76. });
  77. }
  78. /** Validates if the gdtTransport logger has received network trace perfMetric. */
  79. - (void)testLogAndProcessEventsForNetworkTrace {
  80. // Network type PerfMetric for event dispatch.
  81. firebase_perf_v1_PerfMetric perfMetric =
  82. [FPRTestUtils createRandomNetworkPerfMetric:@"https://abc.xyz"];
  83. // Act on event logging call.
  84. [self.client processAndLogEvent:perfMetric];
  85. firebase_perf_v1_PerfMetric expectedMetric = perfMetric;
  86. expectedMetric.application_info.app_instance_id = FPREncodeString(kFPRMockInstallationId);
  87. // Wait for async job to execute event logging.
  88. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  89. // Validate the event is received by gdtTransport logger.
  90. dispatch_sync(self.client.gdtLogger.queue, ^{
  91. GDTCORTransportFake *fakeGdtTransport =
  92. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  93. XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
  94. GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
  95. XCTAssertNotNil(
  96. FPRDecodeString([(FPRGDTEvent *)event.dataObject metric].application_info.app_instance_id));
  97. XCTAssertEqualObjects([event.dataObject transportBytes],
  98. [[FPRGDTEvent gdtEventForPerfMetric:expectedMetric] transportBytes]);
  99. });
  100. }
  101. /** Validates if the gdtTransport logger has received session gauge perfMetric. */
  102. - (void)testLogAndProcessEventsForGauge {
  103. // Gauge type PerfMetric for event dispatch.
  104. firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomGaugePerfMetric];
  105. // Act on event logging call.
  106. [self.client processAndLogEvent:perfMetric];
  107. firebase_perf_v1_PerfMetric expectedMetric = perfMetric;
  108. expectedMetric.application_info.app_instance_id = FPREncodeString(kFPRMockInstallationId);
  109. // Wait for async job to execute event logging.
  110. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  111. // Validate the event is received by gdtTransport logger.
  112. dispatch_sync(self.client.gdtLogger.queue, ^{
  113. GDTCORTransportFake *fakeGdtTransport =
  114. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  115. XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
  116. GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
  117. XCTAssertNotNil(
  118. FPRDecodeString([(FPRGDTEvent *)event.dataObject metric].application_info.app_instance_id));
  119. XCTAssertEqualObjects([event.dataObject transportBytes],
  120. [[FPRGDTEvent gdtEventForPerfMetric:expectedMetric] transportBytes]);
  121. });
  122. }
  123. /** Validates if the gdtTransport logger will not receive event when data collection is disabled. */
  124. - (void)testLogAndProcessEventsNotDispatchWhenDisabled {
  125. // Trace type PerfMetric for event dispatch.
  126. firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
  127. // Act on event logging call when data collection is disabled.
  128. self.configurations.dataCollectionEnabled = NO;
  129. [self.client processAndLogEvent:perfMetric];
  130. // Wait for async job to execute event logging.
  131. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  132. // Validate the event is not received by gdtTransport logger.
  133. dispatch_sync(self.client.gdtLogger.queue, ^{
  134. GDTCORTransportFake *fakeGdtTransport =
  135. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  136. XCTAssertEqual(fakeGdtTransport.logEvents.count, 0);
  137. });
  138. }
  139. /** Validates if the gdtTransport logger will resume receiving event when data collection is
  140. * re-enabled. */
  141. - (void)testLogAndProcessEventsAfterReenabled {
  142. // Trace type PerfMetric for event dispatch.
  143. firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
  144. // Act on event logging call when data collection is disabled.
  145. self.configurations.dataCollectionEnabled = NO;
  146. [self.client processAndLogEvent:perfMetric];
  147. // Wait for async job to execute event logging.
  148. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  149. // Validate the event is not received by gdtTransport logger.
  150. dispatch_sync(self.client.gdtLogger.queue, ^{
  151. GDTCORTransportFake *fakeGdtTransport =
  152. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  153. XCTAssertEqual(fakeGdtTransport.logEvents.count, 0);
  154. });
  155. // Act on event logging call after re-enable data collection.
  156. self.configurations.dataCollectionEnabled = YES;
  157. [self.client processAndLogEvent:perfMetric];
  158. // Wait for async job to execute event logging.
  159. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  160. // Validate the event is received by gdtTransport logger.
  161. dispatch_sync(self.client.gdtLogger.queue, ^{
  162. GDTCORTransportFake *fakeGdtTransport =
  163. (GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
  164. XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
  165. });
  166. }
  167. /** Validates that the Clearcut log directory removal method is called. */
  168. - (void)testClearcutLogDirectoryCleanupInitiates {
  169. id clientMock = OCMClassMock(self.client.class);
  170. [self.client startWithConfiguration:[[FPRConfiguration alloc] initWithAppID:@"RandomAppId"
  171. APIKey:nil
  172. autoPush:YES]
  173. error:nil];
  174. // Wait for async job to initiate cleanup logic.
  175. dispatch_group_wait(self.client.eventsQueueGroup, DISPATCH_TIME_FOREVER);
  176. OCMVerify([clientMock cleanupClearcutCacheDirectory]);
  177. }
  178. /**
  179. * Validates that the log directory path in the cache directory created for Clearcut logs storage
  180. * gets removed (if exist).
  181. */
  182. - (void)testValidateClearcutLogDirectoryCleanupIfExists {
  183. // Create the log directory and make sure it exists.
  184. NSString *logDirectoryPath = [FPRClient logDirectoryPath];
  185. [[NSFileManager defaultManager] createDirectoryAtPath:logDirectoryPath
  186. withIntermediateDirectories:YES
  187. attributes:nil
  188. error:nil];
  189. BOOL logDirectoryExists = [[NSFileManager defaultManager] fileExistsAtPath:logDirectoryPath];
  190. XCTAssertTrue(logDirectoryExists);
  191. [FPRClient cleanupClearcutCacheDirectory];
  192. logDirectoryExists = [[NSFileManager defaultManager] fileExistsAtPath:logDirectoryPath];
  193. XCTAssertFalse(logDirectoryExists);
  194. }
  195. /**
  196. * Validates that the Clearcut log directory path removal logic doesn't explode if directory doesn't
  197. * exist.
  198. */
  199. - (void)testValidateClearcutLogDirectoryCleanupIfNotExists {
  200. NSString *logDirectoryPath = [FPRClient logDirectoryPath];
  201. BOOL logDirectoryExists = [[NSFileManager defaultManager] fileExistsAtPath:logDirectoryPath];
  202. XCTAssertFalse(logDirectoryExists);
  203. XCTAssertNoThrow([FPRClient cleanupClearcutCacheDirectory]);
  204. }
  205. @end