Skip to content

Commit 37d3ca2

Browse files
authored
HeapBasedRateTracker uses time provider to allow simluating of time in unit tests (#3934)
Signed-off-by: Peter Nied <petern@amazon.com>
1 parent fdfe087 commit 37d3ca2

2 files changed

Lines changed: 24 additions & 13 deletions

File tree

src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
package org.opensearch.security.util.ratetracking;
1919

2020
import java.util.Arrays;
21+
import java.util.Optional;
2122
import java.util.concurrent.ExecutionException;
2223
import java.util.concurrent.TimeUnit;
24+
import java.util.function.LongSupplier;
2325

2426
import com.google.common.cache.Cache;
2527
import com.google.common.cache.CacheBuilder;
@@ -33,16 +35,22 @@ public class HeapBasedRateTracker<ClientIdType> implements RateTracker<ClientIdT
3335
private final Logger log = LogManager.getLogger(this.getClass());
3436

3537
private final Cache<ClientIdType, ClientRecord> cache;
38+
private final LongSupplier timeProvider;
3639
private final long timeWindowMs;
3740
private final int maxTimeOffsets;
3841

3942
public HeapBasedRateTracker(long timeWindowMs, int allowedTries, int maxEntries) {
43+
this(timeWindowMs, allowedTries, maxEntries, null);
44+
}
45+
46+
public HeapBasedRateTracker(long timeWindowMs, int allowedTries, int maxEntries, LongSupplier timeProvider) {
4047
if (allowedTries < 2) {
4148
throw new IllegalArgumentException("allowedTries must be >= 2");
4249
}
4350

4451
this.timeWindowMs = timeWindowMs;
4552
this.maxTimeOffsets = allowedTries > 2 ? allowedTries - 2 : 0;
53+
this.timeProvider = Optional.ofNullable(timeProvider).orElse(System::currentTimeMillis);
4654
this.cache = CacheBuilder.newBuilder()
4755
.expireAfterAccess(this.timeWindowMs, TimeUnit.MILLISECONDS)
4856
.maximumSize(maxEntries)
@@ -89,7 +97,7 @@ private class ClientRecord {
8997
private short timeOffsetEnd = -1;
9098

9199
synchronized boolean track() {
92-
long timestamp = System.currentTimeMillis();
100+
long timestamp = timeProvider.getAsLong();
93101

94102
if (this.startTime == -1 || timestamp - getMostRecent() >= timeWindowMs) {
95103
this.startTime = timestamp;

src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
package org.opensearch.security.auth.limiting;
1919

20-
import org.junit.Ignore;
20+
import java.util.concurrent.atomic.AtomicLong;
21+
import java.util.function.LongSupplier;
22+
2123
import org.junit.Test;
2224

2325
import org.opensearch.security.util.ratetracking.HeapBasedRateTracker;
@@ -27,9 +29,12 @@
2729

2830
public class HeapBasedRateTrackerTest {
2931

32+
private final AtomicLong currentTime = new AtomicLong(1);
33+
private LongSupplier timeProvider = () -> currentTime.getAndAdd(1);
34+
3035
@Test
3136
public void simpleTest() throws Exception {
32-
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 5, 100_000);
37+
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 5, 100_000, timeProvider);
3338

3439
assertFalse(tracker.track("a"));
3540
assertFalse(tracker.track("a"));
@@ -40,9 +45,8 @@ public void simpleTest() throws Exception {
4045
}
4146

4247
@Test
43-
@Ignore // https://github.com/opensearch-project/security/issues/2193
4448
public void expiryTest() throws Exception {
45-
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 5, 100_000);
49+
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 5, 100_000, timeProvider);
4650

4751
assertFalse(tracker.track("a"));
4852
assertFalse(tracker.track("a"));
@@ -58,42 +62,41 @@ public void expiryTest() throws Exception {
5862

5963
assertFalse(tracker.track("c"));
6064

61-
Thread.sleep(50);
65+
currentTime.addAndGet(50);
6266

6367
assertFalse(tracker.track("c"));
6468
assertFalse(tracker.track("c"));
6569
assertFalse(tracker.track("c"));
6670

67-
Thread.sleep(55);
71+
currentTime.addAndGet(55);
6872

6973
assertFalse(tracker.track("c"));
7074
assertTrue(tracker.track("c"));
7175

7276
assertFalse(tracker.track("a"));
7377

74-
Thread.sleep(55);
78+
currentTime.addAndGet(55);
7579
assertFalse(tracker.track("c"));
7680
assertFalse(tracker.track("c"));
7781
assertTrue(tracker.track("c"));
7882

7983
}
8084

8185
@Test
82-
@Ignore // https://github.com/opensearch-project/security/issues/2193
8386
public void maxTwoTriesTest() throws Exception {
84-
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 2, 100_000);
87+
HeapBasedRateTracker<String> tracker = new HeapBasedRateTracker<>(100, 2, 100_000, timeProvider);
8588

8689
assertFalse(tracker.track("a"));
8790
assertTrue(tracker.track("a"));
8891

8992
assertFalse(tracker.track("b"));
90-
Thread.sleep(50);
93+
currentTime.addAndGet(50);
9194
assertTrue(tracker.track("b"));
9295

93-
Thread.sleep(55);
96+
currentTime.addAndGet(55);
9497
assertTrue(tracker.track("b"));
9598

96-
Thread.sleep(105);
99+
currentTime.addAndGet(105);
97100
assertFalse(tracker.track("b"));
98101
assertTrue(tracker.track("b"));
99102

0 commit comments

Comments
 (0)