private RequestLimitRule toLimitRule(Rate rate) { return RequestLimitRule.of(Duration.ofMillis(rate.timeUnit().toMillis(rate.duration())), rate.limit()); } }
@Test @DisplayName("should encode limit rule in JSON array") void shouldEncode() { ImmutableList<RequestLimitRule> rules = ImmutableList.of(RequestLimitRule.of(Duration.ofSeconds(10), 10L), RequestLimitRule.of(Duration.ofMinutes(1), 20L)); assertThat(serialiser.encode(rules)).isEqualTo("[[10,10,10],[60,20,60]]"); }
@Test void shouldReturnTheSameInstanceForSameSetOfRules() { RequestLimitRule rule1a = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestLimitRule rule1b = RequestLimitRule.of(Duration.ofHours(1), 100); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1a, rule1b)); RequestLimitRule rule2a = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestLimitRule rule2b = RequestLimitRule.of(Duration.ofHours(1), 100); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2a, rule2b)); assertThat(rateLimiter1).isSameAs(rateLimiter2); }
@Test void shouldReturnTheSameInstanceForSameSetOfRules() { RequestLimitRule rule1a = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestLimitRule rule1b = RequestLimitRule.of(Duration.ofHours(1), 100); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1a, rule1b)); RequestLimitRule rule2a = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestLimitRule rule2b = RequestLimitRule.of(Duration.ofHours(1), 100); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2a, rule2b)); assertThat(rateLimiter1).isSameAs(rateLimiter2); }
@Test void shouldNotReturnTheSameInstanceForSameRules() { RequestLimitRule rule1 = RequestLimitRule.of(Duration.ofMinutes(1), 22); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1)); RequestLimitRule rule2 = RequestLimitRule.of(Duration.ofMinutes(1), 33); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2)); assertThat(rateLimiter1).isNotSameAs(rateLimiter2); } }
@Test void shouldHaveDuration60Seconds() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofMinutes(1), 5); assertThat(requestLimitRule.getDurationSeconds()).isEqualTo(60); }
@Test void shouldHaveLimit5() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofMinutes(1), 5); assertThat(requestLimitRule.getLimit()).isEqualTo(5); }
@Test void shouldHaveDuration1Seconds() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofSeconds(1), 5); assertThat(requestLimitRule.getDurationSeconds()).isEqualTo(1); }
@Test void shouldDefaultPrecisionToEqualDuration() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofMinutes(1), 5); assertThat(requestLimitRule.getPrecision()).isEqualTo(60); }
@Test void shouldReturnTheSameInstanceForSameRules() { RequestLimitRule rule1 = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1)); RequestLimitRule rule2 = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2)); assertThat(rateLimiter1).isSameAs(rateLimiter2); }
@Test void shouldReturnTheSameInstanceForSameRules() { RequestLimitRule rule1 = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1)); RequestLimitRule rule2 = RequestLimitRule.of(Duration.ofMinutes(1), 10); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2)); assertThat(rateLimiter1).isSameAs(rateLimiter2); }
@Test void shouldNotReturnTheSameInstanceForSameRules() { RequestLimitRule rule1 = RequestLimitRule.of(Duration.ofMinutes(1), 22); RequestRateLimiter rateLimiter1 = factory.getInstance(ImmutableSet.of(rule1)); RequestLimitRule rule2 = RequestLimitRule.of(Duration.ofMinutes(1), 33); RequestRateLimiter rateLimiter2 = factory.getInstance(ImmutableSet.of(rule2)); assertThat(rateLimiter1).isNotSameAs(rateLimiter2); } }
@Test public void shouldHaveLimitGreaterThanZero() { assertThatThrownBy(() -> RequestLimitRule.of(Duration.ofSeconds(1), -1).withName("boom")).isInstanceOf(IllegalArgumentException.class); }
@Test @DisplayName("should encode limit rule with precision in JSON array") void shouldEncodeWithPrecisions() { ImmutableList<RequestLimitRule> rules = ImmutableList.of(RequestLimitRule.of(Duration.ofSeconds(10), 10L).withPrecision(4), RequestLimitRule.of(Duration.ofMinutes(1), 20L).withPrecision(8)); assertThat(serialiser.encode(rules)).isEqualTo("[[10,10,4],[60,20,8]]"); }
DefaultRequestLimitRulesSupplierTest() { allRules.add(RequestLimitRule.of(Duration.ofSeconds(1), 10).withName("localhostPerSeconds") .matchingKeys("localhost", "127.0.0.1")); allRules.add(RequestLimitRule.of(Duration.ofHours(1), 2000).withName("localhostPerHours") .matchingKeys("localhost", "127.0.0.1")); allRules.add(RequestLimitRule.of(Duration.ofSeconds(1), 5).withName("perSeconds")); allRules.add(RequestLimitRule.of(Duration.ofHours(1), 1000).withName("perHours")); requestLimitRulesSupplier = new DefaultRequestLimitRulesSupplier(allRules); }
@Test void shouldHavePrecisionOf10() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofSeconds(1), 5).withPrecision(10); assertThat(requestLimitRule.getPrecision()).isEqualTo(10); }
@Test void shouldHaveNameOfBoom() { RequestLimitRule requestLimitRule = RequestLimitRule.of(Duration.ofSeconds(1), 5).withName("boom"); assertThat(requestLimitRule.getName()).isEqualTo("boom"); }
@Test void shouldReloadMissingScript() { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(60), 1)); ReactiveRequestRateLimiter rateLimiter = getRateLimiter(rules, new SystemTimeSupplier()); rateLimiter.overLimitWhenIncrementedReactive(UUID.randomUUID().toString()).block(Duration.ofSeconds(5)); getRedisScriptingReactiveCommands().scriptFlush().block(); rateLimiter.overLimitWhenIncrementedReactive(UUID.randomUUID().toString()).block(Duration.ofSeconds(5)); } }
@Test @Disabled void shouldEventuallyCleanUpExpiredKeys() throws Exception { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(1), 5)); RequestRateLimiter requestRateLimiter = getRateLimiter(rules, timeBandit); String key = "ip:127.0.0.5"; IntStream.rangeClosed(1, 5).forEach(value -> { timeBandit.addUnixTimeMilliSeconds(100L); assertThat(requestRateLimiter.overLimitWhenIncremented(key)).isFalse(); }); while (expiryingKeyMap.size() != 0) { Thread.sleep(50); } assertThat(expiryingKeyMap.size()).isZero(); }
@Test void shouldRetryWhenScriptIfFlushed() { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(10), 5)); RedisSlidingWindowRequestRateLimiter requestRateLimiter = new RedisSlidingWindowRequestRateLimiter(extension.getScriptingReactiveCommands(), extension.getKeyReactiveCommands(), rules); assertThat(requestRateLimiter.overLimitWhenIncremented("ip:127.0.1.1")).isFalse(); extension.getScriptingReactiveCommands().scriptFlush().block(); requestRateLimiter.overLimitWhenIncremented("ip:127.0.1.1"); } }