Skip to content

Commit ab2665f

Browse files
Bouncheckdkropachev
authored andcommitted
Stabilize will_cache_invalid_cql test method.
The main issue is that it uses `cache.size()`. While it may not be a bad idea to use that, the documentation mentions that it returns an approximate size of the cache. `CqlPrepareAsyncProcessor` actually invalidates the prepare requests that finish with errors (see `process` method). Such is the case with this test. The `PreparedStatement` gets cached for a really short period and then invalidated because of the exception. Depending on the exact timings it would be correct for the cache to report either size 0 or size 1. Additionally the moment when the size gets updated may differ from the moments modifications to the cache contents are made. This change is a quick workaround that should achieve the same end result as the setup in PreparedStatementCachingIT. Here we use reflection to forcibly change the cache used by the request processor. Same type, but has removal listener added to it. Instead of relying on the uncertain cache size the test will listen for the removal from the cache. The alternative would be reimplementing similar setup as in PreparedStatementCachingIT with some changes. That means having a test version of DefaultDriverContext, CqlPrepareAsyncProcessor, SessionBuilder and necessary methods, so that we could inject the listener without the reflection. The other option is moving this test method to the PreparedStatementCachingIT, but then the cache's remove callback which is used there throughout the class needs to be adjusted specifically for this method.
1 parent 0a00189 commit ab2665f

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementCancellationIT.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@
3131
import com.datastax.oss.driver.internal.core.cql.CqlPrepareAsyncProcessor;
3232
import com.datastax.oss.driver.shaded.guava.common.base.Predicates;
3333
import com.datastax.oss.driver.shaded.guava.common.cache.Cache;
34+
import com.datastax.oss.driver.shaded.guava.common.cache.CacheBuilder;
3435
import com.datastax.oss.driver.shaded.guava.common.collect.Iterables;
36+
import java.lang.reflect.Field;
3537
import java.util.concurrent.CompletableFuture;
38+
import java.util.concurrent.TimeUnit;
39+
import java.util.concurrent.atomic.AtomicInteger;
40+
import org.awaitility.Awaitility;
3641
import org.junit.After;
3742
import org.junit.Before;
3843
import org.junit.Rule;
@@ -118,6 +123,20 @@ public void will_cache_invalid_cql() throws Exception {
118123

119124
CqlSession session = SessionUtils.newSession(ccmRule, sessionRule.keyspace());
120125
CqlPrepareAsyncProcessor processor = findProcessor(session);
126+
AtomicInteger removals = new AtomicInteger();
127+
128+
// Forcibly replace the cache with one that has a removal listener
129+
Field cacheField = CqlPrepareAsyncProcessor.class.getDeclaredField("cache");
130+
cacheField.setAccessible(true);
131+
Cache<PrepareRequest, CompletableFuture<PreparedStatement>> newCache =
132+
CacheBuilder.newBuilder()
133+
.removalListener(
134+
(evt) -> {
135+
removals.incrementAndGet();
136+
})
137+
.weakValues()
138+
.build();
139+
cacheField.set(processor, newCache);
121140
Cache<PrepareRequest, CompletableFuture<PreparedStatement>> cache = processor.getCache();
122141
assertThat(cache.size()).isEqualTo(0);
123142

@@ -133,8 +152,9 @@ public void will_cache_invalid_cql() throws Exception {
133152
fail();
134153
} catch (Exception e) {
135154
}
136-
137-
assertThat(cache.size()).isEqualTo(1);
155+
cache.cleanUp();
156+
// If an entry was evicted, it had to be cached first
157+
Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> removals.get() == 1);
138158
}
139159

140160
@Test

0 commit comments

Comments
 (0)