FPRGDTRateLimiterTest.m 9.5 KB

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