Skip to content

Commit 3a92e98

Browse files
Add unit tests for byte-capacity cache
1 parent 9f6b995 commit 3a92e98

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpCache.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ static <V> GeoIpCache createGeoIpCacheWithMaxCount(long maxSize) {
4545
return new GeoIpCache(System::nanoTime, CacheBuilder.<CacheKey, CacheableValue>builder().setMaximumWeight(maxSize).build());
4646
}
4747

48-
// TODO PETE: Add tests for this
4948
// TODO PETE: Make plugin use this instead of the other factory method when the settings require it
5049
static GeoIpCache createGeoIpCacheWithMaxBytes(ByteSizeValue maxByteSize) {
5150
if (maxByteSize.getBytes() < 0) {
@@ -168,8 +167,13 @@ private record CacheKey(String ip, String databasePath) {
168167

169168
private static final long BASE_BYTES = RamUsageEstimator.shallowSizeOfInstance(CacheKey.class);
170169

171-
public long sizeInBytes() {
172-
return BASE_BYTES + RamUsageEstimator.sizeOf(ip) + RamUsageEstimator.sizeOf(databasePath);
170+
private long sizeInBytes() {
171+
return keySizeInBytes(ip, databasePath);
173172
}
174173
}
174+
175+
// visible for testing
176+
static long keySizeInBytes(String ip, String databasePath) {
177+
return CacheKey.BASE_BYTES + RamUsageEstimator.sizeOf(ip) + RamUsageEstimator.sizeOf(databasePath);
178+
}
175179
}

modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpCacheTests.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
package org.elasticsearch.ingest.geoip;
1111

12+
import org.elasticsearch.common.unit.ByteSizeValue;
1213
import org.elasticsearch.core.TimeValue;
1314
import org.elasticsearch.ingest.geoip.stats.CacheStats;
1415
import org.elasticsearch.test.ESTestCase;
@@ -18,17 +19,18 @@
1819
import java.util.function.Function;
1920

2021
import static org.hamcrest.Matchers.equalTo;
21-
import static org.mockito.Mockito.mock;
2222

2323
public class GeoIpCacheTests extends ESTestCase {
2424

25-
public void testCachesAndEvictsResults() {
25+
private record FakeResponse(long sizeInBytes) implements GeoIpCache.CacheableValue {}
26+
27+
public void testCachesAndEvictsResults_maxCount() {
2628
GeoIpCache cache = GeoIpCache.createGeoIpCacheWithMaxCount(1);
27-
GeoIpCache.CacheableValue response1 = mock(GeoIpCache.CacheableValue.class);
28-
GeoIpCache.CacheableValue response2 = mock(GeoIpCache.CacheableValue.class);
29+
FakeResponse response1 = new FakeResponse(0);
30+
FakeResponse response2 = new FakeResponse(0);
2931

3032
// add a key
31-
GeoIpCache.CacheableValue cachedResponse = cache.putIfAbsent("127.0.0.1", "path/to/db", ip -> response1);
33+
FakeResponse cachedResponse = cache.putIfAbsent("127.0.0.1", "path/to/db", ip -> response1);
3234
assertSame(cachedResponse, response1);
3335
assertSame(cachedResponse, cache.putIfAbsent("127.0.0.1", "path/to/db", ip -> response1));
3436
assertSame(cachedResponse, cache.get("127.0.0.1", "path/to/db"));
@@ -41,15 +43,42 @@ public void testCachesAndEvictsResults() {
4143
assertNotSame(response1, cache.get("127.0.0.1", "path/to/db"));
4244
}
4345

46+
public void testCachesAndEvictsResults_maxBytes() {
47+
String ip1 = "127.0.0.1";
48+
String databasePath1 = "path/to/db";
49+
FakeResponse response1 = new FakeResponse(111);
50+
String ip2 = "127.0.0.2";
51+
String databasePath2 = "path/to/db";
52+
FakeResponse response2 = new FakeResponse(222);
53+
long totalSize = GeoIpCache.keySizeInBytes(ip1, databasePath1) + response1.sizeInBytes() + GeoIpCache.keySizeInBytes(
54+
ip2,
55+
databasePath2
56+
) + response2.sizeInBytes();
57+
58+
GeoIpCache justBigEnoughCache = GeoIpCache.createGeoIpCacheWithMaxBytes(ByteSizeValue.ofBytes(totalSize));
59+
justBigEnoughCache.putIfAbsent(ip1, databasePath1, ip -> response1);
60+
justBigEnoughCache.putIfAbsent(ip2, databasePath2, ip -> response2);
61+
// Cache is just big enough for both values:
62+
assertSame(response2, justBigEnoughCache.get(ip2, databasePath2));
63+
assertSame(response1, justBigEnoughCache.get(ip1, databasePath1));
64+
65+
GeoIpCache justTooSmallCache = GeoIpCache.createGeoIpCacheWithMaxBytes(ByteSizeValue.ofBytes(totalSize - 1L));
66+
justTooSmallCache.putIfAbsent(ip1, databasePath1, ip -> response1);
67+
justTooSmallCache.putIfAbsent(ip2, databasePath2, ip -> response2);
68+
// Cache is just too small for both values, so the older one should have been evicted:
69+
assertSame(response2, justTooSmallCache.get(ip2, databasePath2));
70+
assertNull(justTooSmallCache.get(ip1, databasePath1));
71+
}
72+
4473
public void testCachesNoResult() {
4574
GeoIpCache cache = GeoIpCache.createGeoIpCacheWithMaxCount(1);
4675
final AtomicInteger count = new AtomicInteger(0);
47-
Function<String, GeoIpCache.CacheableValue> countAndReturnNull = (ip) -> {
76+
Function<String, FakeResponse> countAndReturnNull = (ip) -> {
4877
count.incrementAndGet();
4978
return null;
5079
};
5180

52-
GeoIpCache.CacheableValue response = cache.putIfAbsent("127.0.0.1", "path/to/db", countAndReturnNull);
81+
FakeResponse response = cache.putIfAbsent("127.0.0.1", "path/to/db", countAndReturnNull);
5382
assertNull(response);
5483
assertNull(cache.putIfAbsent("127.0.0.1", "path/to/db", countAndReturnNull));
5584
assertEquals(1, count.get());
@@ -60,8 +89,8 @@ public void testCachesNoResult() {
6089

6190
public void testCacheKey() {
6291
GeoIpCache cache = GeoIpCache.createGeoIpCacheWithMaxCount(2);
63-
GeoIpCache.CacheableValue response1 = mock(GeoIpCache.CacheableValue.class);
64-
GeoIpCache.CacheableValue response2 = mock(GeoIpCache.CacheableValue.class);
92+
FakeResponse response1 = new FakeResponse(0);
93+
FakeResponse response2 = new FakeResponse(0);
6594

6695
assertSame(response1, cache.putIfAbsent("127.0.0.1", "path/to/db1", ip -> response1));
6796
assertSame(response2, cache.putIfAbsent("127.0.0.1", "path/to/db2", ip -> response2));
@@ -93,7 +122,7 @@ public void testGetCacheStats() {
93122
maxCacheSize,
94123
() -> testNanoTime.addAndGet(TimeValue.timeValueMillis(1).getNanos())
95124
);
96-
GeoIpCache.CacheableValue response = mock(GeoIpCache.CacheableValue.class);
125+
FakeResponse response = new FakeResponse(0);
97126
String databasePath = "path/to/db1";
98127
String key1 = "127.0.0.1";
99128
String key2 = "127.0.0.2";

0 commit comments

Comments
 (0)