Skip to content

Commit

Permalink
Refine tests involving async caching support.
Browse files Browse the repository at this point in the history
Closes #2741
  • Loading branch information
jxblum committed Oct 18, 2023
1 parent d499c7c commit 1f97357
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@
*/
package org.springframework.data.redis.cache;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.time.Duration;

Expand All @@ -26,8 +32,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.redis.connection.ReactiveRedisConnection;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;

import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStringCommands;
Expand All @@ -41,33 +46,25 @@
@ExtendWith(MockitoExtension.class)
class DefaultRedisCacheWriterUnitTests {

@Mock private CacheStatisticsCollector mockCacheStatisticsCollector = mock(CacheStatisticsCollector.class);

@Mock private RedisConnection mockConnection;
@Mock
private CacheStatisticsCollector mockCacheStatisticsCollector = mock(CacheStatisticsCollector.class);

@Mock(strictness = Mock.Strictness.LENIENT) private RedisConnectionFactory mockConnectionFactory;
@Mock
private RedisConnection mockConnection;

@Mock private ReactiveRedisConnection mockReactiveConnection;

@Mock(strictness = Mock.Strictness.LENIENT) private TestReactiveRedisConnectionFactory mockReactiveConnectionFactory;
@Mock(strictness = Mock.Strictness.LENIENT)
private RedisConnectionFactory mockConnectionFactory;

@BeforeEach
void setup() {
doReturn(this.mockConnection).when(this.mockConnectionFactory).getConnection();
doReturn(this.mockConnection).when(this.mockReactiveConnectionFactory).getConnection();
doReturn(this.mockReactiveConnection).when(this.mockReactiveConnectionFactory).getReactiveConnection();
}

private RedisCacheWriter newRedisCacheWriter() {
return spy(new DefaultRedisCacheWriter(this.mockConnectionFactory, mock(BatchStrategy.class))
.withStatisticsCollector(this.mockCacheStatisticsCollector));
}

private RedisCacheWriter newReactiveRedisCacheWriter() {
return spy(new DefaultRedisCacheWriter(this.mockReactiveConnectionFactory, Duration.ZERO, mock(BatchStrategy.class))
.withStatisticsCollector(this.mockCacheStatisticsCollector));
}

@Test // GH-2351
void getWithNonNullTtl() {

Expand All @@ -86,9 +83,9 @@ void getWithNonNullTtl() {

assertThat(cacheWriter.get("TestCache", key, ttl)).isEqualTo(value);

verify(this.mockConnection).stringCommands();
verify(mockStringCommands).getEx(eq(key), eq(expiration));
verify(this.mockConnection).close();
verify(this.mockConnection, times(1)).stringCommands();
verify(mockStringCommands, times(1)).getEx(eq(key), eq(expiration));
verify(this.mockConnection, times(1)).close();
verifyNoMoreInteractions(this.mockConnection, mockStringCommands);
}

Expand All @@ -107,12 +104,9 @@ void getWithNullTtl() {

assertThat(cacheWriter.get("TestCache", key, null)).isEqualTo(value);

verify(this.mockConnection).stringCommands();
verify(mockStringCommands).get(eq(key));
verify(this.mockConnection).close();
verify(this.mockConnection, times(1)).stringCommands();
verify(mockStringCommands, times(1)).get(eq(key));
verify(this.mockConnection, times(1)).close();
verifyNoMoreInteractions(this.mockConnection, mockStringCommands);
}

interface TestReactiveRedisConnectionFactory extends ReactiveRedisConnectionFactory, RedisConnectionFactory {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
*/
package org.springframework.data.redis.cache;

import static org.assertj.core.api.Assertions.*;
import static org.awaitility.Awaitility.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.awaitility.Awaitility.await;

import io.netty.util.concurrent.DefaultThreadFactory;

Expand Down Expand Up @@ -573,10 +575,16 @@ void cacheGetWithTimeToIdleExpirationAfterEntryExpiresShouldReturnNull() {
void retrieveCacheValueUsingJedis() {

assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(() -> this.cache.retrieve(this.binaryCacheKey)).withMessageContaining("RedisCache");
.isThrownBy(() -> this.cache.retrieve(this.binaryCacheKey))
.withMessageContaining("RedisCache");
}

@ParameterizedRedisTest // GH-2650
@EnabledOnRedisDriver(RedisDriver.JEDIS)
void retrieveLoadedValueUsingJedis() {

assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(() -> this.cache.retrieve(this.binaryCacheKey, () -> CompletableFuture.completedFuture("TEST")))
.isThrownBy(() -> this.cache.retrieve(this.binaryCacheKey, () -> usingCompletedFuture("TEST")))
.withMessageContaining("RedisCache");
}

Expand Down Expand Up @@ -611,9 +619,11 @@ void retrieveReturnsCachedValueWhenLockIsReleased() throws Exception {
usingRedisCacheConfiguration());

DefaultRedisCacheWriter cacheWriter = (DefaultRedisCacheWriter) cache.getCacheWriter();

cacheWriter.lock("cache");

CompletableFuture<String> value = (CompletableFuture<String>) cache.retrieve(this.key);

assertThat(value).isNotDone();

cacheWriter.unlock("cache");
Expand All @@ -626,11 +636,12 @@ void retrieveReturnsCachedValueWhenLockIsReleased() throws Exception {
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void retrieveReturnsLoadedValue() throws Exception {

RedisCache cache = new RedisCache("cache", usingLockingRedisCacheWriter(), usingRedisCacheConfiguration());
AtomicBoolean loaded = new AtomicBoolean(false);
Person jon = new Person("Jon", Date.from(Instant.now()));
CompletableFuture<Person> valueLoader = CompletableFuture.completedFuture(jon);

RedisCache cache = new RedisCache("cache", usingLockingRedisCacheWriter(), usingRedisCacheConfiguration());

Supplier<CompletableFuture<Person>> valueLoaderSupplier = () -> {
loaded.set(true);
return valueLoader;
Expand All @@ -648,15 +659,15 @@ void retrieveReturnsLoadedValue() throws Exception {
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void retrieveStoresLoadedValue() throws Exception {

RedisCache cache = new RedisCache("cache", usingLockingRedisCacheWriter(), usingRedisCacheConfiguration());
Person jon = new Person("Jon", Date.from(Instant.now()));
Supplier<CompletableFuture<Person>> valueLoaderSupplier = () -> CompletableFuture.completedFuture(jon);

RedisCache cache = new RedisCache("cache", usingLockingRedisCacheWriter(), usingRedisCacheConfiguration());

cache.retrieve(this.key, valueLoaderSupplier).get();

doWithConnection(
connection -> assertThat(connection.keyCommands().exists("cache::key-1".getBytes(StandardCharsets.UTF_8)))
.isTrue());
doWithConnection(connection ->
assertThat(connection.keyCommands().exists("cache::key-1".getBytes(StandardCharsets.UTF_8))).isTrue());
}

@ParameterizedRedisTest // GH-2650
Expand All @@ -674,6 +685,10 @@ void retrieveReturnsNull() throws Exception {
assertThat(value).isDone();
}

private <T> CompletableFuture<T> usingCompletedFuture(T value) {
return CompletableFuture.completedFuture(value);
}

private RedisCacheConfiguration usingRedisCacheConfiguration() {
return usingRedisCacheConfiguration(Function.identity());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@
*/
package org.springframework.data.redis.cache;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.util.concurrent.CompletableFuture;

Expand All @@ -33,16 +40,18 @@
class RedisCacheUnitTests {

@Test // GH-2650
@SuppressWarnings("unchecked")
void cacheRetrieveValueCallsCacheWriterRetrieveCorrectly() throws Exception {

RedisCacheWriter mockCacheWriter = mock(RedisCacheWriter.class);

when(mockCacheWriter.supportsAsyncRetrieve()).thenReturn(true);
when(mockCacheWriter.retrieve(anyString(), any(byte[].class)))
.thenReturn(CompletableFuture.completedFuture("TEST".getBytes()));
doReturn(true).when(mockCacheWriter).supportsAsyncRetrieve();
doReturn(usingCompletedFuture("TEST".getBytes())).when(mockCacheWriter).retrieve(anyString(), any(byte[].class));

RedisCache cache = new RedisCache("TestCache", mockCacheWriter,
RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(SerializationPair.byteArray()));
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(SerializationPair.byteArray());

RedisCache cache = new RedisCache("TestCache", mockCacheWriter, cacheConfiguration);

CompletableFuture<byte[]> value = (CompletableFuture<byte[]>) cache.retrieve("TestKey");

Expand All @@ -54,4 +63,7 @@ void cacheRetrieveValueCallsCacheWriterRetrieveCorrectly() throws Exception {
verifyNoMoreInteractions(mockCacheWriter);
}

private <T> CompletableFuture<T> usingCompletedFuture(T value) {
return CompletableFuture.completedFuture(value);
}
}

0 comments on commit 1f97357

Please sign in to comment.