diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java index b0469ffc8..78ffeb756 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java @@ -43,7 +43,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range.Bound; @@ -119,7 +118,7 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests { } @BeforeEach - void tearDown() throws IOException { + void beforeEach() throws IOException { for (ConnectionPool pool : nativeConnection.getClusterNodes().values()) { try (Jedis jedis = new Jedis(pool.getResource())) { diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/extension/JedisConnectionFactoryExtension.java b/src/test/java/org/springframework/data/redis/connection/jedis/extension/JedisConnectionFactoryExtension.java index 133a903f0..bba8ce1fb 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/extension/JedisConnectionFactoryExtension.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/extension/JedisConnectionFactoryExtension.java @@ -16,6 +16,7 @@ package org.springframework.data.redis.connection.jedis.extension; import java.io.Closeable; +import java.io.IOException; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; @@ -25,7 +26,6 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; - import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.connection.RedisClusterConfiguration; @@ -64,7 +64,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver { CLIENT_CONFIGURATION); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); @@ -75,7 +75,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver { CLIENT_CONFIGURATION); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); @@ -86,7 +86,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver { CLIENT_CONFIGURATION); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); @@ -171,7 +171,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver { } static class ManagedJedisConnectionFactory extends JedisConnectionFactory - implements ConnectionFactoryTracker.Managed { + implements ConnectionFactoryTracker.Managed, Closeable { private volatile boolean mayClose; @@ -219,15 +219,14 @@ public class JedisConnectionFactoryExtension implements ParameterResolver { return builder.toString(); } - Closeable toCloseable() { - return () -> { - try { - mayClose = true; - destroy(); - } catch (Exception e) { - e.printStackTrace(); - } - }; + @Override + public void close() throws IOException { + try { + mayClose = true; + destroy(); + } catch (Exception e) { + e.printStackTrace(); + } } } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceAclIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceAclIntegrationTests.java index 7eec02fcb..612ed0919 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceAclIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceAclIntegrationTests.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.util.Collections; import org.junit.jupiter.api.Test; - import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.RedisSentinelConnection; @@ -88,8 +87,7 @@ class LettuceAclIntegrationTests { // Note: As per https://github.com/redis/redis/issues/7708, Sentinel does not support ACL authentication yet. - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()) + LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder() .clientOptions(ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build()).build(); RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("mymaster", diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java index 0f2ad5154..59f5bc608 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java @@ -41,7 +41,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range.Bound; @@ -144,6 +143,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests { LettucePoolingClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() // .clientResources(LettuceTestClientResources.getSharedClientResources()) // .shutdownTimeout(Duration.ZERO) // + .shutdownQuietPeriod(Duration.ZERO) // .build(); RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java index fea1ebb1b..1be106f79 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java @@ -36,7 +36,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.RedisConnectionFailureException; import org.springframework.data.redis.RedisSystemException; @@ -238,7 +237,6 @@ class LettuceConnectionFactoryTests { .getNativeConnection(); factory.resetConnection(); assertThat(factory.getConnection().getNativeConnection()).isNotSameAs(nativeConn); - nativeConn.getStatefulConnection().close(); } @SuppressWarnings("unchecked") @@ -352,7 +350,8 @@ class LettuceConnectionFactoryTests { GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); LettuceClientConfiguration configuration = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig) - .clientResources(LettuceTestClientResources.getSharedClientResources()).shutdownTimeout(Duration.ZERO).build(); + .clientResources(LettuceTestClientResources.getSharedClientResources()).shutdownTimeout(Duration.ZERO) + .shutdownQuietPeriod(Duration.ZERO).build(); LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), configuration); factory.setShareNativeConnection(false); @@ -431,8 +430,8 @@ class LettuceConnectionFactoryTests { RedisStaticMasterReplicaConfiguration elastiCache = new RedisStaticMasterReplicaConfiguration( SettingsUtils.getHost()).node(SettingsUtils.getHost(), SettingsUtils.getPort() + 1); - LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache); - factory.setClientResources(LettuceTestClientResources.getSharedClientResources()); + LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache, + LettuceTestClientConfiguration.defaultConfiguration()); factory.afterPropertiesSet(); RedisConnection connection = factory.getConnection(); @@ -502,8 +501,8 @@ class LettuceConnectionFactoryTests { @Test // DATAREDIS-576 void connectionAppliesClientName() { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).clientName("clientName").build(); + LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder().clientName("clientName") + .build(); LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), configuration); factory.setShareNativeConnection(false); @@ -536,8 +535,7 @@ class LettuceConnectionFactoryTests { @Test // GH-2186 void shouldInitializeMasterReplicaConnectionsEagerly() { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder().build(); RedisStaticMasterReplicaConfiguration elastiCache = new RedisStaticMasterReplicaConfiguration( SettingsUtils.getHost()).node(SettingsUtils.getHost(), SettingsUtils.getPort() + 1); @@ -557,8 +555,7 @@ class LettuceConnectionFactoryTests { @EnabledOnRedisClusterAvailable void shouldInitializeClusterConnectionsEagerly() { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder().build(); LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.clusterConfiguration(), configuration); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java index 529942d31..2c8356b34 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java @@ -48,7 +48,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; - import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.DisposableBean; import org.springframework.data.redis.ConnectionFactoryTracker; @@ -94,8 +93,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-315 void shouldInitClientCorrectlyWhenClusterConfigPresent() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -128,7 +127,7 @@ class LettuceConnectionFactoryUnitTests { RedisConfiguration redisConfiguration = new RedisStandaloneConfiguration("localhost", 16379); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisConfiguration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPort()).isEqualTo(16379); } @@ -139,7 +138,7 @@ class LettuceConnectionFactoryUnitTests { RedisConfiguration redisConfiguration = new CustomRedisConfiguration("localhost", 16379); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisConfiguration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPort()).isEqualTo(16379); assertThat(connectionFactory.getHostName()).isEqualTo("localhost"); @@ -151,7 +150,7 @@ class LettuceConnectionFactoryUnitTests { RedisConfiguration redisConfiguration = new RedisStandaloneConfiguration("external"); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisConfiguration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getHostName()).isEqualTo("external"); } @@ -162,7 +161,7 @@ class LettuceConnectionFactoryUnitTests { RedisConfiguration redisConfiguration = new CustomRedisConfiguration("external"); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisConfiguration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPort()).isEqualTo(6379); assertThat(connectionFactory.getHostName()).isEqualTo("external"); @@ -172,8 +171,8 @@ class LettuceConnectionFactoryUnitTests { @SuppressWarnings("unchecked") void passwordShouldBeSetCorrectlyOnClusterClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("o_O"); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -195,8 +194,7 @@ class LettuceConnectionFactoryUnitTests { clusterConfig.setUsername("foo"); clusterConfig.setPassword("bar"); - LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() - .clientResources(getSharedClientResources()) + LettuceClientConfiguration clientConfiguration = LettuceTestClientConfiguration.builder() .redisCredentialsProviderFactory(new RedisCredentialsProviderFactory() {}).build(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, clientConfiguration); connectionFactory.afterPropertiesSet(); @@ -223,7 +221,7 @@ class LettuceConnectionFactoryUnitTests { config.setUsername("foo"); config.setPassword("bar"); - LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() + LettuceClientConfiguration clientConfiguration = LettuceTestClientConfiguration.builder() .clientResources(getSharedClientResources()) .redisCredentialsProviderFactory(new RedisCredentialsProviderFactory() {}).build(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config, clientConfiguration); @@ -245,8 +243,8 @@ class LettuceConnectionFactoryUnitTests { void passwordShouldNotBeSetOnSentinelClient() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory( - new RedisSentinelConfiguration("mymaster", Collections.singleton("host:1234"))); - connectionFactory.setClientResources(getSharedClientResources()); + new RedisSentinelConfiguration("mymaster", Collections.singleton("host:1234")), + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("o_O"); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -269,8 +267,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration config = new RedisSentinelConfiguration("mymaster", Collections.singleton("host:1234")); config.setSentinelPassword("sentinel-pwd"); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config, + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("o_O"); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -295,8 +293,7 @@ class LettuceConnectionFactoryUnitTests { config.setPassword("data-pwd"); config.setSentinelPassword("sentinel-pwd"); - LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() - .clientResources(getSharedClientResources()) + LettuceClientConfiguration clientConfiguration = LettuceTestClientConfiguration.builder() .redisCredentialsProviderFactory(new RedisCredentialsProviderFactory() {}).build(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config, clientConfiguration); @@ -328,8 +325,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration config = new RedisSentinelConfiguration("mymaster", Collections.singleton("host:1234")); config.setSentinelPassword("sentinel-pwd"); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config, + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -361,8 +358,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-480 void sslOptionsShouldBeDisabledByDefaultOnClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -382,9 +379,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-476 void sslShouldBeSetCorrectlyOnClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setUseSsl(true); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), + LettuceTestClientConfiguration.builder().useSsl().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -402,9 +398,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-480 void verifyPeerOptionShouldBeSetCorrectlyOnClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setVerifyPeer(false); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), + LettuceTestClientConfiguration.builder().useSsl().disablePeerVerification().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -420,9 +415,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-480 void startTLSOptionShouldBeSetCorrectlyOnClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setStartTls(true); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), + LettuceTestClientConfiguration.builder().useSsl().startTls().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -440,9 +434,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("myMaster", Collections.singleton("localhost:1234")); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setUseSsl(true); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration, + LettuceTestClientConfiguration.builder().useSsl().startTls().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -462,9 +455,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("myMaster", Collections.singleton("localhost:1234")); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setVerifyPeer(false); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration, + LettuceTestClientConfiguration.builder().useSsl().disablePeerVerification().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -482,9 +474,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("myMaster", Collections.singleton("localhost:1234")); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setStartTls(true); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration, + LettuceTestClientConfiguration.builder().useSsl().startTls().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -501,9 +492,8 @@ class LettuceConnectionFactoryUnitTests { void sslShouldBeSetCorrectlyOnClusterClient() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory( - new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1)); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setUseSsl(true); + new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1), + LettuceTestClientConfiguration.builder().useSsl().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -521,9 +511,8 @@ class LettuceConnectionFactoryUnitTests { void startTLSOptionShouldBeSetCorrectlyOnClusterClient() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory( - new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1)); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setStartTls(true); + new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1), + LettuceTestClientConfiguration.builder().useSsl().startTls().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -541,9 +530,8 @@ class LettuceConnectionFactoryUnitTests { void verifyPeerTLSOptionShouldBeSetCorrectlyOnClusterClient() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory( - new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1)); - connectionFactory.setClientResources(getSharedClientResources()); - connectionFactory.setVerifyPeer(true); + new RedisClusterConfiguration().clusterNode(CLUSTER_NODE_1), + LettuceTestClientConfiguration.builder().useSsl().startTls().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -560,8 +548,8 @@ class LettuceConnectionFactoryUnitTests { @Test // DATAREDIS-682 void socketShouldBeSetOnStandaloneClient() { - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisSocketConfiguration()); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisSocketConfiguration(), + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -580,7 +568,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPassword()).isEqualTo("foo"); } @@ -592,7 +580,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("bar"); assertThat(connectionFactory.getPassword()).isEqualTo("bar"); @@ -606,7 +594,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPassword()).isEqualTo("foo"); } @@ -618,7 +606,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("bar"); assertThat(connectionFactory.getPassword()).isEqualTo("bar"); @@ -632,7 +620,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("bar"); assertThat(connectionFactory.getPassword()).isEqualTo("bar"); @@ -646,7 +634,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getPassword()).isEqualTo("foo"); } @@ -658,7 +646,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setPassword(RedisPassword.of("foo")); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("bar"); assertThat(connectionFactory.getPassword()).isEqualTo("bar"); @@ -672,7 +660,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setDatabase(2); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getDatabase()).isEqualTo(2); } @@ -684,7 +672,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setDatabase(2); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setDatabase(3); assertThat(connectionFactory.getDatabase()).isEqualTo(3); @@ -698,7 +686,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setDatabase(2); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getDatabase()).isEqualTo(2); } @@ -710,7 +698,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setDatabase(2); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setDatabase(3); assertThat(connectionFactory.getDatabase()).isEqualTo(3); @@ -724,7 +712,7 @@ class LettuceConnectionFactoryUnitTests { envConfig.setDatabase(2); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setDatabase(3); assertThat(connectionFactory.getDatabase()).isEqualTo(3); @@ -765,7 +753,7 @@ class LettuceConnectionFactoryUnitTests { RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getStandaloneConfiguration()).isEqualTo(configuration); assertThat(connectionFactory.getSentinelConfiguration()).isNull(); @@ -777,7 +765,7 @@ class LettuceConnectionFactoryUnitTests { RedisSocketConfiguration configuration = new RedisSocketConfiguration("/var/redis/socket"); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getStandaloneConfiguration()).isNotNull(); assertThat(connectionFactory.getSocketConfiguration()).isEqualTo(configuration); @@ -790,7 +778,7 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration configuration = new RedisSentinelConfiguration(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getStandaloneConfiguration()).isNotNull(); assertThat(connectionFactory.getSentinelConfiguration()).isEqualTo(configuration); @@ -802,7 +790,7 @@ class LettuceConnectionFactoryUnitTests { RedisClusterConfiguration configuration = new RedisClusterConfiguration(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThat(connectionFactory.getStandaloneConfiguration()).isNotNull(); assertThat(connectionFactory.getSentinelConfiguration()).isNull(); @@ -813,7 +801,7 @@ class LettuceConnectionFactoryUnitTests { void shouldDenyChangesToImmutableClientConfiguration() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), - LettuceClientConfiguration.defaultConfiguration()); + LettuceTestClientConfiguration.defaultConfiguration()); assertThatIllegalStateException().isThrownBy(() -> connectionFactory.setUseSsl(false)); } @@ -839,8 +827,7 @@ class LettuceConnectionFactoryUnitTests { void timeoutSetOnClientConfigShouldBePassedOnToClusterConnection() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, - LettuceClientConfiguration.builder().commandTimeout(Duration.ofSeconds(2)).shutdownTimeout(Duration.ZERO) - .clientResources(getSharedClientResources()).build()); + LettuceTestClientConfiguration.builder().commandTimeout(Duration.ofSeconds(2)).build()); connectionFactory.setShareNativeConnection(false); connectionFactory.afterPropertiesSet(); @@ -861,7 +848,7 @@ class LettuceConnectionFactoryUnitTests { .thenReturn(CompletableFuture.completedFuture(connectionMock)); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, - LettuceClientConfiguration.defaultConfiguration()) { + LettuceTestClientConfiguration.defaultConfiguration()) { @Override protected AbstractRedisClient createClient() { @@ -891,7 +878,7 @@ class LettuceConnectionFactoryUnitTests { when(connectionMock.sync()).thenReturn(syncMock); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, - LettuceClientConfiguration.defaultConfiguration()) { + LettuceTestClientConfiguration.defaultConfiguration()) { @Override protected AbstractRedisClient createClient() { @@ -920,7 +907,7 @@ class LettuceConnectionFactoryUnitTests { when(connectionMock.closeAsync()).thenReturn(CompletableFuture.completedFuture(null)); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfig, - LettuceClientConfiguration.defaultConfiguration()) { + LettuceTestClientConfiguration.defaultConfiguration()) { @Override protected AbstractRedisClient createClient() { @@ -1008,8 +995,8 @@ class LettuceConnectionFactoryUnitTests { RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration("mymaster", Collections.singleton("host:1234")); redisSentinelConfiguration.setDatabase(1); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisSentinelConfiguration); - connectionFactory.setClientResources(getSharedClientResources()); + LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisSentinelConfiguration, + LettuceTestClientConfiguration.defaultConfiguration()); connectionFactory.setPassword("o_O"); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -1029,7 +1016,7 @@ class LettuceConnectionFactoryUnitTests { clusterConfiguration.clusterNode("localhost", 1234).setMaxRedirects(42); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfiguration, - LettuceClientConfiguration.builder().clientResources(getSharedClientResources()).build()); + LettuceTestClientConfiguration.builder().build()); connectionFactory.afterPropertiesSet(); ConnectionFactoryTracker.add(connectionFactory); @@ -1048,9 +1035,9 @@ class LettuceConnectionFactoryUnitTests { RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(); clusterConfiguration.clusterNode("localhost", 1234).setMaxRedirects(42); - LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() + LettuceClientConfiguration clientConfiguration = LettuceTestClientConfiguration.builder() .clientOptions(ClusterClientOptions.builder().validateClusterNodeMembership(false).build()) - .clientResources(getSharedClientResources()).build(); + .build(); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfiguration); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java index fb803caa4..8fc9e52cc 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java @@ -21,12 +21,11 @@ import java.util.Arrays; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.StringRedisConnection; -import org.springframework.data.redis.test.extension.LettuceTestClientResources; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -54,8 +53,8 @@ public class LettuceConnectionPipelineIntegrationTests extends AbstractConnectio actual.add(connection.move("foo", 1)); verifyResults(Arrays.asList(new Object[] { true, true })); // Lettuce does not support select when using shared conn, use a new conn factory - LettuceConnectionFactory factory2 = new LettuceConnectionFactory(); - factory2.setClientResources(LettuceTestClientResources.getSharedClientResources()); + LettuceConnectionFactory factory2 = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), + LettuceTestClientConfiguration.builder().build()); factory2.setDatabase(1); factory2.afterPropertiesSet(); StringRedisConnection conn2 = new DefaultStringRedisConnection(factory2.getConnection()); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestSupport.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestSupport.java index e34612a3b..1ba37c1c4 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestSupport.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.connection.lettuce; +import io.lettuce.core.AbstractRedisClient; import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; @@ -24,14 +25,18 @@ import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; import io.lettuce.core.cluster.api.sync.RedisClusterCommands; import io.lettuce.core.codec.StringCodec; +import java.io.Closeable; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import org.assertj.core.api.Assumptions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.DisposableBean; import org.springframework.data.redis.connection.lettuce.LettuceReactiveRedisConnection.ByteBufferCodec; import org.springframework.data.redis.test.condition.RedisDetector; import org.springframework.data.redis.test.extension.LettuceExtension; @@ -97,37 +102,36 @@ public abstract class LettuceReactiveCommandsTestSupport { List parameters = new ArrayList<>(); StandaloneConnectionProvider standaloneProvider = new StandaloneConnectionProvider( - extension.getInstance(RedisClient.class), - LettuceReactiveRedisConnection.CODEC); + extension.getInstance(RedisClient.class), LettuceReactiveRedisConnection.CODEC); StandaloneConnectionProvider nativeConnectionProvider = new StandaloneConnectionProvider( - extension.getInstance(RedisClient.class), - StringCodec.UTF8); + extension.getInstance(RedisClient.class), StringCodec.UTF8); StandaloneConnectionProvider nativeBinaryConnectionProvider = new StandaloneConnectionProvider( extension.getInstance(RedisClient.class), ByteBufferCodec.INSTANCE); - parameters.add( - new Fixture(standaloneProvider, nativeConnectionProvider, nativeBinaryConnectionProvider, "Standalone")); - parameters.add(new Fixture( - new LettucePoolingConnectionProvider(standaloneProvider, LettucePoolingClientConfiguration.builder().build()), - nativeConnectionProvider, nativeBinaryConnectionProvider, "Pooling")); - + /*parameters + .add(new Fixture(standaloneProvider, nativeConnectionProvider, nativeBinaryConnectionProvider, "Standalone"));*/ + LettucePoolingClientConfiguration poolingClientConfiguration = LettucePoolingClientConfiguration.builder() + .shutdownQuietPeriod(Duration.ZERO).shutdownTimeout(Duration.ZERO).build(); + parameters.add(new Fixture(new LettucePoolingConnectionProvider(standaloneProvider, poolingClientConfiguration), + new LettucePoolingConnectionProvider(nativeConnectionProvider, poolingClientConfiguration), + new LettucePoolingConnectionProvider(nativeBinaryConnectionProvider, poolingClientConfiguration), "Pooling")); ClusterConnectionProvider clusterProvider = new ClusterConnectionProvider( - extension.getInstance(RedisClusterClient.class), - LettuceReactiveRedisConnection.CODEC); + extension.getInstance(RedisClusterClient.class), LettuceReactiveRedisConnection.CODEC); ClusterConnectionProvider nativeClusterConnectionProvider = new ClusterConnectionProvider( - extension.getInstance(RedisClusterClient.class), - StringCodec.UTF8); - ClusterConnectionProvider nativeBinaryClusterConnectionProvider = new ClusterConnectionProvider( - extension.getInstance(RedisClusterClient.class), ByteBufferCodec.INSTANCE); + extension.getInstance(RedisClusterClient.class), StringCodec.UTF8); + ClusterConnectionProvider nativeBinaryClusterConnectionProvider = new ClusterConnectionProvider( + extension.getInstance(RedisClusterClient.class), ByteBufferCodec.INSTANCE); - parameters.add(new Fixture(clusterProvider, nativeClusterConnectionProvider, - nativeBinaryClusterConnectionProvider, "Cluster")); + parameters.add(new Fixture(new LettucePoolingConnectionProvider(clusterProvider, poolingClientConfiguration), + new LettucePoolingConnectionProvider(nativeClusterConnectionProvider, poolingClientConfiguration), + new LettucePoolingConnectionProvider(nativeBinaryClusterConnectionProvider, poolingClientConfiguration), + "Cluster")); return parameters; } - static class Fixture { + static class Fixture implements Closeable { final LettuceConnectionProvider connectionProvider; final LettuceConnectionProvider nativeConnectionProvider; @@ -146,12 +150,34 @@ public abstract class LettuceReactiveCommandsTestSupport { public String toString() { return label; } + + @Override + public void close() throws IOException { + + try { + if (connectionProvider instanceof DisposableBean) { + ((DisposableBean) connectionProvider).destroy(); + } + + if (nativeConnectionProvider instanceof DisposableBean) { + ((DisposableBean) nativeConnectionProvider).destroy(); + } + + if (nativeBinaryConnectionProvider instanceof DisposableBean) { + ((DisposableBean) nativeBinaryConnectionProvider).destroy(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } } @BeforeEach public void setUp() { - if (nativeConnectionProvider instanceof StandaloneConnectionProvider) { + AbstractRedisClient redisClient = ((RedisClientProvider) nativeConnectionProvider).getRedisClient(); + + if (redisClient instanceof RedisClient) { nativeCommands = nativeConnectionProvider.getConnection(StatefulRedisConnection.class).sync(); nativeBinaryCommands = nativeBinaryConnectionProvider.getConnection(StatefulRedisConnection.class).sync(); @@ -160,11 +186,9 @@ public abstract class LettuceReactiveCommandsTestSupport { Assumptions.assumeThat(RedisDetector.isClusterAvailable()).isTrue(); - ClusterConnectionProvider clusterConnectionProvider = (ClusterConnectionProvider) nativeConnectionProvider; nativeCommands = nativeConnectionProvider.getConnection(StatefulRedisClusterConnection.class).sync(); nativeBinaryCommands = nativeBinaryConnectionProvider.getConnection(StatefulRedisClusterConnection.class).sync(); - this.connection = new LettuceReactiveRedisClusterConnection(connectionProvider, - clusterConnectionProvider.getRedisClient()); + this.connection = new LettuceReactiveRedisClusterConnection(connectionProvider, (RedisClusterClient) redisClient); } } @@ -181,6 +205,15 @@ public abstract class LettuceReactiveCommandsTestSupport { if (nativeCommands instanceof RedisAdvancedClusterCommands) { nativeConnectionProvider.release(((RedisAdvancedClusterCommands) nativeCommands).getStatefulConnection()); } + + if (nativeBinaryCommands instanceof RedisCommands) { + nativeBinaryConnectionProvider.release(((RedisCommands) nativeBinaryCommands).getStatefulConnection()); + } + + if (nativeBinaryCommands instanceof RedisAdvancedClusterCommands) { + nativeBinaryConnectionProvider + .release(((RedisAdvancedClusterCommands) nativeBinaryCommands).getStatefulConnection()); + } } if (connection != null) { diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommandsIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommandsIntegrationTests.java index 11638caac..040216b0d 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommandsIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommandsIntegrationTests.java @@ -558,7 +558,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // GH-2041 void zDiffShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); @@ -584,7 +584,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // GH-2041 void zDiffStoreShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); @@ -600,7 +600,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // GH-2042 void zInterShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); @@ -626,7 +626,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // DATAREDIS-525 void zInterStoreShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); @@ -642,7 +642,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // GH-2042 void zUnionShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); @@ -669,7 +669,7 @@ public class LettuceReactiveZSetCommandsIntegrationTests extends LettuceReactive @ParameterizedRedisTest // DATAREDIS-525 void zUnionStoreShouldWorkCorrectly() { - assumeThat(connectionProvider).isInstanceOf(StandaloneConnectionProvider.class); + assumeThat(nativeCommands).isInstanceOf(io.lettuce.core.api.sync.RedisCommands.class); nativeCommands.zadd(KEY_1, 1D, VALUE_1); nativeCommands.zadd(KEY_1, 2D, VALUE_2); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java index c983dd8a5..539138169 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelIntegrationTests.java @@ -28,7 +28,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; @@ -192,8 +191,7 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati @Test // DATAREDIS-576 void connectionAppliesClientName() { - LettuceClientConfiguration clientName = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).clientName("clientName").build(); + LettuceClientConfiguration clientName = LettuceTestClientConfiguration.builder().clientName("clientName").build(); LettuceConnectionFactory factory = new LettuceConnectionFactory(SENTINEL_CONFIG, clientName); factory.afterPropertiesSet(); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceTestClientConfiguration.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceTestClientConfiguration.java index 6c48d123f..504ffec79 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceTestClientConfiguration.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceTestClientConfiguration.java @@ -34,14 +34,15 @@ public class LettuceTestClientConfiguration { * @see LettuceTestClientResources#getSharedClientResources() */ public static LettuceClientConfigurationBuilder builder() { - return LettuceClientConfiguration.builder().shutdownTimeout(Duration.ZERO) + return LettuceClientConfiguration.builder().shutdownTimeout(Duration.ZERO).shutdownQuietPeriod(Duration.ZERO) .clientResources(LettuceTestClientResources.getSharedClientResources()); } /** * @return a defaulted {@link LettuceClientConfiguration} for testing. */ - public static LettuceClientConfiguration create() { + public static LettuceClientConfiguration defaultConfiguration() { return builder().build(); } + } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/extension/LettuceConnectionFactoryExtension.java b/src/test/java/org/springframework/data/redis/connection/lettuce/extension/LettuceConnectionFactoryExtension.java index d9ec302e2..b11dfed22 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/extension/LettuceConnectionFactoryExtension.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/extension/LettuceConnectionFactoryExtension.java @@ -16,7 +16,9 @@ package org.springframework.data.redis.connection.lettuce.extension; import java.io.Closeable; +import java.io.IOException; import java.lang.annotation.Annotation; +import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -24,7 +26,6 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; - import org.springframework.data.redis.ConnectionFactoryTracker; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; @@ -35,6 +36,7 @@ import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder; import org.springframework.data.redis.test.extension.LettuceTestClientResources; import org.springframework.data.redis.test.extension.RedisCluster; import org.springframework.data.redis.test.extension.RedisSentinel; @@ -59,84 +61,87 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver { private static final Lazy STANDALONE = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettucePoolingClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultPoolConfigBuilder().build(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory( - SettingsUtils.standaloneConfiguration(), - configuration); + SettingsUtils.standaloneConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); private static final Lazy SENTINEL = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettucePoolingClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultPoolConfigBuilder().build(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.sentinelConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); private static final Lazy CLUSTER = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettucePoolingClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultPoolConfigBuilder().build(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.clusterConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); private static final Lazy STANDALONE_UNPOOLED = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultClientConfiguration(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory( - SettingsUtils.standaloneConfiguration(), - configuration); + SettingsUtils.standaloneConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); private static final Lazy SENTINEL_UNPOOLED = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultClientConfiguration(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.sentinelConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); private static final Lazy CLUSTER_UNPOOLED = Lazy.of(() -> { - LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() - .clientResources(LettuceTestClientResources.getSharedClientResources()).build(); + LettuceClientConfiguration configuration = defaultClientConfiguration(); ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.clusterConfiguration(), configuration); factory.afterPropertiesSet(); - ShutdownQueue.register(factory.toCloseable()); + ShutdownQueue.register(factory); return factory; }); + private static LettucePoolingClientConfigurationBuilder defaultPoolConfigBuilder() { + return LettucePoolingClientConfiguration.builder() + .clientResources(LettuceTestClientResources.getSharedClientResources()).shutdownTimeout(Duration.ZERO) + .shutdownQuietPeriod(Duration.ZERO); + } + + private static LettuceClientConfiguration defaultClientConfiguration() { + return LettuceClientConfiguration.builder().clientResources(LettuceTestClientResources.getSharedClientResources()) + .shutdownQuietPeriod(Duration.ZERO).shutdownQuietPeriod(Duration.ZERO).build(); + } + private static final Map, Lazy> pooledFactories; private static final Map, Lazy> unpooledFactories; @@ -207,7 +212,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver { } static class ManagedLettuceConnectionFactory extends LettuceConnectionFactory - implements ConnectionFactoryTracker.Managed { + implements ConnectionFactoryTracker.Managed, Closeable { private volatile boolean mayClose; @@ -257,15 +262,11 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver { return builder.toString(); } - Closeable toCloseable() { - return () -> { - try { - mayClose = true; - destroy(); - } catch (Exception e) { - e.printStackTrace(); - } - }; + @Override + public void close() throws IOException { + + mayClose = true; + destroy(); } } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/observability/TestConfig.java b/src/test/java/org/springframework/data/redis/connection/lettuce/observability/TestConfig.java index dc9802f86..d6def0d93 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/observability/TestConfig.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/observability/TestConfig.java @@ -15,18 +15,22 @@ */ package org.springframework.data.redis.connection.lettuce.observability; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.SettingsUtils; -import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; - import io.lettuce.core.resource.ClientResources; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.micrometer.observation.ObservationRegistry; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.SettingsUtils; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.test.extension.ShutdownQueue; + /** * @author Mark Paluch */ @@ -40,16 +44,21 @@ class TestConfig { OBSERVATION_REGISTRY.observationConfig().observationHandler(new DefaultMeterObservationHandler(METER_REGISTRY)); } - @Bean(destroyMethod = "shutdown") + @Bean(destroyMethod = "timer") ClientResources clientResources(ObservationRegistry observationRegistry) { - return ClientResources.builder().tracing(new MicrometerTracingAdapter(observationRegistry, "Redis", true)) - .build(); + + ClientResources resources = ClientResources.builder() + .tracing(new MicrometerTracingAdapter(observationRegistry, "Redis", true)).build(); + + ShutdownQueue.register(() -> resources.shutdown(0, 0, TimeUnit.MILLISECONDS)); + return resources; } @Bean LettuceConnectionFactory connectionFactory(ClientResources clientResources) { LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() + .shutdownTimeout(Duration.ZERO).shutdownQuietPeriod(Duration.ZERO) .clientResources(clientResources).build(); return new LettuceConnectionFactory(SettingsUtils.standaloneConfiguration(), clientConfiguration); diff --git a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsIntegrationTests.java b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsIntegrationTests.java index f0716130b..d45e3ec13 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsIntegrationTests.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; - +import org.springframework.data.redis.DoubleObjectFactory; import org.springframework.data.redis.ObjectFactory; import org.springframework.data.redis.test.condition.EnabledIfLongRunningTest; import org.springframework.data.redis.test.condition.EnabledOnCommand; @@ -110,20 +110,20 @@ public class DefaultValueOperationsIntegrationTests { @ParameterizedRedisTest // DATAREDIS-247 void testIncrementDouble() { + assumeThat(valueFactory).isInstanceOf(DoubleObjectFactory.class); + K key = keyFactory.instance(); - V value = valueFactory.instance(); + Double value = (Double) valueFactory.instance(); - assumeThat(value instanceof Double).isTrue(); - - valueOps.set(key, value); + valueOps.set(key, (V) value); DecimalFormat twoDForm = (DecimalFormat) DecimalFormat.getInstance(Locale.US); assertThat(valueOps.increment(key, 1.4)).isEqualTo(Double.valueOf(twoDForm.format((Double) value + 1.4))); - assertThat(valueOps.get(key)).isEqualTo(Double.valueOf(twoDForm.format((Double) value + 1.4))); + assertThat((Double) valueOps.get(key)).isBetween(value + 1.3, value + 1.4); valueOps.increment(key, -10d); - assertThat(valueOps.get(key)).isEqualTo(Double.valueOf(twoDForm.format((Double) value + 1.4 - 10d))); + assertThat((Double) valueOps.get(key)).isBetween(value + 1.3 - 10, value + 1.4 - 10); } @ParameterizedRedisTest // DATAREDIS-784 diff --git a/src/test/java/org/springframework/data/redis/test/condition/EnabledOnCommandCondition.java b/src/test/java/org/springframework/data/redis/test/condition/EnabledOnCommandCondition.java index 49bf4d394..d2f28c293 100644 --- a/src/test/java/org/springframework/data/redis/test/condition/EnabledOnCommandCondition.java +++ b/src/test/java/org/springframework/data/redis/test/condition/EnabledOnCommandCondition.java @@ -39,6 +39,8 @@ class EnabledOnCommandCondition implements ExecutionCondition { private static final ConditionEvaluationResult ENABLED_BY_DEFAULT = enabled("@EnabledOnCommand is not present"); private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create(RedisConditions.class); + private final LettuceExtension lettuceExtension = new LettuceExtension(); + @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { @@ -51,11 +53,12 @@ class EnabledOnCommandCondition implements ExecutionCondition { String command = optional.get().value(); - ExtensionContext.Store store = context.getStore(NAMESPACE); + ExtensionContext.Store store = context.getRoot().getStore(NAMESPACE); RedisConditions conditions = store.getOrComputeIfAbsent(RedisConditions.class, ignore -> { - StatefulRedisConnection connection = new LettuceExtension().resolve(context, StatefulRedisConnection.class); - return RedisConditions.of(connection); + try (StatefulRedisConnection connection = lettuceExtension.resolve(context, StatefulRedisConnection.class)) { + return RedisConditions.of(connection); + } }, RedisConditions.class); boolean hasCommand = conditions.hasCommand(command); diff --git a/src/test/java/org/springframework/data/redis/test/condition/EnabledOnRedisVersionCondition.java b/src/test/java/org/springframework/data/redis/test/condition/EnabledOnRedisVersionCondition.java index 5fa92eb9c..5a082873b 100644 --- a/src/test/java/org/springframework/data/redis/test/condition/EnabledOnRedisVersionCondition.java +++ b/src/test/java/org/springframework/data/redis/test/condition/EnabledOnRedisVersionCondition.java @@ -36,8 +36,9 @@ import org.springframework.data.redis.test.extension.LettuceExtension; class EnabledOnRedisVersionCondition implements ExecutionCondition { private static final ConditionEvaluationResult ENABLED_BY_DEFAULT = enabled("@EnabledOnVersion is not present"); - private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace - .create(EnabledOnRedisVersionCondition.class); + private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create(RedisConditions.class); + + private final LettuceExtension lettuceExtension = new LettuceExtension(); @Override @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -52,11 +53,12 @@ class EnabledOnRedisVersionCondition implements ExecutionCondition { String requiredVersion = optional.get().value(); - ExtensionContext.Store store = context.getStore(NAMESPACE); + ExtensionContext.Store store = context.getRoot().getStore(NAMESPACE); RedisConditions conditions = store.getOrComputeIfAbsent(RedisConditions.class, ignore -> { - StatefulRedisConnection connection = new LettuceExtension().resolve(context, StatefulRedisConnection.class); - return RedisConditions.of(connection); + try (StatefulRedisConnection connection = lettuceExtension.resolve(context, StatefulRedisConnection.class)) { + return RedisConditions.of(connection); + } }, RedisConditions.class); boolean versionMet = conditions.hasVersionGreaterOrEqualsTo(requiredVersion); diff --git a/src/test/java/org/springframework/data/redis/test/extension/LettuceExtension.java b/src/test/java/org/springframework/data/redis/test/extension/LettuceExtension.java index ab5416bcc..1c7018765 100644 --- a/src/test/java/org/springframework/data/redis/test/extension/LettuceExtension.java +++ b/src/test/java/org/springframework/data/redis/test/extension/LettuceExtension.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.test.extension; +import io.lettuce.core.AbstractRedisClient; import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.api.StatefulConnection; @@ -27,6 +28,8 @@ import io.lettuce.core.protocol.ProtocolVersion; import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import io.lettuce.core.resource.ClientResources; +import java.io.Closeable; +import java.io.IOException; import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.util.Arrays; @@ -48,7 +51,6 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; - import org.springframework.core.ResolvableType; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.util.Lazy; @@ -80,7 +82,7 @@ import org.springframework.data.util.Lazy; * *

Resource lifecycle

This extension allocates resources lazily and stores them in its {@link ExtensionContext} * {@link ExtensionContext.Store} for reuse across multiple tests. Client and {@link ClientResources} are allocated - * through{@link DefaultRedisClient} respective {@link TestClientResources} so shutdown is managed by the actual + * through default {@link RedisClient} respective {@link RedisClientSupplier} so shutdown is managed by the actual * suppliers. Singleton connection resources are closed after the test class (test container) is finished. * * @author Mark Paluch @@ -142,6 +144,17 @@ public class LettuceExtension implements ParameterResolver, AfterAllCallback, Af return store.getOrComputeIfAbsent(parameter.getType(), it -> doGetInstance(parameterizedType)); } + @Override + public void afterEach(ExtensionContext context) { + + ExtensionContext.Store store = getStore(context); + + RedisClient redisClient = store.get(RedisClient.class, RedisClient.class); + if (redisClient != null) { + redisClient.setOptions(DEFAULT_OPTIONS); + } + } + @Override public void afterAll(ExtensionContext context) { @@ -158,17 +171,6 @@ public class LettuceExtension implements ParameterResolver, AfterAllCallback, Af }); } - @Override - public void afterEach(ExtensionContext context) { - - ExtensionContext.Store store = getStore(context); - - RedisClient redisClient = store.get(RedisClient.class, RedisClient.class); - if (redisClient != null) { - redisClient.setOptions(DEFAULT_OPTIONS); - } - } - @SuppressWarnings("unchecked") private static Supplier findSupplier(Type type) { @@ -238,16 +240,25 @@ public class LettuceExtension implements ParameterResolver, AfterAllCallback, Af } } + record RedisClientCloseable(AbstractRedisClient client) implements Closeable { + + @Override + public void close() throws IOException { + client.shutdown(0, 0, TimeUnit.MILLISECONDS); + } + } + enum RedisClientSupplier implements Supplier { INSTANCE; final Lazy lazy = Lazy.of(() -> { - RedisClient client = RedisClient.create(ClientResourcesSupplier.INSTANCE.get(), + + RedisClient client = RedisClient.create(LettuceTestClientResources.getSharedClientResources(), RedisURI.create(SettingsUtils.getHost(), SettingsUtils.getPort())); client.setOptions(DEFAULT_OPTIONS); - ShutdownQueue.register(() -> client.shutdown(0, 0, TimeUnit.MILLISECONDS)); + ShutdownQueue.register(new RedisClientCloseable(client)); return client; }); @@ -262,11 +273,11 @@ public class LettuceExtension implements ParameterResolver, AfterAllCallback, Af INSTANCE; final Lazy lazy = Lazy.of(() -> { - RedisClusterClient client = RedisClusterClient.create(ClientResourcesSupplier.INSTANCE.get(), + RedisClusterClient client = RedisClusterClient.create(LettuceTestClientResources.getSharedClientResources(), RedisURI.create(SettingsUtils.getHost(), SettingsUtils.getClusterPort())); client.setOptions(DEFAULT_OPTIONS); - ShutdownQueue.register(() -> client.shutdown(0, 0, TimeUnit.MILLISECONDS)); + ShutdownQueue.register(new RedisClientCloseable(client)); return client; }); diff --git a/src/test/java/org/springframework/data/redis/test/extension/LettuceTestClientResources.java b/src/test/java/org/springframework/data/redis/test/extension/LettuceTestClientResources.java index 88a85785d..03a0c396f 100644 --- a/src/test/java/org/springframework/data/redis/test/extension/LettuceTestClientResources.java +++ b/src/test/java/org/springframework/data/redis/test/extension/LettuceTestClientResources.java @@ -21,8 +21,12 @@ import io.lettuce.core.resource.ClientResources; import io.lettuce.core.resource.DefaultClientResources; import reactor.core.publisher.Flux; +import java.io.Closeable; +import java.io.IOException; import java.util.concurrent.TimeUnit; +import org.springframework.core.Ordered; + /** * Client-Resources suitable for testing. Every time a new {@link LettuceTestClientResources} instance is created, a * {@link Runtime#addShutdownHook(Thread) shutdown hook} is added to close the client resources. @@ -36,7 +40,13 @@ public class LettuceTestClientResources { static { - SHARED_CLIENT_RESOURCES = DefaultClientResources.builder().eventBus(new EventBus() { + SHARED_CLIENT_RESOURCES = newClientResources(); + ShutdownQueue.register(new SharedClientResources(SHARED_CLIENT_RESOURCES)); + } + + private static ClientResources newClientResources() { + + return DefaultClientResources.builder().ioThreadPoolSize(4).computationThreadPoolSize(4).eventBus(new EventBus() { @Override public Flux get() { return Flux.empty(); @@ -46,9 +56,7 @@ public class LettuceTestClientResources { public void publish(Event event) { } - }) - .build(); - ShutdownQueue.INSTANCE.register(() -> SHARED_CLIENT_RESOURCES.shutdown(0, 0, TimeUnit.MILLISECONDS)); + }).build(); } private LettuceTestClientResources() {} @@ -59,4 +67,22 @@ public class LettuceTestClientResources { public static ClientResources getSharedClientResources() { return SHARED_CLIENT_RESOURCES; } + + static class SharedClientResources implements Ordered, Closeable { + private final ClientResources clientResources; + + public SharedClientResources(ClientResources clientResources) { + this.clientResources = clientResources; + } + + @Override + public void close() throws IOException { + clientResources.shutdown(0, 0, TimeUnit.MILLISECONDS); + } + + @Override + public int getOrder() { + return HIGHEST_PRECEDENCE; + } + } } diff --git a/src/test/java/org/springframework/data/redis/test/extension/ShutdownQueue.java b/src/test/java/org/springframework/data/redis/test/extension/ShutdownQueue.java index 7251e9553..2841216c3 100644 --- a/src/test/java/org/springframework/data/redis/test/extension/ShutdownQueue.java +++ b/src/test/java/org/springframework/data/redis/test/extension/ShutdownQueue.java @@ -20,6 +20,8 @@ import redis.clients.jedis.util.IOUtils; import java.io.Closeable; import java.util.LinkedList; +import org.springframework.core.OrderComparator; + /** * Shutdown queue allowing ordered resource shutdown (LIFO). * @@ -31,22 +33,23 @@ public enum ShutdownQueue { static { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { + Runtime.getRuntime().addShutdownHook(new Thread(ShutdownQueue::close)); + } - Closeable closeable; - while ((closeable = INSTANCE.closeables.pollLast()) != null) { - try { - closeable.close(); - } catch (Exception o_O) { - // ignore - o_O.printStackTrace(); - } - } + private static void close() { + Closeable closeable; + + OrderComparator.sort(INSTANCE.closeables); + + while ((closeable = INSTANCE.closeables.pollLast()) != null) { + try { + closeable.close(); + } catch (Exception o_O) { + // ignore + o_O.printStackTrace(); } - }); + } } private final LinkedList closeables = new LinkedList<>(); @@ -58,4 +61,5 @@ public enum ShutdownQueue { public static void register(AutoCloseable closeable) { INSTANCE.closeables.add(() -> IOUtils.closeQuietly(closeable)); } + } diff --git a/src/test/java/org/springframework/data/redis/test/extension/parametrized/MethodArgumentsProvider.java b/src/test/java/org/springframework/data/redis/test/extension/parametrized/MethodArgumentsProvider.java index 89b5700da..b0306ca6a 100644 --- a/src/test/java/org/springframework/data/redis/test/extension/parametrized/MethodArgumentsProvider.java +++ b/src/test/java/org/springframework/data/redis/test/extension/parametrized/MethodArgumentsProvider.java @@ -18,11 +18,15 @@ package org.springframework.data.redis.test.extension.parametrized; import static java.lang.String.*; import static org.junit.jupiter.params.provider.Arguments.*; +import java.io.Closeable; import java.lang.reflect.Method; import java.util.Arrays; import java.util.stream.Stream; import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ExtensionContext.Store.CloseableResource; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.support.AnnotationConsumer; @@ -31,12 +35,14 @@ import org.junit.platform.commons.util.CollectionUtils; import org.junit.platform.commons.util.Preconditions; import org.junit.platform.commons.util.ReflectionUtils; import org.junit.platform.commons.util.StringUtils; +import org.springframework.data.redis.ConnectionFactoryTracker.Managed; /** * Copy of {@code org.junit.jupiter.params.provider.MethodArgumentsProvider}. */ class MethodArgumentsProvider implements ArgumentsProvider, AnnotationConsumer { + private final static Namespace NAMESPACE = Namespace.create(MethodArgumentsProvider.class); private String[] methodNames = new String[0]; @Override @@ -46,12 +52,14 @@ class MethodArgumentsProvider implements ArgumentsProvider, AnnotationConsumer provideArguments(ExtensionContext context) { + + Store store = context.getRoot().getStore(NAMESPACE); Object testInstance = context.getTestInstance().orElse(null); - // @formatter:off return Arrays.stream(this.methodNames).map(factoryMethodName -> getMethod(context, factoryMethodName)) - .map(method -> ReflectionUtils.invokeMethod(method, testInstance)).flatMap(CollectionUtils::toStream) + .map(method -> (CloseablePararmeters) store.getOrComputeIfAbsent(new SourceKey(method, testInstance), + key -> new CloseablePararmeters(ReflectionUtils.invokeMethod(method, testInstance), context))) + .map(CloseablePararmeters::parameters).flatMap(CollectionUtils::toStream) .map(MethodArgumentsProvider::toArguments); - // @formatter:on } private Method getMethod(ExtensionContext context, String factoryMethodName) { @@ -105,4 +113,64 @@ class MethodArgumentsProvider implements ArgumentsProvider, AnnotationConsumer) { + ((Iterable) object).forEach(this::close0); + } + } + } + }