FPRGDTRateLimiterTest.m 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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/Loggers/FPRGDTEvent.h"
  16. #import "FirebasePerformance/Sources/Loggers/FPRGDTRateLimiter+Private.h"
  17. #import "FirebasePerformance/Sources/Loggers/FPRGDTRateLimiter.h"
  18. #import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
  19. #import "FirebasePerformance/Sources/FPRProtoUtils.h"
  20. #import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
  21. #import "FirebasePerformance/Sources/Public/FIRPerformance.h"
  22. #import "FirebasePerformance/Sources/Public/FIRTrace.h"
  23. #import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
  24. #import "FirebasePerformance/Tests/Unit/Common/FPRFakeDate.h"
  25. #import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
  26. #import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
  27. #import <GoogleDataTransport/GoogleDataTransport.h>
  28. #import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
  29. @interface FPRGDTRateLimiterTest : FPRTestCase
  30. @end
  31. @implementation FPRGDTRateLimiterTest
  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 that the object creation was successful and default values are correct. */
  43. - (void)testInstanceCreation {
  44. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] init];
  45. XCTAssertNotNil(transformer);
  46. if ([FPRAppActivityTracker sharedInstance].applicationState == FPRApplicationStateBackground) {
  47. XCTAssertEqual(transformer.allowedTraceEventsCount, 30);
  48. XCTAssertEqual(transformer.allowedNetworkEventsCount, 70);
  49. } else {
  50. XCTAssertEqual(transformer.allowedTraceEventsCount, 300);
  51. XCTAssertEqual(transformer.allowedNetworkEventsCount, 700);
  52. }
  53. }
  54. /** Validates the rate limiter allows sending valid events. */
  55. - (void)testRateLimitingAlgorithmValidEvent {
  56. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  57. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  58. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomTraceGDTEvent:@"trace"];
  59. XCTAssertNotNil([transformer transform:gdtEvent]);
  60. }
  61. /** Validates the rate limiter allows sending valid network events. */
  62. - (void)testRateLimitingAlgorithmValidNetworkRequestEvent {
  63. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  64. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  65. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomNetworkGDTEvent:@"https://abc.xyz"];
  66. XCTAssertNotNil([transformer transform:gdtEvent]);
  67. }
  68. /** Validates the rate limiter allows sending events and drops events when exceeds allowed events
  69. * count. */
  70. - (void)testRateLimitingAlgorithmDropsEventsWhenExceedsAllowedEventsCount {
  71. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  72. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  73. // Set the rate limit to 60 events per minute.
  74. [transformer setOverrideRate:60];
  75. transformer.traceEventBurstSize = 100;
  76. transformer.allowedTraceEventsCount = 0;
  77. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomTraceGDTEvent:@"trace"];
  78. transformer.lastTraceEventTime = fakeDate.now;
  79. [fakeDate incrementTime:1];
  80. // Send an event to see if that event is accepted.
  81. XCTAssertNotNil([transformer transform:gdtEvent]);
  82. // Ensure that the event is dropped as we have reached allowed events count.
  83. XCTAssertNil([transformer transform:gdtEvent]);
  84. // Events should be accepted after few seconds.
  85. transformer.lastTraceEventTime = fakeDate.now;
  86. [fakeDate incrementTime:1];
  87. XCTAssertNotNil([transformer transform:gdtEvent]);
  88. }
  89. /** Validates the rate limiter does not apply on internal traces even when exceeds allowed events
  90. * count. */
  91. - (void)testRateLimitingAlgorithmDoesNotSkipInternalTracesWhenExceedsAllowedEventsCount {
  92. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  93. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  94. // Set the rate limit to 60 events per minute.
  95. [transformer setOverrideRate:60];
  96. transformer.traceEventBurstSize = 100;
  97. transformer.allowedTraceEventsCount = 0;
  98. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomInternalTraceGDTEvent:@"internal_trace"];
  99. transformer.lastTraceEventTime = fakeDate.now;
  100. [fakeDate incrementTime:1];
  101. // Send an event to see if that event is accepted.
  102. XCTAssertNotNil([transformer transform:gdtEvent]);
  103. // Ensure that the internal event is not dropped even though we have exceeded allowed events
  104. // count.
  105. XCTAssertNotNil([transformer transform:gdtEvent]);
  106. }
  107. /** Validates the rate limiter allows sending network events drops network events when exceeds
  108. * allowed events count.*/
  109. - (void)testRateLimitingAlgorithmDropsNetworkEventsWhenExceedsAllowedEventsCount {
  110. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  111. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  112. // Set the rate limit to 60 events per minute.
  113. [transformer setOverrideNetworkRate:60];
  114. transformer.networkEventburstSize = 100;
  115. transformer.allowedNetworkEventsCount = 0;
  116. // Send an event to see if that event is accepted.
  117. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomNetworkGDTEvent:@"https://abc.xyz"];
  118. transformer.lastNetworkEventTime = fakeDate.now;
  119. [fakeDate incrementTime:1];
  120. XCTAssertNotNil([transformer transform:gdtEvent]);
  121. // Ensure that the event is dropped as we have reached the rate limit and the burst size.
  122. XCTAssertNil([transformer transform:gdtEvent]);
  123. // Events should be accepted after few seconds.
  124. transformer.lastTraceEventTime = fakeDate.now;
  125. [fakeDate incrementTime:1];
  126. XCTAssertNotNil([transformer transform:gdtEvent]);
  127. }
  128. /** Validates the rate limiter allows sending events and adjusts the rate dynamically. */
  129. - (void)testRateLimitingAlgorithmWithChangingLimits {
  130. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  131. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  132. // Set the rate limit to 60 events per minute.
  133. [transformer setOverrideRate:60];
  134. transformer.traceEventBurstSize = 100;
  135. transformer.allowedTraceEventsCount = 0;
  136. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomTraceGDTEvent:@"trace"];
  137. transformer.lastTraceEventTime = fakeDate.now;
  138. [fakeDate incrementTime:1];
  139. // Send an event to see if that event is accepted.
  140. XCTAssertNotNil([transformer transform:gdtEvent]);
  141. // Set the rate limit to 15 events per minute.
  142. [transformer setOverrideRate:15];
  143. // Since the rate limit is set to 15 events a minute, incrementing the time by a second would not
  144. // allow a new event to flow through.
  145. transformer.lastTraceEventTime = fakeDate.now;
  146. [fakeDate incrementTime:1];
  147. XCTAssertNil([transformer transform:gdtEvent]);
  148. // Incrementing the time with another 4 seconds would allow an event to flow through.
  149. [fakeDate incrementTime:4];
  150. XCTAssertNotNil([transformer transform:gdtEvent]);
  151. }
  152. /** Validates the rate limiter drops events when exceeds burst size. */
  153. - (void)testRateLimitingAlgorithmDropsEventsWhenExceedsBurstSize {
  154. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  155. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  156. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  157. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  158. object:[UIApplication sharedApplication]];
  159. transformer.traceEventBurstSize = 60;
  160. transformer.allowedTraceEventsCount = 60;
  161. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomTraceGDTEvent:@"trace"];
  162. // Send an event to see if that event is accepted.
  163. transformer.lastTraceEventTime = fakeDate.now;
  164. for (int i = 0; i < 60; i++) {
  165. XCTAssertNotNil([transformer transform:gdtEvent]);
  166. }
  167. // After 60 events, no more events should be allowed.
  168. XCTAssertNil([transformer transform:gdtEvent]);
  169. }
  170. /** Validates the rate limiter drops network events when exceeds burst size. */
  171. - (void)testRateLimitingAlgorithmDropsNetworkEventsWhenExceedsBurstSize {
  172. FPRFakeDate *fakeDate = [[FPRFakeDate alloc] init];
  173. FPRGDTRateLimiter *transformer = [[FPRGDTRateLimiter alloc] initWithDate:fakeDate];
  174. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  175. [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
  176. object:[UIApplication sharedApplication]];
  177. transformer.networkEventburstSize = 60;
  178. transformer.allowedNetworkEventsCount = 60;
  179. // Send an event to see if that event is accepted.
  180. GDTCOREvent *gdtEvent = [FPRTestUtils createRandomNetworkGDTEvent:@"https://abc.xyz"];
  181. transformer.lastNetworkEventTime = fakeDate.now;
  182. for (int i = 0; i < 60; i++) {
  183. XCTAssertNotNil([transformer transform:gdtEvent]);
  184. }
  185. // After 60 events, no more events should be allowed.
  186. XCTAssertNil([transformer transform:gdtEvent]);
  187. }
  188. @end