FPRGDTLoggerTest.m 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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/FPRNanoPbUtils.h"
  16. #import "FirebasePerformance/Sources/Loggers/FPRGDTLogSampler.h"
  17. #import "FirebasePerformance/Sources/Loggers/FPRGDTLogger.h"
  18. #import "FirebasePerformance/Sources/Loggers/FPRGDTLogger_Private.h"
  19. #import "FirebasePerformance/Sources/Loggers/FPRGDTRateLimiter.h"
  20. #import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
  21. #import <GoogleDataTransport/GoogleDataTransport.h>
  22. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h"
  23. #import "SharedTestUtilities/GDTCORTransportFake.h"
  24. @interface FPRGDTLoggerTest : XCTestCase
  25. /** Fll logger used to dispatch events to Fll using Google Data Transport. */
  26. @property(nonatomic) FPRGDTLogger *logger;
  27. /** A fake for the GDTCORTransport for FLL. */
  28. @property(nonatomic) GDTCORTransportFake *transportFLLFake;
  29. /** The log source for the FPRGDTLogger to be used. */
  30. @property(nonatomic) NSInteger logSource;
  31. /** The target backend of the GDTCORTransport - FLL. */
  32. @property(nonatomic) NSInteger targetFL;
  33. @end
  34. @implementation FPRGDTLoggerTest
  35. - (void)setUp {
  36. [super setUp];
  37. self.logSource = 1;
  38. self.targetFL = kGDTCORTargetFLL; // FLL
  39. self.logger = [[FPRGDTLogger alloc] initWithLogSource:self.logSource];
  40. self.logger.isSimulator = YES;
  41. // Set up for Fake logging.
  42. self.transportFLLFake =
  43. [[GDTCORTransportFake alloc] initWithMappingID:@(self.logSource).stringValue
  44. transformers:nil
  45. target:self.targetFL];
  46. self.logger.gdtfllTransport = self.transportFLLFake;
  47. }
  48. - (void)tearDown {
  49. [self.transportFLLFake reset];
  50. [super tearDown];
  51. }
  52. /** Tests the designated initializer. */
  53. - (void)testInitWithLogSource {
  54. NSInteger randomLogSource = 1;
  55. FPRGDTLogger *logger = [[FPRGDTLogger alloc] initWithLogSource:randomLogSource];
  56. XCTAssertNotNil(logger);
  57. XCTAssertEqual(logger.logSource, randomLogSource);
  58. XCTAssertNotNil(logger.gdtfllTransport);
  59. }
  60. /** Tests the GDTLogger is generated with designated transformers. */
  61. - (void)testInitWithTransformers {
  62. NSInteger randomLogSource = 1;
  63. FPRGDTLogger *logger = [[FPRGDTLogger alloc] initWithLogSource:randomLogSource];
  64. XCTAssertNotNil(logger);
  65. XCTAssertNotNil(logger.gdtfllTransport);
  66. // GDT logger tests
  67. XCTAssertEqual(logger.gdtfllTransport.transformers.count, 2);
  68. XCTAssertTrue(
  69. [logger.gdtfllTransport.transformers.firstObject isKindOfClass:[FPRGDTLogSampler class]]);
  70. XCTAssertTrue(
  71. [logger.gdtfllTransport.transformers.lastObject isKindOfClass:[FPRGDTRateLimiter class]]);
  72. }
  73. /** Validate all the required fields are set when logging an Event. */
  74. - (void)testValidateEventFieldsToBeLogged {
  75. // Log the event.
  76. firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
  77. event.application_info.app_instance_id = FPREncodeString(@"abc");
  78. [self.logger logEvent:event];
  79. // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
  80. dispatch_sync(self.logger.queue, ^{
  81. // Fetch the logged event.
  82. NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportFLLFake logEvents];
  83. GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
  84. // Validate that only 1 event is logged.
  85. XCTAssertEqual(gdtCorEventArray.count, 1);
  86. // Validate that the corresponding GDTEvent to be logged is not nil.
  87. XCTAssertNotNil(gdtCorEvent.dataObject);
  88. // Validate that the mapping ID is correctly associated.
  89. XCTAssertEqual(gdtCorEvent.mappingID, @(self.logSource).stringValue);
  90. // Validate that the target is correctly associated.
  91. XCTAssertEqual(gdtCorEvent.target, self.targetFL);
  92. // Validate that the QoS is set to GDTCOREventQoSFast in debug mode.
  93. XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQoSFast);
  94. });
  95. }
  96. /** Validate that multiple events are logged correctly. */
  97. - (void)testLogMultipleEvents {
  98. // Log the events.
  99. int logCount = 3;
  100. for (int i = 1; i <= logCount; i++) {
  101. NSString *traceName = [NSString stringWithFormat:@"t%d", i];
  102. firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:traceName];
  103. event.application_info.app_instance_id = FPREncodeString(@"abc");
  104. [self.logger logEvent:event];
  105. }
  106. // Note: "dispatch_async issue"
  107. //
  108. // There's a race condition between we checking the logEvents property on the "transportFake"
  109. // and writing to that property using the "logEvent" method from the "logger" class
  110. // because we are dispatching that event in a "dispatch_async" queue.
  111. //
  112. // To mitigate this we want that block to finish executing, so we call "dispatch_sync"
  113. // on the same "queue" and perform all the validations inside that block.
  114. //
  115. // This is because it will block the current thread until all queued blocks are done.
  116. dispatch_sync(self.logger.queue, ^{
  117. // Fetch the logged events.
  118. NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportFLLFake logEvents];
  119. // Validate that the count of logged events is what is expected.
  120. XCTAssertEqual(gdtCorEventArray.count, logCount);
  121. });
  122. }
  123. /** Validate events' QoS are set to GDTCOREventQoSFast when running in Simulator. */
  124. - (void)testEventsSimulatorQoS {
  125. self.logger.isSimulator = YES;
  126. // Log the event.
  127. firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
  128. event.application_info.app_instance_id = FPREncodeString(@"abc");
  129. [self.logger logEvent:event];
  130. // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
  131. dispatch_sync(self.logger.queue, ^{
  132. // Fetch the logged event.
  133. NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportFLLFake logEvents];
  134. GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
  135. // Validate that the QoS is set to GDTCOREventQoSFast.
  136. XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQoSFast);
  137. });
  138. }
  139. /** Validate events' QoS are set to GDTCOREventQosDefault in actual device. */
  140. - (void)testEventsRealDeviceQoS {
  141. self.logger.isSimulator = NO;
  142. // Log the event.
  143. firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
  144. event.application_info.app_instance_id = FPREncodeString(@"abc");
  145. [self.logger logEvent:event];
  146. // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
  147. dispatch_sync(self.logger.queue, ^{
  148. // Fetch the logged event.
  149. NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportFLLFake logEvents];
  150. GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
  151. // Validate that the QoS is set to GDTCOREventQosDefault.
  152. XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQosDefault);
  153. });
  154. }
  155. @end