Skip to content

Commit 749faf7

Browse files
committed
Added burst tests to the RateLimiter
1 parent a70ec5e commit 749faf7

File tree

1 file changed

+96
-2
lines changed

1 file changed

+96
-2
lines changed

firebase-perf/src/test/java/com/google/firebase/perf/transport/RateLimiterTest.java

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class RateLimiterTest extends FirebasePerformanceTestBase {
6161
private static final Rate TWO_TOKENS_PER_MINUTE = new Rate(2, 1, MINUTES);
6262
private static final Rate FOUR_TOKENS_PER_MINUTE = new Rate(4, 1, MINUTES);
6363
private static final Rate TWO_TOKENS_PER_SECOND = new Rate(2, 1, SECONDS);
64+
private static final Rate THREE_TOKENS_PER_SECOND = new Rate(3, 1, SECONDS);
65+
private static final Rate TEN_TOKENS_PER_SECOND = new Rate(10, 1, SECONDS);
6466

6567
@Before
6668
public void setUp() {
@@ -125,7 +127,7 @@ public void testRateLimitImpl() {
125127

126128
/** An edge test case for Token Bucket algorithm. */
127129
@Test
128-
public void testRateLimitImplWithIrregularTimeIntervals() {
130+
public void testRateLimiterImplWithIrregularTimeIntervals() {
129131

130132
makeConfigResolverReturnDefaultValues();
131133

@@ -165,7 +167,8 @@ public void testRateLimitImplWithIrregularTimeIntervals() {
165167
}
166168

167169
@Test
168-
public void testRateLimitImplWithLongTimeGapBetweenEvents_doesNotAccumulateTokensOrCauseBurst() {
170+
public void
171+
testRateLimiterImplWithLongTimeGapBetweenEvents_doesNotAccumulateTokensOrCauseBurst() {
169172

170173
makeConfigResolverReturnDefaultValues();
171174

@@ -206,6 +209,97 @@ public void testRateLimitImplWithLongTimeGapBetweenEvents_doesNotAccumulateToken
206209
assertThat(limiter.check(metric)).isFalse();
207210
}
208211

212+
@Test
213+
public void testRateLimiterImplWithBursts_rateLessThanCapacity_doesNotAllowMoreThanCapacity() {
214+
215+
makeConfigResolverReturnDefaultValues();
216+
217+
// Make Config Resolver returns default value for resource sampling rate.
218+
when(mockConfigResolver.getTraceSamplingRate()).thenReturn(1.0f);
219+
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(1.0f);
220+
221+
// allow 3 logs per second. token bucket capacity is 4.
222+
RateLimiterImpl limiter =
223+
new RateLimiterImpl(THREE_TOKENS_PER_SECOND, 4, mClock, mockConfigResolver, NETWORK, false);
224+
PerfMetric metric = PerfMetric.getDefaultInstance();
225+
226+
// clock is 0, token count starts at 4, none should be replenished
227+
assertThat(limiter.check(metric)).isTrue();
228+
assertThat(limiter.check(metric)).isTrue();
229+
assertThat(limiter.check(metric)).isTrue();
230+
assertThat(limiter.check(metric)).isTrue();
231+
assertThat(limiter.check(metric)).isFalse();
232+
assertThat(limiter.check(metric)).isFalse();
233+
234+
// clock is 1 second, 3 events should be allowed within the second
235+
currentTime = currentTime.plusSeconds(1);
236+
assertThat(limiter.check(metric)).isTrue();
237+
assertThat(limiter.check(metric)).isTrue();
238+
assertThat(limiter.check(metric)).isTrue();
239+
assertThat(limiter.check(metric)).isFalse();
240+
241+
// the first burst has finished, and there are 1 event per second for the next 3 seconds
242+
currentTime = currentTime.plusSeconds(1);
243+
assertThat(limiter.check(metric)).isTrue();
244+
currentTime = currentTime.plusSeconds(1);
245+
assertThat(limiter.check(metric)).isTrue();
246+
currentTime = currentTime.plusSeconds(1);
247+
assertThat(limiter.check(metric)).isTrue();
248+
249+
// after 10 seconds, the second burst is here, but capacity = 4 events are allowed
250+
currentTime = currentTime.plusSeconds(10);
251+
assertThat(limiter.check(metric)).isTrue();
252+
assertThat(limiter.check(metric)).isTrue();
253+
assertThat(limiter.check(metric)).isTrue();
254+
assertThat(limiter.check(metric)).isTrue();
255+
assertThat(limiter.check(metric)).isFalse();
256+
assertThat(limiter.check(metric)).isFalse();
257+
assertThat(limiter.check(metric)).isFalse();
258+
}
259+
260+
@Test
261+
public void testRateLimiterImplWithBursts_rateMoreThanCapacity_doesNotAllowMoreThanCapacity() {
262+
263+
makeConfigResolverReturnDefaultValues();
264+
265+
// Make Config Resolver returns default value for resource sampling rate.
266+
when(mockConfigResolver.getTraceSamplingRate()).thenReturn(1.0f);
267+
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(1.0f);
268+
269+
// allow 3 logs per second. token bucket capacity is 2.
270+
RateLimiterImpl limiter =
271+
new RateLimiterImpl(THREE_TOKENS_PER_SECOND, 2, mClock, mockConfigResolver, NETWORK, false);
272+
PerfMetric metric = PerfMetric.getDefaultInstance();
273+
274+
// clock is 0, token count starts at 2, none should be replenished
275+
assertThat(limiter.check(metric)).isTrue();
276+
assertThat(limiter.check(metric)).isTrue();
277+
assertThat(limiter.check(metric)).isFalse();
278+
assertThat(limiter.check(metric)).isFalse();
279+
280+
// clock is 1 second, 2 events should be allowed within the second due to capacity cap
281+
currentTime = currentTime.plusSeconds(1);
282+
assertThat(limiter.check(metric)).isTrue();
283+
assertThat(limiter.check(metric)).isTrue();
284+
assertThat(limiter.check(metric)).isFalse();
285+
assertThat(limiter.check(metric)).isFalse();
286+
287+
// the first burst has finished, and there are 1 event per second for the next 3 seconds
288+
currentTime = currentTime.plusSeconds(1);
289+
assertThat(limiter.check(metric)).isTrue();
290+
currentTime = currentTime.plusSeconds(1);
291+
assertThat(limiter.check(metric)).isTrue();
292+
currentTime = currentTime.plusSeconds(1);
293+
assertThat(limiter.check(metric)).isTrue();
294+
295+
// the second burst is here, but only capacity = 2 events are allowed
296+
currentTime = currentTime.plusSeconds(10);
297+
assertThat(limiter.check(metric)).isTrue();
298+
assertThat(limiter.check(metric)).isTrue();
299+
assertThat(limiter.check(metric)).isFalse();
300+
assertThat(limiter.check(metric)).isFalse();
301+
}
302+
209303
/**
210304
* Inside class RateLimiter, there is one RateLimiterImpl instance for TraceMetric object, and one
211305
* RateLimiterImpl instance for NetworkRequestMetric object, each RateLimiterImpl instance is a

0 commit comments

Comments
 (0)