From 1ce4f31669c3ac20f4a77bf529cfc4de0c29c338 Mon Sep 17 00:00:00 2001 From: ggivo Date: Sun, 10 Nov 2024 21:04:00 +0200 Subject: [PATCH 01/44] Introduces test matrix based on Redis versions [8.0-M1, 7.4.1, 7.2.6, 6.2.16] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use docker composer to bring up the test env using `redislabs/client-libs-test` image. When run against older Redis version some tests are using commands available only in newer Redis server versions. To resolve this we are introducing two new annotations/rules - Introduce `SinceRedisVersion` annotation/Rule - for conditionally running tests based on Redis server version contacted - Introduce `EnableOnCommad` annotation/Rule - for conditionally running tests based on command availability on the server And mark respective tests with the least Redis Version required by the test - SinceRedisVersion ("7.4.0") - Mark tests using commands/modifiers introduced with Redis 7.4.0 - SinceRedisVersion ("7.2.0") - Mark tests using commands/modifiers introduced with Redis 7.2.0 - SinceRedisVersion ("7.0.0") - Mark tests using commands/modifiers introduced with Redis 7.0.0 The same approach used to mark CSC tests - Disabled client-side caching tests for versions below 7.4 Fix in Jedis Client against Redis server 6.x - Fix NPW on CommandInfo - some of the array elements returned are available based from given RedisServer aclCategories (as of Redis 6.0) , tips , (as of Redis 7.0) subcommands - Fix NPE AccessControlLogEntry when used against Redis 6 Starting with Redis version 7.2.0: Added entry ID, timestamp created, and timestamp last updated fields. Fix Test failures against 6.x - Fix JedisPooledClientSideCacheTest - Fix AccessControlListCommandsTest.aclLogTest:372 » NullPointer - Fix AccessControlListCommandsTest.aclLogWithEntryID:473 » NullPointer - Fix StreamsCommandsTest - Fix StreamsPipelineCommandsTest xadd - Starting with Redis version 7.0.0: Added support for the -* explicit ID form. - Test env migrated to use native Redis server TLS instead of using stunnel Not all tests were migrated - Disable Modules test in containerized test env ModuleTest uses custom test module to test load/unload/sendCommand. Requires pre-build test module on the same os like test container to avoid errors - Disable UDS tests in containerized test env No easy way to make unix sockets work on MAC with docker --- .github/workflows/integration.yml | 4 +- .github/workflows/test-on-docker.yml | 128 ++++++++ .gitignore | 2 + Makefile | 12 +- .../jedis/resps/AccessControlLogEntry.java | 10 +- .../clients/jedis/resps/CommandInfo.java | 10 +- .../test/annotations/EnabledOnCommand.java | 11 + .../test/annotations/SinceRedisVersion.java | 11 + .../test/utils/EnabledOnCommandRule.java | 126 ++++++++ .../java/io/redis/test/utils/RedisInfo.java | 67 ++++ .../io/redis/test/utils/RedisVersion.java | 92 ++++++ .../io/redis/test/utils/RedisVersionRule.java | 90 ++++++ .../io/redis/test/utils/RedisVersionUtil.java | 44 +++ .../redis/clients/jedis/ACLJedisPoolTest.java | 16 +- .../jedis/ACLJedisSentinelPoolTest.java | 16 +- .../redis/clients/jedis/ACLJedisTest.java | 5 +- .../redis/clients/jedis/EndpointConfig.java | 4 + .../redis/clients/jedis/JedisClusterTest.java | 4 +- .../clients/jedis/JedisClusterTestBase.java | 9 + .../java/redis/clients/jedis/JedisTest.java | 4 + .../clients/jedis/SSLACLJedisClusterTest.java | 252 +++++++++------ .../redis/clients/jedis/SSLACLJedisTest.java | 121 ++------ .../clients/jedis/SSLJedisClusterTest.java | 180 ++++++----- .../jedis/SSLJedisSentinelPoolTest.java | 49 ++- .../redis/clients/jedis/SSLJedisTest.java | 210 ++++--------- .../java/redis/clients/jedis/UdsTest.java | 8 + .../CommandObjectsBitmapCommandsTest.java | 3 + .../CommandObjectsGenericCommandsTest.java | 19 ++ .../CommandObjectsHashCommandsTest.java | 12 + .../CommandObjectsListCommandsTest.java | 3 + .../CommandObjectsScriptingCommandsTest.java | 15 + .../CommandObjectsSetCommandsTest.java | 2 + .../CommandObjectsSortedSetCommandsTest.java | 9 + .../CommandObjectsStandaloneTestBase.java | 8 + .../CommandObjectsStringCommandsTest.java | 3 + .../CommandObjectsTestBase.java | 13 +- .../jedis/AccessControlListCommandsTest.java | 45 +-- .../jedis/AllKindOfValuesCommandsTest.java | 14 +- .../jedis/commands/jedis/BitCommandsTest.java | 22 +- .../commands/jedis/ClientCommandsTest.java | 11 + .../commands/jedis/ClusterCommandsTest.java | 21 +- .../jedis/ClusterJedisCommandsTestBase.java | 13 +- .../jedis/ClusterScriptingCommandsTest.java | 3 + ...erShardedPublishSubscribeCommandsTest.java | 13 + .../commands/jedis/ControlCommandsTest.java | 13 + .../commands/jedis/HashesCommandsTest.java | 25 ++ .../commands/jedis/JedisCommandsTestBase.java | 17 +- .../commands/jedis/ListCommandsTest.java | 3 + .../jedis/commands/jedis/ModuleTest.java | 11 +- .../commands/jedis/ScriptingCommandsTest.java | 21 +- .../jedis/commands/jedis/SetCommandsTest.java | 2 + .../commands/jedis/SlowlogCommandsTest.java | 29 +- .../commands/jedis/SortedSetCommandsTest.java | 6 + .../commands/jedis/SortingCommandsTest.java | 3 + .../commands/jedis/StreamsCommandsTest.java | 55 +++- .../jedis/StringValuesCommandsTest.java | 3 + .../AllKindOfValuesCommandsTestBase.java | 8 + .../commands/unified/BitCommandsTestBase.java | 7 + .../unified/HashesCommandsTestBase.java | 14 + .../unified/ListCommandsTestBase.java | 3 + .../commands/unified/SetCommandsTestBase.java | 2 + .../unified/SortedSetCommandsTestBase.java | 6 + .../unified/StringValuesCommandsTestBase.java | 3 + .../ClusterAllKindOfValuesCommandsTest.java | 14 + .../cluster/ClusterBitCommandsTest.java | 18 +- .../cluster/ClusterCommandsTestHelper.java | 2 +- .../cluster/ClusterHashesCommandsTest.java | 14 + .../cluster/ClusterListCommandsTest.java | 17 ++ .../cluster/ClusterSetCommandsTest.java | 16 + .../cluster/ClusterSortedSetCommandsTest.java | 16 + .../ClusterStringValuesCommandsTest.java | 16 + .../pipeline/ListPipelineCommandsTest.java | 3 + .../pipeline/PipelineCommandsTestBase.java | 15 +- .../pipeline/SetPipelineCommandsTest.java | 2 + .../SortedSetPipelineCommandsTest.java | 5 + .../pipeline/StreamsPipelineCommandsTest.java | 42 ++- .../PooledAllKindOfValuesCommandsTest.java | 13 + .../unified/pooled/PooledBitCommandsTest.java | 12 + .../pooled/PooledCommandsTestHelper.java | 2 +- .../pooled/PooledHashesCommandsTest.java | 12 + .../pooled/PooledListCommandsTest.java | 13 + .../pooled/PooledMiscellaneousTest.java | 20 +- .../unified/pooled/PooledSetCommandsTest.java | 12 + .../pooled/PooledSortedSetCommandsTest.java | 12 + .../PooledStringValuesCommandsTest.java | 11 + .../csc/AllowAndDenyListCacheableTest.java | 2 + .../csc/ClientSideCacheFunctionalityTest.java | 21 +- .../jedis/csc/ClientSideCacheTestBase.java | 25 +- .../csc/JedisClusterClientSideCacheTest.java | 30 +- .../csc/JedisPooledClientSideCacheTest.java | 10 +- .../JedisPooledClientSideCacheTestBase.java | 2 + .../JedisSentineledClientSideCacheTest.java | 47 +-- .../SSLJedisPooledClientSideCacheTest.java | 23 +- .../UnifiedJedisClientSideCacheTestBase.java | 4 +- .../modules/RedisModuleCommandsTestBase.java | 9 +- .../clients/jedis/util/RedisVersionUtil.java | 32 -- .../redis/clients/jedis/util/TestEnvUtil.java | 19 ++ .../redis/clients/jedis/util/TlsUtil.java | 286 ++++++++++++++++++ .../config/node-sentinel5/redis.conf | 11 + src/test/resources/env/.env | 7 + src/test/resources/env/.env.v6.2.16 | 8 + .../config/node-7379-8379/redis.conf | 9 + .../config/node-7380-8380/redis.conf | 8 + .../config/node-7381-8381/redis.conf | 9 + .../config/node-7382-8382/redis.conf | 9 + .../config/node-7383-8383/redis.conf | 9 + .../node-sentinel-26381-36381/redis.conf | 9 + src/test/resources/env/docker-compose.yml | 160 ++++++++++ src/test/resources/env/endpoint.map | 20 ++ .../env/redis-uds/config/node-0/redis.conf | 2 + .../config/node-6379-6390/redis.conf | 11 + .../config/node-6380/redis.conf | 8 + .../config/node-6383-6391/redis.conf | 9 + .../config/node-6386/redis.conf | 6 + .../node-sentinel-26379-36379/redis.conf | 8 + .../redis10-11/config/node-6388/redis.conf | 3 + .../redis10-11/config/node-6389/redis.conf | 4 + .../config/node-6381-16381/redis.conf | 6 + .../config/node-6382-16382/redis.conf | 7 + .../node-sentinel-26380-36380/redis.conf | 8 + .../node-sentinel-26382-36382/redis.conf | 8 + .../config/node-6384/redis.conf | 5 + .../config/node-6385/redis.conf | 6 + .../node-sentinel-26381-36381/redis.conf | 7 + .../config/node-6387-16387/redis.conf | 9 + .../node-sentinel-26383-36383/redis.conf | 12 + src/test/resources/private.crt | 21 ++ 127 files changed, 2522 insertions(+), 619 deletions(-) create mode 100644 .github/workflows/test-on-docker.yml create mode 100644 src/test/java/io/redis/test/annotations/EnabledOnCommand.java create mode 100644 src/test/java/io/redis/test/annotations/SinceRedisVersion.java create mode 100644 src/test/java/io/redis/test/utils/EnabledOnCommandRule.java create mode 100644 src/test/java/io/redis/test/utils/RedisInfo.java create mode 100644 src/test/java/io/redis/test/utils/RedisVersion.java create mode 100644 src/test/java/io/redis/test/utils/RedisVersionRule.java create mode 100644 src/test/java/io/redis/test/utils/RedisVersionUtil.java delete mode 100644 src/test/java/redis/clients/jedis/util/RedisVersionUtil.java create mode 100644 src/test/java/redis/clients/jedis/util/TestEnvUtil.java create mode 100644 src/test/java/redis/clients/jedis/util/TlsUtil.java create mode 100644 src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf create mode 100644 src/test/resources/env/.env create mode 100644 src/test/resources/env/.env.v6.2.16 create mode 100644 src/test/resources/env/cluster-unbound/config/node-7379-8379/redis.conf create mode 100644 src/test/resources/env/cluster-unbound/config/node-7380-8380/redis.conf create mode 100644 src/test/resources/env/cluster-unbound/config/node-7381-8381/redis.conf create mode 100644 src/test/resources/env/cluster-unbound/config/node-7382-8382/redis.conf create mode 100644 src/test/resources/env/cluster-unbound/config/node-7383-8383/redis.conf create mode 100644 src/test/resources/env/config/redis6-7/node-sentinel-26381-36381/redis.conf create mode 100644 src/test/resources/env/docker-compose.yml create mode 100644 src/test/resources/env/endpoint.map create mode 100644 src/test/resources/env/redis-uds/config/node-0/redis.conf create mode 100644 src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf create mode 100644 src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf create mode 100644 src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf create mode 100644 src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf create mode 100644 src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf create mode 100644 src/test/resources/env/redis10-11/config/node-6388/redis.conf create mode 100644 src/test/resources/env/redis10-11/config/node-6389/redis.conf create mode 100644 src/test/resources/env/redis3-4-sentinel/config/node-6381-16381/redis.conf create mode 100644 src/test/resources/env/redis3-4-sentinel/config/node-6382-16382/redis.conf create mode 100644 src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26380-36380/redis.conf create mode 100644 src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26382-36382/redis.conf create mode 100644 src/test/resources/env/redis6-7-sentinel/config/node-6384/redis.conf create mode 100644 src/test/resources/env/redis6-7-sentinel/config/node-6385/redis.conf create mode 100644 src/test/resources/env/redis6-7-sentinel/config/node-sentinel-26381-36381/redis.conf create mode 100644 src/test/resources/env/redis9-sentinel/config/node-6387-16387/redis.conf create mode 100644 src/test/resources/env/redis9-sentinel/config/node-sentinel-26383-36383/redis.conf create mode 100644 src/test/resources/private.crt diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3df4e12271..70342266fe 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -34,8 +34,8 @@ jobs: - name: System setup run: | sudo apt update - sudo apt install -y stunnel make - make system-setup + sudo apt install -y make + make compile-module - name: Cache dependencies uses: actions/cache@v2 with: diff --git a/.github/workflows/test-on-docker.yml b/.github/workflows/test-on-docker.yml new file mode 100644 index 0000000000..bccdeab4e5 --- /dev/null +++ b/.github/workflows/test-on-docker.yml @@ -0,0 +1,128 @@ +--- + +name: Build and Test using containerized environment + +on: + push: + paths-ignore: + - 'docs/**' + - '**/*.md' + - '**/*.rst' + branches: + - master + - '[0-9].*' + pull_request: + branches: + - master + - '[0-9].*' + schedule: + - cron: '0 1 * * *' # nightly build + workflow_dispatch: + inputs: + specific_test: + description: 'Run specific test(s) (optional)' + required: false + default: '' +jobs: + + build: + name: Build and Test + runs-on: ubuntu-latest + env: + REDIS_ENV_WORK_DIR: ${{ github.workspace }}/redis-env-work + REDIS_ENV_CONF_DIR: ${{ github.workspace }}/src/test/resources/env + CLIENT_LIBS_IMAGE_PREFIX: "redislabs/client-libs-test" + strategy: + fail-fast: false + matrix: + redis_version: + - "8.0-M01" + - "7.4.1" + - "7.2.6" + - "6.2.16" + steps: + - uses: actions/checkout@v2 + - name: Set up publishing to maven central + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'temurin' + - name: System setup + run: | + sudo apt update + sudo apt install -y make + make compile-module + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: | + ~/.m2/repository + /var/cache/apt + key: jedis-${{hashFiles('**/pom.xml')}} + # Set up Docker Compose environment + - name: Set up Docker Compose environment + run: | + mkdir -m 777 $REDIS_ENV_WORK_DIR + export CLIENT_LIBS_TEST_IMAGE="${CLIENT_LIBS_IMAGE_PREFIX}:${{ matrix.redis_version }}" + export COMPOSE_ENV_FILES="src/test/resources/env/.env" + if [[ "${{ matrix.redis_version }}" == "6.2.16" ]]; then + COMPOSE_ENV_FILES+=",src/test/resources/env/.env.v${{ matrix.redis_version }}" + fi + docker compose -f src/test/resources/env/docker-compose.yml up -d + - name: Maven offline + run: | + mvn -q dependency:go-offline + - name: Build docs + run: | + mvn javadoc:jar + # Run Tests + - name: Run Maven tests + run: | + export TEST_ENV_PROVIDER=docker + export TEST_WORK_FOLDER=$REDIS_ENV_WORK_DIR + echo $TEST_WORK_FOLDER + if [ -z "$TESTS" ]; then + mvn clean compile test + else + mvn -Dtest=$SPECIFIC_TEST clean compile test + fi + env: + TESTS: ${{ github.event.inputs.specific_test || '' }} + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: | + target/surefire-reports/**/*.xml + # Collect logs on failure + - name: Collect logs on failure + if: failure() # This runs only if the previous steps failed + run: | + echo "Collecting logs from $WORK_DIR..." + ls -la $REDIS_ENV_WORK_DIR + # Upload logs as artifacts + - name: Upload logs on failure + if: failure() + uses: actions/upload-artifact@v3 + with: + name: redis-env-work-logs + path: ${{ env.REDIS_ENV_WORK_DIR }} + # Bring down the Docker Compose test environment + - name: Tear down Docker Compose environment + if: always() + run: | + docker compose $COMPOSE_ENV_FILES -f src/test/resources/env/docker-compose.yml down + continue-on-error: true + # Upload code coverage + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results to Codecov + if: ${{ github.event_name == 'schedule' || (github.event_name == 'push') || github.event_name == 'workflow_dispatch'}} + uses: codecov/test-results-action@v1 + with: + fail_ci_if_error: false + files: ./target/surefire-reports/TEST* + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 8cb08a2658..5477116e12 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,9 @@ build/ bin/ tags .idea +.run *.aof *.rdb redis-git appendonlydir/ +.DS_Store diff --git a/Makefile b/Makefile index 1800f00d7e..45df2f9059 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ protected-mode no port 6379 requirepass foobared user acljedis on allcommands allkeys >fizzbuzz +user deploy on allcommands allkeys >verify pidfile /tmp/redis1.pid logfile /tmp/redis1.log save "" @@ -189,6 +190,7 @@ endef define REDIS_SENTINEL5 port 26383 +tlsport 36383 daemonize yes protected-mode no user default off @@ -525,8 +527,14 @@ mvn-release: mvn release:prepare mvn release:perform -DskipTests -system-setup: - sudo apt install -y gcc g++ +install-gcc: + @if [ "$(shell uname)" = "Darwin" ]; then \ + brew install gcc; \ + else \ + sudo apt install -y gcc g++; \ + fi + +system-setup: install-gcc [ ! -e redis-git ] && git clone https://github.com/redis/redis.git --branch unstable --single-branch redis-git || true $(MAKE) -C redis-git clean $(MAKE) -C redis-git diff --git a/src/main/java/redis/clients/jedis/resps/AccessControlLogEntry.java b/src/main/java/redis/clients/jedis/resps/AccessControlLogEntry.java index 930c9b064d..f95ade23cd 100644 --- a/src/main/java/redis/clients/jedis/resps/AccessControlLogEntry.java +++ b/src/main/java/redis/clients/jedis/resps/AccessControlLogEntry.java @@ -38,6 +38,10 @@ public class AccessControlLogEntry implements Serializable { private final long timestampCreated; private final long timestampLastUpdated; + /* + * Starting with Redis version 7.2.0: Added entry ID, timestamp created, and timestamp last updated. + * @see https://redis.io/docs/latest/commands/acl-log/ + */ public AccessControlLogEntry(Map map) { count = (long) map.get(COUNT); reason = (String) map.get(REASON); @@ -47,9 +51,9 @@ public AccessControlLogEntry(Map map) { ageSeconds = (Double) map.get(AGE_SECONDS); clientInfo = getMapFromRawClientInfo((String) map.get(CLIENT_INFO)); logEntry = map; - entryId = (long) map.get(ENTRY_ID); - timestampCreated = (long) map.get(TIMESTAMP_CREATED); - timestampLastUpdated = (long) map.get(TIMESTAMP_LAST_UPDATED); + entryId = map.get(ENTRY_ID) == null ? 0L : (long) map.get(ENTRY_ID); + timestampCreated = map.get(TIMESTAMP_CREATED) == null ? 0L : (long) map.get(TIMESTAMP_CREATED); + timestampLastUpdated = map.get(TIMESTAMP_LAST_UPDATED) == null ? 0L : (long) map.get(TIMESTAMP_LAST_UPDATED); } public long getCount() { diff --git a/src/main/java/redis/clients/jedis/resps/CommandInfo.java b/src/main/java/redis/clients/jedis/resps/CommandInfo.java index efdf582102..a8365a9806 100644 --- a/src/main/java/redis/clients/jedis/resps/CommandInfo.java +++ b/src/main/java/redis/clients/jedis/resps/CommandInfo.java @@ -2,6 +2,7 @@ import redis.clients.jedis.Builder; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -135,9 +136,12 @@ public CommandInfo build(Object data) { long firstKey = LONG.build(commandData.get(3)); long lastKey = LONG.build(commandData.get(4)); long step = LONG.build(commandData.get(5)); - List aclCategories = STRING_LIST.build(commandData.get(6)); - List tips = STRING_LIST.build(commandData.get(7)); - Map subcommands = COMMAND_INFO_RESPONSE.build(commandData.get(9)); + // (as of Redis 6.0) + List aclCategories = commandData.size()>=6?STRING_LIST.build(commandData.get(6)): Collections.emptyList(); + + // (as of Redis 7.0) + List tips = commandData.size()>=8?STRING_LIST.build(commandData.get(7)):Collections.emptyList(); + Map subcommands = commandData.size()>=10?COMMAND_INFO_RESPONSE.build(commandData.get(9)):Collections.EMPTY_MAP; return new CommandInfo(name, arity, flags, firstKey, lastKey, step, aclCategories, tips, subcommands); } diff --git a/src/test/java/io/redis/test/annotations/EnabledOnCommand.java b/src/test/java/io/redis/test/annotations/EnabledOnCommand.java new file mode 100644 index 0000000000..1d3a963766 --- /dev/null +++ b/src/test/java/io/redis/test/annotations/EnabledOnCommand.java @@ -0,0 +1,11 @@ +package io.redis.test.annotations; + +import java.lang.annotation.*; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface EnabledOnCommand { + String value(); + String subCommand() default ""; +} \ No newline at end of file diff --git a/src/test/java/io/redis/test/annotations/SinceRedisVersion.java b/src/test/java/io/redis/test/annotations/SinceRedisVersion.java new file mode 100644 index 0000000000..9ae1d3f353 --- /dev/null +++ b/src/test/java/io/redis/test/annotations/SinceRedisVersion.java @@ -0,0 +1,11 @@ +package io.redis.test.annotations; + +import java.lang.annotation.*; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface SinceRedisVersion { + String value(); + String message() default ""; +} diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java new file mode 100644 index 0000000000..d32152341f --- /dev/null +++ b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java @@ -0,0 +1,126 @@ +package io.redis.test.utils; + +import io.redis.test.annotations.EnabledOnCommand; +import org.junit.Assume; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.*; +import redis.clients.jedis.resps.CommandInfo; + +import java.lang.reflect.Method; +import java.util.Map; + + +public class EnabledOnCommandRule implements TestRule { + private static final Logger logger = LoggerFactory.getLogger(EnabledOnCommandRule.class); + + private final HostAndPort hostPort; + private final JedisClientConfig config; + + public EnabledOnCommandRule(HostAndPort hostPort, JedisClientConfig config) { + this.hostPort = hostPort; + this.config = config; + } + + public EnabledOnCommandRule(EndpointConfig endpointConfig) { + this.hostPort = endpointConfig.getHostAndPort(); + this.config = endpointConfig.getClientConfigBuilder().build(); + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try (Jedis jedisClient = new Jedis(hostPort, config)) { + String[] command = getCommandFromAnnotations(description); + + if (command != null && !isCommandAvailable(jedisClient, command[0],command[1])) { + Assume.assumeTrue("Test requires Redis command '" + command[0] + " " + command[1] + "' to be available, but it was not found.", false); + } + + base.evaluate(); + } + } + + /** + * Retrieves the command from either class-level or method-level annotations. + * + * @param description The test description containing annotations. + * @return The Redis array containing command, subcommand from the annotations, or null if not found. + */ + private String[] getCommandFromAnnotations(Description description) { + // Retrieve class-level and method-level annotations + EnabledOnCommand descriptionCommandAnnotation = description.getAnnotation(EnabledOnCommand.class); + if (descriptionCommandAnnotation != null) { + return new String[] {descriptionCommandAnnotation.value(), descriptionCommandAnnotation.subCommand()}; + } + + EnabledOnCommand methodCommand = getMethodAnnotation(description); + if (methodCommand != null) { + return new String[] {methodCommand.value(), methodCommand.subCommand()}; + } + + EnabledOnCommand classCommand = description.getTestClass().getAnnotation(EnabledOnCommand.class); + if (classCommand != null) { + return new String[] {classCommand.value(), classCommand.subCommand()}; + } + + return null; + } + + private EnabledOnCommand getMethodAnnotation(Description description) { + try { + // description.getAnnotation() does not return anootaion when used + // with parametrised tests + String methodName = description.getMethodName(); + if (methodName != null) { + Class testClass = description.getTestClass(); + if (testClass != null) { + for (Method method : testClass.getDeclaredMethods()) { + if (method.getName().equals(methodName)) { + return method.getAnnotation(EnabledOnCommand.class); + } + } + } + } + } catch (Exception e) { + // Handle any potential exceptions here + throw new RuntimeException("Could not resolve EnabledOnCommand annotation",e); + } + return null; + } + + /** + * Checks if the specified Redis command is available. + */ + private boolean isCommandAvailable(Jedis jedisClient, String command, String subCommand) { + try { + Object raw = jedisClient.sendCommand(redis.clients.jedis.Protocol.Command.COMMAND); + Map commandList = BuilderFactory.COMMAND_INFO_RESPONSE.build(raw); + CommandInfo commandInfo = commandList.get(command.toLowerCase()); + if (commandInfo != null) { + // If a subCommand is provided, check for the subcommand under this command + if (subCommand != null && !subCommand.isEmpty()) { + // Check if this command supports the provided subcommand + for (String supportedSubCommand : commandInfo.getSubcommands()) { + if (subCommand.equalsIgnoreCase(supportedSubCommand)) { + return true; + } + } + return false; // Subcommand not found + } + return true; // Command found (no subcommand required) + } + return false; // Command not found + } catch (Exception e) { + logger.error("Error checking command '{}' availability: {}", command, e.getMessage()); + return false; + } + } + }; + } +} diff --git a/src/test/java/io/redis/test/utils/RedisInfo.java b/src/test/java/io/redis/test/utils/RedisInfo.java new file mode 100644 index 0000000000..fa69432fb2 --- /dev/null +++ b/src/test/java/io/redis/test/utils/RedisInfo.java @@ -0,0 +1,67 @@ +package io.redis.test.utils; + +import java.util.HashMap; +import java.util.Map; + +public class RedisInfo { + private final Map infoMap; + + public RedisInfo() { + this.infoMap = new HashMap<>(); + } + + public void setField(String key, String value) { + infoMap.put(key, value); + } + + public String getField(String key) { + return infoMap.get(key); + } + + public String getRedisVersion() { + return infoMap.get("redis_version"); + } + + public String getOs() { + return infoMap.get("os"); + } + + public String getMode() { + return infoMap.get("redis_mode"); + } + + public String getPorts() { + return infoMap.get("tcp_port"); // Assuming "tcp_port" is the key for ports + } + + @Override + public String toString() { + return "RedisInfo{" + + "infoMap=" + infoMap + + '}'; + } + + public static RedisInfo parseInfoServer(String infoOutput) { + RedisInfo redisInfo = new RedisInfo(); + + String[] lines = infoOutput.split("\n"); + + for (String line : lines) { + // Only parse lines that contain a colon (indicating a key-value pair) + if (line.contains(":")) { + String[] parts = line.split(":", 2); + if (parts.length == 2) { + redisInfo.setField(parts[0].trim(), parts[1].trim()); + } + } + } + + // You can still check for required fields if necessary + // Example: Ensure that specific fields are set + if (redisInfo.getField("redis_version") == null || redisInfo.getField("redis_mode") == null) { + throw new IllegalArgumentException("Missing required fields in Redis server info."); + } + + return redisInfo; + } +} \ No newline at end of file diff --git a/src/test/java/io/redis/test/utils/RedisVersion.java b/src/test/java/io/redis/test/utils/RedisVersion.java new file mode 100644 index 0000000000..a87d60262e --- /dev/null +++ b/src/test/java/io/redis/test/utils/RedisVersion.java @@ -0,0 +1,92 @@ +package io.redis.test.utils; + +public class RedisVersion implements Comparable{ + public static final RedisVersion V6_0_0 = RedisVersion.of("6.0.0"); + public static final RedisVersion V7_0_0 = RedisVersion.of("7.0.0"); + public static final RedisVersion V7_2_0 = RedisVersion.of("7.2.0"); + public static final RedisVersion V7_4 = RedisVersion.of("7.4"); + public static final RedisVersion V8_0_0 = RedisVersion.of("8.0.0"); + + private final int major; + private final int minor; + private final int patch; + + // Private constructor to enforce use of the static factory method + private RedisVersion(int major, int minor, int patch) { + this.major = major; + this.minor = minor; + this.patch = patch; + } + + // Static method to create a RedisVersion from a version string + public static RedisVersion of(String version) { + // Check for the "redis_version:" prefix and remove it if present + if (version.startsWith("redis_version:")) { + version = version.substring("redis_version:".length()); + } + + // Split the version string by the '.' character + String[] parts = version.split("\\."); + + // Parse each component, setting defaults for missing parts + int major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; + int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; + int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; + + return new RedisVersion(major, minor, patch); + } + + public int getMajor() { + return major; + } + + public int getMinor() { + return minor; + } + + public int getPatch() { + return patch; + } + + @Override + public String toString() { + return "RedisVersion{" + + "major=" + major + + ", minor=" + minor + + ", patch=" + patch + + '}'; + } + + @Override + public int compareTo(RedisVersion other) { + // Compare major, minor, and patch versions + if (this.major != other.major) { + return Integer.compare(this.major, other.major); + } + if (this.minor != other.minor) { + return Integer.compare(this.minor, other.minor); + } + return Integer.compare(this.patch, other.patch); + } + + public boolean isLessThanOrEqualTo(RedisVersion other) { + return this.compareTo(other) <= 0; + } + + public boolean isLessThan(RedisVersion other) { + return this.compareTo(other) < 0; + } + + public boolean isGreaterThanOrEqualTo(RedisVersion other) { + return this.compareTo(other) >= 0; + } + + public boolean isGreaterThan(RedisVersion other) { + return this.compareTo(other) > 0; + } + + // Static method to compare two RedisVersion instances + public static int compare(RedisVersion v1, RedisVersion v2) { + return v1.compareTo(v2); + } +} \ No newline at end of file diff --git a/src/test/java/io/redis/test/utils/RedisVersionRule.java b/src/test/java/io/redis/test/utils/RedisVersionRule.java new file mode 100644 index 0000000000..d8d8ee2770 --- /dev/null +++ b/src/test/java/io/redis/test/utils/RedisVersionRule.java @@ -0,0 +1,90 @@ +package io.redis.test.utils; + +import io.redis.test.annotations.SinceRedisVersion; +import org.junit.Assume; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.EndpointConfig; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisClientConfig; + +import java.lang.reflect.Method; + +public class RedisVersionRule implements TestRule { + private static final Logger logger = LoggerFactory.getLogger(RedisVersionRule.class); + + private final HostAndPort hostPort; + private final JedisClientConfig config; + + public RedisVersionRule(EndpointConfig endpoint) { + this.hostPort = endpoint.getHostAndPort(); + this.config = endpoint.getClientConfigBuilder().build(); + } + + public RedisVersionRule(HostAndPort hostPort, JedisClientConfig config) { + this.hostPort = hostPort; + this.config = config; + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try ( Jedis jedisClient = new Jedis(hostPort, config)) { + SinceRedisVersion descriptionVersionAnnotation = description.getAnnotation(SinceRedisVersion.class); + if (descriptionVersionAnnotation != null) { + checkRedisVersion(jedisClient, descriptionVersionAnnotation); + } + + SinceRedisVersion classVersionAnnotation = description.getTestClass().getAnnotation(SinceRedisVersion.class); + if (classVersionAnnotation != null) { + checkRedisVersion(jedisClient, classVersionAnnotation); + } + + SinceRedisVersion methodVersionAnnotation = getMethodAnnotation(description); + if (methodVersionAnnotation != null) { + checkRedisVersion(jedisClient, methodVersionAnnotation); + } + + // Return the base statement to execute the test + base.evaluate(); + } + } + private void checkRedisVersion(Jedis jedisClient, SinceRedisVersion versionAnnotation) { + RedisVersion minRequiredVersion = RedisVersion.of(versionAnnotation.value()); + RedisInfo info = RedisInfo.parseInfoServer(jedisClient.info("server")); + RedisVersion currentVersion = RedisVersion.of(info.getRedisVersion()); + if (currentVersion.isLessThan(minRequiredVersion)) { + Assume.assumeTrue("Test requires Redis version " + minRequiredVersion + " or later, but found " + currentVersion, false); + } + } + + private SinceRedisVersion getMethodAnnotation(Description description) { + try { + // description.getAnnotation() does not return any method level annotation when used + // with parametrised tests + String methodName = description.getMethodName(); + if (methodName != null) { + Class testClass = description.getTestClass(); + if (testClass != null) { + for (Method method : testClass.getDeclaredMethods()) { + if (method.getName().equals(methodName)) { + return method.getAnnotation(SinceRedisVersion.class); + } + } + } + } + } catch (Exception e) { + // Handle any potential exceptions here + throw new RuntimeException("Could not resolve EnabledOnCommand annotation", e); + } + return null; + } + }; + } +} diff --git a/src/test/java/io/redis/test/utils/RedisVersionUtil.java b/src/test/java/io/redis/test/utils/RedisVersionUtil.java new file mode 100644 index 0000000000..8ddcba16b8 --- /dev/null +++ b/src/test/java/io/redis/test/utils/RedisVersionUtil.java @@ -0,0 +1,44 @@ +package io.redis.test.utils; + +import redis.clients.jedis.*; +import redis.clients.jedis.util.SafeEncoder; + +import java.util.Map; + +import static redis.clients.jedis.util.TlsUtil.createTrustAllSslSocketFactory; + +public class RedisVersionUtil { + + + public static RedisVersion getRedisVersion(Connection conn) { + + try (Jedis jedis = new Jedis(conn)) { + Object response = SafeEncoder.encodeObject(jedis.sendCommand(Protocol.Command.INFO, "server")); + RedisInfo info = RedisInfo.parseInfoServer(response.toString()); + return RedisVersion.of(info.getRedisVersion()); + } + } + + public static RedisVersion getRedisVersion(UnifiedJedis jedis) { + + Object response = SafeEncoder.encodeObject(jedis.sendCommand(Protocol.Command.INFO, "server")); + RedisInfo info = RedisInfo.parseInfoServer(response.toString()); + return RedisVersion.of(info.getRedisVersion()); + } + + public static RedisVersion getRedisVersion(Jedis jedis) { + + RedisInfo info = RedisInfo.parseInfoServer(jedis.info("server")); + return RedisVersion.of(info.getRedisVersion()); + } + + public static RedisVersion getRedisVersion(EndpointConfig endpoint) { + DefaultJedisClientConfig.Builder builder = endpoint.getClientConfigBuilder(); + if (endpoint.isTls()) { + builder.sslSocketFactory(createTrustAllSslSocketFactory()); + } + try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), builder.build())) { + return getRedisVersion(jedis); + } + } +} diff --git a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java index 5d7579b367..0d160e8697 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java @@ -4,33 +4,33 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; import java.net.URI; import java.net.URISyntaxException; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; import redis.clients.jedis.exceptions.InvalidURIException; import redis.clients.jedis.exceptions.JedisException; -import redis.clients.jedis.util.RedisVersionUtil; /** * This test class is a copy of {@link JedisPoolTest}. *

* This test is only executed when the server/cluster is Redis 6. or more. */ +@SinceRedisVersion("6.0.0") public class ACLJedisPoolTest { private static final EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("standalone0-acl"); private static final EndpointConfig endpointWithDefaultUser = HostAndPorts.getRedisEndpoint("standalone0"); - @BeforeClass - public static void prepare() throws Exception { - // Use to check if the ACL test should be ran. ACL are available only in 6.0 and later - org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, endpoint)); - } + @ClassRule + public static RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); @Test public void checkConnections() { diff --git a/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java b/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java index b62809f0bb..a14cfbbc9a 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java @@ -1,25 +1,26 @@ package redis.clients.jedis; import static org.junit.Assert.*; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisException; -import redis.clients.jedis.util.RedisVersionUtil; /** * This test class is mostly a copy of {@link JedisSentinelPoolTest}. *

* This tests are only executed when the server/cluster is Redis 6 or more. */ +@SinceRedisVersion("6.0.0") public class ACLJedisSentinelPoolTest { private static final String MASTER_NAME = "aclmaster"; @@ -31,9 +32,10 @@ public class ACLJedisSentinelPoolTest { @BeforeClass public static void prepare() throws Exception { EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("standalone2-primary"); - org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, endpoint)); } + @ClassRule + public static RedisVersionRule versionRule = new RedisVersionRule(HostAndPorts.getRedisEndpoint("standalone2-primary")); + @Before public void setUp() throws Exception { diff --git a/src/test/java/redis/clients/jedis/ACLJedisTest.java b/src/test/java/redis/clients/jedis/ACLJedisTest.java index d1ef40b95b..1d72195a5d 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisTest.java @@ -1,6 +1,7 @@ package redis.clients.jedis; import static org.junit.Assert.assertEquals; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; import java.net.URISyntaxException; import org.junit.BeforeClass; @@ -9,7 +10,7 @@ import org.junit.runners.Parameterized; import redis.clients.jedis.commands.jedis.JedisCommandsTestBase; -import redis.clients.jedis.util.RedisVersionUtil; +import io.redis.test.utils.RedisVersion; /** * This test class is a copy of {@link JedisTest}. @@ -28,7 +29,7 @@ public class ACLJedisTest extends JedisCommandsTestBase { @BeforeClass public static void prepare() throws Exception { org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, endpoint)); + getRedisVersion(endpoint).isGreaterThanOrEqualTo(RedisVersion.of("6.0.0"))); } public ACLJedisTest(RedisProtocol redisProtocol) { diff --git a/src/test/java/redis/clients/jedis/EndpointConfig.java b/src/test/java/redis/clients/jedis/EndpointConfig.java index 68f927be0e..cae5a2139c 100644 --- a/src/test/java/redis/clients/jedis/EndpointConfig.java +++ b/src/test/java/redis/clients/jedis/EndpointConfig.java @@ -50,6 +50,10 @@ public String getHost() { public int getPort() { return getHostAndPort().getPort(); } + public Boolean isTls() { + return tls; + } + public int getBdbId() { return bdbId; } diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index f3dfe630e5..f29e735617 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -26,6 +26,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import io.redis.test.annotations.EnabledOnCommand; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.Test; @@ -667,7 +668,8 @@ public void testInvalidStartNodeNotAdded() { } @Test - public void clusterLinks2() throws InterruptedException { + @EnabledOnCommand(value = "CLUSTER", subCommand = "LINKS") + public void clusterLinks2() { Set mapKeys = new HashSet<>(Arrays.asList("direction", "node", "create-time", "events", "send-buffer-allocated", "send-buffer-used")); diff --git a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java index bb6656a812..7d9813b760 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java @@ -2,8 +2,11 @@ import static redis.clients.jedis.Protocol.CLUSTER_HASHSLOTS; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import redis.clients.jedis.args.ClusterResetType; import redis.clients.jedis.util.JedisClusterTestUtil; @@ -23,6 +26,12 @@ public abstract class JedisClusterTestBase { protected static final String LOCAL_IP = "127.0.0.1"; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(nodeInfo1,DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + + @Before public void setUp() throws InterruptedException { node1 = new Jedis(nodeInfo1); diff --git a/src/test/java/redis/clients/jedis/JedisTest.java b/src/test/java/redis/clients/jedis/JedisTest.java index 560c5a0577..adab12acf4 100644 --- a/src/test/java/redis/clients/jedis/JedisTest.java +++ b/src/test/java/redis/clients/jedis/JedisTest.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.Map; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -308,6 +309,7 @@ public void checkDisconnectOnQuit() { } @Test + @SinceRedisVersion(value = "7.2.0", message = "see https://redis.io/docs/latest/commands/client-setinfo/") public void clientSetInfoDefault() { try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder() .clientSetInfoConfig(ClientSetInfoConfig.DEFAULT).build())) { @@ -319,6 +321,7 @@ public void clientSetInfoDefault() { } @Test + @SinceRedisVersion(value = "7.2.0", message = "@see https://redis.io/docs/latest/commands/client-setinfo/") public void clientSetInfoDisabled() { try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder() .clientSetInfoConfig(ClientSetInfoConfig.DISABLED).build())) { @@ -330,6 +333,7 @@ public void clientSetInfoDisabled() { } @Test + @SinceRedisVersion(value = "7.2.0", message = "@see https://redis.io/docs/latest/commands/client-setinfo/") public void clientSetInfoLibNameSuffix() { final String libNameSuffix = "for-redis"; ClientSetInfoConfig setInfoConfig = ClientSetInfoConfig.withLibNameSuffix(libNameSuffix); diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index 16eb63c0e0..d0ab1cfd22 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -2,102 +2,147 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static redis.clients.jedis.util.TlsUtil.*; import java.util.Collections; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLParameters; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionRule; +import io.redis.test.utils.RedisVersionUtil; +import org.junit.*; +import redis.clients.jedis.util.TlsUtil; import redis.clients.jedis.exceptions.JedisClusterOperationException; -import redis.clients.jedis.SSLJedisTest.BasicHostnameVerifier; -import redis.clients.jedis.util.RedisVersionUtil; +@SinceRedisVersion("6.0.0") public class SSLACLJedisClusterTest extends JedisClusterTestBase { private static final int DEFAULT_REDIRECTIONS = 5; private static final ConnectionPoolConfig DEFAULT_POOL_CONFIG = new ConnectionPoolConfig(); - private final HostAndPortMapper hostAndPortMap = (HostAndPort hostAndPort) -> { - String host = hostAndPort.getHost(); - int port = hostAndPort.getPort(); - if (host.equals("127.0.0.1")) { - host = "localhost"; - port = port + 1000; - } - return new HostAndPort(host, port); - }; - // don't map IP addresses so that we try to connect with host 127.0.0.1 - private final HostAndPortMapper portMap = (HostAndPort hostAndPort) -> { - if ("localhost".equals(hostAndPort.getHost())) { - return hostAndPort; - } - return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() + 1000); - }; + // legacy test env bootstrap uses stunnel causing redis server to report non-tls port instead tls one + // containerised test env enables tls directly on Redis nodes and in this case tls_port is correctly reported + // TODO : remove stunnel from legacy env + // static int tlsPortOffset = 0; + HostAndPortMapper hostAndPortMap = (hostAndPort) -> { + String host = hostAndPort.getHost(); + int port = hostAndPort.getPort(); + + if ("127.0.0.1".equals(host)) { + host = "localhost"; + //port += tlsPortOffset; // Apply the port offset + } + + return new HostAndPort(host, port); + }; + + // don't map IP addresses so that we try to connect with host 127.0.0.1 + HostAndPortMapper portMap = (hostAndPort) -> { + if ("localhost".equals(hostAndPort.getHost())) { + return hostAndPort; + } + return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() /* + tlsPortOffset */); + }; + @BeforeClass public static void prepare() { - // We need to set up certificates first before connecting to the endpoint with enabled TLS - SSLJedisTest.setupTrustStore(); - - // TODO(imalinovskyi): Remove hardcoded connection settings - // once this test is refactored to support RE - org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, - new EndpointConfig(new HostAndPort("localhost", 8379), - "default", "cluster", true))); + TlsUtil.createAndSaveEnvTruststore("cluster-unbound", "changeit"); } @Test public void testSSLDiscoverNodesAutomatically() { + DefaultJedisClientConfig config = DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap) + .build(); + try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { - Map clusterNodes = jc.getClusterNodes(); + config, + DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG) + ) { + Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + + /** + * In versions prior to Redis 7.x, Redis does not natively support automatic port switching between TLS and non-TLS ports for CLUSTER SLOTS. + * When using Redis 6.2.16 in a cluster mode with TLS, CLUSTER command returns the regular (non-TLS) port rather than the TLS port. + */ + if (RedisVersionUtil.getRedisVersion(jc.getConnectionFromSlot(0)).isLessThanOrEqualTo(RedisVersion.V7_0_0)) { + assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + } else { + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); + } jc.get("foo"); } try (JedisCluster jc2 = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap) + .build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { Map clusterNodes = jc2.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); jc2.get("foo"); } } + @Test public void testSSLWithoutPortMap() { try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// Map clusterNodes = jc.getClusterNodes(); Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + /** + * In versions prior to Redis 7.x, Redis does not natively support automatic port switching between TLS and non-TLS ports for CLUSTER SLOTS. + * When using Redis 6.2.16 in a cluster mode with TLS, CLUSTER command returns the regular (non-TLS) port rather than the TLS port. + */ + if (RedisVersionUtil.getRedisVersion(jc.getConnectionFromSlot(0)).isLessThanOrEqualTo(RedisVersion.V7_0_0)) { + assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + } else { + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); + } } } @Test public void connectByIpAddress() { - try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 7379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), + try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); } @@ -109,12 +154,16 @@ public void connectToNodesFailsWithSSLParametersAndNoHostMapping() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, - DEFAULT_POOL_CONFIG)) { + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .sslParameters(sslParameters) + .hostAndPortMapper(portMap) + .build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); Assert.fail("It should fail after all cluster attempts."); -// } catch (JedisClusterMaxAttemptsException e) { } catch (JedisClusterOperationException e) { // initial connection to localhost works, but subsequent connections to nodes use 127.0.0.1 // and fail hostname verification @@ -128,8 +177,13 @@ public void connectToNodesSucceedsWithSSLParametersAndHostMapping() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(hostAndPortMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .sslParameters(sslParameters) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); } @@ -141,30 +195,33 @@ public void connectByIpAddressFailsWithSSLParameters() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(hostAndPortMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .sslParameters(sslParameters).hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc.get("key"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { } catch (JedisClusterOperationException e) { -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } } @Test public void connectWithCustomHostNameVerifier() { - HostnameVerifier hostnameVerifier = new BasicHostnameVerifier(); - HostnameVerifier localhostVerifier = new LocalhostVerifier(); + HostnameVerifier hostnameVerifier = new TlsUtil.BasicHostnameVerifier(); + HostnameVerifier localhostVerifier = new TlsUtil.LocalhostVerifier(); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); Assert.fail("It should fail after all cluster attempts."); -// } catch (JedisClusterMaxAttemptsException e) { } catch (JedisClusterOperationException e) { // initial connection made with 'localhost' but subsequent connections to nodes use 127.0.0.1 // which causes custom hostname verification to fail @@ -172,34 +229,41 @@ public void connectWithCustomHostNameVerifier() { } try (JedisCluster jc2 = new JedisCluster(new HostAndPort("127.0.0.1", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc2.get("key"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { } catch (JedisClusterOperationException e) { // JedisNoReachableClusterNodeException exception occurs from not being able to connect since // the socket factory fails the hostname verification -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } try (JedisCluster jc3 = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .hostnameVerifier(localhostVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(localhostVerifier) + .hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc3.get("foo"); } } @Test - public void connectWithCustomSocketFactory() throws Exception { - final SSLSocketFactory sslSocketFactory = SSLJedisTest.createTrustStoreSslSocketFactory(); - + public void connectWithCustomSocketFactory() { try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .sslSocketFactory(sslSocketFactory).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { assertEquals(3, jc.getClusterNodes().size()); } @@ -207,16 +271,14 @@ public void connectWithCustomSocketFactory() throws Exception { @Test public void connectWithEmptyTrustStore() throws Exception { - final SSLSocketFactory sslSocketFactory = SSLJedisTest.createTrustNoOneSslSocketFactory(); - try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(true) - .sslSocketFactory(sslSocketFactory).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc.get("key"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { + DefaultJedisClientConfig.builder() + .user("default") + .password("cluster") + .sslSocketFactory(createTrustNoOneSslSocketFactory()) + .ssl(true) + .build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { } catch (JedisClusterOperationException e) { -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } } @@ -228,21 +290,11 @@ public void defaultHostAndPortUsedIfMapReturnsNull() { try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 7379), DefaultJedisClientConfig.builder().user("default").password("cluster").ssl(false) .hostAndPortMapper(nullHostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { - Map clusterNodes = jc.getClusterNodes(); + Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); } } - - public class LocalhostVerifier extends BasicHostnameVerifier { - @Override - public boolean verify(String hostname, SSLSession session) { - if (hostname.equals("127.0.0.1")) { - hostname = "localhost"; - } - return super.verify(hostname, session); - } - } } diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java index 8151729e6e..d90965aa0f 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java @@ -1,20 +1,17 @@ package redis.clients.jedis; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; import static org.junit.Assert.*; +import static redis.clients.jedis.util.TlsUtil.*; -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import javax.net.ssl.*; +import java.nio.file.Path; +import org.junit.AfterClass; +import io.redis.test.utils.RedisVersion; +import redis.clients.jedis.util.TlsUtil; import org.junit.BeforeClass; import org.junit.Test; -import redis.clients.jedis.util.RedisVersionUtil; - /** * This test class is a copy of {@link SSLJedisTest}. *

@@ -26,18 +23,28 @@ public class SSLACLJedisTest { protected static final EndpointConfig endpointWithDefaultUser = HostAndPorts.getRedisEndpoint("standalone0-tls"); + @BeforeClass public static void prepare() { - // We need to set up certificates first before connecting to the endpoint with enabled TLS - SSLJedisTest.setupTrustStore(); + Path trusStorePath = createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); // Use to check if the ACL test should be ran. ACL are available only in 6.0 and later org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, endpoint)); + getRedisVersion(endpoint).isGreaterThanOrEqualTo(RedisVersion.V6_0_0)); + } + + @AfterClass + public static void teardownTrustStore() { + TlsUtil.restoreOriginalTrustStore(); } @Test public void connectWithSsl() { - try (Jedis jedis = new Jedis(endpoint.getHost(), endpoint.getPort(), true)) { + try (Jedis jedis = new Jedis(endpoint.getHost(), endpoint.getPort(), + DefaultJedisClientConfig.builder() + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .ssl(true) + .build())) { jedis.auth(endpoint.getUsername(), endpoint.getPassword()); assertEquals("PONG", jedis.ping()); } @@ -46,7 +53,9 @@ public void connectWithSsl() { @Test public void connectWithConfig() { try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), - DefaultJedisClientConfig.builder().ssl(true).build())) { + DefaultJedisClientConfig.builder() + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .ssl(true).build())) { jedis.auth(endpoint.getUsername(), endpoint.getPassword()); assertEquals("PONG", jedis.ping()); } @@ -69,84 +78,18 @@ public void connectWithUrl() { public void connectWithUri() { // The "rediss" scheme instructs jedis to open a SSL/TLS connection. try (Jedis jedis = new Jedis( - endpointWithDefaultUser.getURIBuilder().defaultCredentials().build())) { + endpointWithDefaultUser.getURIBuilder() + .defaultCredentials().build(), + DefaultJedisClientConfig.builder() + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .build())) { assertEquals("PONG", jedis.ping()); } - try (Jedis jedis = new Jedis(endpoint.getURIBuilder().defaultCredentials().build())) { + try (Jedis jedis = new Jedis(endpoint.getURIBuilder().defaultCredentials().build(), + DefaultJedisClientConfig.builder() + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .build())) { assertEquals("PONG", jedis.ping()); } } - - /** - * Creates an SSLSocketFactory that trusts all certificates in truststore.jceks. - */ - static SSLSocketFactory createTrustStoreSslSocketFactory() throws Exception { - - KeyStore trustStore = KeyStore.getInstance("jceks"); - try (InputStream inputStream = new FileInputStream("src/test/resources/truststore.jceks")) { - trustStore.load(inputStream, null); - } - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); - trustManagerFactory.init(trustStore); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustManagers, new SecureRandom()); - return sslContext.getSocketFactory(); - } - - /** - * Creates an SSLSocketFactory with a trust manager that does not trust any certificates. - */ - static SSLSocketFactory createTrustNoOneSslSocketFactory() throws Exception { - TrustManager[] unTrustManagers = new TrustManager[] { new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) { - throw new RuntimeException(new InvalidAlgorithmParameterException()); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) { - throw new RuntimeException(new InvalidAlgorithmParameterException()); - } - } }; - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, unTrustManagers, new SecureRandom()); - return sslContext.getSocketFactory(); - } - - /** - * Very basic hostname verifier implementation for testing. NOT recommended for production. - */ - static class BasicHostnameVerifier implements HostnameVerifier { - - private static final String COMMON_NAME_RDN_PREFIX = "CN="; - - @Override - public boolean verify(String hostname, SSLSession session) { - X509Certificate peerCertificate; - try { - peerCertificate = (X509Certificate) session.getPeerCertificates()[0]; - } catch (SSLPeerUnverifiedException e) { - throw new IllegalStateException("The session does not contain a peer X.509 certificate.", e); - } - String peerCertificateCN = getCommonName(peerCertificate); - return hostname.equals(peerCertificateCN); - } - - private String getCommonName(X509Certificate peerCertificate) { - String subjectDN = peerCertificate.getSubjectDN().getName(); - String[] dnComponents = subjectDN.split(","); - for (String dnComponent : dnComponents) { - dnComponent = dnComponent.trim(); - if (dnComponent.startsWith(COMMON_NAME_RDN_PREFIX)) { - return dnComponent.substring(COMMON_NAME_RDN_PREFIX.length()); - } - } - throw new IllegalArgumentException("The certificate has no common name."); - } - } } diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index f4763fe875..3abf60ef15 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -2,20 +2,22 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static redis.clients.jedis.util.TlsUtil.*; import java.util.Collections; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLParameters; -import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.TlsUtil; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import redis.clients.jedis.exceptions.JedisClusterOperationException; -import redis.clients.jedis.SSLJedisTest.BasicHostnameVerifier; public class SSLJedisClusterTest extends JedisClusterTestBase { @@ -27,7 +29,7 @@ public class SSLJedisClusterTest extends JedisClusterTestBase { int port = hostAndPort.getPort(); if (host.equals("127.0.0.1")) { host = "localhost"; - port = port + 1000; + //port = port + 1000; } return new HostAndPort(host, port); }; @@ -37,38 +39,52 @@ public class SSLJedisClusterTest extends JedisClusterTestBase { if ("localhost".equals(hostAndPort.getHost())) { return hostAndPort; } - return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() + 1000); + //return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() + 1000); + return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() ); }; @BeforeClass public static void prepare() { - SSLJedisTest.setupTrustStore(); // set up trust store for SSL tests + TlsUtil.createAndSaveEnvTruststore("cluster-unbound", "changeit"); } @Test public void testSSLDiscoverNodesAutomatically() { try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// Map clusterNodes = jc.getClusterNodes(); + DefaultJedisClientConfig.builder().password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + /** + * In versions prior to Redis 7.x, Redis does not natively support automatic port switching between TLS and non-TLS ports for CLUSTER SLOTS. + * When using Redis 6.2.16 in a cluster mode with TLS, CLUSTER command returns the regular (non-TLS) port rather than the TLS port. + */ + if (RedisVersionUtil.getRedisVersion(jc.getConnectionFromSlot(0)).isLessThanOrEqualTo(RedisVersion.V7_0_0)) { + assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + } else { + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); + } jc.get("foo"); } try (JedisCluster jc2 = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// Map clusterNodes = jc2.getClusterNodes(); + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { Map clusterNodes = jc2.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); jc2.get("foo"); } } @@ -76,22 +92,37 @@ public void testSSLDiscoverNodesAutomatically() { @Test public void testSSLWithoutPortMap() { try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), - DefaultJedisClientConfig.builder().password("cluster").ssl(true).build(), - DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// Map clusterNodes = jc.getClusterNodes(); + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true).build(), + DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); - assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); - assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + /** + * In versions prior to Redis 7.x, Redis does not natively support automatic port switching between TLS and non-TLS ports for CLUSTER SLOTS. + * When using Redis 6.2.16 in a cluster mode with TLS, CLUSTER command returns the regular (non-TLS) port rather than the TLS port. + */ + if (RedisVersionUtil.getRedisVersion(jc.getConnectionFromSlot(0)).isLessThanOrEqualTo(RedisVersion.V7_0_0)) { + assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); + } else { + assertTrue(clusterNodes.containsKey("127.0.0.1:8379")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8380")); + assertTrue(clusterNodes.containsKey("127.0.0.1:8381")); + } } } @Test public void connectByIpAddress() { - try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 7379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostAndPortMapper(hostAndPortMap).build(), + try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); } @@ -103,12 +134,14 @@ public void connectToNodesFailsWithSSLParametersAndNoHostMapping() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .sslParameters(sslParameters).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); Assert.fail("It should fail after all cluster attempts."); -// } catch (JedisClusterMaxAttemptsException e) { } catch (JedisClusterOperationException e) { // initial connection to localhost works, but subsequent connections to nodes use 127.0.0.1 // and fail hostname verification @@ -122,8 +155,12 @@ public void connectToNodesSucceedsWithSSLParametersAndHostMapping() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(hostAndPortMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .sslParameters(sslParameters) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); } @@ -135,26 +172,30 @@ public void connectByIpAddressFailsWithSSLParameters() { sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .sslParameters(sslParameters).hostAndPortMapper(hostAndPortMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .ssl(true) + .sslParameters(sslParameters) + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .hostAndPortMapper(hostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc.get("key"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { } catch (JedisClusterOperationException e) { -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } } @Test public void connectWithCustomHostNameVerifier() { - HostnameVerifier hostnameVerifier = new BasicHostnameVerifier(); - HostnameVerifier localhostVerifier = new LocalhostVerifier(); + HostnameVerifier hostnameVerifier = new TlsUtil.BasicHostnameVerifier(); + HostnameVerifier localhostVerifier = new TlsUtil.LocalhostVerifier(); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(hostnameVerifier) + .hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc.get("foo"); Assert.fail("It should fail after all cluster attempts."); @@ -166,22 +207,23 @@ public void connectWithCustomHostNameVerifier() { } try (JedisCluster jc2 = new JedisCluster(new HostAndPort("127.0.0.1", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostnameVerifier(hostnameVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(hostnameVerifier) + .hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc2.get("foo"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { } catch (JedisClusterOperationException e) { - // JedisNoReachableClusterNodeException exception occurs from not being able to connect - // since the socket factory fails the hostname verification -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } try (JedisCluster jc3 = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .hostnameVerifier(localhostVerifier).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostnameVerifier(localhostVerifier).hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { jc3.get("foo"); } @@ -189,11 +231,13 @@ public void connectWithCustomHostNameVerifier() { @Test public void connectWithCustomSocketFactory() throws Exception { - final SSLSocketFactory sslSocketFactory = SSLJedisTest.createTrustStoreSslSocketFactory(); try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .sslSocketFactory(sslSocketFactory).hostAndPortMapper(portMap).build(), + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(sslSocketFactoryForEnv("cluster-unbound")) + .ssl(true) + .hostAndPortMapper(portMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { assertEquals(3, jc.getClusterNodes().size()); } @@ -201,16 +245,13 @@ public void connectWithCustomSocketFactory() throws Exception { @Test public void connectWithEmptyTrustStore() throws Exception { - final SSLSocketFactory sslSocketFactory = SSLJedisTest.createTrustNoOneSslSocketFactory(); - try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 8379), - DefaultJedisClientConfig.builder().password("cluster").ssl(true) - .sslSocketFactory(sslSocketFactory).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// jc.get("key"); -// Assert.fail("There should be no reachable node in cluster."); -//// } catch (JedisNoReachableClusterNodeException e) { + DefaultJedisClientConfig.builder() + .password("cluster") + .sslSocketFactory(createTrustNoOneSslSocketFactory()) + .ssl(true) + .build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { } catch (JedisClusterOperationException e) { -// assertEquals("No reachable node in cluster.", e.getMessage()); assertEquals("Could not initialize cluster slots cache.", e.getMessage()); } } @@ -220,10 +261,11 @@ public void defaultHostAndPortUsedIfMapReturnsNull() { HostAndPortMapper nullHostAndPortMap = (HostAndPort hostAndPort) -> null; try (JedisCluster jc = new JedisCluster(new HostAndPort("localhost", 7379), - DefaultJedisClientConfig.builder().password("cluster").ssl(false) + DefaultJedisClientConfig.builder() + .password("cluster") + .ssl(false) .hostAndPortMapper(nullHostAndPortMap).build(), DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { -// Map clusterNodes = jc.getClusterNodes(); Map clusterNodes = jc.getClusterNodes(); assertEquals(3, clusterNodes.size()); assertTrue(clusterNodes.containsKey("127.0.0.1:7379")); @@ -231,14 +273,4 @@ public void defaultHostAndPortUsedIfMapReturnsNull() { assertTrue(clusterNodes.containsKey("127.0.0.1:7381")); } } - - public class LocalhostVerifier extends BasicHostnameVerifier { - @Override - public boolean verify(String hostname, SSLSession session) { - if (hostname.equals("127.0.0.1")) { - hostname = "localhost"; - } - return super.verify(hostname, session); - } - } } diff --git a/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java b/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java index 7468c9abfa..1490cb5af5 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java @@ -2,10 +2,14 @@ import java.util.HashSet; import java.util.Set; + +import redis.clients.jedis.util.TlsUtil; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.BeforeClass; import org.junit.Test; +import static redis.clients.jedis.util.TlsUtil.envTruststore; + public class SSLJedisSentinelPoolTest { private static final String MASTER_NAME = "aclmaster"; @@ -19,7 +23,8 @@ public class SSLJedisSentinelPoolTest { @BeforeClass public static void prepare() { - SSLJedisTest.setupTrustStore(); + TlsUtil.createAndSaveEnvTruststore("redis9-sentinel", "changeit"); + //TlsUtil.setJvmTrustStore(envTruststore("redis9-sentinel")); sentinels.add(HostAndPorts.getSentinelServers().get(4)); } @@ -28,11 +33,18 @@ public static void prepare() { public void sentinelWithoutSslConnectsToRedisWithSsl() { DefaultJedisClientConfig masterConfig = DefaultJedisClientConfig.builder() - .user("acljedis").password("fizzbuzz").clientName("master-client").ssl(true) - .hostAndPortMapper(SSL_PORT_MAPPER).build(); + .user("acljedis") + .password("fizzbuzz") + .clientName("master-client") + .sslSocketFactory(TlsUtil.sslSocketFactoryForEnv("redis9-sentinel")) + .ssl(true) + .hostAndPortMapper(SSL_PORT_MAPPER).build(); DefaultJedisClientConfig sentinelConfig = DefaultJedisClientConfig.builder() - .user("sentinel").password("foobared").clientName("sentinel-client").ssl(false).build(); + .user("sentinel") + .password("foobared") + .clientName("sentinel-client") + .ssl(false).build(); try (JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels, masterConfig, sentinelConfig)) { pool.getResource().close(); @@ -48,11 +60,18 @@ public void sentinelWithoutSslConnectsToRedisWithSsl() { public void sentinelWithSslConnectsToRedisWithoutSsl() { DefaultJedisClientConfig masterConfig = DefaultJedisClientConfig.builder() - .user("acljedis").password("fizzbuzz").clientName("master-client").ssl(false).build(); + .user("acljedis") + .password("fizzbuzz") + .clientName("master-client") + .ssl(false).build(); DefaultJedisClientConfig sentinelConfig = DefaultJedisClientConfig.builder() - .user("sentinel").password("foobared").clientName("sentinel-client") - .ssl(true).hostAndPortMapper(SSL_PORT_MAPPER).build(); + .user("sentinel") + .password("foobared") + .clientName("sentinel-client") + .sslSocketFactory(TlsUtil.sslSocketFactoryForEnv("redis9-sentinel")) + .ssl(true) + .hostAndPortMapper(SSL_PORT_MAPPER).build(); try (JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels, masterConfig, sentinelConfig)) { pool.getResource().close(); @@ -68,12 +87,20 @@ public void sentinelWithSslConnectsToRedisWithoutSsl() { public void sentinelWithSslConnectsToRedisWithSsl() { DefaultJedisClientConfig masterConfig = DefaultJedisClientConfig.builder() - .user("acljedis").password("fizzbuzz").clientName("master-client").ssl(true) - .hostAndPortMapper(SSL_PORT_MAPPER).build(); + .user("acljedis") + .password("fizzbuzz") + .clientName("master-client") + .sslSocketFactory(TlsUtil.sslSocketFactoryForEnv("redis9-sentinel")) + .ssl(true) + .hostAndPortMapper(SSL_PORT_MAPPER).build(); DefaultJedisClientConfig sentinelConfig = DefaultJedisClientConfig.builder() - .user("sentinel").password("foobared").clientName("sentinel-client") - .ssl(true).hostAndPortMapper(SSL_PORT_MAPPER).build(); + .user("sentinel") + .password("foobared") + .clientName("sentinel-client") + .sslSocketFactory(TlsUtil.sslSocketFactoryForEnv("redis9-sentinel")) + .ssl(true) + .hostAndPortMapper(SSL_PORT_MAPPER).build(); try (JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels, masterConfig, sentinelConfig)) { pool.getResource().close(); diff --git a/src/test/java/redis/clients/jedis/SSLJedisTest.java b/src/test/java/redis/clients/jedis/SSLJedisTest.java index 4ef4f969bb..89a448fd30 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisTest.java @@ -1,174 +1,86 @@ package redis.clients.jedis; +import static redis.clients.jedis.util.TlsUtil.envTruststore; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - +import org.junit.AfterClass; +import redis.clients.jedis.util.TlsUtil; import org.junit.BeforeClass; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class SSLJedisTest { - - protected static final EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("standalone0-tls"); - - @BeforeClass - public static void prepare() { - setupTrustStore(); - } - - public static void setupTrustStore() { - setJvmTrustStore("src/test/resources/truststore.jceks", "jceks"); - } +import java.nio.file.Path; - private static void setJvmTrustStore(String trustStoreFilePath, String trustStoreType) { - assertTrue(String.format("Could not find trust store at '%s'.", trustStoreFilePath), - new File(trustStoreFilePath).exists()); - System.setProperty("javax.net.ssl.trustStore", trustStoreFilePath); - System.setProperty("javax.net.ssl.trustStoreType", trustStoreType); - } - - @Test - public void connectWithSsl() { - try (Jedis jedis = new Jedis(endpoint.getHost(), endpoint.getPort(), true)) { - jedis.auth(endpoint.getPassword()); - assertEquals("PONG", jedis.ping()); - } - } +public class SSLJedisTest { + static Logger log = LoggerFactory.getLogger(SSLJedisTest.class); + protected static final EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("standalone0-tls"); - @Test - public void connectWithConfig() { - try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), - DefaultJedisClientConfig.builder().ssl(true).build())) { - jedis.auth(endpoint.getPassword()); - assertEquals("PONG", jedis.ping()); + @BeforeClass + public static void prepare() { + Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); } - } - @Test - public void connectWithConfigInterface() { - try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), - new JedisClientConfig() { - @Override - public boolean isSsl() { - return true; - } - })) { - jedis.auth(endpoint.getPassword()); - assertEquals("PONG", jedis.ping()); + @AfterClass + public static void teardownTrustStore() { + TlsUtil.restoreOriginalTrustStore(); } - } - /** - * Tests opening a default SSL/TLS connection to redis using "rediss://" scheme url. - */ - @Test - public void connectWithUrl() { - // The "rediss" scheme instructs jedis to open a SSL/TLS connection. - try (Jedis jedis = new Jedis(endpoint.getURI().toString())) { - jedis.auth(endpoint.getPassword()); - assertEquals("PONG", jedis.ping()); + @Test + public void connectWithSsl() { + try (Jedis jedis = new Jedis(endpoint.getHost(), endpoint.getPort(), true)) { + jedis.auth(endpoint.getPassword()); + assertEquals("PONG", jedis.ping()); + } } - } - /** - * Tests opening a default SSL/TLS connection to redis. - */ - @Test - public void connectWithUri() { - // The "rediss" scheme instructs jedis to open a SSL/TLS connection. - try (Jedis jedis = new Jedis(endpoint.getURI())) { - jedis.auth(endpoint.getPassword()); - assertEquals("PONG", jedis.ping()); + @Test + public void connectWithConfig() { + try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), + DefaultJedisClientConfig.builder().ssl(true).build())) { + jedis.auth(endpoint.getPassword()); + assertEquals("PONG", jedis.ping()); + } } - } - - /** - * Creates an SSLSocketFactory that trusts all certificates in truststore.jceks. - */ - static SSLSocketFactory createTrustStoreSslSocketFactory() throws Exception { - KeyStore trustStore = KeyStore.getInstance("jceks"); - - try (InputStream inputStream = new FileInputStream("src/test/resources/truststore.jceks")) { - trustStore.load(inputStream, null); + @Test + public void connectWithConfigInterface() { + try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), + new JedisClientConfig() { + @Override + public boolean isSsl() { + return true; + } + })) { + jedis.auth(endpoint.getPassword()); + assertEquals("PONG", jedis.ping()); + } } - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); - trustManagerFactory.init(trustStore); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustManagers, new SecureRandom()); - return sslContext.getSocketFactory(); - } - - /** - * Creates an SSLSocketFactory with a trust manager that does not trust any certificates. - */ - static SSLSocketFactory createTrustNoOneSslSocketFactory() throws Exception { - TrustManager[] unTrustManagers = new TrustManager[] { new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) { - throw new RuntimeException(new InvalidAlgorithmParameterException()); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) { - throw new RuntimeException(new InvalidAlgorithmParameterException()); - } - } }; - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, unTrustManagers, new SecureRandom()); - return sslContext.getSocketFactory(); - } - - /** - * Very basic hostname verifier implementation for testing. NOT recommended for production. - */ - static class BasicHostnameVerifier implements HostnameVerifier { - - private static final String COMMON_NAME_RDN_PREFIX = "CN="; - - @Override - public boolean verify(String hostname, SSLSession session) { - X509Certificate peerCertificate; - try { - peerCertificate = (X509Certificate) session.getPeerCertificates()[0]; - } catch (SSLPeerUnverifiedException e) { - throw new IllegalStateException("The session does not contain a peer X.509 certificate.", e); - } - String peerCertificateCN = getCommonName(peerCertificate); - return hostname.equals(peerCertificateCN); + /** + * Tests opening a default SSL/TLS connection to redis using "rediss://" scheme url. + */ + @Test + public void connectWithUrl() { + // The "rediss" scheme instructs jedis to open a SSL/TLS connection. + try (Jedis jedis = new Jedis(endpoint.getURI().toString())) { + jedis.auth(endpoint.getPassword()); + assertEquals("PONG", jedis.ping()); + } } - private String getCommonName(X509Certificate peerCertificate) { - String subjectDN = peerCertificate.getSubjectDN().getName(); - String[] dnComponents = subjectDN.split(","); - for (String dnComponent : dnComponents) { - dnComponent = dnComponent.trim(); - if (dnComponent.startsWith(COMMON_NAME_RDN_PREFIX)) { - return dnComponent.substring(COMMON_NAME_RDN_PREFIX.length()); + /** + * Tests opening a default SSL/TLS connection to redis. + */ + @Test + public void connectWithUri() { + // The "rediss" scheme instructs jedis to open a SSL/TLS connection. + try (Jedis jedis = new Jedis(endpoint.getURI())) { + jedis.auth(endpoint.getPassword()); + assertEquals("PONG", jedis.ping()); } - } - throw new IllegalArgumentException("The certificate has no common name."); } - } + } diff --git a/src/test/java/redis/clients/jedis/UdsTest.java b/src/test/java/redis/clients/jedis/UdsTest.java index e29c65dedd..7993b06107 100644 --- a/src/test/java/redis/clients/jedis/UdsTest.java +++ b/src/test/java/redis/clients/jedis/UdsTest.java @@ -3,14 +3,22 @@ import java.io.File; import java.io.IOException; import java.net.Socket; + +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; import org.newsclub.net.unix.AFUNIXSocket; import org.newsclub.net.unix.AFUNIXSocketAddress; import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.util.TestEnvUtil; import static org.junit.Assert.assertEquals; public class UdsTest { + @BeforeClass + public static void checkDockerEnvironment() { + Assume.assumeFalse("Unix sockets tests not supported against dockerised test env yet!", TestEnvUtil.isContainerEnv()); + } @Test public void jedisConnectsToUds() { diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsBitmapCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsBitmapCommandsTest.java index 5427447100..3c511fa823 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsBitmapCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsBitmapCommandsTest.java @@ -6,6 +6,7 @@ import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.BitCountOption; @@ -52,6 +53,7 @@ public void testSetbitAndGetbitBinary() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added the BYTE|BIT option.") public void testBitcount() { String key = "bitcountKey"; byte[] keyBytes = key.getBytes(); @@ -82,6 +84,7 @@ public void testBitcount() { } @Test + @SinceRedisVersion(value = "7.0.0", message="Starting with Redis version 7.0.0: Added the BYTE|BIT option.") public void testBitpos() { String key = "bitposKey"; byte[] keyBytes = key.getBytes(); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsGenericCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsGenericCommandsTest.java index f558a4f686..d9072d9736 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsGenericCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsGenericCommandsTest.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.RedisProtocol; @@ -202,6 +203,7 @@ public void testDumpAndRestoreBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAndExpireTime() { String key = "expireKey"; String value = "value"; @@ -221,6 +223,7 @@ public void testExpireAndExpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAndExpireTimeBinary() { byte[] key = "expireKey".getBytes(); byte[] value = "value".getBytes(); @@ -240,6 +243,7 @@ public void testExpireAndExpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireWithExpiryOption() { String key = "expireWithOptionKey"; String value = "value"; @@ -263,6 +267,7 @@ public void testExpireWithExpiryOption() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireWithExpiryOptionTimeBinary() { byte[] key = "expireWithOptionKey".getBytes(); byte[] value = "value".getBytes(); @@ -286,6 +291,7 @@ public void testExpireWithExpiryOptionTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireAndPexpireTime() { String key = "pexpireKey"; String value = "value"; @@ -305,6 +311,7 @@ public void testPexpireAndPexpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireAndPexpireTimeBinary() { byte[] key = "pexpireKey".getBytes(); byte[] value = "value".getBytes(); @@ -324,6 +331,7 @@ public void testPexpireAndPexpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireWithOptionsAndPexpireTime() { String key = "pexpireWithOptionsKey"; String value = "value"; @@ -349,6 +357,7 @@ public void testPexpireWithOptionsAndPexpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void testPexpireWithOptionsAndPexpireTimeBinary() { byte[] key = "pexpireWithOptionsKey".getBytes(); byte[] value = "value".getBytes(); @@ -374,6 +383,7 @@ public void testPexpireWithOptionsAndPexpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAtAndExpireTime() { String key = "expireAtKey"; String value = "value"; @@ -399,6 +409,7 @@ public void testExpireAtAndExpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAtAndExpireTimeBinary() { byte[] key = "expireAtKey".getBytes(); byte[] value = "value".getBytes(); @@ -424,6 +435,7 @@ public void testExpireAtAndExpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAtWithOptionsAndExpireTime() { String key = "expireAtWithOptionsKey"; String value = "value"; @@ -456,6 +468,7 @@ public void testExpireAtWithOptionsAndExpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testExpireAtWithOptionsAndExpireTimeBinary() { byte[] key = "expireAtWithOptionsKey".getBytes(); byte[] value = "value".getBytes(); @@ -488,6 +501,7 @@ public void testExpireAtWithOptionsAndExpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireAtAndPexpireTime() { String key = "pexpireAtKey"; String value = "value"; @@ -512,6 +526,7 @@ public void testPexpireAtAndPexpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireAtAndPexpireTimeBinary() { byte[] key = "pexpireAtKey".getBytes(); byte[] value = "value".getBytes(); @@ -536,6 +551,7 @@ public void testPexpireAtAndPexpireTimeBinary() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void testPexpireAtWithOptionsAndPexpireTime() { String key = "pexpireAtWithOptionsKey"; String value = "value"; @@ -568,6 +584,7 @@ public void testPexpireAtWithOptionsAndPexpireTime() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testPexpireAtWithOptionsAndPexpireTimeBinary() { byte[] key = "pexpireAtWithOptionsKey".getBytes(); byte[] value = "value".getBytes(); @@ -812,6 +829,7 @@ public void testSortWithParamsAndStoreBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testSortReadonly() { String listKey = "readonlySortList"; @@ -824,6 +842,7 @@ public void testSortReadonly() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testSortReadonlyBinary() { byte[] listKey = "readonlySortList".getBytes(); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsHashCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsHashCommandsTest.java index a8de3122ab..73013bb24e 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsHashCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsHashCommandsTest.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.ExpiryOption; @@ -351,6 +352,7 @@ public void testHashRandfield() { } @Test + @SinceRedisVersion("7.4.0") public void testHscan() { String key = "testHashScan"; byte[] bkey = key.getBytes(); @@ -416,6 +418,7 @@ public void testHashStrlen() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttl() { long seconds1 = 20; long seconds2 = 10; @@ -433,6 +436,7 @@ public void hexpireAndHttl() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttlBinary() { long seconds1 = 20; long seconds2 = 10; @@ -450,6 +454,7 @@ public void hexpireAndHttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttl() { long millis1 = 20_000; long millis2 = 10_000; @@ -465,6 +470,7 @@ public void hpexpireAndHpttl() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttlBinary() { long millis1 = 20_000; long millis2 = 10_000; @@ -480,6 +486,7 @@ public void hpexpireAndHpttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTime() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -498,6 +505,7 @@ public void hexpireAtAndExpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTimeBinary() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -516,6 +524,7 @@ public void hexpireAtAndExpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTime() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -531,6 +540,7 @@ public void hpexpireAtAndPexpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTimeBinary() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -546,6 +556,7 @@ public void hpexpireAtAndPexpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpersist() { long seconds = 20; @@ -560,6 +571,7 @@ public void hpersist() { } @Test + @SinceRedisVersion("7.4.0") public void hpersistBinary() { long seconds = 20; diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsListCommandsTest.java index c7f84157d1..9ea0c1534f 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsListCommandsTest.java @@ -9,6 +9,7 @@ import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.ListDirection; @@ -608,6 +609,7 @@ public void testLmoveAndBlmoveBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testLmpopAndBlmpop() { String key1 = "list1"; String key2 = "list2"; @@ -635,6 +637,7 @@ public void testLmpopAndBlmpop() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testLmpopAndBlmpopBinary() { byte[] key1 = "list1".getBytes(); byte[] key2 = "list2".getBytes(); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsScriptingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsScriptingCommandsTest.java index 7b6c1feae9..814de156de 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsScriptingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsScriptingCommandsTest.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.FlushMode; @@ -146,6 +147,7 @@ public void testEvalWithScriptKeysAndArgsList() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testEvalReadonlyWithScriptKeysAndArgsList() { exec(commandObjects.set("readonlyKey1", "readonlyValue1")); exec(commandObjects.set("readonlyKey2", "readonlyValue2")); @@ -282,6 +284,7 @@ public void testEvalWithScriptKeysAndArgsListSha() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testEvalReadonlyWithScriptKeysAndArgsListSha() { exec(commandObjects.set("readonlyKey1", "readonlyValue1")); exec(commandObjects.set("readonlyKey2", "readonlyValue2")); @@ -468,6 +471,7 @@ public void testScriptKill() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testSumValuesFunction() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args)\n" + @@ -517,6 +521,7 @@ public void testSumValuesFunction() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testSumValuesFunctionReadonly() { String luaScript = "#!lua name=mylib\n" + "redis.register_function{function_name='sumValues', callback=function(keys, args)\n" + @@ -550,6 +555,7 @@ public void testSumValuesFunctionReadonly() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionDeletion() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -572,6 +578,7 @@ public void testFunctionDeletion() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionDeletionBinary() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -594,6 +601,7 @@ public void testFunctionDeletionBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionListing() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -651,6 +659,7 @@ public void testFunctionListing() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionReload() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('dummy', function(keys, args) return 42 end)"; @@ -672,6 +681,7 @@ public void testFunctionReload() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionReloadBinary() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('dummy', function(keys, args) return 42 end)"; @@ -693,6 +703,7 @@ public void testFunctionReloadBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionStats() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('dummy', function(keys, args) return 42 end)"; @@ -719,6 +730,7 @@ public void testFunctionStats() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionDumpFlushRestore() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -752,6 +764,7 @@ public void testFunctionDumpFlushRestore() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionDumpFlushRestoreWithPolicy() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -785,6 +798,7 @@ public void testFunctionDumpFlushRestoreWithPolicy() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionFlushWithMode() { String luaScript = "#!lua name=mylib\n" + "redis.register_function('sumValues', function(keys, args) return 42 end)"; @@ -807,6 +821,7 @@ public void testFunctionFlushWithMode() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testFunctionKill() { JedisException e = assertThrows(JedisException.class, () -> exec(commandObjects.functionKill())); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSetCommandsTest.java index 6a6874ef4d..84c82ac78f 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSetCommandsTest.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.params.ScanParams; @@ -228,6 +229,7 @@ public void testSdiffstoreBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testSinterAndSinterCard() { String key1 = "testSetInter1"; String key2 = "testSetInter2"; diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSortedSetCommandsTest.java index 21a573c8db..292ed25572 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsSortedSetCommandsTest.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.SortedSetOption; @@ -328,6 +329,7 @@ public void testZrankAndZrevrank() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testZrankWithScoreAndZrevrankWithScore() { String key = "zset"; String member1 = "one"; @@ -1198,6 +1200,7 @@ public void testZdiffStoreBinary() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testZinterAndZintercard() { ZParams params = new ZParams().aggregate(ZParams.Aggregate.SUM).weights(1, 2); @@ -1419,6 +1422,7 @@ public void testZunionstoreBinary() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testZmpopAndZmpopWithCount() { String key1 = "sortedSet1"; String key2 = "sortedSet2"; @@ -1444,6 +1448,7 @@ public void testZmpopAndZmpopWithCount() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testZmpopAndZmpopWithCountBinary() { byte[] key1 = "sortedSet1".getBytes(); byte[] key2 = "sortedSet2".getBytes(); @@ -1469,6 +1474,7 @@ public void testZmpopAndZmpopWithCountBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testBzmpop() { String key1 = "sortedSet1"; String key2 = "sortedSet2"; @@ -1496,6 +1502,7 @@ public void testBzmpop() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testBzmpopBinary() { byte[] key1 = "sortedSet1".getBytes(); byte[] key2 = "sortedSet2".getBytes(); @@ -1523,6 +1530,7 @@ public void testBzmpopBinary() { } @Test + @SinceRedisVersion(value = "7.2.0") public void testBzmpopCount() { String key1 = "sortedSet1"; String key2 = "sortedSet2"; @@ -1542,6 +1550,7 @@ public void testBzmpopCount() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testBzmpopCountBinary() { byte[] key1 = "sortedSet1".getBytes(); byte[] key2 = "sortedSet2".getBytes(); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java index 128642d2a7..00a57f1ff6 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java @@ -1,5 +1,8 @@ package redis.clients.jedis.commands.commandobjects; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; +import org.junit.Rule; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; @@ -8,6 +11,11 @@ */ public abstract class CommandObjectsStandaloneTestBase extends CommandObjectsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public CommandObjectsStandaloneTestBase(RedisProtocol protocol) { super(protocol, HostAndPorts.getRedisEndpoint("standalone0")); } diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStringCommandsTest.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStringCommandsTest.java index 9a35cd88e4..a192a462d9 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStringCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStringCommandsTest.java @@ -10,6 +10,7 @@ import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.params.GetExParams; @@ -298,6 +299,7 @@ public void testIncrementOperationsBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testLcs() { String keyA = "keyA"; String keyB = "keyB"; @@ -338,6 +340,7 @@ public void testLcs() { } @Test + @SinceRedisVersion(value = "7.0.0") public void testLcsBinary() { byte[] keyA = "keyA".getBytes(); byte[] keyB = "keyB".getBytes(); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java index 45e0c71ad4..8e194105e0 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java @@ -5,6 +5,8 @@ import java.util.Collection; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionUtil; import org.junit.Before; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -84,9 +86,14 @@ public void setUp() { commandExecutor.executeCommand(commandObjects.flushAll()), equalTo("OK")); - assertThat( - commandExecutor.executeCommand(commandObjects.functionFlush(FlushMode.SYNC)), - equalTo("OK")); + if ( RedisVersionUtil + .getRedisVersion(endpoint) + .isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + assertThat( + commandExecutor.executeCommand(commandObjects.functionFlush(FlushMode.SYNC)), + equalTo("OK")); + + } } /** diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java index 150211383e..a184dc52b8 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java @@ -11,9 +11,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; import java.util.Arrays; import java.util.List; + +import io.redis.test.annotations.EnabledOnCommand; +import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.Matchers; import org.junit.After; import org.junit.BeforeClass; @@ -30,7 +34,7 @@ import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.resps.AccessControlLogEntry; import redis.clients.jedis.resps.AccessControlUser; -import redis.clients.jedis.util.RedisVersionUtil; +import io.redis.test.utils.RedisVersion; import redis.clients.jedis.util.SafeEncoder; /** @@ -41,12 +45,13 @@ public class AccessControlListCommandsTest extends JedisCommandsTestBase { public static final String USER_NAME = "newuser"; public static final String USER_PASSWORD = "secret"; + public static final String USER_ANTIREZ = "antirez"; @BeforeClass public static void prepare() throws Exception { // Use to check if the ACL test should be ran. ACL are available only in 6.0 and later org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", - RedisVersionUtil.checkRedisMajorVersionNumber(6, endpoint)); + getRedisVersion(endpoint).isGreaterThanOrEqualTo(RedisVersion.V6_0_0)); } public AccessControlListCommandsTest(RedisProtocol protocol) { @@ -58,6 +63,7 @@ public AccessControlListCommandsTest(RedisProtocol protocol) { public void tearDown() throws Exception { try { jedis.aclDelUser(USER_NAME); + jedis.aclDelUser(USER_ANTIREZ); } catch (Exception e) { } super.tearDown(); } @@ -95,10 +101,11 @@ public void addAndRemoveUser() { @Test public void aclUsers() { List users = jedis.aclUsers(); - assertEquals(2, users.size()); + assertEquals(3, users.size()); assertThat(users, Matchers.hasItem("default")); - - assertEquals(2, jedis.aclUsersBinary().size()); // Test binary + assertThat(users, Matchers.hasItem("deploy")); + assertThat(users, Matchers.hasItem("acljedis")); + assertEquals(3, jedis.aclUsersBinary().size()); // Test binary } @Test @@ -109,6 +116,7 @@ public void aclGetUser() { assertFalse(userInfo.getFlags().isEmpty()); assertEquals(1, userInfo.getPassword().size()); assertEquals("+@all", userInfo.getCommands()); + assertEquals("~*", userInfo.getKeys()); // create new user @@ -219,13 +227,14 @@ public void aclExcudeSingleCommand() { fail("Should throw a NOPERM exception"); } catch (JedisAccessControlException e) { assertThat(e.getMessage(), startsWith("NOPERM ")); - assertThat(e.getMessage(), endsWith(" has no permissions to run the 'ping' command")); + assertThat(e.getMessage(), containsString(" has no permissions to run the 'ping' command")); } jedis2.close(); } @Test + @EnabledOnCommand(value = "ACL", subCommand = "DRYRUN") public void aclDryRun() { jedis.aclSetUser(USER_NAME, "nopass", "allkeys", "+set", "-get"); @@ -240,6 +249,7 @@ public void aclDryRun() { } @Test + @EnabledOnCommand(value = "ACL", subCommand = "DRYRUN") public void aclDryRunBinary() { byte[] username = USER_NAME.getBytes(); @@ -284,7 +294,7 @@ public void basicPermissionsTest() { fail("Should throw a NOPERM exception"); } catch (JedisAccessControlException e) { assertThat(e.getMessage(), startsWith("NOPERM ")); - assertThat(e.getMessage(), endsWith(" has no permissions to run the 'set' command")); + assertThat(e.getMessage(), containsString(" has no permissions to run the 'set' command")); } // change permissions of the user @@ -305,7 +315,7 @@ public void basicPermissionsTest() { } // allow user to access a subset of the key - jedis.aclSetUser(USER_NAME, "allcommands", "~foo:*", "~bar:*"); // TODO : Define a DSL + jedis.aclSetUser(USER_NAME, "allcommands", "~foo:*", "~bar:*"); // TODO : a DSL // create key foo, bar and zap jedis2.set("foo:1", "a"); @@ -347,9 +357,9 @@ public void aclLogTest() { assertTrue(jedis.aclLog().isEmpty()); // create new user and cconnect - jedis.aclSetUser("antirez", ">foo", "on", "+set", "~object:1234"); - jedis.aclSetUser("antirez", "+eval", "+multi", "+exec"); - jedis.auth("antirez", "foo"); + jedis.aclSetUser(USER_ANTIREZ, ">foo", "on", "+set", "~object:1234"); + jedis.aclSetUser(USER_ANTIREZ, "+eval", "+multi", "+exec"); + jedis.auth(USER_ANTIREZ, "foo"); // generate an error (antirez user does not have the permission to access foo) try { @@ -364,7 +374,7 @@ public void aclLogTest() { List aclEntries = jedis.aclLog(); assertEquals("Number of log messages ", 1, aclEntries.size()); assertEquals(1, aclEntries.get(0).getCount()); - assertEquals("antirez", aclEntries.get(0).getUsername()); + assertEquals(USER_ANTIREZ, aclEntries.get(0).getUsername()); assertEquals("toplevel", aclEntries.get(0).getContext()); assertEquals("command", aclEntries.get(0).getReason()); assertEquals("get", aclEntries.get(0).getObject()); @@ -373,7 +383,7 @@ public void aclLogTest() { jedis.aclLogReset(); assertTrue(jedis.aclLog().isEmpty()); - jedis.auth("antirez", "foo"); + jedis.auth(USER_ANTIREZ, "foo"); for (int i = 0; i < 10; i++) { // generate an error (antirez user does not have the permission to access foo) @@ -391,7 +401,7 @@ public void aclLogTest() { assertEquals("get", jedis.aclLog().get(0).getObject()); // Generate another type of error - jedis.auth("antirez", "foo"); + jedis.auth(USER_ANTIREZ, "foo"); try { jedis.set("somekeynotallowed", "1234"); fail("Should have thrown an JedisAccessControlException: user does not have the permission to set(\"somekeynotallowed\", \"1234\")"); @@ -408,7 +418,7 @@ public void aclLogTest() { jedis.aclLogReset(); assertTrue(jedis.aclLog().isEmpty()); - jedis.auth("antirez", "foo"); + jedis.auth(USER_ANTIREZ, "foo"); Transaction t = jedis.multi(); t.incr("foo"); try { @@ -425,7 +435,7 @@ public void aclLogTest() { assertEquals("incr", jedis.aclLog().get(0).getObject()); // ACL LOG can accept a numerical argument to show less entries - jedis.auth("antirez", "foo"); + jedis.auth(USER_ANTIREZ, "foo"); for (int i = 0; i < 5; i++) { try { jedis.incr("foo"); @@ -451,10 +461,11 @@ public void aclLogTest() { String status = jedis.aclLogReset(); assertEquals(status, "OK"); - jedis.aclDelUser("antirez"); + jedis.aclDelUser(USER_ANTIREZ); } @Test + @SinceRedisVersion(value = "7.2.0", message = "Starting with Redis version 7.2.0: Added entry ID, timestamp created, and timestamp last updated.") public void aclLogWithEntryID() { try { jedis.auth("wronguser", "wrongpass"); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java index 868195961e..821f61babd 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java @@ -1,6 +1,7 @@ package redis.clients.jedis.commands.jedis; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.junit.Assert.*; import static redis.clients.jedis.Protocol.Command.BLPOP; @@ -14,7 +15,10 @@ import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START; import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START_BINARY; +import java.time.Duration; import java.util.*; + +import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.Matchers; import org.junit.Assume; import org.junit.Test; @@ -35,6 +39,8 @@ @RunWith(Parameterized.class) public class AllKindOfValuesCommandsTest extends JedisCommandsTestBase { + private static final long TIME_SKEW = Duration.ofMillis(5).toMillis(); + final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bfoo1 = { 0x01, 0x02, 0x03, 0x04, 0x0A }; final byte[] bfoo2 = { 0x01, 0x02, 0x03, 0x04, 0x0B }; @@ -305,6 +311,7 @@ public void dbSize() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void expire() { assertEquals(0, jedis.expire("foo", 20L)); @@ -321,6 +328,7 @@ public void expire() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void expireAt() { long unixTime = (System.currentTimeMillis() / 1000L) + 20; @@ -341,6 +349,7 @@ public void expireAt() { } @Test + @SinceRedisVersion(value = "7.0.0") public void expireTime() { long unixTime; @@ -626,7 +635,8 @@ public void restoreParams() { assertTrue(jedis2.pttl("foo") <= 1000); jedis2.restore("bar", System.currentTimeMillis() + 1000, serialized, RestoreParams.restoreParams().replace().absTtl()); - assertTrue(jedis2.pttl("bar") <= 1000); + assertThat("ttl", jedis2.pttl("bar"), lessThanOrEqualTo(1000l + TIME_SKEW)); + jedis2.restore("bar1", 1000, serialized, RestoreParams.restoreParams().replace().idleTime(1000)); assertEquals(1000, jedis2.objectIdletime("bar1").longValue()); @@ -639,6 +649,7 @@ public void restoreParams() { } @Test + @SinceRedisVersion(value = "7.0.0") public void pexpire() { assertEquals(0, jedis.pexpire("foo", 10000)); @@ -680,6 +691,7 @@ public void pexpireAt() { } @Test + @SinceRedisVersion(value = "7.0.0") public void pexpireTime() { long unixTime = (System.currentTimeMillis()) + 10000; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/BitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/BitCommandsTest.java index 01cc61b3c9..2976526e61 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/BitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/BitCommandsTest.java @@ -7,6 +7,8 @@ import static org.junit.Assert.fail; import java.util.List; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -153,13 +155,20 @@ public void bitposModifier() { assertEquals(1, jedis.bitpos("mykey", true, BitPosParams.bitPosParams())); assertEquals(18, jedis.bitpos("mykey", true, BitPosParams.bitPosParams().start(2))); assertEquals(18, jedis.bitpos("mykey", true, BitPosParams.bitPosParams().start(2).end(-1))); + } + + @Test + @SinceRedisVersion(value = "7.0.0", message = "7.0.0 Added the BYTE|BIT option.") + public void bitposModifierByte() { + jedis.set("mykey", "\\x00\\xff\\xf0"); assertEquals(18, jedis.bitpos("mykey", true, BitPosParams.bitPosParams().start(2).end(-1) - .modifier(BitCountOption.BYTE))); + .modifier(BitCountOption.BYTE))); assertEquals(9, jedis.bitpos("mykey", true, BitPosParams.bitPosParams().start(7).end(15) - .modifier(BitCountOption.BIT))); + .modifier(BitCountOption.BIT))); } @Test + @SinceRedisVersion("7.0.0") public void setAndgetrange() { jedis.set("key1", "Hello World"); assertEquals(11, jedis.setrange("key1", 6, "Jedis")); @@ -182,6 +191,15 @@ public void bitCount() { assertEquals(3, (long) jedis.bitcount("foo", 2L, 5L)); assertEquals(3, (long) jedis.bitcount("foo".getBytes(), 2L, 5L)); + } + + @Test + @SinceRedisVersion("7.0.0") + public void bitCountByteOptions() { + jedis.setbit("foo", 16, true); + jedis.setbit("foo", 24, true); + jedis.setbit("foo", 40, true); + jedis.setbit("foo", 56, true); assertEquals(3, (long) jedis.bitcount("foo", 2L, 5L, BitCountOption.BYTE)); assertEquals(3, (long) jedis.bitcount("foo".getBytes(), 2L, 5L, BitCountOption.BYTE)); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java index 1b221cfc55..24dd66e914 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java @@ -15,8 +15,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -38,6 +42,11 @@ public class ClientCommandsTest extends JedisCommandsTestBase { private Jedis client; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public ClientCommandsTest(RedisProtocol protocol) { super(protocol); } @@ -73,6 +82,7 @@ public void nameBinary() { } @Test + @SinceRedisVersion("7.2.0") public void clientSetInfoCommand() { String libName = "Jedis::A-Redis-Java-library"; String libVersion = "999.999.999"; @@ -243,6 +253,7 @@ public void killUser() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "MAXAGE (since Redis 7.4)") public void killMaxAge() throws InterruptedException { long maxAge = 2; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java index 7e5c5db875..c94585ac3e 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java @@ -9,14 +9,14 @@ import java.util.List; import java.util.Map; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; +import redis.clients.jedis.DefaultJedisClientConfig; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.Jedis; import redis.clients.jedis.args.ClusterResetType; @@ -35,6 +35,11 @@ public class ClusterCommandsTest { private static HostAndPort nodeInfo1 = HostAndPorts.getClusterServers().get(0); private static HostAndPort nodeInfo2 = HostAndPorts.getClusterServers().get(1); + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + @Before public void setUp() throws Exception { node1 = new Jedis(nodeInfo1); @@ -124,6 +129,7 @@ public void clusterInfo() { } @Test + @SinceRedisVersion("7.0.0") public void addAndDelSlotsRange() { // test add assertEquals("OK", node1.clusterAddSlotsRange(100, 105)); @@ -203,6 +209,7 @@ public void clusterSlots() { } @Test + @SinceRedisVersion("7.0.0") public void clusterShards() { assertEquals("OK", node1.clusterAddSlots(3100, 3101, 3102, 3105)); @@ -224,7 +231,7 @@ public void clusterShards() { assertNotNull(nodeInfo.getIp()); assertNull(nodeInfo.getHostname()); assertNotNull(nodeInfo.getPort()); - assertNull(nodeInfo.getTlsPort()); + assertNotNull(nodeInfo.getTlsPort()); assertNotNull(nodeInfo.getRole()); assertNotNull(nodeInfo.getReplicationOffset()); assertNotNull(nodeInfo.getHealth()); @@ -234,6 +241,7 @@ public void clusterShards() { } @Test + @SinceRedisVersion("7.0.0") public void clusterLinks() throws InterruptedException { List> links = node1.clusterLinks(); assertNotNull(links); @@ -264,6 +272,7 @@ public void clusterMyId() { } @Test + @SinceRedisVersion("7.2.0") public void clusterMyShardId() { MatcherAssert.assertThat(node1.clusterMyShardId(), Matchers.not(Matchers.isEmptyOrNullString())); } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java index 8cd4b8379d..e96a4896d3 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java @@ -5,14 +5,14 @@ import java.util.HashSet; import java.util.Set; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; -import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.HostAndPorts; -import redis.clients.jedis.JedisCluster; +import org.junit.Rule; +import redis.clients.jedis.*; import redis.clients.jedis.util.JedisClusterCRC16; public abstract class ClusterJedisCommandsTestBase { @@ -27,6 +27,11 @@ public abstract class ClusterJedisCommandsTestBase { private final Set jedisClusterNode = new HashSet<>(); JedisCluster cluster; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + @Before public void setUp() throws InterruptedException { node1 = new Jedis(nodeInfo1); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java index 503337683e..bb5e4c4688 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterScriptingCommandsTest.java @@ -10,6 +10,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.HostAndPort; @@ -115,6 +117,7 @@ public void broadcast() { } @Test + @SinceRedisVersion("7.0.0") public void broadcastWithError() { JedisBroadcastException error = assertThrows(JedisBroadcastException.class, () -> cluster.functionDelete("xyz")); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java index 65d36fd5df..c1863892bd 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java @@ -7,6 +7,11 @@ import java.util.HashMap; import java.util.Map; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionRule; +import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.BinaryJedisShardedPubSub; @@ -16,6 +21,7 @@ import redis.clients.jedis.util.JedisClusterCRC16; import redis.clients.jedis.util.SafeEncoder; +@SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public class ClusterShardedPublishSubscribeCommandsTest extends ClusterJedisCommandsTestBase { private void publishOne(final String channel, final String message) { @@ -24,6 +30,7 @@ private void publishOne(final String channel, final String message) { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void subscribe() throws InterruptedException { cluster.ssubscribe(new JedisShardedPubSub() { @Override public void onSMessage(String channel, String message) { @@ -48,6 +55,7 @@ public void subscribe() throws InterruptedException { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void subscribeMany() { cluster.ssubscribe(new JedisShardedPubSub() { @Override public void onSMessage(String channel, String message) { @@ -62,6 +70,7 @@ public void subscribeMany() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubChannels() { cluster.ssubscribe(new JedisShardedPubSub() { private int count = 0; @@ -82,6 +91,7 @@ public void pubSubChannels() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubChannelsWithPattern() { cluster.ssubscribe(new JedisShardedPubSub() { private int count = 0; @@ -102,6 +112,7 @@ public void pubSubChannelsWithPattern() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubNumSub() { final Map expectedNumSub = new HashMap<>(); expectedNumSub.put("{testchannel}1", 1L); @@ -125,6 +136,7 @@ public void pubSubNumSub() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void binarySubscribe() { cluster.ssubscribe(new BinaryJedisShardedPubSub() { @Override public void onSMessage(byte[] channel, byte[] message) { @@ -147,6 +159,7 @@ public void binarySubscribe() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void binarySubscribeMany() { cluster.ssubscribe(new BinaryJedisShardedPubSub() { @Override public void onSMessage(byte[] channel, byte[] message) { diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 4b67a295c7..7772338612 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -21,6 +21,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Test; @@ -253,6 +254,7 @@ public void configSetBinary() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Added the ability to pass multiple pattern parameters in one call") public void configGetSetMulti() { String[] params = new String[]{"hash-max-listpack-entries", "set-max-intset-entries", "zset-max-listpack-entries"}; Map info = jedis.configGet(params); @@ -272,6 +274,7 @@ public void waitReplicas() { } @Test + @SinceRedisVersion("7.2.0") public void waitAof() { assertEquals(KeyValue.of(0L, 0L), jedis.waitAOF(0L, 0L, 100L)); } @@ -379,12 +382,14 @@ public void clientUnpause() { } @Test + @SinceRedisVersion("7.0.0") public void clientNoEvict() { assertEquals("OK", jedis.clientNoEvictOn()); assertEquals("OK", jedis.clientNoEvictOff()); } @Test + @SinceRedisVersion("7.2.0") public void clientNoTouch() { assertEquals("OK", jedis.clientNoTouchOn()); assertEquals("OK", jedis.clientNoTouchOff()); @@ -475,6 +480,7 @@ public void commandCount() { } @Test + @SinceRedisVersion("7.0.0") public void commandDocs() { Map docs = jedis.commandDocs("SORT", "SET"); @@ -496,12 +502,18 @@ public void commandGetKeys() { List keys = jedis.commandGetKeys("SORT", "mylist", "ALPHA", "STORE", "outlist"); assertEquals(2, keys.size()); + } + + @Test + @SinceRedisVersion("7.0.0") + public void commandGetKeysAndFlags() { List>> keySandFlags = jedis.commandGetKeysAndFlags("SET", "k1", "v1"); assertEquals("k1", keySandFlags.get(0).getKey()); assertEquals(2, keySandFlags.get(0).getValue().size()); } @Test + @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Allowed to be called with no argument to get info on all commands.") public void commandInfo() { Map infos = jedis.commandInfo("GET", "foo", "SET"); @@ -542,6 +554,7 @@ public void commandInfoAcl() { } @Test + @SinceRedisVersion("7.0.0") public void commandList() { List commands = jedis.commandList(); assertTrue(commands.size() > 100); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java index 88ca543fc4..a3d85d2c92 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java @@ -31,10 +31,15 @@ import java.util.Set; import java.util.stream.Collectors; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.Pipeline; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.Response; @@ -46,6 +51,13 @@ @RunWith(Parameterized.class) public class HashesCommandsTest extends JedisCommandsTestBase { + + @Rule + public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C }; @@ -479,6 +491,7 @@ public void hscanCount() { } @Test + @SinceRedisVersion("7.4.0") public void hscanNoValues() { jedis.hset("foo", "b", "y"); jedis.hset("foo", "a", "x"); @@ -502,6 +515,7 @@ public void hscanNoValues() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "NOVALUES flag (since Redis 7.4)") public void hscanNoValuesMatch() { ScanParams params = new ScanParams(); params.match("a*"); @@ -534,6 +548,7 @@ public void hscanNoValuesMatch() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "NOVALUES flag (since Redis 7.4)") public void hscanNoValuesCount() { ScanParams params = new ScanParams(); params.count(2); @@ -653,6 +668,7 @@ public void hrandfield() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttl() { long seconds1 = 20; long seconds2 = 10; @@ -670,6 +686,7 @@ public void hexpireAndHttl() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttlBinary() { long seconds1 = 20; long seconds2 = 10; @@ -687,6 +704,7 @@ public void hexpireAndHttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttl() { long millis1 = 20_000; long millis2 = 10_000; @@ -702,6 +720,7 @@ public void hpexpireAndHpttl() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttlBinary() { long millis1 = 20_000; long millis2 = 10_000; @@ -717,6 +736,7 @@ public void hpexpireAndHpttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTime() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -735,6 +755,7 @@ public void hexpireAtAndExpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTimeBinary() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -753,6 +774,7 @@ public void hexpireAtAndExpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTime() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -768,6 +790,7 @@ public void hpexpireAtAndPexpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTimeBinary() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -783,6 +806,7 @@ public void hpexpireAtAndPexpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpersist() { long seconds = 20; @@ -797,6 +821,7 @@ public void hpersist() { } @Test + @SinceRedisVersion("7.4.0") public void hpersistBinary() { long seconds = 20; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java index cec36a0866..7a25858160 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java @@ -2,14 +2,27 @@ import java.util.Collection; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runners.Parameterized.Parameters; import redis.clients.jedis.*; import redis.clients.jedis.commands.CommandsTestsParameters; public abstract class JedisCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getRedisEndpoint("standalone0").getHostAndPort(), + HostAndPorts.getRedisEndpoint("standalone0").getClientConfigBuilder().build()); + + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getRedisEndpoint("standalone0").getHostAndPort(), + HostAndPorts.getRedisEndpoint("standalone0").getClientConfigBuilder().build()); + /** * Input data for parameterized tests. In principle all subclasses of this * class should be parameterized tests, to run with several versions of RESP. @@ -26,7 +39,6 @@ public static Collection data() { protected final RedisProtocol protocol; protected Jedis jedis; - /** * The RESP protocol is to be injected by the subclasses, usually via JUnit * parameterized tests, because most of the subclassed tests are meant to be @@ -43,7 +55,8 @@ public JedisCommandsTestBase(RedisProtocol protocol) { @Before public void setUp() throws Exception { jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder() - .protocol(protocol).timeoutMillis(500).build()); + .protocol(protocol) + .timeoutMillis(500).build()); jedis.flushAll(); } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ListCommandsTest.java index 194bed29ae..f052c7d58c 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ListCommandsTest.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -881,6 +882,7 @@ public void blmove() { } @Test + @SinceRedisVersion("7.0.0") public void lmpop() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; @@ -906,6 +908,7 @@ public void lmpop() { } @Test + @SinceRedisVersion("7.0.0") public void blmpopSimple() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java index bef13001ef..dc84ef2efe 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java @@ -5,6 +5,10 @@ import java.util.Collections; import java.util.List; + +import org.junit.Assume; +import org.junit.BeforeClass; +import redis.clients.jedis.util.TestEnvUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -17,6 +21,11 @@ @RunWith(Parameterized.class) public class ModuleTest extends JedisCommandsTestBase { + @BeforeClass + public static void checkDockerEnvironment() { + Assume.assumeFalse("Module tests not supported against dockerised test env yet!",TestEnvUtil.isContainerEnv()); + } + static enum ModuleCommand implements ProtocolCommand { SIMPLE("testmodule.simple"); @@ -40,7 +49,7 @@ public ModuleTest(RedisProtocol protocol) { @Test public void testModules() { try { - assertEquals("OK", jedis.moduleLoad("/tmp/testmodule.so")); + assertEquals("OK", jedis.moduleLoad(TestEnvUtil.testModuleSo())); List modules = jedis.moduleList(); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java index 9f4c60de0b..fd0a7a86c0 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java @@ -8,6 +8,9 @@ import java.util.List; import java.util.Map; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionUtil; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Before; @@ -39,7 +42,11 @@ public ScriptingCommandsTest(RedisProtocol redisProtocol) { @Override public void setUp() throws Exception { super.setUp(); - jedis.functionFlush(); + if ( RedisVersionUtil + .getRedisVersion(jedis) + .isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + jedis.functionFlush(); + } } final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; @@ -142,6 +149,7 @@ public void evalNoArgs() { } @Test + @SinceRedisVersion(value = "7.0.0") public void evalReadonly() { String script = "return KEYS[1]"; List keys = new ArrayList(); @@ -165,6 +173,7 @@ public void evalsha() { } @Test + @SinceRedisVersion(value = "7.0.0") public void evalshaReadonly() { jedis.set("foo", "bar"); jedis.eval("return redis.call('get','foo')"); @@ -185,6 +194,7 @@ public void evalshaBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void evalshaReadonlyBinary() { jedis.set(SafeEncoder.encode("foo"), SafeEncoder.encode("bar")); jedis.eval(SafeEncoder.encode("return redis.call('get','foo')")); @@ -335,6 +345,7 @@ public void emptyLuaTableReply() { } @Test + @SinceRedisVersion(value = "7.0.0") public void functionLoadAndDelete() { String engine = "Lua"; String library = "mylib"; @@ -354,6 +365,7 @@ public void functionLoadAndDelete() { } @Test + @SinceRedisVersion(value = "7.0.0") public void functionFlush() { String engine = "Lua"; String library = "mylib"; @@ -369,6 +381,7 @@ public void functionFlush() { } @Test + @SinceRedisVersion(value = "7.0.0") public void functionList() { String engine = "LUA"; String library = "mylib"; @@ -436,6 +449,7 @@ public void functionList() { } @Test + @SinceRedisVersion(value = "7.0.0") public void functionDumpRestore() { String engine = "Lua"; String library = "mylib"; @@ -455,6 +469,7 @@ public void functionDumpRestore() { } @Test + @SinceRedisVersion(value = "7.0.0") public void functionStatsWithoutRunning() { String engine = "Lua"; String library = "mylib"; @@ -490,6 +505,7 @@ public void functionStatsWithoutRunning() { // } @Test + @SinceRedisVersion(value = "7.0.0") public void functionKillWithoutRunningFunction() { String engine = "Lua"; String library = "mylib"; @@ -505,6 +521,7 @@ public void functionKillWithoutRunningFunction() { } @Test + @SinceRedisVersion(value = "7.0.0") public void fcall() { String engine = "Lua"; String library = "mylib"; @@ -516,6 +533,7 @@ public void fcall() { } @Test + @SinceRedisVersion(value = "7.0.0") public void fcallBinary() { String engine = "Lua"; String library = "mylib"; @@ -527,6 +545,7 @@ public void fcallBinary() { } @Test + @SinceRedisVersion(value = "7.0.0") public void fcallReadonly() { String engine = "Lua"; String library = "mylib"; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SetCommandsTest.java index d2b660b5b4..67ede2b75c 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SetCommandsTest.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -364,6 +365,7 @@ public void sinterstore() { } @Test + @SinceRedisVersion("7.0.0") public void sintercard() { jedis.sadd("foo", "a"); jedis.sadd("foo", "b"); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java index 0377c481b4..a10c7c1290 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java @@ -5,8 +5,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.util.Arrays; -import java.util.List; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.*; + import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; @@ -22,8 +25,6 @@ @RunWith(Parameterized.class) public class SlowlogCommandsTest extends JedisCommandsTestBase { - private static final List LOCAL_IPS = Arrays.asList("127.0.0.1", "[::1]"); - private static final String SLOWLOG_TIME_PARAM = "slowlog-log-slower-than"; private static final String ZERO_STRING = "0"; @@ -81,7 +82,7 @@ public void slowlog() { @Test public void slowlogObjectDetails() { - final String clientName = "slowlog-object-client"; + final String clientName = "slowlog-object-client-" + UUID.randomUUID(); jedis.clientSetname(clientName); jedis.slowlogReset(); jedis.configSet(SLOWLOG_TIME_PARAM, ZERO_STRING); @@ -90,6 +91,7 @@ public void slowlogObjectDetails() { //assertEquals(1, logs.size()); assertThat(logs.size(), Matchers.allOf(Matchers.greaterThanOrEqualTo(1), Matchers.lessThanOrEqualTo(2))); Slowlog log = logs.get(0); + assertEquals(clientName, log.getClientName()); assertThat(log.getId(), Matchers.greaterThan(0L)); assertThat(log.getTimeStamp(), Matchers.greaterThan(0L)); assertThat(log.getExecutionTime(), Matchers.greaterThanOrEqualTo(0L)); @@ -98,9 +100,8 @@ public void slowlogObjectDetails() { assertEquals(SafeEncoder.encode(Protocol.Keyword.SET.getRaw()), log.getArgs().get(1)); assertEquals(SLOWLOG_TIME_PARAM, log.getArgs().get(2)); assertEquals(ZERO_STRING, log.getArgs().get(3)); - assertThat(log.getClientIpPort().getHost(), Matchers.in(LOCAL_IPS)); + assertThat(log.getClientIpPort().getHost(), Matchers.in(getAllLocalIps())); assertThat(log.getClientIpPort().getPort(), Matchers.greaterThan(0)); - assertEquals(clientName, log.getClientName()); } @Test @@ -127,4 +128,18 @@ public void slowlogBinaryObjectDetails() { assertThat(((byte[]) log.get(4)).length, Matchers.greaterThanOrEqualTo(10)); // 'IP:PORT' assertArrayEquals(clientName, (byte[]) log.get(5)); } + + private static Set getAllLocalIps() { + Set allLocalIps = new HashSet<>(); + try { + for (NetworkInterface netIf : Collections.list(NetworkInterface.getNetworkInterfaces())) { + for (InetAddress addr : Collections.list(netIf.getInetAddresses())) { + allLocalIps.add(addr.getHostAddress()); + } + } + } catch (SocketException e) { + throw new RuntimeException(e); + } + return allLocalIps; + } } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SortedSetCommandsTest.java index 9e4cd71a53..d98941dc5b 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SortedSetCommandsTest.java @@ -7,6 +7,8 @@ import static redis.clients.jedis.util.AssertUtil.assertByteArrayListEquals; import java.util.*; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -400,6 +402,7 @@ public void zrank() { } @Test + @SinceRedisVersion("7.2.0") public void zrankWithScore() { jedis.zadd("foo", 1d, "a"); jedis.zadd("foo", 2d, "b"); @@ -1416,6 +1419,7 @@ public void zintertoreParams() { } @Test + @SinceRedisVersion("7.0.0") public void zintercard() { jedis.zadd("foo", 1, "a"); jedis.zadd("foo", 2, "b"); @@ -1658,6 +1662,7 @@ private Double getScoreFromByteMap(Map bhash, byte[] key) { } @Test + @SinceRedisVersion("7.0.0") public void zmpop() { jedis.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); jedis.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); @@ -1673,6 +1678,7 @@ public void zmpop() { } @Test + @SinceRedisVersion("7.0.0") public void bzmpopSimple() { jedis.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); jedis.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java index 1d0a976f41..4ce41722de 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java @@ -6,10 +6,12 @@ import java.util.ArrayList; import java.util.List; +import io.redis.test.annotations.EnabledOnCommand; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.Protocol; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.params.SortingParams; @@ -324,6 +326,7 @@ public void sortStore() { } @Test + @EnabledOnCommand("SORT_RO") public void sort_ro() { jedis.rpush("foo", "1", "3", "2"); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java index 0ac12f9d05..719014bdfc 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java @@ -18,6 +18,9 @@ import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionUtil; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -173,11 +176,13 @@ public void xaddParamsId() { assertEquals(2, id.getTime()); assertEquals(3, id.getSequence()); - id = jedis.xadd(key, XAddParams.xAddParams().id(4), map); - assertNotNull(id); - assertEquals(4, id.getTime()); - assertEquals(0, id.getSequence()); - + // Starting with Redis version 7.0.0: Added support for the -* explicit ID form. + if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + id = jedis.xadd(key, XAddParams.xAddParams().id(4), map); + assertNotNull(id); + assertEquals(4, id.getTime()); + assertEquals(0, id.getSequence()); + } id = jedis.xadd(key, XAddParams.xAddParams().id("5-6"), map); assertNotNull(id); assertEquals(5, id.getTime()); @@ -348,6 +353,31 @@ public void xreadAsMap() { assertEquals(2, streams2.size()); assertEquals(id1, streams2.get(stream1).get(0).getID()); assertEquals(id2, streams2.get(stream2).get(0).getID()); + } + + @Test + @SinceRedisVersion(value = "7.4.0", message = "From Redis 7.4, you can use the + sign as a special ID to request last entry") + public void xreadAsMapLastEntry() { + + final String stream1 = "xread-stream1"; + final String stream2 = "xread-stream2"; + + Map streamQeury1 = singletonMap(stream1, new StreamEntryID()); + + // Before creating Stream + assertNull(jedis.xreadAsMap(XReadParams.xReadParams().block(1), streamQeury1)); + assertNull(jedis.xreadAsMap(XReadParams.xReadParams(), streamQeury1)); + + Map map = new HashMap<>(); + map.put("f1", "v1"); + StreamEntryID id1 = new StreamEntryID(1); + StreamEntryID id2 = new StreamEntryID(2); + StreamEntryID id3 = new StreamEntryID(3); + + assertEquals(id1, jedis.xadd(stream1, id1, map)); + assertEquals(id2, jedis.xadd(stream2, id2, map)); + assertEquals(id3, jedis.xadd(stream1, id3, map)); + // Read from last entry Map streamQueryLE = singletonMap(stream1, StreamEntryID.XREAD_LAST_ENTRY); @@ -880,6 +910,8 @@ public void xinfo() throws InterruptedException { final String MY_CONSUMER = "myConsumer"; final String MY_CONSUMER2 = "myConsumer2"; + final RedisVersion redisVersion = RedisVersionUtil.getRedisVersion(jedis); + Map map1 = new HashMap<>(); map1.put(F1, V1); StreamEntryID id1 = jedis.xadd(STREAM_NAME, (StreamEntryID) null, map1); @@ -942,7 +974,10 @@ public void xinfo() throws InterruptedException { assertEquals(MY_CONSUMER, consumersInfo.get(0).getName()); assertEquals(0L, consumersInfo.get(0).getPending()); assertThat(consumersInfo.get(0).getIdle(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumersInfo.get(0).getInactive(), Matchers.any(Long.class)); + + if ( redisVersion.isGreaterThanOrEqualTo(RedisVersion.V7_2_0)) { + assertThat(consumersInfo.get(0).getInactive(), Matchers.any(Long.class)); + } // Consumer info test assertEquals(MY_CONSUMER, @@ -954,7 +989,9 @@ public void xinfo() throws InterruptedException { assertEquals(MY_CONSUMER, consumerInfo.get(0).getName()); assertEquals(0L, consumerInfo.get(0).getPending()); assertThat(consumerInfo.get(0).getIdle(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumerInfo.get(0).getInactive(), Matchers.any(Long.class)); + if (redisVersion.isGreaterThanOrEqualTo(RedisVersion.V7_2_0)) { + assertThat(consumerInfo.get(0).getInactive(), Matchers.any(Long.class)); + } // test with more groups and consumers jedis.xgroupCreate(STREAM_NAME, G2, StreamEntryID.XGROUP_LAST_ENTRY, false); @@ -1028,7 +1065,9 @@ public void xinfoStreamFullWithPending() { StreamConsumerFullInfo consumer = group.getConsumers().get(0); assertEquals("xreadGroup-consumer", consumer.getName()); assertThat(consumer.getSeenTime(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumer.getActiveTime(), Matchers.greaterThanOrEqualTo(0L)); + if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_2_0)) { + assertThat(consumer.getActiveTime(), Matchers.greaterThanOrEqualTo(0L)); + } assertEquals(1, consumer.getPending().size()); List consumerPendingEntry = consumer.getPending().get(0); assertEquals(id1, consumerPendingEntry.get(0)); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/StringValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/StringValuesCommandsTest.java index 44525e072f..12bcd8aebe 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/StringValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/StringValuesCommandsTest.java @@ -6,6 +6,8 @@ import java.util.ArrayList; import java.util.List; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -247,6 +249,7 @@ public void psetex() { } @Test + @SinceRedisVersion("7.0.0") public void lcs() { jedis.mset("key1", "ohmytext", "key2", "mynewtext"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/AllKindOfValuesCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/AllKindOfValuesCommandsTestBase.java index f31c100988..866b2fc12d 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/AllKindOfValuesCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/AllKindOfValuesCommandsTestBase.java @@ -22,6 +22,7 @@ import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START; import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START_BINARY; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -29,6 +30,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; + +import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.Matchers; import org.junit.Assume; import org.junit.Test; @@ -286,6 +289,7 @@ public void dbSize() { } @Test + @SinceRedisVersion(value="7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void expire() { assertEquals(0, jedis.expire("foo", 20L)); @@ -302,6 +306,7 @@ public void expire() { } @Test + @SinceRedisVersion(value="7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void expireAt() { long unixTime = (System.currentTimeMillis() / 1000L) + 20; @@ -322,6 +327,7 @@ public void expireAt() { } @Test + @SinceRedisVersion(value="7.0.0") public void expireTime() { long unixTime; @@ -458,6 +464,7 @@ public void restoreParams() { } @Test + @SinceRedisVersion(value="7.0.0", message = "Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.") public void pexpire() { assertEquals(0, jedis.pexpire("foo", 10000)); @@ -499,6 +506,7 @@ public void pexpireAt() { } @Test + @SinceRedisVersion(value="7.0.0") public void pexpireTime() { long unixTime = (System.currentTimeMillis()) + 10000; diff --git a/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java index 2101900889..7d559e1518 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java @@ -7,6 +7,10 @@ import static org.junit.Assert.fail; import java.util.List; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersionRule; +import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.Protocol; @@ -19,6 +23,7 @@ public abstract class BitCommandsTestBase extends UnifiedJedisCommandsTestBase { + public BitCommandsTestBase(RedisProtocol protocol) { super(protocol); } @@ -143,6 +148,7 @@ public void bitposWithNoMatchingBitExistWithinRange() { } @Test + @SinceRedisVersion(value="7.0.0", message="Starting with Redis version 7.0.0: Added the BYTE|BIT option.") public void bitposModifier() { jedis.set("mykey", "\\x00\\xff\\xf0"); assertEquals(0, jedis.bitpos("mykey", false)); @@ -168,6 +174,7 @@ public void setAndgetrange() { } @Test + @SinceRedisVersion(value="7.0.0", message="Starting with Redis version 7.0.0: Added the BYTE|BIT option.") public void bitCount() { jedis.setbit("foo", 16, true); jedis.setbit("foo", 24, true); diff --git a/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java index f84b0c2cc6..231b1c8aea 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/HashesCommandsTestBase.java @@ -31,6 +31,7 @@ import java.util.Set; import java.util.stream.Collectors; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; @@ -451,6 +452,7 @@ public void hscanCount() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "NOVALUES flag (since Redis 7.4)") public void hscanNoValues() { jedis.hset("foo", "b", "y"); jedis.hset("foo", "a", "x"); @@ -474,6 +476,7 @@ public void hscanNoValues() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "NOVALUES flag (since Redis 7.4)") public void hscanNoValuesMatch() { ScanParams params = new ScanParams(); params.match("a*"); @@ -506,6 +509,7 @@ public void hscanNoValuesMatch() { } @Test + @SinceRedisVersion(value = "7.4.0", message = "NOVALUES flag (since Redis 7.4)") public void hscanNoValuesCount() { ScanParams params = new ScanParams(); params.count(2); @@ -625,6 +629,7 @@ public void hrandfield() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttl() { long seconds1 = 20; long seconds2 = 10; @@ -642,6 +647,7 @@ public void hexpireAndHttl() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAndHttlBinary() { long seconds1 = 20; long seconds2 = 10; @@ -659,6 +665,7 @@ public void hexpireAndHttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttl() { long millis1 = 20_000; long millis2 = 10_000; @@ -674,6 +681,7 @@ public void hpexpireAndHpttl() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAndHpttlBinary() { long millis1 = 20_000; long millis2 = 10_000; @@ -689,6 +697,7 @@ public void hpexpireAndHpttlBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTime() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -707,6 +716,7 @@ public void hexpireAtAndExpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hexpireAtAndExpireTimeBinary() { long currSeconds = System.currentTimeMillis() / 1000; long seconds1 = currSeconds + 20; @@ -725,6 +735,7 @@ public void hexpireAtAndExpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTime() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -740,6 +751,7 @@ public void hpexpireAtAndPexpireTime() { } @Test + @SinceRedisVersion("7.4.0") public void hpexpireAtAndPexpireTimeBinary() { long currMillis = System.currentTimeMillis(); long unixMillis = currMillis + 20_000; @@ -755,6 +767,7 @@ public void hpexpireAtAndPexpireTimeBinary() { } @Test + @SinceRedisVersion("7.4.0") public void hpersist() { long seconds = 20; @@ -769,6 +782,7 @@ public void hpersist() { } @Test + @SinceRedisVersion("7.4.0") public void hpersistBinary() { long seconds = 20; diff --git a/src/test/java/redis/clients/jedis/commands/unified/ListCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/ListCommandsTestBase.java index 05c741de41..2d7372f000 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/ListCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/ListCommandsTestBase.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -865,6 +866,7 @@ public void blmove() { } @Test + @SinceRedisVersion(value="7.0.0") public void lmpop() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; @@ -890,6 +892,7 @@ public void lmpop() { } @Test + @SinceRedisVersion(value="7.0.0") public void blmpopSimple() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; diff --git a/src/test/java/redis/clients/jedis/commands/unified/SetCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/SetCommandsTestBase.java index d4c1456218..3f21a2f9f5 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/SetCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/SetCommandsTestBase.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; @@ -361,6 +362,7 @@ public void sinterstore() { } @Test + @SinceRedisVersion(value="7.0.0") public void sintercard() { jedis.sadd("foo", "a"); jedis.sadd("foo", "b"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/SortedSetCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/SortedSetCommandsTestBase.java index 126a884993..000a005eb6 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/SortedSetCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/SortedSetCommandsTestBase.java @@ -7,6 +7,8 @@ import static redis.clients.jedis.util.AssertUtil.assertByteArrayListEquals; import java.util.*; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; @@ -454,6 +456,7 @@ public void zrank() { } @Test + @SinceRedisVersion(value="7.2.0") public void zrankWithScore() { jedis.zadd("foo", 1d, "a"); jedis.zadd("foo", 2d, "b"); @@ -1402,6 +1405,7 @@ public void zintertoreParams() { } @Test + @SinceRedisVersion(value="7.0.0") public void zintercard() { jedis.zadd("foo", 1, "a"); jedis.zadd("foo", 2, "b"); @@ -1644,6 +1648,7 @@ private Double getScoreFromByteMap(Map bhash, byte[] key) { } @Test + @SinceRedisVersion(value="7.0.0") public void zmpop() { jedis.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); jedis.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); @@ -1659,6 +1664,7 @@ public void zmpop() { } @Test + @SinceRedisVersion(value="7.0.0") public void bzmpopSimple() { jedis.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); jedis.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); diff --git a/src/test/java/redis/clients/jedis/commands/unified/StringValuesCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/StringValuesCommandsTestBase.java index 8309978fad..f21876979e 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/StringValuesCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/StringValuesCommandsTestBase.java @@ -6,6 +6,8 @@ import java.util.ArrayList; import java.util.List; + +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.RedisProtocol; @@ -244,6 +246,7 @@ public void psetex() { } @Test + @SinceRedisVersion(value="7.0.0") public void lcs() { jedis.mset("key1", "ohmytext", "key2", "mynewtext"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java index e0f5c7af26..ca8be570ee 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java @@ -10,11 +10,16 @@ import java.util.HashSet; import java.util.Set; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.AllKindOfValuesCommandsTestBase; import redis.clients.jedis.params.ScanParams; @@ -23,6 +28,15 @@ @RunWith(Parameterized.class) public class ClusterAllKindOfValuesCommandsTest extends AllKindOfValuesCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + public ClusterAllKindOfValuesCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java index 078e8d8851..505722574b 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java @@ -2,12 +2,13 @@ import static org.junit.Assert.assertEquals; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; +import org.junit.*; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.BitOP; import redis.clients.jedis.commands.unified.BitCommandsTestBase; @@ -16,6 +17,15 @@ @RunWith(Parameterized.class) public class ClusterBitCommandsTest extends BitCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0) + ,DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + public ClusterBitCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java index 6c8f3e25cc..9fc35f96ab 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java @@ -14,7 +14,7 @@ static JedisCluster getCleanCluster(RedisProtocol protocol) { clearClusterData(); return new JedisCluster( Collections.singleton(HostAndPorts.getStableClusterServers().get(0)), - DefaultJedisClientConfig.builder().password("cluster").protocol(protocol).build()); + DefaultJedisClientConfig.builder().password("cluster").protocol(protocol).build()); } static void clearClusterData() { diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java index a5590a2730..81a6889dd5 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java @@ -1,15 +1,29 @@ package redis.clients.jedis.commands.unified.cluster; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.HashesCommandsTestBase; @RunWith(Parameterized.class) public class ClusterHashesCommandsTest extends HashesCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster") .build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + public ClusterHashesCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java index 666752050b..ef24a93e3b 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java @@ -10,13 +10,19 @@ import java.util.Collections; import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.args.ListDirection; import redis.clients.jedis.commands.unified.ListCommandsTestBase; @@ -27,6 +33,15 @@ public class ClusterListCommandsTest extends ListCommandsTestBase { private final Logger logger = LoggerFactory.getLogger(getClass()); + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + public ClusterListCommandsTest(RedisProtocol protocol) { super(protocol); } @@ -259,6 +274,7 @@ public void blmove() { } @Test + @SinceRedisVersion(value="7.0.0") public void lmpop() { String mylist1 = "mylist1{.}"; String mylist2 = "mylist2{.}"; @@ -284,6 +300,7 @@ public void lmpop() { } @Test + @SinceRedisVersion(value="7.0.0") public void blmpopSimple() { String mylist1 = "mylist1{.}"; String mylist2 = "mylist2{.}"; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java index 75d2b6bbdc..b71a7fe663 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java @@ -5,11 +5,17 @@ import java.util.HashSet; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.SetCommandsTestBase; @@ -26,6 +32,15 @@ public ClusterSetCommandsTest(RedisProtocol protocol) { super(protocol); } + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Before public void setUp() { jedis = ClusterCommandsTestHelper.getCleanCluster(protocol); @@ -178,6 +193,7 @@ public void sdiffstore() { } @Test + @SinceRedisVersion(value="7.0.0") public void sintercard() { jedis.sadd("foo{.}", "a"); jedis.sadd("foo{.}", "b"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java index b08d7b1773..095f4a24c7 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java @@ -10,11 +10,17 @@ import java.util.Collections; import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.SortedSetCommandsTestBase; import redis.clients.jedis.params.ZAddParams; @@ -32,6 +38,15 @@ public class ClusterSortedSetCommandsTest extends SortedSetCommandsTestBase { final byte[] bb = { 0x0B }; final byte[] bc = { 0x0C }; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + public ClusterSortedSetCommandsTest(RedisProtocol protocol) { super(protocol); } @@ -234,6 +249,7 @@ public void zrangestore() { } @Test + @SinceRedisVersion(value="7.0.0") public void zintercard() { jedis.zadd("foo{.}", 1, "a"); jedis.zadd("foo{.}", 2, "b"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java index a8f980bd9a..8b2d62f05c 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java @@ -5,11 +5,17 @@ import java.util.ArrayList; import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.StringValuesCommandsTestBase; import redis.clients.jedis.params.LCSParams; @@ -22,6 +28,15 @@ public ClusterStringValuesCommandsTest(RedisProtocol protocol) { super(protocol); } + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); + @Before public void setUp() { jedis = ClusterCommandsTestHelper.getCleanCluster(protocol); @@ -84,6 +99,7 @@ public void msetnx() { } @Test + @SinceRedisVersion(value="7.0.0") public void lcs() { jedis.mset("key1{.}", "ohmytext", "key2{.}", "mynewtext"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java index 36313c24ca..f9a17e8522 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java @@ -10,6 +10,7 @@ import java.util.List; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -976,6 +977,7 @@ public void blmove() { } @Test + @SinceRedisVersion(value="7.0.0") public void lmpop() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; @@ -1004,6 +1006,7 @@ public void lmpop() { } @Test + @SinceRedisVersion(value="7.0.0") public void blmpopSimple() { String mylist1 = "mylist1"; String mylist2 = "mylist2"; diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java index 55dfec6e98..ecef988fa7 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java @@ -2,12 +2,13 @@ import java.util.Collection; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runners.Parameterized; -import redis.clients.jedis.JedisPooled; -import redis.clients.jedis.Pipeline; -import redis.clients.jedis.RedisProtocol; +import redis.clients.jedis.*; import redis.clients.jedis.commands.CommandsTestsParameters; import redis.clients.jedis.commands.unified.pooled.PooledCommandsTestHelper; @@ -29,6 +30,14 @@ public static Collection data() { protected final RedisProtocol protocol; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); /** * The RESP protocol is to be injected by the subclasses, usually via JUnit * parameterized tests, because most of the subclassed tests are meant to be diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java index 0dd0a18559..c311e1134c 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Set; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -378,6 +379,7 @@ public void sinterstore() { } @Test + @SinceRedisVersion(value="7.0.0") public void sintercard() { pipe.sadd("foo", "a"); pipe.sadd("foo", "b"); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/SortedSetPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SortedSetPipelineCommandsTest.java index a6915ce3a7..dfd46c7ae8 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/SortedSetPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SortedSetPipelineCommandsTest.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.stream.Collectors; +import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -542,6 +543,7 @@ public void zrank() { } @Test + @SinceRedisVersion(value="7.2.0", message = "Starting with Redis version 7.2.0: Added the optional WITHSCORE argument.") public void zrankWithScore() { pipe.zadd("foo", 1d, "a"); pipe.zadd("foo", 2d, "b"); @@ -1516,6 +1518,7 @@ public void zintertoreParams() { } @Test + @SinceRedisVersion(value="7.0.0") public void zintercard() { pipe.zadd("foo", 1, "a"); pipe.zadd("foo", 2, "b"); @@ -1840,6 +1843,7 @@ private Double getScoreFromByteMap(Map bhash, byte[] key) { } @Test + @SinceRedisVersion(value="7.0.0") public void zmpop() { pipe.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); pipe.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); @@ -1863,6 +1867,7 @@ public void zmpop() { } @Test + @SinceRedisVersion(value="7.0.0") public void bzmpopSimple() { pipe.zadd("foo", 1d, "a", ZAddParams.zAddParams().nx()); pipe.zadd("foo", 10d, "b", ZAddParams.zAddParams().nx()); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java index af64b17576..78627e1cf3 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java @@ -27,6 +27,9 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersion; +import io.redis.test.utils.RedisVersionUtil; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -257,7 +260,7 @@ public void xaddParamsId() { pipe.xadd(key, XAddParams.xAddParams().id(new StreamEntryID(0, 1)), map); pipe.xadd(key, XAddParams.xAddParams().id(2, 3), map); - pipe.xadd(key, XAddParams.xAddParams().id(4), map); + pipe.xadd(key, XAddParams.xAddParams().id("4-0"), map); pipe.xadd(key, XAddParams.xAddParams().id("5-6"), map); pipe.xadd(key, XAddParams.xAddParams().id("7-8".getBytes()), map); pipe.xadd(key, XAddParams.xAddParams(), map); @@ -277,6 +280,31 @@ public void xaddParamsId() { greaterThan((StreamEntryID) results.get(4))); } + @Test + @SinceRedisVersion(value = "7.2.0", message = "Starting with Redis version 7.0.0: Added support for the -* explicit ID form.") + public void xaddParamsExplicitId() { + String key = "kk"; + Map map = singletonMap("ff", "vv"); + + pipe.xadd(key, XAddParams.xAddParams().id(new StreamEntryID(0, 1)), map); + pipe.xadd(key, XAddParams.xAddParams().id(2), map); + pipe.xadd(key, XAddParams.xAddParams().id(2), map); + pipe.xadd(key, XAddParams.xAddParams(), map); + + List results = pipe.syncAndReturnAll(); + + assertThat(results, contains( + equalTo(new StreamEntryID(0, 1)), + equalTo(new StreamEntryID(2, 0)), + equalTo(new StreamEntryID(2, 1)), + instanceOf(StreamEntryID.class) + )); + + assertThat((StreamEntryID) results.get(2), + greaterThan((StreamEntryID) results.get(1))); + } + + @Test public void xdel() { Map map1 = new HashMap<>(); @@ -1208,7 +1236,9 @@ public void xinfo() throws InterruptedException { assertEquals(MY_CONSUMER, consumersInfo.get(0).getName()); assertEquals(0L, consumersInfo.get(0).getPending()); assertThat(consumersInfo.get(0).getIdle(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumersInfo.get(0).getInactive(), Matchers.any(Long.class)); + if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + assertThat(consumersInfo.get(0).getInactive(), Matchers.any(Long.class)); + } // Consumer info test List consumerInfo = consumerInfoResponse.get(); @@ -1222,7 +1252,9 @@ public void xinfo() throws InterruptedException { assertEquals(MY_CONSUMER, consumerInfo.get(0).getName()); assertEquals(0L, consumerInfo.get(0).getPending()); assertThat(consumerInfo.get(0).getIdle(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumerInfo.get(0).getInactive(), Matchers.any(Long.class)); + if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + assertThat(consumerInfo.get(0).getInactive(), Matchers.any(Long.class)); + } // test with more groups and consumers pipe.xgroupCreate(STREAM_NAME, G2, StreamEntryID.XGROUP_LAST_ENTRY, false); @@ -1305,7 +1337,9 @@ public void xinfoStreamFullWithPending() { StreamConsumerFullInfo consumer = group.getConsumers().get(0); assertEquals("xreadGroup-consumer", consumer.getName()); assertThat(consumer.getSeenTime(), Matchers.greaterThanOrEqualTo(0L)); - assertThat(consumer.getActiveTime(), Matchers.greaterThanOrEqualTo(0L)); + if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { + assertThat(consumer.getActiveTime(), Matchers.greaterThanOrEqualTo(0L)); + } assertEquals(1, consumer.getPending().size()); List consumerPendingEntry = consumer.getPending().get(0); assertEquals(id1, consumerPendingEntry.get(0)); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java index a1b53de023..1e2fc5d94d 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java @@ -1,15 +1,28 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.AllKindOfValuesCommandsTestBase; @RunWith(Parameterized.class) public class PooledAllKindOfValuesCommandsTest extends AllKindOfValuesCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); public PooledAllKindOfValuesCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java index 5764a1bbfa..b1428d46ca 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -11,6 +14,15 @@ @RunWith(Parameterized.class) public class PooledBitCommandsTest extends BitCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort() + ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledBitCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledCommandsTestHelper.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledCommandsTestHelper.java index ab69c57f4e..86e1f666de 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledCommandsTestHelper.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledCommandsTestHelper.java @@ -4,7 +4,7 @@ public class PooledCommandsTestHelper { - private static final EndpointConfig nodeInfo = HostAndPorts.getRedisEndpoint("standalone0"); + public static final EndpointConfig nodeInfo = HostAndPorts.getRedisEndpoint("standalone0"); public static JedisPooled getPooled(RedisProtocol redisProtocol) { return new JedisPooled(nodeInfo.getHostAndPort(), nodeInfo.getClientConfigBuilder() diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java index bb5741d967..95f4020549 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -11,6 +14,15 @@ @RunWith(Parameterized.class) public class PooledHashesCommandsTest extends HashesCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledHashesCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java index 5d38fe43d5..606e91bcc3 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java @@ -1,16 +1,29 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.ListCommandsTestBase; @RunWith(Parameterized.class) public class PooledListCommandsTest extends ListCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort() + ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledListCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java index d6feb05fa3..4ef5361caa 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java @@ -7,22 +7,33 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import redis.clients.jedis.AbstractPipeline; -import redis.clients.jedis.AbstractTransaction; -import redis.clients.jedis.RedisProtocol; -import redis.clients.jedis.Response; +import redis.clients.jedis.*; import redis.clients.jedis.commands.unified.UnifiedJedisCommandsTestBase; import redis.clients.jedis.exceptions.JedisDataException; @RunWith(Parameterized.class) public class PooledMiscellaneousTest extends UnifiedJedisCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort() + ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledMiscellaneousTest(RedisProtocol protocol) { super(protocol); } @@ -148,6 +159,7 @@ public void broadcast() { } @Test + @SinceRedisVersion(value="7.0.0") public void broadcastWithError() { JedisDataException error = assertThrows(JedisDataException.class, () -> jedis.functionDelete("xyz")); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java index 2be9dbbf1c..f8a2aa05e6 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -11,6 +14,15 @@ @RunWith(Parameterized.class) public class PooledSetCommandsTest extends SetCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledSetCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java index c3d0b76ece..5499b0495f 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -11,6 +14,15 @@ @RunWith(Parameterized.class) public class PooledSortedSetCommandsTest extends SortedSetCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public PooledSortedSetCommandsTest(RedisProtocol protocol) { super(protocol); } diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java index c9a1c39ae1..ab8da3db7a 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis.commands.unified.pooled; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -10,6 +13,14 @@ @RunWith(Parameterized.class) public class PooledStringValuesCommandsTest extends StringValuesCommandsTestBase { + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + PooledCommandsTestHelper.nodeInfo.getHostAndPort(), + PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); public PooledStringValuesCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/csc/AllowAndDenyListCacheableTest.java b/src/test/java/redis/clients/jedis/csc/AllowAndDenyListCacheableTest.java index a0b7d68381..a2fbe4ea8a 100644 --- a/src/test/java/redis/clients/jedis/csc/AllowAndDenyListCacheableTest.java +++ b/src/test/java/redis/clients/jedis/csc/AllowAndDenyListCacheableTest.java @@ -3,12 +3,14 @@ import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; + import io.redis.test.annotations.SinceRedisVersion; import org.junit.Test; import redis.clients.jedis.JedisPooled; import redis.clients.jedis.Protocol; import redis.clients.jedis.csc.util.AllowAndDenyListWithStringKeys; +@SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") public class AllowAndDenyListCacheableTest extends ClientSideCacheTestBase { private static CacheConfig createConfig(Cacheable cacheable) { diff --git a/src/test/java/redis/clients/jedis/csc/ClientSideCacheFunctionalityTest.java b/src/test/java/redis/clients/jedis/csc/ClientSideCacheFunctionalityTest.java index d2032e5d23..49cb6dafeb 100644 --- a/src/test/java/redis/clients/jedis/csc/ClientSideCacheFunctionalityTest.java +++ b/src/test/java/redis/clients/jedis/csc/ClientSideCacheFunctionalityTest.java @@ -1,5 +1,6 @@ package redis.clients.jedis.csc; +import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.aMapWithSize; import static org.hamcrest.Matchers.hasSize; @@ -8,23 +9,18 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collector; import java.util.stream.Collectors; +import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -34,6 +30,7 @@ import redis.clients.jedis.JedisPooled; import redis.clients.jedis.UnifiedJedis; +@SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") public class ClientSideCacheFunctionalityTest extends ClientSideCacheTestBase { @Test // T.5.1 @@ -508,7 +505,7 @@ public void run() { @Test public void testNullValue() throws InterruptedException { int MAX_SIZE = 20; - String nonExisting = "non-existing-key"; + String nonExisting = "non-existing-key-"+ UUID.randomUUID().toString(); control.del(nonExisting); try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(), CacheConfig.builder().maxSize(MAX_SIZE).build())) { @@ -529,8 +526,10 @@ public void testNullValue() throws InterruptedException { assertEquals(1, stats.getMissCount()); control.set(nonExisting, "bar"); - val = jedis.get(nonExisting); - assertEquals("bar", val); + await() + .atMost(5, TimeUnit.SECONDS) + .pollInterval(10, TimeUnit.MILLISECONDS) + .untilAsserted(() -> assertEquals("bar", jedis.get(nonExisting))); assertEquals(1, cache.getSize()); assertEquals("bar", cache.getCacheEntries().iterator().next().getValue()); assertEquals(1, stats.getHitCount()); diff --git a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java index db53b085be..47f2d1142c 100644 --- a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java @@ -1,19 +1,19 @@ package redis.clients.jedis.csc; import java.util.function.Supplier; + +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.EnabledOnCommandRule; +import io.redis.test.utils.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.After; import org.junit.Before; -import redis.clients.jedis.Connection; -import redis.clients.jedis.ConnectionPoolConfig; -import redis.clients.jedis.EndpointConfig; -import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.HostAndPorts; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisClientConfig; +import org.junit.Rule; +import redis.clients.jedis.*; -abstract class ClientSideCacheTestBase { +@SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") +public abstract class ClientSideCacheTestBase { protected static final EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("standalone1"); @@ -21,6 +21,15 @@ abstract class ClientSideCacheTestBase { protected Jedis control; + @Rule + public RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), + HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + @Rule + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( + HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), + HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + @Before public void setUp() throws Exception { control = new Jedis(hnp, endpoint.getClientConfigBuilder().build()); diff --git a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java index 89114d154f..41d163e202 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java @@ -4,16 +4,14 @@ import java.util.Set; import java.util.function.Supplier; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import redis.clients.jedis.Connection; -import redis.clients.jedis.ConnectionPoolConfig; -import redis.clients.jedis.DefaultJedisClientConfig; -import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.HostAndPorts; -import redis.clients.jedis.JedisClientConfig; -import redis.clients.jedis.JedisCluster; +import org.junit.ClassRule; +import redis.clients.jedis.*; +@SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") public class JedisClusterClientSideCacheTest extends UnifiedJedisClientSideCacheTestBase { private static final Set hnp = new HashSet<>(HostAndPorts.getStableClusterServers()); @@ -28,14 +26,16 @@ public class JedisClusterClientSideCacheTest extends UnifiedJedisClientSideCache return poolConfig; }; - @Override - protected JedisCluster createRegularJedis() { - return new JedisCluster(hnp, clientConfig.get()); - } + @ClassRule + public static RedisVersionRule versionRule = new RedisVersionRule(hnp.iterator().next(), clientConfig.get()); - @Override - protected JedisCluster createCachedJedis(CacheConfig cacheConfig) { - return new JedisCluster(hnp, clientConfig.get(), cacheConfig); - } + @Override + protected JedisCluster createRegularJedis() { + return new JedisCluster(hnp, clientConfig.get()); + } + @Override + protected JedisCluster createCachedJedis(CacheConfig cacheConfig) { + return new JedisCluster(hnp, clientConfig.get(), cacheConfig); + } } diff --git a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java index d7b2bd4989..2bca0fe73a 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java @@ -1,13 +1,21 @@ package redis.clients.jedis.csc; +import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisVersionRule; import org.junit.BeforeClass; +import org.junit.ClassRule; import redis.clients.jedis.HostAndPorts; +@SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") public class JedisPooledClientSideCacheTest extends JedisPooledClientSideCacheTestBase { + @ClassRule + public static RedisVersionRule versionRule = new RedisVersionRule( + HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), + HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + @BeforeClass public static void prepare() { endpoint = HostAndPorts.getRedisEndpoint("standalone1"); } - } diff --git a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java index 133efcb3fc..d30ba58ba0 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java @@ -2,6 +2,8 @@ import static org.junit.Assert.assertEquals; +import io.redis.test.utils.RedisVersionRule; +import org.junit.ClassRule; import org.junit.Test; import redis.clients.jedis.EndpointConfig; diff --git a/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java index 82da0b14af..136448a73c 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java @@ -4,33 +4,42 @@ import java.util.HashSet; import java.util.Set; -import redis.clients.jedis.DefaultJedisClientConfig; -import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.HostAndPorts; -import redis.clients.jedis.JedisClientConfig; -import redis.clients.jedis.JedisSentineled; +import org.junit.BeforeClass; +import redis.clients.jedis.*; +import io.redis.test.utils.RedisVersion; + +import static org.junit.Assume.assumeTrue; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; public class JedisSentineledClientSideCacheTest extends UnifiedJedisClientSideCacheTestBase { - private static final String MASTER_NAME = "mymaster"; + private static final String MASTER_NAME = "mymaster"; - protected static final HostAndPort sentinel1 = HostAndPorts.getSentinelServers().get(1); - protected static final HostAndPort sentinel2 = HostAndPorts.getSentinelServers().get(3); + protected static final HostAndPort sentinel1 = HostAndPorts.getSentinelServers().get(1); + protected static final HostAndPort sentinel2 = HostAndPorts.getSentinelServers().get(3); - private static final Set sentinels = new HashSet<>(Arrays.asList(sentinel1, sentinel2)); + private static final Set sentinels = new HashSet<>(Arrays.asList(sentinel1, sentinel2)); - private static final JedisClientConfig masterClientConfig = DefaultJedisClientConfig.builder().resp3().password("foobared").build(); + private static final JedisClientConfig masterClientConfig = DefaultJedisClientConfig.builder().resp3().password("foobared").build(); - private static final JedisClientConfig sentinelClientConfig = DefaultJedisClientConfig.builder().resp3().build(); + private static final JedisClientConfig sentinelClientConfig = DefaultJedisClientConfig.builder().resp3().build(); - @Override - protected JedisSentineled createRegularJedis() { - return new JedisSentineled(MASTER_NAME, masterClientConfig, sentinels, sentinelClientConfig); - } + @Override + protected JedisSentineled createRegularJedis() { + return new JedisSentineled(MASTER_NAME, masterClientConfig, sentinels, sentinelClientConfig); + } - @Override - protected JedisSentineled createCachedJedis(CacheConfig cacheConfig) { - return new JedisSentineled(MASTER_NAME, masterClientConfig, cacheConfig, sentinels, sentinelClientConfig); - } + @Override + protected JedisSentineled createCachedJedis(CacheConfig cacheConfig) { + return new JedisSentineled(MASTER_NAME, masterClientConfig, cacheConfig, sentinels, sentinelClientConfig); + } + @BeforeClass + public static void prepare() { + try (JedisSentineled sentinelClient = new JedisSentineled(MASTER_NAME, masterClientConfig, sentinels, sentinelClientConfig); + Jedis master = new Jedis(sentinelClient.getCurrentMaster(),masterClientConfig)) { + assumeTrue("Jedis Client side caching is only supported with 'Redis 7.4' or later.", + getRedisVersion(master).isGreaterThanOrEqualTo(RedisVersion.V7_4)); + } + } } diff --git a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java index b8df3910cd..8458e0ffdb 100644 --- a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java @@ -1,16 +1,35 @@ package redis.clients.jedis.csc; +import org.junit.AfterClass; + +import redis.clients.jedis.Jedis; +import io.redis.test.utils.RedisVersion; +import redis.clients.jedis.util.TlsUtil; import org.junit.BeforeClass; import redis.clients.jedis.HostAndPorts; -import redis.clients.jedis.SSLJedisTest; + +import java.nio.file.Path; + +import static org.junit.Assume.assumeTrue; +import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; public class SSLJedisPooledClientSideCacheTest extends JedisPooledClientSideCacheTestBase { @BeforeClass public static void prepare() { - SSLJedisTest.setupTrustStore(); + Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); endpoint = HostAndPorts.getRedisEndpoint("standalone0-tls"); + + try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build())) { + assumeTrue("Jedis Client side caching is only supported with 'Redis 7.4' or later.", + getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_4)); + } } + @AfterClass + public static void teardownTrustStore() { + TlsUtil.restoreOriginalTrustStore(); + } } diff --git a/src/test/java/redis/clients/jedis/csc/UnifiedJedisClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/UnifiedJedisClientSideCacheTestBase.java index e07bf578ee..1dd11c238d 100644 --- a/src/test/java/redis/clients/jedis/csc/UnifiedJedisClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/UnifiedJedisClientSideCacheTestBase.java @@ -9,9 +9,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.*; import redis.clients.jedis.UnifiedJedis; diff --git a/src/test/java/redis/clients/jedis/modules/RedisModuleCommandsTestBase.java b/src/test/java/redis/clients/jedis/modules/RedisModuleCommandsTestBase.java index 9e21fba23f..9d51928aa7 100644 --- a/src/test/java/redis/clients/jedis/modules/RedisModuleCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/modules/RedisModuleCommandsTestBase.java @@ -70,12 +70,5 @@ public void setUp() { public void tearDown() throws Exception { client.close(); } -// -// public static void tearDown() { -// client.close(); -// } -// -// protected static Connection createConnection() { -// return new Connection(hnp); -// } + } diff --git a/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java b/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java deleted file mode 100644 index fed3055b4f..0000000000 --- a/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -package redis.clients.jedis.util; - -import redis.clients.jedis.EndpointConfig; -import redis.clients.jedis.Jedis; - -public class RedisVersionUtil { - - public static Integer getRedisMajorVersionNumber(EndpointConfig endpoint) { - String completeVersion = null; - - try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), - endpoint.getClientConfigBuilder().build())) { - String info = jedis.info("server"); - String[] splitted = info.split("\\s+|:"); - for (int i = 0; i < splitted.length; i++) { - if (splitted[i].equalsIgnoreCase("redis_version")) { - completeVersion = splitted[i + 1]; - break; - } - } - } - - if (completeVersion == null) { - return null; - } - return Integer.parseInt(completeVersion.substring(0, completeVersion.indexOf("."))); - } - - public static boolean checkRedisMajorVersionNumber(int minVersion, EndpointConfig endpoint) { - return getRedisMajorVersionNumber(endpoint) >= minVersion; - } -} diff --git a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java new file mode 100644 index 0000000000..a9da3bd029 --- /dev/null +++ b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java @@ -0,0 +1,19 @@ +package redis.clients.jedis.util; + +import java.util.Optional; + +public class TestEnvUtil { + private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", "docker"); + private static final String TESTMODULE_SO = Optional.ofNullable(System.getenv("TESTMODULE_SO")) + .orElseGet(() -> isContainerEnv() + ? "/redis/work/modules/testmodule.so" + : "/tmp/testmodule.so"); + + public static String testModuleSo() { + return TESTMODULE_SO; + } + + public static boolean isContainerEnv() { + return TEST_ENV_PROVIDER.equals("docker"); + } +} diff --git a/src/test/java/redis/clients/jedis/util/TlsUtil.java b/src/test/java/redis/clients/jedis/util/TlsUtil.java new file mode 100644 index 0000000000..dedb89a57b --- /dev/null +++ b/src/test/java/redis/clients/jedis/util/TlsUtil.java @@ -0,0 +1,286 @@ +package redis.clients.jedis.util; + +import javax.net.ssl.*; +import java.io.*; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import static org.junit.Assert.assertTrue; + +public class TlsUtil { + + private static final String TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore"; + private static final String TRUST_STORE_PASSWORD_PROPERTY = "javax.net.ssl.trustStorePassword"; + private static final String TRUST_STORE_TYPE_PROPERTY = "javax.net.ssl.trustStoreType"; + + private static String originalTrustStore; + private static String originalTrustStoreType; + private static String originalTrustStorePassword; + + private static final String TRUST_STORE_TYPE = "JCEKS"; + private static final String CERTIFICATE_TYPE = "X.509"; + + private static final String TEST_WORK_FOLDER = System.getenv().getOrDefault("TEST_WORK_FOLDER", "./redis-env/"); + private static final String TEST_TRUSTSTORE = System.getenv().getOrDefault("TEST_TRUSTSTORE", "truststore.jceks"); + private static final String TEST_CA_CERT = System.getenv().getOrDefault("TEST_CA_CERT", "work/tls/ca.crt"); + + public static void setCustomTrustStore(Path customTrustStorePath, String customTrustStorePassword) { + // Store original properties + originalTrustStore = System.getProperty(TRUST_STORE_PROPERTY); + originalTrustStorePassword = System.getProperty(TRUST_STORE_PASSWORD_PROPERTY); + originalTrustStoreType = System.getProperty(TRUST_STORE_TYPE_PROPERTY, "JKS"); + // Set new properties for the custom truststore + System.setProperty(TRUST_STORE_PROPERTY, customTrustStorePath.toAbsolutePath().toString()); + System.setProperty(TRUST_STORE_TYPE_PROPERTY, TRUST_STORE_TYPE); + if (customTrustStorePassword != null) { + System.setProperty(TRUST_STORE_PASSWORD_PROPERTY, customTrustStorePassword); + } else { + System.clearProperty(TRUST_STORE_PASSWORD_PROPERTY); + } + } + + public static void restoreOriginalTrustStore() { + // Restore original properties + if (originalTrustStore != null) { + System.setProperty(TRUST_STORE_PROPERTY, originalTrustStore); + } else { + System.clearProperty(TRUST_STORE_PROPERTY); + } + + if ( originalTrustStoreType != null) { + System.setProperty(TRUST_STORE_TYPE_PROPERTY, originalTrustStoreType); + } else { + System.clearProperty(TRUST_STORE_TYPE_PROPERTY); + } + + if (originalTrustStorePassword != null) { + System.setProperty(TRUST_STORE_PASSWORD_PROPERTY, originalTrustStorePassword); + } else { + System.clearProperty(TRUST_STORE_PASSWORD_PROPERTY); + } + } + + public static Path envCa(String env) { + if (TestEnvUtil.isContainerEnv()) { + return Paths.get(TEST_WORK_FOLDER, env, TEST_CA_CERT); + } else { + return Paths.get("src/test/resources/private.crt"); + } + } + + public static Path envTruststore(String env) { + + if (TestEnvUtil.isContainerEnv()) { + return Paths.get(TEST_WORK_FOLDER, env + '-' + TEST_TRUSTSTORE); + } else { + return Paths.get("src/test/resources/truststore.jceks"); + } + } + + /** + * Loads the CA certificate from the provided file path. + * + * @param caCertPath Path to the CA certificate file (ca.crt). + * @return Loaded X509Certificate. + * @throws Exception If there's an error reading the certificate. + */ + public static X509Certificate loadCACertificate(String caCertPath) { + File caCertFile = new File(caCertPath); + try (FileInputStream fis = new FileInputStream(caCertFile)) { + CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_TYPE); + return (X509Certificate) certificateFactory.generateCertificate(fis); + } catch (CertificateException | IOException e) { + throw new RuntimeException(e); + } + } + + public static Path createAndSaveEnvTruststore(String env, String truststorePassword) { + String caPath = envCa(env).toAbsolutePath().toString(); + String trustStorePath = envTruststore(env).toAbsolutePath().toString(); + return createAndSaveTruststore(caPath, trustStorePath, truststorePassword); + } + + /** + * Creates a truststore with the given CA certificate. + * + * @param caCertPath Path to the CA certificate file (ca.crt). + * @return A KeyStore object containing the CA certificate. + * @throws Exception If there's an error creating the truststore. + */ + public static KeyStore createTruststore(String caCertPath) throws Exception { + X509Certificate caCert = loadCACertificate(caCertPath); + + KeyStore trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); + trustStore.load(null, null); + trustStore.setCertificateEntry("ca-cert", caCert); + + return trustStore; + } + + /** + * Creates a truststore with the given CA certificate and saves it to the specified path. + * + * @param caCertPath Path to the CA certificate file (ca.crt). + * @param truststorePath Path to save the generated truststore. + * @param truststorePassword Password for the truststore. + * @return Path to the saved truststore file. + * @throws Exception If there's an error creating or saving the truststore. + */ + public static Path createAndSaveTruststore(String caCertPath, String truststorePath, String truststorePassword) { + try { + KeyStore trustStore = createTruststore(caCertPath); + + // Save the truststore to the specified path + try (FileOutputStream fos = new FileOutputStream(truststorePath)) { + trustStore.store(fos, truststorePassword.toCharArray()); + } catch (IOException e) { + throw new RuntimeException("Failed to save truststore to " + truststorePath + ": " + e.getMessage(), e); + } + } catch (Exception e) { + throw new RuntimeException("Failed to create and save truststore: " + e.getMessage(), e); + } + + return Paths.get(truststorePath); + } + + + /** + * Creates an SSLSocketFactory that trusts all certificates in truststore.jceks. + * for given test environment + */ + public static SSLSocketFactory sslSocketFactoryForEnv(String envName){ + return sslSocketFactory(envCa(envName)); + } + + /** + * Returns SSLSocketFactory configured with Truststore containing provided CA cert + */ + public static SSLSocketFactory sslSocketFactory(Path caCertPath){ + + KeyStore truststore = null; + try { + truststore = createTruststore(caCertPath.toAbsolutePath().toString()); + + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); + trustManagerFactory.init(truststore); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (Exception e) { + throw new RuntimeException("Failed to initialise SslSocketFactory for " + caCertPath, e); + } + + } + + /** + * Creates an SSLSocketFactory with a trust manager that does not trust any certificates. + */ + public static SSLSocketFactory createTrustNoOneSslSocketFactory() throws Exception { + TrustManager[] unTrustManagers = new TrustManager[]{new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) { + throw new RuntimeException(new InvalidAlgorithmParameterException()); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) { + throw new RuntimeException(new InvalidAlgorithmParameterException()); + } + }}; + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, unTrustManagers, new SecureRandom()); + return sslContext.getSocketFactory(); + } + + public static class LocalhostVerifier extends BasicHostnameVerifier { + @Override + public boolean verify(String hostname, SSLSession session) { + if (hostname.equals("127.0.0.1")) { + hostname = "localhost"; + } + return super.verify(hostname, session); + } + } + + /** + * Very basic hostname verifier implementation for testing. NOT recommended for production. + */ + public static class BasicHostnameVerifier implements HostnameVerifier { + + private static final String COMMON_NAME_RDN_PREFIX = "CN="; + + @Override + public boolean verify(String hostname, SSLSession session) { + X509Certificate peerCertificate; + try { + peerCertificate = (X509Certificate) session.getPeerCertificates()[0]; + } catch (SSLPeerUnverifiedException e) { + throw new IllegalStateException("The session does not contain a peer X.509 certificate.", e); + } + String peerCertificateCN = getCommonName(peerCertificate); + return hostname.equals(peerCertificateCN); + } + + private String getCommonName(X509Certificate peerCertificate) { + String subjectDN = peerCertificate.getSubjectDN().getName(); + String[] dnComponents = subjectDN.split(","); + for (String dnComponent : dnComponents) { + dnComponent = dnComponent.trim(); + if (dnComponent.startsWith(COMMON_NAME_RDN_PREFIX)) { + return dnComponent.substring(COMMON_NAME_RDN_PREFIX.length()); + } + } + throw new IllegalArgumentException("The certificate has no common name."); + } + } + + public static SSLSocketFactory createTrustAllSslSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) { + // Trust all clients + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) { + // Trust all servers + } + } + }; + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (GeneralSecurityException e) { + throw new RuntimeException("Failed to create a trust-all SSL socket factory", e); + } + } + + public static void main(String[] args) { + try { + + String truststorePassword = null; + + String caCertPath = "./work/redis1-2-5-10-sentinel/work/tls/ca.crt"; + String truststorePath = "./work/redis1-2-5-10-sentinel/work/truststore.jceks"; + Path truststore = createAndSaveTruststore(caCertPath, truststorePath, "change_me"); + System.out.println("Truststore saved at: " + truststore.toAbsolutePath()); + + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf b/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf new file mode 100644 index 0000000000..f3104c5ba6 --- /dev/null +++ b/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf @@ -0,0 +1,11 @@ +port 26383 +tls-port 36383 +tls-auth-clients no +user default off +user sentinel on allcommands allkeys allchannels >foobared +sentinel monitor aclmaster 127.0.0.1 6387 1 +sentinel auth-user aclmaster acljedis +sentinel auth-pass aclmaster fizzbuzz +sentinel down-after-milliseconds aclmaster 2000 +sentinel failover-timeout aclmaster 120000 +sentinel parallel-syncs aclmaster 1 \ No newline at end of file diff --git a/src/test/resources/env/.env b/src/test/resources/env/.env new file mode 100644 index 0000000000..ef6dc4179c --- /dev/null +++ b/src/test/resources/env/.env @@ -0,0 +1,7 @@ +CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:8.0-M01 +REDIS_IMAGE=redis:8.0-M01 +REDIS_ENV_CONF_DIR=./ +REDIS_MODULES_DIR=/tmp +REDIS_ENV_WORK_DIR=./redis-env-work + +ENABLE_MODULE_COMMAND_DIRECTIVE=--enable-module-command yes \ No newline at end of file diff --git a/src/test/resources/env/.env.v6.2.16 b/src/test/resources/env/.env.v6.2.16 new file mode 100644 index 0000000000..c285604372 --- /dev/null +++ b/src/test/resources/env/.env.v6.2.16 @@ -0,0 +1,8 @@ +CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:8.0-M01 +REDIS_IMAGE=redis:6.2.16 +REDIS_ENV_CONF_DIR=./ +REDIS_MODULES_DIR=/tmp +REDIS_ENV_WORK_DIR=./redis-env-work + +#REMOVE UNSUPPORTED DIRECTIVE +ENABLE_MODULE_COMMAND_DIRECTIVE= \ No newline at end of file diff --git a/src/test/resources/env/cluster-unbound/config/node-7379-8379/redis.conf b/src/test/resources/env/cluster-unbound/config/node-7379-8379/redis.conf new file mode 100644 index 0000000000..03a685ca8b --- /dev/null +++ b/src/test/resources/env/cluster-unbound/config/node-7379-8379/redis.conf @@ -0,0 +1,9 @@ +bind 0.0.0.0 +port 7379 +tls-port 8379 +requirepass cluster +tls-auth-clients no +cluster-node-timeout 15000 +save "" +appendonly no +cluster-enabled yes \ No newline at end of file diff --git a/src/test/resources/env/cluster-unbound/config/node-7380-8380/redis.conf b/src/test/resources/env/cluster-unbound/config/node-7380-8380/redis.conf new file mode 100644 index 0000000000..7991ea74bd --- /dev/null +++ b/src/test/resources/env/cluster-unbound/config/node-7380-8380/redis.conf @@ -0,0 +1,8 @@ +bind 0.0.0.0 +requirepass cluster +port 7380 +tls-port 8380 +tls-auth-clients no +save "" +appendonly no +cluster-enabled yes \ No newline at end of file diff --git a/src/test/resources/env/cluster-unbound/config/node-7381-8381/redis.conf b/src/test/resources/env/cluster-unbound/config/node-7381-8381/redis.conf new file mode 100644 index 0000000000..27e5faa26d --- /dev/null +++ b/src/test/resources/env/cluster-unbound/config/node-7381-8381/redis.conf @@ -0,0 +1,9 @@ +bind 0.0.0.0 +port 7381 +tls-port 8381 +requirepass cluster +tls-auth-clients no +cluster-node-timeout 15000 +save "" +appendonly no +cluster-enabled yes \ No newline at end of file diff --git a/src/test/resources/env/cluster-unbound/config/node-7382-8382/redis.conf b/src/test/resources/env/cluster-unbound/config/node-7382-8382/redis.conf new file mode 100644 index 0000000000..dbe32b3b7d --- /dev/null +++ b/src/test/resources/env/cluster-unbound/config/node-7382-8382/redis.conf @@ -0,0 +1,9 @@ +bind 0.0.0.0 +requirepass cluster +port 7382 +tls-port 8382 +tls-auth-clients no +cluster-node-timeout 15000 +save "" +appendonly no +cluster-enabled yes \ No newline at end of file diff --git a/src/test/resources/env/cluster-unbound/config/node-7383-8383/redis.conf b/src/test/resources/env/cluster-unbound/config/node-7383-8383/redis.conf new file mode 100644 index 0000000000..6928409ec7 --- /dev/null +++ b/src/test/resources/env/cluster-unbound/config/node-7383-8383/redis.conf @@ -0,0 +1,9 @@ +bind 0.0.0.0 +port 7383 +tls-port 8383 +requirepass cluster +tls-auth-clients no +cluster-node-timeout 15000 +save "" +appendonly no +cluster-enabled yes \ No newline at end of file diff --git a/src/test/resources/env/config/redis6-7/node-sentinel-26381-36381/redis.conf b/src/test/resources/env/config/redis6-7/node-sentinel-26381-36381/redis.conf new file mode 100644 index 0000000000..4268f7b62d --- /dev/null +++ b/src/test/resources/env/config/redis6-7/node-sentinel-26381-36381/redis.conf @@ -0,0 +1,9 @@ +port 26380 +tls-port 36380 +tls-auth-clients no +user deploy on allcommands allkeys >verify +sentinel monitor mymaster 127.0.0.1 6381 1 +sentinel auth-pass mymaster foobared +sentinel down-after-milliseconds mymaster 2000 +sentinel parallel-syncs mymaster 1 +sentinel failover-timeout mymaster 120000 \ No newline at end of file diff --git a/src/test/resources/env/docker-compose.yml b/src/test/resources/env/docker-compose.yml new file mode 100644 index 0000000000..c5858527ea --- /dev/null +++ b/src/test/resources/env/docker-compose.yml @@ -0,0 +1,160 @@ +services: + redis1-2-5-10-sentinel: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis1-2-5-10-sentinel + #network_mode: host + environment: + - REDIS_CLUSTER=no + - REDIS_PASSWORD=foobared + - TLS_ENABLED=yes + ports: + - "6379:6379" + - "6380:6380" + - "6383:6383" + - "6386:6386" + - "6390:6390" + - "6391:6391" + - "26379:26379" # sentinel + - "36379:36379" # sentinel tls + command: ${ENABLE_MODULE_COMMAND_DIRECTIVE} + volumes: + - ${REDIS_ENV_CONF_DIR}/redis1-2-5-10-sentinel/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis1-2-5-10-sentinel/work:/redis/work:rw + redis3-4-sentinel: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis3-4-sentinel + #network_mode: host + environment: + - REDIS_CLUSTER=no + - TLS_ENABLED=yes + - REDIS_PASSWORD=foobared + ports: + - "6381:6381" + - "16381:16381" + - "6382:6382" + - "16382:16382" + - "26380:26380" # sentinel + - "36380:36380" # sentinel tls + - "26382:26382" # sentinel + - "36382:36382" # sentinel tls + volumes: + - ${REDIS_ENV_CONF_DIR}/redis3-4-sentinel/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis3-4-sentinel/work:/redis/work:rw + + redis6-7-sentinel: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis6-7-sentinel + #network_mode: host + environment: + - REDIS_CLUSTER=no + - REDIS_PASSWORD=foobared + ports: + - "6384:6384" + - "6385:6385" + - "26381:26381" # sentinel + - "36381:36381" # sentinel tls + volumes: + - ${REDIS_ENV_CONF_DIR}/redis6-7-sentinel/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis6-7-sentinel/work:/redis/work:rw + redis9-sentinel: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis9-sentinel + #network_mode: host + environment: + - REDIS_CLUSTER=no + - REDIS_CLIENT_USER=deploy + - REDIS_CLIENT_PASSWORD=verify + - TLS_ENABLED=yes + ports: + - "6387:6387" + - "16387:16387" + - "26383:26383" # sentinel + - "36383:36383" # sentinel tls + volumes: + - ${REDIS_ENV_CONF_DIR}/redis9-sentinel/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis9-sentinel/work:/redis/work:rw + + redis10-11: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis10-11 + #network_mode: host + environment: + - REDIS_CLUSTER=no + ports: + - "6388:6388" + - "6389:6389" + volumes: + - ${REDIS_ENV_CONF_DIR}/redis10-11/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis10-11/work:/redis/work:rw + redis-unavailable: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: redis-unavailable-1 + #network_mode: host + environment: + - REDIS_CLUSTER=no + - PORT=6400 + ports: + - "6400:6400" + volumes: + - ${REDIS_ENV_WORK_DIR}/redis-unavailable/work:/redis/work:rw + + cluster-unbound: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: cluster-unbound-1 + environment: + - TLS_ENABLED=yes + - REDIS_PASSWORD=cluster + ports: + - "7379-7383:7379-7383" + - "8379-8383:8379-8383" + volumes: + - ${REDIS_ENV_CONF_DIR}/cluster-unbound/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/cluster-unbound/work:/redis/work:rw + + cluster-stable: + sysctls: + - net.ipv6.conf.all.disable_ipv6=1 + image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + container_name: cluster-stable-1 + #network_mode: host + command: --cluster-announce-ip 127.0.0.1 + environment: + - REDIS_CLUSTER=yes + - REDIS_PASSWORD=cluster + - PORT=7479 + - NODES=3 + - REPLICAS=0 + ports: + - "7479-7481:7479-7481" + volumes: + - ${REDIS_ENV_CONF_DIR}/cluster-stable/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/cluster-stable/work:/redis/work:rw + + jedis-stack: + image: redis/redis-stack-server:edge + container_name: jedis-stack + ports: + - "6479:6379" +#todo find a way to connect from mac os host to exposed unix socket in container +# redis_uds: +# image: redis:8.0-M01 +# container_name: redis_uds +# #network_mode: host +# command: redis-server /etc/redis.conf +# volumes: +# - "./redis_uds/config/node-0/redis.conf:/etc/redis.conf" +# - "./work/redis_uds/work:/tmp/docker/" \ No newline at end of file diff --git a/src/test/resources/env/endpoint.map b/src/test/resources/env/endpoint.map new file mode 100644 index 0000000000..5070ec216b --- /dev/null +++ b/src/test/resources/env/endpoint.map @@ -0,0 +1,20 @@ +REDIS1_CONF 6379:6390 "standalone0" : "redis://localhost:6379" +REDIS1_CONF 6379:6390 "standalone0-acl" : "redis://localhost:6379", +REDIS1_CONF 6379:6390 "standalone0-tls" : "rediss://localhost:6390" +REDIS1_CONF 6379:6390 "standalone0-acl-tls" : "rediss://localhost:6390" +------------ +REDIS2_CONF 6380 "standalone1" : "redis://localhost:6380" +REDIS3_CONF 6381:16381 "standalone2-primary" : "redis://localhost:6381" +REDIS4_CONF 6382:16382 "standalone3-replica-of-standalone2" : "redis://localhost:6382" + (slaveof 6381) +REDIS5_CONF 6383 "standalone4-replica-of-standalone1" : "redis://localhost:6383" + (slaveof 6379) +REDIS6_CONF 6384 "standalone5-primary" : "redis://localhost:6384" +REDIS7_CONF 6385 "standalone6-replica-of-standalone5" : "redis://localhost:6385" + (slaveof 6384) +REDIS8_CONF 6386 "standalone7-with-lfu-policy" : "redis://localhost:6386" +REDIS9_CONF 6387:16387 ? missing +REDIS10_CONF 6388 "standalone9" : "redis://localhost:6388" +REDIS11_CONF 6389 "standalone10-replica-of-standalone9" : "redis://localhost:6389" + (replicaof 6388) +jedis-stack 6479 "modules-docker" : "redis://localhost:6479" diff --git a/src/test/resources/env/redis-uds/config/node-0/redis.conf b/src/test/resources/env/redis-uds/config/node-0/redis.conf new file mode 100644 index 0000000000..dbcfd53b5f --- /dev/null +++ b/src/test/resources/env/redis-uds/config/node-0/redis.conf @@ -0,0 +1,2 @@ +unixsocket /tmp/docker/redis.sock +unixsocketperm 777 \ No newline at end of file diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf new file mode 100644 index 0000000000..d0b4944b89 --- /dev/null +++ b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf @@ -0,0 +1,11 @@ +port 6379 +tls-port 6390 +requirepass foobared +user deploy on allcommands allkeys >verify +user acljedis on allcommands allkeys >fizzbuzz +save "" +appendonly no +tls-auth-clients no + # Not supported on v6. provided as argument on node start +# enable-module-command yes +client-output-buffer-limit pubsub 256k 128k 5 \ No newline at end of file diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf new file mode 100644 index 0000000000..8c1e0b9873 --- /dev/null +++ b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf @@ -0,0 +1,8 @@ +protected-mode no +port 6380 +user deploy on allcommands allkeys >verify +requirepass foobared +pidfile /tmp/redis2.pid +logfile /tmp/redis2.log +save "" +appendonly no \ No newline at end of file diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf new file mode 100644 index 0000000000..7ec2b09d49 --- /dev/null +++ b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf @@ -0,0 +1,9 @@ +port 6383 +tls-port 6391 +user deploy on allcommands allkeys >verify +requirepass foobared +masterauth foobared +tls-auth-clients no +save "" +appendonly no +slaveof localhost 6379 \ No newline at end of file diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf new file mode 100644 index 0000000000..df268e026c --- /dev/null +++ b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf @@ -0,0 +1,6 @@ +protected-mode no +port 6386 +user deploy on allcommands allkeys >verify +save "" +appendonly no +maxmemory-policy allkeys-lfu \ No newline at end of file diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf new file mode 100644 index 0000000000..8ff68c24cb --- /dev/null +++ b/src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf @@ -0,0 +1,8 @@ +port 26379 +tls-port 36379 +tls-auth-clients no +sentinel monitor mymaster 127.0.0.1 6379 1 +sentinel auth-pass mymaster foobared +sentinel down-after-milliseconds mymaster 2000 +sentinel failover-timeout mymaster 120000 +sentinel parallel-syncs mymaster 1 \ No newline at end of file diff --git a/src/test/resources/env/redis10-11/config/node-6388/redis.conf b/src/test/resources/env/redis10-11/config/node-6388/redis.conf new file mode 100644 index 0000000000..deab0b333c --- /dev/null +++ b/src/test/resources/env/redis10-11/config/node-6388/redis.conf @@ -0,0 +1,3 @@ +port 6388 +save "" +appendonly no \ No newline at end of file diff --git a/src/test/resources/env/redis10-11/config/node-6389/redis.conf b/src/test/resources/env/redis10-11/config/node-6389/redis.conf new file mode 100644 index 0000000000..bff698c1bd --- /dev/null +++ b/src/test/resources/env/redis10-11/config/node-6389/redis.conf @@ -0,0 +1,4 @@ +port 6389 +save "" +appendonly no +replicaof localhost 6388 \ No newline at end of file diff --git a/src/test/resources/env/redis3-4-sentinel/config/node-6381-16381/redis.conf b/src/test/resources/env/redis3-4-sentinel/config/node-6381-16381/redis.conf new file mode 100644 index 0000000000..2a8295ba66 --- /dev/null +++ b/src/test/resources/env/redis3-4-sentinel/config/node-6381-16381/redis.conf @@ -0,0 +1,6 @@ +port 6381 +tls-port 16381 +requirepass foobared +masterauth foobared +save "" +appendonly no \ No newline at end of file diff --git a/src/test/resources/env/redis3-4-sentinel/config/node-6382-16382/redis.conf b/src/test/resources/env/redis3-4-sentinel/config/node-6382-16382/redis.conf new file mode 100644 index 0000000000..e0b7881f88 --- /dev/null +++ b/src/test/resources/env/redis3-4-sentinel/config/node-6382-16382/redis.conf @@ -0,0 +1,7 @@ +port 6382 +tls-port 16382 +requirepass foobared +masterauth foobared +save "" +appendonly no +slaveof localhost 6381 \ No newline at end of file diff --git a/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26380-36380/redis.conf b/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26380-36380/redis.conf new file mode 100644 index 0000000000..1f15e2bb71 --- /dev/null +++ b/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26380-36380/redis.conf @@ -0,0 +1,8 @@ +port 26380 +tls-port 36380 +tls-auth-clients no +sentinel monitor mymaster 127.0.0.1 6381 1 +sentinel auth-pass mymaster foobared +sentinel down-after-milliseconds mymaster 2000 +sentinel parallel-syncs mymaster 1 +sentinel failover-timeout mymaster 120000 \ No newline at end of file diff --git a/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26382-36382/redis.conf b/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26382-36382/redis.conf new file mode 100644 index 0000000000..971b7115a5 --- /dev/null +++ b/src/test/resources/env/redis3-4-sentinel/config/node-sentinel-26382-36382/redis.conf @@ -0,0 +1,8 @@ +port 26382 +tls-port 36382 +tls-auth-clients no +sentinel monitor mymaster 127.0.0.1 6381 1 +sentinel auth-pass mymaster foobared +sentinel down-after-milliseconds mymaster 2000 +sentinel parallel-syncs mymaster 1 +sentinel failover-timeout mymaster 120000 \ No newline at end of file diff --git a/src/test/resources/env/redis6-7-sentinel/config/node-6384/redis.conf b/src/test/resources/env/redis6-7-sentinel/config/node-6384/redis.conf new file mode 100644 index 0000000000..6c9d2f611c --- /dev/null +++ b/src/test/resources/env/redis6-7-sentinel/config/node-6384/redis.conf @@ -0,0 +1,5 @@ +port 6384 +requirepass foobared +masterauth foobared +save "" +appendonly no \ No newline at end of file diff --git a/src/test/resources/env/redis6-7-sentinel/config/node-6385/redis.conf b/src/test/resources/env/redis6-7-sentinel/config/node-6385/redis.conf new file mode 100644 index 0000000000..b9820488cf --- /dev/null +++ b/src/test/resources/env/redis6-7-sentinel/config/node-6385/redis.conf @@ -0,0 +1,6 @@ +port 6385 +requirepass foobared +masterauth foobared +save "" +appendonly no +slaveof localhost 6384 \ No newline at end of file diff --git a/src/test/resources/env/redis6-7-sentinel/config/node-sentinel-26381-36381/redis.conf b/src/test/resources/env/redis6-7-sentinel/config/node-sentinel-26381-36381/redis.conf new file mode 100644 index 0000000000..e71d81bf5f --- /dev/null +++ b/src/test/resources/env/redis6-7-sentinel/config/node-sentinel-26381-36381/redis.conf @@ -0,0 +1,7 @@ +port 26381 +protected-mode no +sentinel monitor mymasterfailover 127.0.0.1 6384 1 +sentinel auth-pass mymasterfailover foobared +sentinel down-after-milliseconds mymasterfailover 2000 +sentinel failover-timeout mymasterfailover 120000 +sentinel parallel-syncs mymasterfailover 1 \ No newline at end of file diff --git a/src/test/resources/env/redis9-sentinel/config/node-6387-16387/redis.conf b/src/test/resources/env/redis9-sentinel/config/node-6387-16387/redis.conf new file mode 100644 index 0000000000..fae3fa276d --- /dev/null +++ b/src/test/resources/env/redis9-sentinel/config/node-6387-16387/redis.conf @@ -0,0 +1,9 @@ +port 6387 +tls-port 16387 +tls-auth-clients no +user default off +user deploy on allcommands allkeys >verify +user acljedis on allcommands allkeys >fizzbuzz +save "" +appendonly no +client-output-buffer-limit pubsub 256k 128k 5 \ No newline at end of file diff --git a/src/test/resources/env/redis9-sentinel/config/node-sentinel-26383-36383/redis.conf b/src/test/resources/env/redis9-sentinel/config/node-sentinel-26383-36383/redis.conf new file mode 100644 index 0000000000..c190c2c4f8 --- /dev/null +++ b/src/test/resources/env/redis9-sentinel/config/node-sentinel-26383-36383/redis.conf @@ -0,0 +1,12 @@ +port 26383 +tls-port 36383 +tls-auth-clients no +user default off +user deploy on allcommands allkeys >verify +user sentinel on allcommands allkeys allchannels >foobared +sentinel monitor aclmaster 127.0.0.1 6387 1 +sentinel auth-user aclmaster acljedis +sentinel auth-pass aclmaster fizzbuzz +sentinel down-after-milliseconds aclmaster 2000 +sentinel failover-timeout aclmaster 120000 +sentinel parallel-syncs aclmaster 1 \ No newline at end of file diff --git a/src/test/resources/private.crt b/src/test/resources/private.crt new file mode 100644 index 0000000000..4c560cfeae --- /dev/null +++ b/src/test/resources/private.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhzCCAm+gAwIBAgIJALGtKQQvKbGEMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzESMBAG +A1UECgwJVHJ1U3BoZXJlMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTYwMTA5MjEw +ODMyWhcNMjYwMTA2MjEwODMyWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0Ex +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoMCVRydVNwaGVyZTESMBAG +A1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +4nb/9hXI5iFXIHh34gpvQMGTqTCf2im/FCvXYoDer/FTLKxdr3Bw0Cj9NarMpVZO +fBRykVdKir8v1+Gv0mUVwHkEJ2Mouxo6mqDQEKRt9G/gbzcC+AoMEUsnV4tKaptX +dWDLcZU9oer6wLicmAyV+4vlUJn+j6ADXBk4pJT+wbG/oawJ0op4vQNeVcJPr7Bc +fMLG60UOTABEPBM6YWqVe2pLPX4a4ec84kcFDLjRfU9ZTy+fD+BP5XQjIJyjyjTS +iOSy+qQM8Yk0CjJ/zfysChApCefP1/kOiIeStuE8jkmkVW6atprb9Vr+E5jnHKeh +SmZmXq9BRjF2OyUMG8m4DwIDAQABo1AwTjAdBgNVHQ4EFgQUSg+P0noapK2yuFoH +v9xe5HNYNiYwHwYDVR0jBBgwFoAUSg+P0noapK2yuFoHv9xe5HNYNiYwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAakaOSczmzRoPg3etzWiKTYht+CbA +/UtOdRxwTTHLauDUtGo6YTT+HG4tItwNxI9n3CZvcX68fNTi99fxzrHddiAwnCPv +DqEv2ASxed95/6QZIzPVFT7GZZDOUrwFkC01vawaVyl0f8UbeOWCly7eetu3mV2r +VFNPxPPT622cGn8uSqnpN1cQ4LdsDpVUR+YDAxIB8YbsWgtl79evwcnTWINy3CSc +QjAYQe1aC/kAs3VfIymdu9xEv2Er9NOidUx23RD54jrFCXNUYEBnSc2yi7YSTTzT +4cKnp7wuVdacd1noQRZFEEsVd6tmtiJKZhdllJ21Rb5g1q50dBlbq25hnw== +-----END CERTIFICATE----- \ No newline at end of file From da0474d84b3e2a16e4f3ac77af1bfd52500e7b7c Mon Sep 17 00:00:00 2001 From: ggivo Date: Sun, 10 Nov 2024 20:45:43 +0200 Subject: [PATCH 02/44] Fix GeoXXX tests java.lang.AssertionError: Expected :[(2.1909382939338684,41.433790281840835), (2.187376320362091,41.40634178640635)] Actual :[(2.1909382939338684,41.43379028184083), (2.187376320362091,41.40634178640635)] Compare with tolerance to avoid error on returned precision on mac --- .../clients/jedis/ClusterPipeliningTest.java | 31 ++++++---- .../jedis/commands/jedis/GeoCommandsTest.java | 3 +- .../commands/unified/GeoCommandsTestBase.java | 3 +- .../pipeline/GeoPipelineCommandsTest.java | 32 +++++----- .../jedis/util/GeoCoordinateMatcher.java | 50 +++++++++++----- .../jedis/util/GeoRadiusResponseMatcher.java | 58 +++++++++++++++++++ 6 files changed, 134 insertions(+), 43 deletions(-) create mode 100644 src/test/java/redis/clients/jedis/util/GeoRadiusResponseMatcher.java diff --git a/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java b/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java index 2edcb67456..8b28e7b436 100644 --- a/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java +++ b/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java @@ -1,7 +1,10 @@ package redis.clients.jedis; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.*; import static redis.clients.jedis.Protocol.CLUSTER_HASHSLOTS; +import static redis.clients.jedis.util.GeoRadiusResponseMatcher.isEqualToGeoRadiusResponse; import java.util.*; @@ -21,6 +24,7 @@ import redis.clients.jedis.resps.StreamEntry; import redis.clients.jedis.resps.Tuple; import redis.clients.jedis.util.AssertUtil; +import redis.clients.jedis.util.GeoCoordinateMatcher; import redis.clients.jedis.util.JedisClusterTestUtil; import redis.clients.jedis.util.SafeEncoder; @@ -693,9 +697,6 @@ public void clusterPipelineGeo() { hm.put("place1", new GeoCoordinate(2.1909389952632, 41.433791470673)); hm.put("place2", new GeoCoordinate(2.1873744593677, 41.406342043777)); - List values = new ArrayList<>(); - values.add(new GeoCoordinate(2.19093829393386841, 41.43379028184083523)); - values.add(new GeoCoordinate(2.18737632036209106, 41.40634178640635099)); List hashValues = new ArrayList<>(); hashValues.add("sp3e9yg3kd0"); @@ -706,11 +707,6 @@ public void clusterPipelineGeo() { GeoRadiusParam params2 = new GeoRadiusParam().count(1, true); GeoRadiusStoreParam storeParams = new GeoRadiusStoreParam().store("radius{#}"); - GeoRadiusResponse expectedResponse = new GeoRadiusResponse("place1".getBytes()); - expectedResponse.setCoordinate(new GeoCoordinate(2.19093829393386841, 41.43379028184083523)); - expectedResponse.setDistance(0.0881); - expectedResponse.setRawScore(3471609698139488L); - ClusterConnectionProvider provider = new ClusterConnectionProvider(nodes, DEFAULT_CLIENT_CONFIG); ClusterPipeline p = new ClusterPipeline(provider); @@ -738,11 +734,24 @@ public void clusterPipelineGeo() { assertEquals(Double.valueOf(3067.4157), r2.get()); assertEquals(Double.valueOf(3.0674), r3.get()); assertEquals(hashValues, r4.get()); - assertEquals(values, r5.get()); + assertThat(r5.get(), contains( + GeoCoordinateMatcher.isEqualWithTolerance(2.19093829393386841, 41.43379028184083523), + GeoCoordinateMatcher.isEqualWithTolerance(2.18737632036209106, 41.40634178640635099)) + ); assertTrue(r6.get().size() == 1 && r6.get().get(0).getMemberByString().equals("place1")); assertTrue(r7.get().size() == 1 && r7.get().get(0).getMemberByString().equals("place1")); - assertEquals(expectedResponse, r8.get().get(0)); - assertEquals(expectedResponse, r9.get().get(0)); + + + GeoRadiusResponse expectedResponse = new GeoRadiusResponse("place1".getBytes()); + expectedResponse.setCoordinate(new GeoCoordinate(2.19093829393386841, 41.43379028184083523)); + expectedResponse.setDistance(0.0881); + expectedResponse.setRawScore(3471609698139488L); + + assertThat(r8.get().get(0),isEqualToGeoRadiusResponse(expectedResponse)); + assertThat(r9.get().get(0),isEqualToGeoRadiusResponse(expectedResponse)); + + + assertEquals(Long.valueOf(1), r10.get()); assertTrue(r11.get().size() == 1 && r11.get().contains("place1")); assertTrue(r12.get().size() == 2 && r12.get().get(0).getMemberByString().equals("place2")); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/GeoCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/GeoCommandsTest.java index be00a4d665..2b9bb98d2a 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/GeoCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/GeoCommandsTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.*; import static redis.clients.jedis.util.AssertUtil.assertByteArrayListEquals; +import static redis.clients.jedis.util.GeoCoordinateMatcher.isEqualWithTolerance; import java.util.ArrayList; import java.util.HashMap; @@ -532,7 +533,7 @@ public void geosearch() { assertEquals(1, members.size()); assertEquals("place1", members.get(0).getMemberByString()); assertEquals(0.0881, members.get(0).getDistance(), 10); - assertEquals(new GeoCoordinate(2.19093829393386841, 41.43379028184083523), members.get(0).getCoordinate()); + assertThat(members.get(0).getCoordinate(), isEqualWithTolerance( 2.19093829393386841, 41.43379028184083523)); } @Test diff --git a/src/test/java/redis/clients/jedis/commands/unified/GeoCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/GeoCommandsTestBase.java index e05a5f99cf..14647a880d 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/GeoCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/GeoCommandsTestBase.java @@ -2,6 +2,7 @@ import static org.junit.Assert.*; import static redis.clients.jedis.util.AssertUtil.assertByteArrayListEquals; +import static redis.clients.jedis.util.GeoCoordinateMatcher.isEqualWithTolerance; import java.util.ArrayList; import java.util.HashMap; @@ -529,7 +530,7 @@ public void geosearch() { assertEquals(1, members.size()); assertEquals("place1", members.get(0).getMemberByString()); assertEquals(0.0881, members.get(0).getDistance(), 10); - assertEquals(new GeoCoordinate(2.19093829393386841, 41.43379028184083523), members.get(0).getCoordinate()); + assertThat(members.get(0).getCoordinate(), isEqualWithTolerance(2.19093829393386841, 41.43379028184083523)); } @Test diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/GeoPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/GeoPipelineCommandsTest.java index d8b7443a8f..143bd08c2c 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/GeoPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/GeoPipelineCommandsTest.java @@ -6,10 +6,9 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; -import static redis.clients.jedis.util.GeoCoordinateMatcher.atCoordinates; +import static redis.clients.jedis.util.GeoCoordinateMatcher.isEqualWithTolerance; import java.util.HashMap; import java.util.List; @@ -23,7 +22,6 @@ import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.Response; import redis.clients.jedis.args.GeoUnit; -import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.params.GeoAddParams; import redis.clients.jedis.params.GeoRadiusParam; import redis.clients.jedis.params.GeoRadiusStoreParam; @@ -181,14 +179,14 @@ public void geopos() { pipe.sync(); assertThat(coordinates.get(), contains( - atCoordinates(3.0, 4.0), - atCoordinates(2.0, 3.0), + isEqualWithTolerance(3.0, 4.0), + isEqualWithTolerance(2.0, 3.0), null )); assertThat(bcoordinates.get(), contains( - atCoordinates(3.0, 4.0), - atCoordinates(2.0, 3.0), + isEqualWithTolerance(3.0, 4.0), + isEqualWithTolerance(2.0, 3.0), null )); } @@ -257,7 +255,7 @@ public void georadius() { assertThat(members4.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(56.4413, EPSILON))); assertThat(members4.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(15.087269, 37.502669))); + contains(isEqualWithTolerance(15.087269, 37.502669))); assertThat(members4.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(3479447370796909L)); @@ -356,7 +354,7 @@ public void georadiusReadonly() { assertThat(members4.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(56.4413, EPSILON))); assertThat(members4.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(15.087269, 37.502669))); + contains(isEqualWithTolerance(15.087269, 37.502669))); assertThat(members4.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -417,7 +415,7 @@ public void georadiusBinary() { assertThat(members4.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(56.4413, EPSILON))); assertThat(members4.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(15.087269, 37.502669))); + contains(isEqualWithTolerance(15.087269, 37.502669))); assertThat(members4.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -498,7 +496,7 @@ public void georadiusReadonlyBinary() { assertThat(members4.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(56.4413, EPSILON))); assertThat(members4.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(15.087269, 37.502669))); + contains(isEqualWithTolerance(15.087269, 37.502669))); assertThat(members4.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -543,7 +541,7 @@ public void georadiusByMember() { assertThat(members3.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0, EPSILON))); assertThat(members3.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(13.583333, 37.316667))); + contains(isEqualWithTolerance(13.583333, 37.316667))); assertThat(members3.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -606,7 +604,7 @@ public void georadiusByMemberReadonly() { assertThat(members3.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0, EPSILON))); assertThat(members3.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(13.583333, 37.316667))); + contains(isEqualWithTolerance(13.583333, 37.316667))); assertThat(members3.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -650,7 +648,7 @@ public void georadiusByMemberBinary() { assertThat(members3.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0, EPSILON))); assertThat(members3.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(13.583333, 37.316667))); + contains(isEqualWithTolerance(13.583333, 37.316667))); assertThat(members3.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -712,7 +710,7 @@ public void georadiusByMemberReadonlyBinary() { assertThat(members3.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0, EPSILON))); assertThat(members3.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(13.583333, 37.316667))); + contains(isEqualWithTolerance(13.583333, 37.316667))); assertThat(members3.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } @@ -775,7 +773,7 @@ public void geosearch() { assertThat(members4.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0, EPSILON), closeTo(3.0674, EPSILON))); assertThat(members4.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(2.1909389952632d, 41.433791470673d), atCoordinates(2.1873744593677d, 41.406342043777d))); + contains(isEqualWithTolerance(2.1909389952632d, 41.433791470673d), isEqualWithTolerance(2.1873744593677d, 41.406342043777d))); assertThat(members4.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(3471609698139488L, 3471609625421029L)); @@ -793,7 +791,7 @@ public void geosearch() { assertThat(members8.get().stream().map(GeoRadiusResponse::getDistance).collect(Collectors.toList()), contains(closeTo(0.0881, EPSILON))); assertThat(members8.get().stream().map(GeoRadiusResponse::getCoordinate).collect(Collectors.toList()), - contains(atCoordinates(2.1909389952632d, 41.433791470673d))); + contains(isEqualWithTolerance(2.1909389952632d, 41.433791470673d))); assertThat(members8.get().stream().map(GeoRadiusResponse::getRawScore).collect(Collectors.toList()), contains(0L)); } diff --git a/src/test/java/redis/clients/jedis/util/GeoCoordinateMatcher.java b/src/test/java/redis/clients/jedis/util/GeoCoordinateMatcher.java index 5b21d3d427..caf82d99c5 100644 --- a/src/test/java/redis/clients/jedis/util/GeoCoordinateMatcher.java +++ b/src/test/java/redis/clients/jedis/util/GeoCoordinateMatcher.java @@ -6,29 +6,53 @@ public class GeoCoordinateMatcher extends TypeSafeMatcher { - public static GeoCoordinateMatcher atCoordinates(double longitude, double latitude) { - return new GeoCoordinateMatcher(longitude, latitude); + public static GeoCoordinateMatcher isEqualWithTolerance(GeoCoordinate expected, double tolerance) { + return new GeoCoordinateMatcher(expected, tolerance); } - private static final double EPSILON = 1e-5; + public static GeoCoordinateMatcher isEqualWithTolerance(GeoCoordinate expected) { + return new GeoCoordinateMatcher(expected, DEFAULT_TOLERANCE); + } + + public static GeoCoordinateMatcher isEqualWithTolerance(double longitude, double latitude, double tolerance) { + return new GeoCoordinateMatcher(new GeoCoordinate(longitude, latitude), tolerance); + } + + public static GeoCoordinateMatcher isEqualWithTolerance(double longitude, double latitude) { + return new GeoCoordinateMatcher(new GeoCoordinate(longitude,latitude), latitude); + } + + public static final double DEFAULT_TOLERANCE = 1e-14; - private final double longitude; - private final double latitude; + private final double tolerance; + private final GeoCoordinate expected; - public GeoCoordinateMatcher(double longitude, double latitude) { - this.longitude = longitude; - this.latitude = latitude; + + public GeoCoordinateMatcher(GeoCoordinate expected, double tolerance) { + this.expected = expected; + this.tolerance = tolerance; + } + + public GeoCoordinateMatcher(GeoCoordinate expected) { + this(expected, DEFAULT_TOLERANCE); } @Override - protected boolean matchesSafely(GeoCoordinate item) { - return item != null && - Math.abs(longitude - item.getLongitude()) < EPSILON && - Math.abs(latitude - item.getLatitude()) < EPSILON; + protected boolean matchesSafely(GeoCoordinate actual) { + return Math.abs(actual.getLatitude() - expected.getLatitude()) < tolerance && + Math.abs(actual.getLongitude() - expected.getLongitude()) < tolerance; } @Override public void describeTo(Description description) { - description.appendText("matches " + longitude + " longitude " + latitude + " latitude with precision " + EPSILON); + description.appendText("a GeoCoordinate within ") + .appendValue(tolerance) + .appendText(" of ") + .appendValue(expected); + } + + @Override + protected void describeMismatchSafely(GeoCoordinate actual, Description mismatchDescription) { + mismatchDescription.appendText("was ").appendValue(actual); } } diff --git a/src/test/java/redis/clients/jedis/util/GeoRadiusResponseMatcher.java b/src/test/java/redis/clients/jedis/util/GeoRadiusResponseMatcher.java new file mode 100644 index 0000000000..4ebe9ad67f --- /dev/null +++ b/src/test/java/redis/clients/jedis/util/GeoRadiusResponseMatcher.java @@ -0,0 +1,58 @@ +package redis.clients.jedis.util; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import redis.clients.jedis.GeoCoordinate; +import redis.clients.jedis.resps.GeoRadiusResponse; + +public class GeoRadiusResponseMatcher extends TypeSafeMatcher { + private final GeoRadiusResponse expected; + private final double coordinateTolerance; + + public static Matcher isEqualToGeoRadiusResponse(GeoRadiusResponse expected) { + return new GeoRadiusResponseMatcher(expected, GeoCoordinateMatcher.DEFAULT_TOLERANCE); + } + + public static Matcher isEqualToGeoRadiusResponse(GeoRadiusResponse expected, double tolerance) { + return new GeoRadiusResponseMatcher(expected, tolerance); + } + + public GeoRadiusResponseMatcher(GeoRadiusResponse expected, double coordinateTolerance) { + this.expected = expected; + this.coordinateTolerance = coordinateTolerance; + } + + @Override + protected boolean matchesSafely(GeoRadiusResponse actual) { + // Check if coordinates match within the tolerance + GeoCoordinate expectedCoord = expected.getCoordinate(); + GeoCoordinate actualCoord = actual.getCoordinate(); + if (!GeoCoordinateMatcher.isEqualWithTolerance(expectedCoord, coordinateTolerance).matches(actualCoord)) { + return false; + } + + // Check if distance and rawScore match exactly + if (Double.compare(expected.getDistance(), actual.getDistance()) != 0) { + return false; + } + return expected.getRawScore() == actual.getRawScore(); + } + + @Override + public void describeTo(Description description) { + description.appendText("a GeoRadiusResponse with coordinate ") + .appendValue(expected.getCoordinate()) + .appendText(", distance ") + .appendValue(expected.getDistance()) + .appendText(", and rawScore ") + .appendValue(expected.getRawScore()); + } + + @Override + protected void describeMismatchSafely(GeoRadiusResponse actual, Description mismatchDescription) { + mismatchDescription.appendText("was ") + .appendValue(actual); + } + +} \ No newline at end of file From 90d93a3069910cfab86cd3862b5dd0f89210d05f Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 09:47:08 +0200 Subject: [PATCH 03/44] REDIS_VERSION env var for setting test container version --- .github/workflows/test-on-docker.yml | 2 +- src/test/resources/env/.env | 4 ++-- src/test/resources/env/.env.v6.2.16 | 3 +-- src/test/resources/env/docker-compose.yml | 16 ++++++++-------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test-on-docker.yml b/.github/workflows/test-on-docker.yml index bccdeab4e5..5580db1f7a 100644 --- a/.github/workflows/test-on-docker.yml +++ b/.github/workflows/test-on-docker.yml @@ -63,7 +63,7 @@ jobs: - name: Set up Docker Compose environment run: | mkdir -m 777 $REDIS_ENV_WORK_DIR - export CLIENT_LIBS_TEST_IMAGE="${CLIENT_LIBS_IMAGE_PREFIX}:${{ matrix.redis_version }}" + export REDIS_VERSION="${{ matrix.redis_version }}" export COMPOSE_ENV_FILES="src/test/resources/env/.env" if [[ "${{ matrix.redis_version }}" == "6.2.16" ]]; then COMPOSE_ENV_FILES+=",src/test/resources/env/.env.v${{ matrix.redis_version }}" diff --git a/src/test/resources/env/.env b/src/test/resources/env/.env index ef6dc4179c..c0b07269aa 100644 --- a/src/test/resources/env/.env +++ b/src/test/resources/env/.env @@ -1,5 +1,5 @@ -CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:8.0-M01 -REDIS_IMAGE=redis:8.0-M01 +REDIS_VERSION=8.0-M01 +CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test REDIS_ENV_CONF_DIR=./ REDIS_MODULES_DIR=/tmp REDIS_ENV_WORK_DIR=./redis-env-work diff --git a/src/test/resources/env/.env.v6.2.16 b/src/test/resources/env/.env.v6.2.16 index c285604372..fbfee3b345 100644 --- a/src/test/resources/env/.env.v6.2.16 +++ b/src/test/resources/env/.env.v6.2.16 @@ -1,5 +1,4 @@ -CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:8.0-M01 -REDIS_IMAGE=redis:6.2.16 +CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test REDIS_ENV_CONF_DIR=./ REDIS_MODULES_DIR=/tmp REDIS_ENV_WORK_DIR=./redis-env-work diff --git a/src/test/resources/env/docker-compose.yml b/src/test/resources/env/docker-compose.yml index c5858527ea..c6bab9b2fd 100644 --- a/src/test/resources/env/docker-compose.yml +++ b/src/test/resources/env/docker-compose.yml @@ -2,7 +2,7 @@ services: redis1-2-5-10-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis1-2-5-10-sentinel #network_mode: host environment: @@ -25,7 +25,7 @@ services: redis3-4-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis3-4-sentinel #network_mode: host environment: @@ -48,7 +48,7 @@ services: redis6-7-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis6-7-sentinel #network_mode: host environment: @@ -65,7 +65,7 @@ services: redis9-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis9-sentinel #network_mode: host environment: @@ -85,7 +85,7 @@ services: redis10-11: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis10-11 #network_mode: host environment: @@ -99,7 +99,7 @@ services: redis-unavailable: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: redis-unavailable-1 #network_mode: host environment: @@ -113,7 +113,7 @@ services: cluster-unbound: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: cluster-unbound-1 environment: - TLS_ENABLED=yes @@ -128,7 +128,7 @@ services: cluster-stable: sysctls: - net.ipv6.conf.all.disable_ipv6=1 - image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.0-M01} + image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" container_name: cluster-stable-1 #network_mode: host command: --cluster-announce-ip 127.0.0.1 From 2f7ee06e022bab4ed178288bb8100e2a97850402 Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 10:10:14 +0200 Subject: [PATCH 04/44] Remove accidentally submitted conf directive --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 45df2f9059..6b9a23507b 100644 --- a/Makefile +++ b/Makefile @@ -190,7 +190,6 @@ endef define REDIS_SENTINEL5 port 26383 -tlsport 36383 daemonize yes protected-mode no user default off From 2ab47f9f2e8b4fa02095edbd33c56cf574066d83 Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 10:28:40 +0200 Subject: [PATCH 05/44] Revert changes in integration action --- .github/workflows/integration.yml | 4 ++-- Makefile | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 70342266fe..3df4e12271 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -34,8 +34,8 @@ jobs: - name: System setup run: | sudo apt update - sudo apt install -y make - make compile-module + sudo apt install -y stunnel make + make system-setup - name: Cache dependencies uses: actions/cache@v2 with: diff --git a/Makefile b/Makefile index 6b9a23507b..6ff0bf4aba 100644 --- a/Makefile +++ b/Makefile @@ -526,14 +526,8 @@ mvn-release: mvn release:prepare mvn release:perform -DskipTests -install-gcc: - @if [ "$(shell uname)" = "Darwin" ]; then \ - brew install gcc; \ - else \ - sudo apt install -y gcc g++; \ - fi - -system-setup: install-gcc +system-setup: + sudo apt install -y gcc g++ [ ! -e redis-git ] && git clone https://github.com/redis/redis.git --branch unstable --single-branch redis-git || true $(MAKE) -C redis-git clean $(MAKE) -C redis-git From 47207c904064cc2c983eb04128f5ab50173b87bd Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 11:17:43 +0200 Subject: [PATCH 06/44] EnabledOnCommandRule get info only for requested command --- .../java/io/redis/test/utils/EnabledOnCommandRule.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java index d32152341f..ef88f96b69 100644 --- a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java +++ b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java @@ -99,9 +99,8 @@ private EnabledOnCommand getMethodAnnotation(Description description) { */ private boolean isCommandAvailable(Jedis jedisClient, String command, String subCommand) { try { - Object raw = jedisClient.sendCommand(redis.clients.jedis.Protocol.Command.COMMAND); - Map commandList = BuilderFactory.COMMAND_INFO_RESPONSE.build(raw); - CommandInfo commandInfo = commandList.get(command.toLowerCase()); + Map commandInfoMap= jedisClient.commandInfo(command); + CommandInfo commandInfo = commandInfoMap.get(command.toLowerCase()); if (commandInfo != null) { // If a subCommand is provided, check for the subcommand under this command if (subCommand != null && !subCommand.isEmpty()) { @@ -117,8 +116,8 @@ private boolean isCommandAvailable(Jedis jedisClient, String command, String sub } return false; // Command not found } catch (Exception e) { - logger.error("Error checking command '{}' availability: {}", command, e.getMessage()); - return false; + String msg = String.format("Error found while EnableOnCommand for command '%s'", command); + throw new RuntimeException(msg, e); } } }; From 7975ce113bacd88b071e96cbb835f0eca3b871b6 Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 11:23:51 +0200 Subject: [PATCH 07/44] Remove accidentally added SinceRedisVersion 7.0.0 for ControlCommandsTest.commandInfo --- .../redis/clients/jedis/commands/jedis/ControlCommandsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 7772338612..8b92313b0f 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -513,7 +513,6 @@ public void commandGetKeysAndFlags() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "Starting with Redis version 7.0.0: Allowed to be called with no argument to get info on all commands.") public void commandInfo() { Map infos = jedis.commandInfo("GET", "foo", "SET"); From c975df126f4d3357c6899c2f942a2f6f26157de5 Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 11:53:47 +0200 Subject: [PATCH 08/44] Found issue with CommandInfo command Adding ignored unit test for repro --- .../clients/jedis/SSLACLJedisClusterTest.java | 2 -- .../commands/jedis/ControlCommandsTest.java | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index d0ab1cfd22..6a97dcd69e 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -10,9 +10,7 @@ import javax.net.ssl.SSLParameters; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionRule; import io.redis.test.utils.RedisVersionUtil; import org.junit.*; import redis.clients.jedis.util.TlsUtil; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 8b92313b0f..8c3f99f0c6 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -24,6 +24,7 @@ import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -552,6 +553,22 @@ public void commandInfoAcl() { }); } + @Test + @Ignore( "Till https://github.com/redis/jedis/issues/4020 is resolved") + public void commandInfoWithSubcommands() { + Map infos = jedis.commandInfo("ACL"); + + CommandInfo aclInfo = infos.get("acl"); + assertEquals(2, aclInfo.getArity()); + assertEquals(0, aclInfo.getFlags().size()); + assertEquals(0, aclInfo.getFirstKey()); + assertEquals(0, aclInfo.getLastKey()); + assertEquals(0, aclInfo.getStep()); + assertEquals(1, aclInfo.getAclCategories().size()); + assertEquals(0, aclInfo.getTips().size()); + assertFalse(aclInfo.getSubcommands().isEmpty()); + } + @Test @SinceRedisVersion("7.0.0") public void commandList() { From 3818236890ff6ca01a0cb299b43b749fdbe05a0f Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 12:09:59 +0200 Subject: [PATCH 09/44] Use SinceRedisVersion instead of "EnableOnCmmand" because of https://github.com/redis/jedis/issues/4020 --- src/test/java/redis/clients/jedis/JedisClusterTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index f29e735617..f5fdce46b3 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import io.redis.test.annotations.EnabledOnCommand; +import io.redis.test.annotations.SinceRedisVersion; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.Test; @@ -668,7 +669,7 @@ public void testInvalidStartNodeNotAdded() { } @Test - @EnabledOnCommand(value = "CLUSTER", subCommand = "LINKS") + @SinceRedisVersion("7.0.0") public void clusterLinks2() { Set mapKeys = new HashSet<>(Arrays.asList("direction", "node", "create-time", "events", "send-buffer-allocated", "send-buffer-used")); From ef9a65b2102c985f81deddbe72682d1dc1fe391f Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 13:05:14 +0200 Subject: [PATCH 10/44] Use SinceRedisVersion instead of "EnableOnCommand" because of https://github.com/redis/jedis/issues/4020 --- .../jedis/commands/jedis/AccessControlListCommandsTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java index a184dc52b8..5c0b231b5a 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java @@ -16,7 +16,6 @@ import java.util.Arrays; import java.util.List; -import io.redis.test.annotations.EnabledOnCommand; import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.Matchers; import org.junit.After; @@ -234,7 +233,7 @@ public void aclExcudeSingleCommand() { } @Test - @EnabledOnCommand(value = "ACL", subCommand = "DRYRUN") + @SinceRedisVersion("7.0.0") public void aclDryRun() { jedis.aclSetUser(USER_NAME, "nopass", "allkeys", "+set", "-get"); @@ -249,7 +248,7 @@ public void aclDryRun() { } @Test - @EnabledOnCommand(value = "ACL", subCommand = "DRYRUN") + @SinceRedisVersion("7.0.0") public void aclDryRunBinary() { byte[] username = USER_NAME.getBytes(); From 9ae14bc627177d1372a4de74f5d24d24a8569f1e Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 11 Nov 2024 19:18:25 +0200 Subject: [PATCH 11/44] switch default TEST_ENV_PROVIDER --- src/test/java/redis/clients/jedis/util/TestEnvUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java index a9da3bd029..0180f745b4 100644 --- a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java +++ b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java @@ -3,7 +3,7 @@ import java.util.Optional; public class TestEnvUtil { - private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", "docker"); + private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", ""); private static final String TESTMODULE_SO = Optional.ofNullable(System.getenv("TESTMODULE_SO")) .orElseGet(() -> isContainerEnv() ? "/redis/work/modules/testmodule.so" From 347c3f75355fdfa2510a5b5337951570eb3d1990 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Tue, 12 Nov 2024 06:07:43 +0600 Subject: [PATCH 12/44] Use CommandInfo for subcommand --- src/test/java/io/redis/test/utils/EnabledOnCommandRule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java index ef88f96b69..aa9e79b886 100644 --- a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java +++ b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java @@ -105,8 +105,8 @@ private boolean isCommandAvailable(Jedis jedisClient, String command, String sub // If a subCommand is provided, check for the subcommand under this command if (subCommand != null && !subCommand.isEmpty()) { // Check if this command supports the provided subcommand - for (String supportedSubCommand : commandInfo.getSubcommands()) { - if (subCommand.equalsIgnoreCase(supportedSubCommand)) { + for (CommandInfo supportedSubCommand : commandInfo.getSubcommands()) { + if ((command+subCommand).equalsIgnoreCase(supportedSubCommand.getName())) { return true; } } From c5564e786ef3b57b35b1587c8534319a0edaa18e Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Tue, 12 Nov 2024 06:12:48 +0600 Subject: [PATCH 13/44] Get Iterable from Map --- src/test/java/io/redis/test/utils/EnabledOnCommandRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java index aa9e79b886..bb772c334d 100644 --- a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java +++ b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java @@ -105,7 +105,7 @@ private boolean isCommandAvailable(Jedis jedisClient, String command, String sub // If a subCommand is provided, check for the subcommand under this command if (subCommand != null && !subCommand.isEmpty()) { // Check if this command supports the provided subcommand - for (CommandInfo supportedSubCommand : commandInfo.getSubcommands()) { + for (CommandInfo supportedSubCommand : commandInfo.getSubcommands().values()) { if ((command+subCommand).equalsIgnoreCase(supportedSubCommand.getName())) { return true; } From 513c0a5d74d5db3a71549eb98e542e1a37e11185 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 12 Nov 2024 13:32:35 +0200 Subject: [PATCH 14/44] Use client-libs-test image based on redis-server-stack --- .github/workflows/test-on-docker.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-on-docker.yml b/.github/workflows/test-on-docker.yml index 5580db1f7a..6c0744ccf5 100644 --- a/.github/workflows/test-on-docker.yml +++ b/.github/workflows/test-on-docker.yml @@ -37,9 +37,9 @@ jobs: matrix: redis_version: - "8.0-M01" - - "7.4.1" - - "7.2.6" - - "6.2.16" + - "rs-7.4.0-v1" + - "rs-7.2.0-v13" + - "rs-6.2.6-v17" steps: - uses: actions/checkout@v2 - name: Set up publishing to maven central From c9464506216a75bd35133116c6c0801ca6f4dd8b Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:34:59 +0600 Subject: [PATCH 15/44] Fix: command and subcommand are concatenated with a pipe --- src/test/java/io/redis/test/utils/EnabledOnCommandRule.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java index bb772c334d..aa1d540188 100644 --- a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java +++ b/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java @@ -105,8 +105,9 @@ private boolean isCommandAvailable(Jedis jedisClient, String command, String sub // If a subCommand is provided, check for the subcommand under this command if (subCommand != null && !subCommand.isEmpty()) { // Check if this command supports the provided subcommand + String replySubCommandName = command + '|' + subCommand; for (CommandInfo supportedSubCommand : commandInfo.getSubcommands().values()) { - if ((command+subCommand).equalsIgnoreCase(supportedSubCommand.getName())) { + if (replySubCommandName.equalsIgnoreCase(supportedSubCommand.getName())) { return true; } } From 185ea05526f1d19973b8c4a62341ccb623af1acb Mon Sep 17 00:00:00 2001 From: ggivo Date: Wed, 13 Nov 2024 15:14:30 +0200 Subject: [PATCH 16/44] Remove commented out code --- src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java | 1 - src/test/java/redis/clients/jedis/SSLJedisClusterTest.java | 2 -- src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java | 1 - 3 files changed, 4 deletions(-) diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index 6a97dcd69e..4e00ba2b44 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -34,7 +34,6 @@ public class SSLACLJedisClusterTest extends JedisClusterTestBase { if ("127.0.0.1".equals(host)) { host = "localhost"; - //port += tlsPortOffset; // Apply the port offset } return new HostAndPort(host, port); diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index 3abf60ef15..b9aab09700 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -29,7 +29,6 @@ public class SSLJedisClusterTest extends JedisClusterTestBase { int port = hostAndPort.getPort(); if (host.equals("127.0.0.1")) { host = "localhost"; - //port = port + 1000; } return new HostAndPort(host, port); }; @@ -39,7 +38,6 @@ public class SSLJedisClusterTest extends JedisClusterTestBase { if ("localhost".equals(hostAndPort.getHost())) { return hostAndPort; } - //return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() + 1000); return new HostAndPort(hostAndPort.getHost(), hostAndPort.getPort() ); }; diff --git a/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java b/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java index 1490cb5af5..feb6bb9a0a 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisSentinelPoolTest.java @@ -24,7 +24,6 @@ public class SSLJedisSentinelPoolTest { @BeforeClass public static void prepare() { TlsUtil.createAndSaveEnvTruststore("redis9-sentinel", "changeit"); - //TlsUtil.setJvmTrustStore(envTruststore("redis9-sentinel")); sentinels.add(HostAndPorts.getSentinelServers().get(4)); } From 18168f8416588204a93beef394192fa9214570d0 Mon Sep 17 00:00:00 2001 From: ggivo Date: Thu, 14 Nov 2024 10:44:33 +0200 Subject: [PATCH 17/44] Revert "Use client-libs-test image based on redis-server-stack" This reverts commit f932e593d57edbbfce28cf4c435ab65df787096d. --- .github/workflows/test-on-docker.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-on-docker.yml b/.github/workflows/test-on-docker.yml index 6c0744ccf5..5580db1f7a 100644 --- a/.github/workflows/test-on-docker.yml +++ b/.github/workflows/test-on-docker.yml @@ -37,9 +37,9 @@ jobs: matrix: redis_version: - "8.0-M01" - - "rs-7.4.0-v1" - - "rs-7.2.0-v13" - - "rs-6.2.6-v17" + - "7.4.1" + - "7.2.6" + - "6.2.16" steps: - uses: actions/checkout@v2 - name: Set up publishing to maven central From 475ff1264ebd214f45e289040e1173362e2db451 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 09:47:26 +0200 Subject: [PATCH 18/44] Use native redis TLS support Remove stunnel. Redis server version 6 and above have native support for TLS. --- Makefile | 130 +++++++++++------- .../clients/jedis/SSLJedisClusterTest.java | 1 - 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 6ff0bf4aba..5e39efd283 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ PATH := ./redis-git/src:${PATH} -STUNNEL_BIN := $(shell which stunnel) define REDIS1_CONF daemonize yes protected-mode no port 6379 +tls-port 6390 requirepass foobared user acljedis on allcommands allkeys >fizzbuzz user deploy on allcommands allkeys >verify @@ -14,6 +14,10 @@ save "" appendonly no enable-module-command yes client-output-buffer-limit pubsub 256k 128k 5 +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS2_CONF @@ -31,18 +35,24 @@ define REDIS3_CONF daemonize yes protected-mode no port 6381 +tls-port 16381 requirepass foobared masterauth foobared pidfile /tmp/redis3.pid logfile /tmp/redis3.log save "" appendonly no +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS4_CONF daemonize yes protected-mode no port 6382 +tls-port 16382 requirepass foobared masterauth foobared pidfile /tmp/redis4.pid @@ -50,6 +60,10 @@ logfile /tmp/redis4.log save "" appendonly no slaveof localhost 6381 +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS5_CONF @@ -105,6 +119,7 @@ define REDIS9_CONF daemonize yes protected-mode no port 6387 +tls-port 16387 user default off user acljedis on allcommands allkeys >fizzbuzz pidfile /tmp/redis9.pid @@ -112,6 +127,10 @@ logfile /tmp/redis9.log save "" appendonly no client-output-buffer-limit pubsub 256k 128k 5 +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS10_CONF @@ -138,6 +157,7 @@ endef # SENTINELS define REDIS_SENTINEL1 port 26379 +tls-port 36379 daemonize yes protected-mode no sentinel monitor mymaster 127.0.0.1 6379 1 @@ -147,10 +167,15 @@ sentinel failover-timeout mymaster 120000 sentinel parallel-syncs mymaster 1 pidfile /tmp/sentinel1.pid logfile /tmp/sentinel1.log +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_SENTINEL2 port 26380 +tls-port 36380 daemonize yes protected-mode no sentinel monitor mymaster 127.0.0.1 6381 1 @@ -160,6 +185,10 @@ sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 120000 pidfile /tmp/sentinel2.pid logfile /tmp/sentinel2.log +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_SENTINEL3 @@ -177,6 +206,7 @@ endef define REDIS_SENTINEL4 port 26382 +tls-port 36382 daemonize yes protected-mode no sentinel monitor mymaster 127.0.0.1 6381 1 @@ -186,10 +216,15 @@ sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 120000 pidfile /tmp/sentinel4.pid logfile /tmp/sentinel4.log +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_SENTINEL5 port 26383 +tls-port 36383 daemonize yes protected-mode no user default off @@ -202,6 +237,10 @@ sentinel failover-timeout aclmaster 120000 sentinel parallel-syncs aclmaster 1 pidfile /tmp/sentinel5.pid logfile /tmp/sentinel5.log +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef # CLUSTER REDIS NODES @@ -210,6 +249,7 @@ daemonize yes protected-mode no requirepass cluster port 7379 +tls-port 8379 cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node1.pid logfile /tmp/redis_cluster_node1.log @@ -217,6 +257,10 @@ save "" appendonly no cluster-enabled yes cluster-config-file /tmp/redis_cluster_node1.conf +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_CLUSTER_NODE2_CONF @@ -224,6 +268,7 @@ daemonize yes protected-mode no requirepass cluster port 7380 +tls-port 8380 cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node2.pid logfile /tmp/redis_cluster_node2.log @@ -231,6 +276,10 @@ save "" appendonly no cluster-enabled yes cluster-config-file /tmp/redis_cluster_node2.conf +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_CLUSTER_NODE3_CONF @@ -238,6 +287,7 @@ daemonize yes protected-mode no requirepass cluster port 7381 +tls-port 8381 cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node3.pid logfile /tmp/redis_cluster_node3.log @@ -245,6 +295,10 @@ save "" appendonly no cluster-enabled yes cluster-config-file /tmp/redis_cluster_node3.conf +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_CLUSTER_NODE4_CONF @@ -252,6 +306,7 @@ daemonize yes protected-mode no requirepass cluster port 7382 +tls-port 8382 cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node4.pid logfile /tmp/redis_cluster_node4.log @@ -259,6 +314,10 @@ save "" appendonly no cluster-enabled yes cluster-config-file /tmp/redis_cluster_node4.conf +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef define REDIS_CLUSTER_NODE5_CONF @@ -266,6 +325,7 @@ daemonize yes protected-mode no requirepass cluster port 7383 +tls-port 8383 cluster-node-timeout 15000 pidfile /tmp/redis_cluster_node5.pid logfile /tmp/redis_cluster_node5.log @@ -273,6 +333,10 @@ save "" appendonly no cluster-enabled yes cluster-config-file /tmp/redis_cluster_node5.conf +tls-auth-clients no +tls-cert-file "src/test/resources/private.crt" +tls-key-file "src/test/resources/private.key" +tls-ca-cert-file "src/test/resources/private.crt" endef # STABLE CLUSTER REDIS NODES @@ -343,42 +407,6 @@ save "" appendonly no endef -#STUNNEL -define STUNNEL_CONF -cert = src/test/resources/private.pem -pid = /tmp/stunnel.pid -[redis_1] -accept = 127.0.0.1:6390 -connect = 127.0.0.1:6379 -[redis_3] -accept = 127.0.0.1:16381 -connect = 127.0.0.1:6381 -[redis_4] -accept = 127.0.0.1:16382 -connect = 127.0.0.1:6382 -[redis_9] -accept = 127.0.0.1:16387 -connect = 127.0.0.1:6387 -[redis_cluster_1] -accept = 127.0.0.1:8379 -connect = 127.0.0.1:7379 -[redis_cluster_2] -accept = 127.0.0.1:8380 -connect = 127.0.001:7380 -[redis_cluster_3] -accept = 127.0.0.1:8381 -connect = 127.0.001:7381 -[redis_cluster_4] -accept = 127.0.0.1:8382 -connect = 127.0.0.1:7382 -[redis_cluster_5] -accept = 127.0.0.1:8383 -connect = 127.0.0.1:7383 -[redis_sentinel_5] -accept = 127.0.0.1:36383 -connect = 127.0.0.1:26383 -endef - export REDIS1_CONF export REDIS2_CONF export REDIS3_CONF @@ -405,16 +433,9 @@ export REDIS_STABLE_CLUSTER_NODE2_CONF export REDIS_STABLE_CLUSTER_NODE3_CONF export REDIS_UDS export REDIS_UNAVAILABLE_CONF -export STUNNEL_CONF -export STUNNEL_BIN - -ifndef STUNNEL_BIN - SKIP_SSL := !SSL*, -endif -export SKIP_SSL -start: stunnel cleanup compile-module +start: cleanup compile-module echo "$$REDIS1_CONF" | redis-server - echo "$$REDIS2_CONF" | redis-server - echo "$$REDIS3_CONF" | redis-server - @@ -451,12 +472,11 @@ start: stunnel cleanup compile-module cleanup: - rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null + - rm -vf /tmp/redis_stable_cluster_node*.conf 2>/dev/null + - rm -vf /tmp/redis_cluster_node*.log 2>/dev/null + - rm -vf /tmp/redis_stable_cluster_node*.log 2>/dev/null - rm dump.rdb appendonly.aof - 2>/dev/null -stunnel: - @if [ -e "$$STUNNEL_BIN" ]; then\ - echo "$$STUNNEL_CONF" | stunnel -fd 0;\ - fi stop: kill `cat /tmp/redis1.pid` @@ -484,7 +504,6 @@ stop: kill `cat /tmp/redis_stable_cluster_node2.pid` kill `cat /tmp/redis_stable_cluster_node3.pid` kill `cat /tmp/redis_uds.pid` || true - kill `cat /tmp/stunnel.pid` || true [ -f /tmp/redis_unavailable.pid ] && kill `cat /tmp/redis_unavailable.pid` || true rm -f /tmp/sentinel1.conf rm -f /tmp/sentinel2.conf @@ -504,7 +523,7 @@ stop: test: | start mvn-test stop mvn-test: - mvn -Dtest=${SKIP_SSL}${TEST} clean compile test + mvn -Dtest=${TEST} clean compile test package: | start mvn-package stop @@ -527,10 +546,15 @@ mvn-release: mvn release:perform -DskipTests system-setup: - sudo apt install -y gcc g++ + # Install gcc with Homebrew (macOS) or apt (Linux) + if [ "$(shell uname)" = "Darwin" ]; then \ + brew install gcc || true; \ + else \ + sudo apt install -y gcc g++; \ + fi [ ! -e redis-git ] && git clone https://github.com/redis/redis.git --branch unstable --single-branch redis-git || true $(MAKE) -C redis-git clean - $(MAKE) -C redis-git + $(MAKE) -C redis-git BUILD_TLS=yes compile-module: gcc -shared -o /tmp/testmodule.so -fPIC src/test/resources/testmodule.c diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index b9aab09700..bbb83bd410 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -8,7 +8,6 @@ import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLParameters; -import javax.net.ssl.SSLSocketFactory; import io.redis.test.utils.RedisVersion; import io.redis.test.utils.RedisVersionUtil; From 208f37cf244ae32b4ad8899c9d93bbd7e7574212 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 10:36:27 +0200 Subject: [PATCH 19/44] Introduce forceRedisServerVersion into test If set will assume this version instead of resolving it from tested server instaces. Used to force running tests agains older server versions --- .../io/redis/test/utils/RedisVersionRule.java | 21 ++++++++++++++++--- .../io/redis/test/utils/RedisVersionUtil.java | 17 +++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/test/java/io/redis/test/utils/RedisVersionRule.java b/src/test/java/io/redis/test/utils/RedisVersionRule.java index d8d8ee2770..abafa6d520 100644 --- a/src/test/java/io/redis/test/utils/RedisVersionRule.java +++ b/src/test/java/io/redis/test/utils/RedisVersionRule.java @@ -14,11 +14,17 @@ import java.lang.reflect.Method; +import static io.redis.test.utils.RedisVersionUtil.FORCE_REDIS_SERVER_VERSION_ENV; + public class RedisVersionRule implements TestRule { private static final Logger logger = LoggerFactory.getLogger(RedisVersionRule.class); private final HostAndPort hostPort; private final JedisClientConfig config; + private static final RedisVersion forcedVersion = System.getenv(FORCE_REDIS_SERVER_VERSION_ENV) != null + ? RedisVersion.of(System.getenv(FORCE_REDIS_SERVER_VERSION_ENV)) + : null; + public RedisVersionRule(EndpointConfig endpoint) { this.hostPort = endpoint.getHostAndPort(); @@ -56,9 +62,19 @@ public void evaluate() throws Throwable { } } private void checkRedisVersion(Jedis jedisClient, SinceRedisVersion versionAnnotation) { + + // Check if the environment variable is set + RedisVersion currentVersion; + + if (forcedVersion != null) { + logger.info("Using forced Redis server version from environment variable: " + forcedVersion); + currentVersion = forcedVersion; + } else { + RedisInfo info = RedisInfo.parseInfoServer(jedisClient.info("server")); + currentVersion = RedisVersion.of(info.getRedisVersion()); + } + RedisVersion minRequiredVersion = RedisVersion.of(versionAnnotation.value()); - RedisInfo info = RedisInfo.parseInfoServer(jedisClient.info("server")); - RedisVersion currentVersion = RedisVersion.of(info.getRedisVersion()); if (currentVersion.isLessThan(minRequiredVersion)) { Assume.assumeTrue("Test requires Redis version " + minRequiredVersion + " or later, but found " + currentVersion, false); } @@ -80,7 +96,6 @@ private SinceRedisVersion getMethodAnnotation(Description description) { } } } catch (Exception e) { - // Handle any potential exceptions here throw new RuntimeException("Could not resolve EnabledOnCommand annotation", e); } return null; diff --git a/src/test/java/io/redis/test/utils/RedisVersionUtil.java b/src/test/java/io/redis/test/utils/RedisVersionUtil.java index 8ddcba16b8..faeec309ec 100644 --- a/src/test/java/io/redis/test/utils/RedisVersionUtil.java +++ b/src/test/java/io/redis/test/utils/RedisVersionUtil.java @@ -9,8 +9,15 @@ public class RedisVersionUtil { + static final String FORCE_REDIS_SERVER_VERSION_ENV = "forceRedisServerVersion"; + private static final RedisVersion forcedVersion = System.getenv(FORCE_REDIS_SERVER_VERSION_ENV) != null + ? RedisVersion.of(System.getenv(FORCE_REDIS_SERVER_VERSION_ENV)) + : null; public static RedisVersion getRedisVersion(Connection conn) { + if (forcedVersion != null) { + return forcedVersion; + } try (Jedis jedis = new Jedis(conn)) { Object response = SafeEncoder.encodeObject(jedis.sendCommand(Protocol.Command.INFO, "server")); @@ -20,6 +27,9 @@ public static RedisVersion getRedisVersion(Connection conn) { } public static RedisVersion getRedisVersion(UnifiedJedis jedis) { + if (forcedVersion != null) { + return forcedVersion; + } Object response = SafeEncoder.encodeObject(jedis.sendCommand(Protocol.Command.INFO, "server")); RedisInfo info = RedisInfo.parseInfoServer(response.toString()); @@ -27,12 +37,19 @@ public static RedisVersion getRedisVersion(UnifiedJedis jedis) { } public static RedisVersion getRedisVersion(Jedis jedis) { + if (forcedVersion != null) { + return forcedVersion; + } RedisInfo info = RedisInfo.parseInfoServer(jedis.info("server")); return RedisVersion.of(info.getRedisVersion()); } public static RedisVersion getRedisVersion(EndpointConfig endpoint) { + if (forcedVersion != null) { + return forcedVersion; + } + DefaultJedisClientConfig.Builder builder = endpoint.getClientConfigBuilder(); if (endpoint.isTls()) { builder.sslSocketFactory(createTrustAllSslSocketFactory()); From ddae82fe6a96526e900ac8fa8d465f82332f460c Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 10:37:16 +0200 Subject: [PATCH 20/44] Fix accidently removed default for 6.2.16 version --- src/test/resources/env/.env.v6.2.16 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/resources/env/.env.v6.2.16 b/src/test/resources/env/.env.v6.2.16 index fbfee3b345..e1851ad1e8 100644 --- a/src/test/resources/env/.env.v6.2.16 +++ b/src/test/resources/env/.env.v6.2.16 @@ -1,3 +1,4 @@ +REDIS_VERSION=6.2.16 CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test REDIS_ENV_CONF_DIR=./ REDIS_MODULES_DIR=/tmp From d1c5a82e6be74acecbb1abd9295d78b58b21963d Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 11:00:31 +0200 Subject: [PATCH 21/44] Generate .key from private.pem --- src/test/resources/private.key | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/resources/private.key diff --git a/src/test/resources/private.key b/src/test/resources/private.key new file mode 100644 index 0000000000..0cf26fe000 --- /dev/null +++ b/src/test/resources/private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDidv/2FcjmIVcg +eHfiCm9AwZOpMJ/aKb8UK9digN6v8VMsrF2vcHDQKP01qsylVk58FHKRV0qKvy/X +4a/SZRXAeQQnYyi7GjqaoNAQpG30b+BvNwL4CgwRSydXi0pqm1d1YMtxlT2h6vrA +uJyYDJX7i+VQmf6PoANcGTiklP7Bsb+hrAnSini9A15Vwk+vsFx8wsbrRQ5MAEQ8 +EzphapV7aks9fhrh5zziRwUMuNF9T1lPL58P4E/ldCMgnKPKNNKI5LL6pAzxiTQK +Mn/N/KwKECkJ58/X+Q6Ih5K24TyOSaRVbpq2mtv1Wv4TmOccp6FKZmZer0FGMXY7 +JQwbybgPAgMBAAECggEBANEPMfOm4LMxjBD5pRISt+l7yiiiLq9jYnXokwjoFqst +iK7w3/uZPUusyzPD3O+04PdCmRD7GGFFZZFRUtJTZuUr0l3Z+DvhVsBwPCNg5/CD +ZxjEHAWGoOVGD6eNesE3bmF5XdYZA7B6D8nhow3qcHqrBqKFxq4n9XIMBnJI6XU8 +OS0dG+xQouvjZ7bG4CXHPEa/B1EjVGRTjfGa+YcgQYkcnuQCCKB+twzt1wkYn16m +PWcxNddhI2FQEieULP5gkDvCFVsni8oM2hkkQuyVViW9iJ93yp0MCqhV/YlqEUGb +vmbUpKOSHPqzSITc1OMJxbt/PS1xM/xnvzJwV1AVV+ECgYEA8ulTuWR5CvTvs+dY +r5B71vJe9V6KWQhiDLE07hntWbxRm2e8FvUe3cxY6x5ao+gYdWoTOGDWmB0oZhbr +5axtQh+BlZDXe5V2wzsZJ66Uc6KeWUb2kysW3yb/yjmNvexLlf6NF+JEKYplUiWW +az5ugUzBzhcQ6BGYLNXSajWm2f0CgYEA7qrPzf6+9BneVbWXPpxSa6cmRK1Vc9ka +91Jd4w+K32T+Axbmkm2OO91tuHpYHeEEd/RIO+1YcbeGXvvRhm/pudPJ6pjqjCx1 +IiFY96Sgp9z6ONkyoPkWnzT6u+qVK/PXKTB/ZT4YX949KzFeMkao7q5b9tLJsF2Y +AIWRa0c4AfsCgYEAg60j642hZ+Uaw0UXeCQ0XXKJMy2KhXTb4dF1xdRcK5bADiQP +e8pobwdE9D9CFzPLfmp//MHR0ieMLLskKR5tI7j8f91CUgXVmUNCAZbLdluixvaG +14Q2I8V6R18njNq4ppiUV2waUwJopj0l6wCu2nyHWnZ6fbJ78WH/a/+lcOkCgYEA +nJRLySW8OYFPMIP2OglsuVvr61qcmWhyHJhZKEJmJbGoRHadxqtBiVz4QvNhJBkg +SWJmkYphYBm7ek1TZRO/Dz83VUYFevkfz8h5Cd9j1z1OnEVCxgElKkYjyW1ZeIB9 +RHSg39chPqQbFV9KIUniQtT5WLFpyN9efdkjUnJi+EkCgYEApJ43b2MnFAnR7AHt +GgICw+uxQltqkaopmtvAszMUXReoQd4PIp5SwqcZRZmFZQOEASVuC3uld1Wu762K +NFzPRxqAb3oZIIfemMa+PytYWI0I4G+Nq8XMPoL5Ms1TaB9e9VjtfaDBIbBNiZ8O +W7dFYnGv0nhO3eudyAlLVC/FFbU= +-----END PRIVATE KEY----- From 7088ed1bc8b8f16b8fd8c2de880fce65ad9f560b Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 11:29:25 +0200 Subject: [PATCH 22/44] add ::1 to expected local ip's in the test --- .../redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java index a10c7c1290..12b61145f8 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java @@ -140,6 +140,8 @@ private static Set getAllLocalIps() { } catch (SocketException e) { throw new RuntimeException(e); } + //ipv6 loopback + allLocalIps.add("::1"); return allLocalIps; } } From 7528799358599ff3f78bda7cf74516fb4a30dd73 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 11:49:15 +0200 Subject: [PATCH 23/44] add ::1 to expected local ip's in the test --- .../redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java index 12b61145f8..63d6b009af 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SlowlogCommandsTest.java @@ -141,7 +141,7 @@ private static Set getAllLocalIps() { throw new RuntimeException(e); } //ipv6 loopback - allLocalIps.add("::1"); + allLocalIps.add("[::1]"); return allLocalIps; } } From 9210bc5a3d04ec339ca2edbbced645c0c6a8a869 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 11:49:51 +0200 Subject: [PATCH 24/44] Switch ctest env setup default from 'local' to 'docker' --- .github/workflows/integration.yml | 1 + .../java/redis/clients/jedis/util/TestEnvUtil.java | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3df4e12271..016eabc9bc 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -51,6 +51,7 @@ jobs: mvn javadoc:jar - name: Run tests run: | + export TEST_ENV_PROVIDER=local make test env: JVM_OPTS: -Xmx3200m diff --git a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java index 0180f745b4..ae72a70fcd 100644 --- a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java +++ b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java @@ -3,7 +3,12 @@ import java.util.Optional; public class TestEnvUtil { - private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", ""); + // Redis servers running inside docker + public static final String ENV_DOCKER = "docker"; + // Redis servers running localy on the test host + public static final String ENV_LOCAL = "local"; + + private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", ENV_DOCKER); private static final String TESTMODULE_SO = Optional.ofNullable(System.getenv("TESTMODULE_SO")) .orElseGet(() -> isContainerEnv() ? "/redis/work/modules/testmodule.so" @@ -14,6 +19,10 @@ public static String testModuleSo() { } public static boolean isContainerEnv() { - return TEST_ENV_PROVIDER.equals("docker"); + return TEST_ENV_PROVIDER.equals(ENV_DOCKER); + } + + public static boolean isLocalEnv() { + return TEST_ENV_PROVIDER.equals(ENV_LOCAL); } } From 4fcd47b44520e439c03c7ca82173bac269582ee2 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 16:53:23 +0200 Subject: [PATCH 25/44] Mark SSL & ACL test's since 7.0 In 6.2.16 CLUSTER slots command returns the non-tls port when contacted by tls one. Tests need to be revisited to make them compatible with 6.2.x --- src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java | 1 + src/test/java/redis/clients/jedis/SSLJedisClusterTest.java | 4 ++++ .../jedis/commands/jedis/AccessControlListCommandsTest.java | 2 ++ .../clients/jedis/commands/jedis/ControlCommandsTest.java | 1 + 4 files changed, 8 insertions(+) diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index 4e00ba2b44..7851d563b1 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -54,6 +54,7 @@ public static void prepare() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void testSSLDiscoverNodesAutomatically() { DefaultJedisClientConfig config = DefaultJedisClientConfig.builder() .user("default") diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index bbb83bd410..cf5b541da2 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -9,6 +9,7 @@ import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLParameters; +import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; import io.redis.test.utils.RedisVersionUtil; import redis.clients.jedis.util.TlsUtil; @@ -46,6 +47,7 @@ public static void prepare() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void testSSLDiscoverNodesAutomatically() { try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), DefaultJedisClientConfig.builder().password("cluster") @@ -113,6 +115,7 @@ public void testSSLWithoutPortMap() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void connectByIpAddress() { try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), DefaultJedisClientConfig.builder() @@ -147,6 +150,7 @@ public void connectToNodesFailsWithSSLParametersAndNoHostMapping() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void connectToNodesSucceedsWithSSLParametersAndHostMapping() { final SSLParameters sslParameters = new SSLParameters(); sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java index 5c0b231b5a..571eb93b8f 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java @@ -108,6 +108,7 @@ public void aclUsers() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x misses [~]>") public void aclGetUser() { // get default user information AccessControlUser userInfo = jedis.aclGetUser("default"); @@ -507,6 +508,7 @@ public void aclGenPassBinary() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x skips [&]>") public void aclBinaryCommandsTest() { jedis.aclSetUser(USER_NAME.getBytes()); assertNotNull(jedis.aclGetUser(USER_NAME)); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 8c3f99f0c6..59a00afe47 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -533,6 +533,7 @@ public void commandInfo() { } @Test // GitHub Issue #4020 + @SinceRedisVersion(value = "7.0.0", message = "In Redis 6.2.x ACL flags not empty") public void commandInfoAcl() { Map infos = jedis.commandInfo("ACL"); assertThat(infos, Matchers.aMapWithSize(1)); From a34d631d04fa0ebdeef2862dd88380aea0092da9 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 17:25:03 +0200 Subject: [PATCH 26/44] Mark SSL & ACL test's since 7.0 In 6.2.16 CLUSTER slots command returns the non-tls port when contacted by tls one. Tests need to be revisited to make them compatible with 6.2.x --- src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java | 3 +-- src/test/java/redis/clients/jedis/SSLJedisClusterTest.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index 7851d563b1..0772ede767 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -17,7 +17,7 @@ import redis.clients.jedis.exceptions.JedisClusterOperationException; -@SinceRedisVersion("6.0.0") +@SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after tests are fixed.") public class SSLACLJedisClusterTest extends JedisClusterTestBase { private static final int DEFAULT_REDIRECTIONS = 5; @@ -54,7 +54,6 @@ public static void prepare() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void testSSLDiscoverNodesAutomatically() { DefaultJedisClientConfig config = DefaultJedisClientConfig.builder() .user("default") diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index cf5b541da2..7465881c15 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -19,6 +19,7 @@ import redis.clients.jedis.exceptions.JedisClusterOperationException; +@SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public class SSLJedisClusterTest extends JedisClusterTestBase { private static final int DEFAULT_REDIRECTIONS = 5; @@ -47,7 +48,6 @@ public static void prepare() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void testSSLDiscoverNodesAutomatically() { try (JedisCluster jc = new JedisCluster(Collections.singleton(new HostAndPort("localhost", 8379)), DefaultJedisClientConfig.builder().password("cluster") @@ -115,7 +115,6 @@ public void testSSLWithoutPortMap() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "Redis 6.2.x returns non-tls port in CLUSTER SLOTS command. Enable for 6.2.x after test is fixed.") public void connectByIpAddress() { try (JedisCluster jc = new JedisCluster(new HostAndPort("127.0.0.1", 8379), DefaultJedisClientConfig.builder() From 1698b769514a5892b63fd7003ff03a1a5f1750b5 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 19 Nov 2024 20:00:23 +0200 Subject: [PATCH 27/44] Fix NPE in test clean up --- .../jedis/ClusterJedisCommandsTestBase.java | 16 ++++++---------- ...usterShardedPublishSubscribeCommandsTest.java | 3 --- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java index e96a4896d3..da973f41ca 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java @@ -58,7 +58,6 @@ public void setUp() throws InterruptedException { int[] node1Slots = new int[slotsPerNode]; int[] node2Slots = new int[slotsPerNode + 1]; int[] node3Slots = new int[slotsPerNode]; -// for (int i = 0, slot1 = 0, slot2 = 0, slot3 = 0; i < JedisCluster.HASHSLOTS; i++) { for (int i = 0, slot1 = 0, slot2 = 0, slot3 = 0; i < CLUSTER_HASHSLOTS; i++) { if (i < slotsPerNode) { node1Slots[slot1++] = i; @@ -76,28 +75,25 @@ public void setUp() throws InterruptedException { waitForClusterReady(); jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379)); -// cluster = new JedisCluster(jedisClusterNode, 2000, 2000, 5, "cluster", new JedisPoolConfig()); -// cluster = new JedisCluster(jedisClusterNode, DefaultJedisClientConfig.builder().password("cluster").build(), 5); cluster = new JedisCluster(jedisClusterNode, null, "cluster"); - } @AfterClass public static void cleanUp() { int slotTest = JedisClusterCRC16.getSlot("test"); int slot51 = JedisClusterCRC16.getSlot("51"); - String node3Id = getNodeId(node3.clusterNodes()); - node2.clusterSetSlotNode(slotTest, node3Id); - node2.clusterSetSlotNode(slot51, node3Id); - node2.clusterDelSlots(slotTest, slot51); + if (node3 != null ) { + String node3Id = getNodeId(node3.clusterNodes()); + node2.clusterSetSlotNode(slotTest, node3Id); + node2.clusterSetSlotNode(slot51, node3Id); + node2.clusterDelSlots(slotTest, slot51); + } } @After public void tearDown() { // clear all slots -// int[] slotsToDelete = new int[JedisCluster.HASHSLOTS]; int[] slotsToDelete = new int[CLUSTER_HASHSLOTS]; -// for (int i = 0; i < JedisCluster.HASHSLOTS; i++) { for (int i = 0; i < CLUSTER_HASHSLOTS; i++) { slotsToDelete[i] = i; } diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java index c1863892bd..5a348cd77a 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java @@ -9,9 +9,6 @@ import java.util.Map; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionRule; -import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.BinaryJedisShardedPubSub; From 83cf38d2f4fb602892243872559311745dc3acf0 Mon Sep 17 00:00:00 2001 From: ggivo Date: Wed, 20 Nov 2024 11:11:34 +0200 Subject: [PATCH 28/44] Add how to bootstrap test env with Docker --- .github/CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e1bb6dcefa..b31015a094 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -25,6 +25,47 @@ Jedis unit tests use many Redis instances, so we use a ```Makefile``` to prepare Start unit tests with ```make test```. Set up test environments with ```make start```, tear down those environments with ```make stop``` and clean up the environment files with ```make cleanup```. + +# Jedis Test Environment Using Docker + +This guide explains how to bootstrap and manage a test environment for Jedis using Docker Compose. + +## Workflow Steps +1. **Bring up the test environment** (examples provided below). +2. **Run tests** (via IDE, Maven, etc.). +3. **Destroy the test environment** using `docker compose down`. + +### Important Note +The default test environment uses the temporary work folder `./redis-env-work`. +Some tests might leave Redis nodes in an inconsistent state, so this folder should be cleaned or removed before bootstrapping the environment again. + + +## Bootstrap test env using Docker +- **Redis 8.0-M01** +``` +rm -rf ./redis-env-work +export REDIS_VERSION=8.0-M01 +docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up +``` +- **Redis 7.4.1** +``` +rm -rf ./redis-env-work +export REDIS_VERSION=7.4.1 +docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up +``` +- **Redis 7.2.6** +``` +rm -rf ./redis-env-work +export REDIS_VERSION=7.2.6 +docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up +``` +- **Redis 6.2.16** + - **NOTE :** 6.2.16 uses a dedicated .env.v6.12.16 file, since some of the redis configuration settings are not supported in 6.2.16 +``` +rm -rf ./redis-env-work +docker compose --env-file src/test/resources/env/.env.v6.12.16 -f src/test/resources/env/docker-compose.yml up +``` + # Some rules of Jedis source code ## Code Convention From e1c0453edcd3e256de597088402863ab88c1ab4d Mon Sep 17 00:00:00 2001 From: ggivo Date: Sat, 23 Nov 2024 20:14:43 +0200 Subject: [PATCH 29/44] Add make target to start containerised test env. --- .github/CONTRIBUTING.md | 50 ++++++++++++++--------------- Makefile | 31 ++++++++++++++++++ src/test/resources/env/.env | 2 +- src/test/resources/env/.env.v6.2.16 | 2 +- 4 files changed, 57 insertions(+), 28 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b31015a094..7e1a906175 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -31,41 +31,39 @@ Set up test environments with ```make start```, tear down those environments wit This guide explains how to bootstrap and manage a test environment for Jedis using Docker Compose. ## Workflow Steps -1. **Bring up the test environment** (examples provided below). -2. **Run tests** (via IDE, Maven, etc.). -3. **Destroy the test environment** using `docker compose down`. +1. **Start the test environment** by running the following command (examples below). + - For instance, to start the environment with Redis 8.0-M01, use `make start-test-env`. +2. **Run tests** through your IDE, Maven, or other testing tools as needed. +3. **Stop the test environment** by running the following command: + - `make stop-test-env` + - This will stop and tear down the Docker containers running the Redis service -### Important Note -The default test environment uses the temporary work folder `./redis-env-work`. -Some tests might leave Redis nodes in an inconsistent state, so this folder should be cleaned or removed before bootstrapping the environment again. +# Start the Test Environment Using Docker +You can bootstrap the test environment for supported versions of Redis using the provided `make` targets. -## Bootstrap test env using Docker -- **Redis 8.0-M01** +## Option 1: Using `make` Targets +To bring up the test environment for a specific Redis version (8.0-M01, 7.4.1, 7.2.6, or 6.2.16), use the following command: +```bash +make start-test-env version=8.0-M01 # Replace with desired version ``` -rm -rf ./redis-env-work + +## Option 2: Using docker compose commands directly +Docker compose file can be found in `src/test/resources/env` folder. +- **Redis 8.0-M01, 7.4.1, 7.2.6** +```bash +rm -rf /tmp/redis-env-work export REDIS_VERSION=8.0-M01 -docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up -``` -- **Redis 7.4.1** -``` -rm -rf ./redis-env-work -export REDIS_VERSION=7.4.1 -docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up -``` -- **Redis 7.2.6** -``` -rm -rf ./redis-env-work -export REDIS_VERSION=7.2.6 -docker compose --env-file src/test/resources/env/.env -f src/test/resources/env/docker-compose.yml up +docker compose up ``` - **Redis 6.2.16** - - **NOTE :** 6.2.16 uses a dedicated .env.v6.12.16 file, since some of the redis configuration settings are not supported in 6.2.16 -``` -rm -rf ./redis-env-work -docker compose --env-file src/test/resources/env/.env.v6.12.16 -f src/test/resources/env/docker-compose.yml up +- **NOTE:** Redis 6.2.16 uses a dedicated `.env.v6.2.16`. +```bash +rm -rf /tmp/redis-env-work +docker compose --env-file .env.v6.2.16 up ``` + # Some rules of Jedis source code ## Code Convention diff --git a/Makefile b/Makefile index 5e39efd283..e391cad707 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ PATH := ./redis-git/src:${PATH} +# Supported test env versions +SUPPORTED_TEST_ENV_VERSIONS := 8.0-M01 7.4.1 7.2.6 6.2.16 +DEFAULT_TEST_ENV_VERSION := 8.0-M01 + define REDIS1_CONF daemonize yes protected-mode no @@ -559,5 +563,32 @@ system-setup: compile-module: gcc -shared -o /tmp/testmodule.so -fPIC src/test/resources/testmodule.c +# Start test environment with specific version using predefined docker compose setup + +start-test-env: + @if [ -z "$(version)" ]; then \ + version=$(arg); \ + if [ -z "$$version" ]; then \ + version="$(DEFAULT_TEST_ENV_VERSION)"; \ + fi; \ + fi; \ + if ! echo "$(SUPPORTED_TEST_ENV_VERSIONS)" | grep -qw "$$version"; then \ + echo "Error: Invalid version '$$version'. Supported versions are: $(SUPPORTED_TEST_ENV_VERSIONS)."; \ + exit 1; \ + fi; \ + env_file="src/test/resources/env/.env"; \ + if [ "$$version" = "6.2.16" ]; then \ + env_file="src/test/resources/env/.env.v6.2.16"; \ + fi; \ + rm -rf /tmp/redis-env-work; \ + export REDIS_VERSION=$$version && \ + docker compose --env-file $$env_file -f src/test/resources/env/docker-compose.yml up -d; \ + echo "Started test environment with Redis version $$version." + +# Stop the test environment +stop-test-env: + docker compose -f src/test/resources/env/docker-compose.yml down; \ + rm -rf /tmp/redis-env-work; \ + echo "Stopped test environment and performed cleanup." .PHONY: test diff --git a/src/test/resources/env/.env b/src/test/resources/env/.env index c0b07269aa..e5c26e6a20 100644 --- a/src/test/resources/env/.env +++ b/src/test/resources/env/.env @@ -2,6 +2,6 @@ REDIS_VERSION=8.0-M01 CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test REDIS_ENV_CONF_DIR=./ REDIS_MODULES_DIR=/tmp -REDIS_ENV_WORK_DIR=./redis-env-work +REDIS_ENV_WORK_DIR=/tmp/redis-env-work ENABLE_MODULE_COMMAND_DIRECTIVE=--enable-module-command yes \ No newline at end of file diff --git a/src/test/resources/env/.env.v6.2.16 b/src/test/resources/env/.env.v6.2.16 index e1851ad1e8..d3d2418bbc 100644 --- a/src/test/resources/env/.env.v6.2.16 +++ b/src/test/resources/env/.env.v6.2.16 @@ -2,7 +2,7 @@ REDIS_VERSION=6.2.16 CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test REDIS_ENV_CONF_DIR=./ REDIS_MODULES_DIR=/tmp -REDIS_ENV_WORK_DIR=./redis-env-work +REDIS_ENV_WORK_DIR=/tmp/redis-env-work #REMOVE UNSUPPORTED DIRECTIVE ENABLE_MODULE_COMMAND_DIRECTIVE= \ No newline at end of file From a826afb2503d29bdcb6da7f21b3e97d4693f7040 Mon Sep 17 00:00:00 2001 From: ggivo Date: Sat, 23 Nov 2024 23:21:06 +0200 Subject: [PATCH 30/44] use dedicate .env file for 6.2.16 --- .github/workflows/test-on-docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-on-docker.yml b/.github/workflows/test-on-docker.yml index 5580db1f7a..b33184cc1d 100644 --- a/.github/workflows/test-on-docker.yml +++ b/.github/workflows/test-on-docker.yml @@ -66,7 +66,7 @@ jobs: export REDIS_VERSION="${{ matrix.redis_version }}" export COMPOSE_ENV_FILES="src/test/resources/env/.env" if [[ "${{ matrix.redis_version }}" == "6.2.16" ]]; then - COMPOSE_ENV_FILES+=",src/test/resources/env/.env.v${{ matrix.redis_version }}" + COMPOSE_ENV_FILES="src/test/resources/env/.env.v${{ matrix.redis_version }}" fi docker compose -f src/test/resources/env/docker-compose.yml up -d - name: Maven offline From 6c588156dad34130ecfbfe6dbfca4e195380346e Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 25 Nov 2024 14:33:25 +0200 Subject: [PATCH 31/44] Apply review comments - Remove unused configuration - [Code clean up] Use endpoint configuration for creating redis version rule --- .../jedis/csc/ClientSideCacheTestBase.java | 6 ++---- .../csc/JedisPooledClientSideCacheTest.java | 3 +-- .../config/node-sentinel5/redis.conf | 11 ---------- src/test/resources/env/endpoint.map | 20 ------------------- 4 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf delete mode 100644 src/test/resources/env/endpoint.map diff --git a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java index 47f2d1142c..4fdf76679b 100644 --- a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java @@ -23,12 +23,10 @@ public abstract class ClientSideCacheTestBase { @Rule public RedisVersionRule versionRule = new RedisVersionRule( - HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), - HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + HostAndPorts.getRedisEndpoint("standalone1")); @Rule public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), - HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + HostAndPorts.getRedisEndpoint("standalone1")); @Before public void setUp() throws Exception { diff --git a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java index 2bca0fe73a..ed1eaf1b93 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java @@ -11,8 +11,7 @@ public class JedisPooledClientSideCacheTest extends JedisPooledClientSideCacheTe @ClassRule public static RedisVersionRule versionRule = new RedisVersionRule( - HostAndPorts.getRedisEndpoint("standalone1").getHostAndPort(), - HostAndPorts.getRedisEndpoint("standalone1").getClientConfigBuilder().build()); + HostAndPorts.getRedisEndpoint("standalone1")); @BeforeClass public static void prepare() { diff --git a/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf b/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf deleted file mode 100644 index f3104c5ba6..0000000000 --- a/src/test/resources/Arch/sentinel5/config/node-sentinel5/redis.conf +++ /dev/null @@ -1,11 +0,0 @@ -port 26383 -tls-port 36383 -tls-auth-clients no -user default off -user sentinel on allcommands allkeys allchannels >foobared -sentinel monitor aclmaster 127.0.0.1 6387 1 -sentinel auth-user aclmaster acljedis -sentinel auth-pass aclmaster fizzbuzz -sentinel down-after-milliseconds aclmaster 2000 -sentinel failover-timeout aclmaster 120000 -sentinel parallel-syncs aclmaster 1 \ No newline at end of file diff --git a/src/test/resources/env/endpoint.map b/src/test/resources/env/endpoint.map deleted file mode 100644 index 5070ec216b..0000000000 --- a/src/test/resources/env/endpoint.map +++ /dev/null @@ -1,20 +0,0 @@ -REDIS1_CONF 6379:6390 "standalone0" : "redis://localhost:6379" -REDIS1_CONF 6379:6390 "standalone0-acl" : "redis://localhost:6379", -REDIS1_CONF 6379:6390 "standalone0-tls" : "rediss://localhost:6390" -REDIS1_CONF 6379:6390 "standalone0-acl-tls" : "rediss://localhost:6390" ------------- -REDIS2_CONF 6380 "standalone1" : "redis://localhost:6380" -REDIS3_CONF 6381:16381 "standalone2-primary" : "redis://localhost:6381" -REDIS4_CONF 6382:16382 "standalone3-replica-of-standalone2" : "redis://localhost:6382" - (slaveof 6381) -REDIS5_CONF 6383 "standalone4-replica-of-standalone1" : "redis://localhost:6383" - (slaveof 6379) -REDIS6_CONF 6384 "standalone5-primary" : "redis://localhost:6384" -REDIS7_CONF 6385 "standalone6-replica-of-standalone5" : "redis://localhost:6385" - (slaveof 6384) -REDIS8_CONF 6386 "standalone7-with-lfu-policy" : "redis://localhost:6386" -REDIS9_CONF 6387:16387 ? missing -REDIS10_CONF 6388 "standalone9" : "redis://localhost:6388" -REDIS11_CONF 6389 "standalone10-replica-of-standalone9" : "redis://localhost:6389" - (replicaof 6388) -jedis-stack 6479 "modules-docker" : "redis://localhost:6479" From 6d61781b666acb700baff19c7b63638e65d3afe6 Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 26 Nov 2024 10:02:31 +0200 Subject: [PATCH 32/44] re-enable commandInfoWithSubcommands() Issue #4020 is resolved now --- .../redis/clients/jedis/commands/jedis/ControlCommandsTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 5e65f349e9..cf4d500fe7 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -24,7 +24,6 @@ import io.redis.test.annotations.SinceRedisVersion; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -577,7 +576,6 @@ public void commandInfoAcl() { } @Test - @Ignore( "Till https://github.com/redis/jedis/issues/4020 is resolved") public void commandInfoWithSubcommands() { Map infos = jedis.commandInfo("ACL"); From c3da29d549fb35dc626a8de1fbb335ebd0e7872e Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 26 Nov 2024 10:33:06 +0200 Subject: [PATCH 33/44] re-enable commandInfoWithSubcommands() Issue #4020 is resolved now --- .../redis/clients/jedis/commands/jedis/ControlCommandsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index cf4d500fe7..950bf5afbb 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -580,7 +580,7 @@ public void commandInfoWithSubcommands() { Map infos = jedis.commandInfo("ACL"); CommandInfo aclInfo = infos.get("acl"); - assertEquals(2, aclInfo.getArity()); + assertEquals(-2, aclInfo.getArity()); assertEquals(0, aclInfo.getFlags().size()); assertEquals(0, aclInfo.getFirstKey()); assertEquals(0, aclInfo.getLastKey()); From 61bef0c35cd5bfce3266655c8de1ae900613222e Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 26 Nov 2024 11:27:44 +0200 Subject: [PATCH 34/44] remove duplicated test --- .../jedis/commands/jedis/ControlCommandsTest.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 950bf5afbb..2ffdbca1d0 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -575,21 +575,6 @@ public void commandInfoAcl() { }); } - @Test - public void commandInfoWithSubcommands() { - Map infos = jedis.commandInfo("ACL"); - - CommandInfo aclInfo = infos.get("acl"); - assertEquals(-2, aclInfo.getArity()); - assertEquals(0, aclInfo.getFlags().size()); - assertEquals(0, aclInfo.getFirstKey()); - assertEquals(0, aclInfo.getLastKey()); - assertEquals(0, aclInfo.getStep()); - assertEquals(1, aclInfo.getAclCategories().size()); - assertEquals(0, aclInfo.getTips().size()); - assertFalse(aclInfo.getSubcommands().isEmpty()); - } - @Test @SinceRedisVersion("7.0.0") public void commandList() { From fbaf8a19b9a696ba5af9ca3d726c01cd8abf482e Mon Sep 17 00:00:00 2001 From: ggivo Date: Tue, 26 Nov 2024 14:13:07 +0200 Subject: [PATCH 35/44] Code clean up Addressing review comments --- .../redis/clients/jedis/ACLJedisPoolTest.java | 4 +-- .../jedis/ACLJedisSentinelPoolTest.java | 4 +-- .../redis/clients/jedis/ACLJedisTest.java | 2 +- .../clients/jedis/JedisClusterTestBase.java | 4 +-- .../clients/jedis/SSLACLJedisClusterTest.java | 2 +- .../redis/clients/jedis/SSLACLJedisTest.java | 2 +- .../clients/jedis/SSLJedisClusterTest.java | 2 +- .../CommandObjectsStandaloneTestBase.java | 8 ++--- .../CommandObjectsTestBase.java | 2 +- .../jedis/AccessControlListCommandsTest.java | 2 +- .../commands/jedis/ClientCommandsTest.java | 8 ++--- .../commands/jedis/ClusterCommandsTest.java | 4 +-- .../jedis/ClusterJedisCommandsTestBase.java | 4 +-- .../commands/jedis/HashesCommandsTest.java | 9 +++--- .../commands/jedis/JedisCommandsTestBase.java | 10 +++--- .../commands/jedis/ScriptingCommandsTest.java | 2 +- .../commands/jedis/StreamsCommandsTest.java | 2 +- .../commands/unified/BitCommandsTestBase.java | 2 -- .../ClusterAllKindOfValuesCommandsTest.java | 4 +-- .../cluster/ClusterBitCommandsTest.java | 4 +-- .../cluster/ClusterHashesCommandsTest.java | 4 +-- .../cluster/ClusterListCommandsTest.java | 4 +-- .../cluster/ClusterSetCommandsTest.java | 4 +-- .../cluster/ClusterSortedSetCommandsTest.java | 4 +-- .../ClusterStringValuesCommandsTest.java | 4 +-- .../pipeline/PipelineCommandsTestBase.java | 12 +++---- .../pipeline/StreamsPipelineCommandsTest.java | 30 ++---------------- .../PooledAllKindOfValuesCommandsTest.java | 15 +++------ .../unified/pooled/PooledBitCommandsTest.java | 12 +++---- .../pooled/PooledHashesCommandsTest.java | 12 +++---- .../pooled/PooledListCommandsTest.java | 13 +++----- .../pooled/PooledMiscellaneousTest.java | 12 +++---- .../unified/pooled/PooledSetCommandsTest.java | 12 +++---- .../pooled/PooledSortedSetCommandsTest.java | 12 +++---- .../PooledStringValuesCommandsTest.java | 12 +++---- .../jedis/csc/ClientSideCacheTestBase.java | 4 +-- .../csc/JedisClusterClientSideCacheTest.java | 31 ++++++++++++------- .../csc/JedisPooledClientSideCacheTest.java | 2 +- .../JedisPooledClientSideCacheTestBase.java | 2 -- .../JedisSentineledClientSideCacheTest.java | 30 +++++++++--------- .../SSLJedisPooledClientSideCacheTest.java | 2 +- .../jedis/util}/EnabledOnCommandRule.java | 2 +- .../clients/jedis/util}/RedisVersionRule.java | 10 +++--- .../clients/jedis/util}/RedisVersionUtil.java | 10 +++--- 44 files changed, 135 insertions(+), 201 deletions(-) rename src/test/java/{io/redis/test/utils => redis/clients/jedis/util}/EnabledOnCommandRule.java (99%) rename src/test/java/{io/redis/test/utils => redis/clients/jedis/util}/RedisVersionRule.java (93%) rename src/test/java/{io/redis/test/utils => redis/clients/jedis/util}/RedisVersionUtil.java (89%) diff --git a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java index 0d160e8697..a019d518d4 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java @@ -4,13 +4,11 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; - import java.net.URI; import java.net.URISyntaxException; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.ClassRule; import org.junit.Test; diff --git a/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java b/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java index a14cfbbc9a..fb1fcc72e1 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisSentinelPoolTest.java @@ -1,14 +1,12 @@ package redis.clients.jedis; import static org.junit.Assert.*; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; - import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.*; diff --git a/src/test/java/redis/clients/jedis/ACLJedisTest.java b/src/test/java/redis/clients/jedis/ACLJedisTest.java index 1d72195a5d..1b10870d5e 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis; import static org.junit.Assert.assertEquals; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; +import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; import java.net.URISyntaxException; import org.junit.BeforeClass; diff --git a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java index 7d9813b760..8720216fae 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java @@ -2,8 +2,8 @@ import static redis.clients.jedis.Protocol.CLUSTER_HASHSLOTS; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java index 0772ede767..516af0f8ec 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisClusterTest.java @@ -11,7 +11,7 @@ import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import org.junit.*; import redis.clients.jedis.util.TlsUtil; diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java index d90965aa0f..06b6fa1f79 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java @@ -1,6 +1,6 @@ package redis.clients.jedis; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; +import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; import static org.junit.Assert.*; import static redis.clients.jedis.util.TlsUtil.*; diff --git a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java index 7465881c15..5f325d4710 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisClusterTest.java @@ -11,7 +11,7 @@ import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import redis.clients.jedis.util.TlsUtil; import org.junit.Assert; import org.junit.BeforeClass; diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java index 00a57f1ff6..707db79bb2 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsStandaloneTestBase.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.commandobjects; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.Rule; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; @@ -12,9 +12,9 @@ public abstract class CommandObjectsStandaloneTestBase extends CommandObjectsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(endpoint); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint); public CommandObjectsStandaloneTestBase(RedisProtocol protocol) { super(protocol, HostAndPorts.getRedisEndpoint("standalone0")); diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java index 8e194105e0..fac2d9efc2 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java @@ -6,7 +6,7 @@ import java.util.Collection; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import org.junit.Before; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java index 571eb93b8f..56d30ac1cc 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AccessControlListCommandsTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; +import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java index 24dd66e914..ec72e266a4 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClientCommandsTest.java @@ -16,8 +16,8 @@ import java.util.regex.Pattern; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -43,9 +43,9 @@ public class ClientCommandsTest extends JedisCommandsTestBase { private Jedis client; @Rule - public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(endpoint); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint); public ClientCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java index c94585ac3e..3b07d14f4b 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterCommandsTest.java @@ -10,8 +10,8 @@ import java.util.Map; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.*; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java index da973f41ca..232e49b6b9 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java @@ -5,8 +5,8 @@ import java.util.HashSet; import java.util.Set; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java index a3d85d2c92..370fb7cfd8 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/HashesCommandsTest.java @@ -32,14 +32,13 @@ import java.util.stream.Collectors; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.Pipeline; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.Response; @@ -53,10 +52,10 @@ public class HashesCommandsTest extends JedisCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(endpoint); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(endpoint); final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java index 7a25858160..b73e707f19 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java @@ -2,8 +2,8 @@ import java.util.Collection; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -15,13 +15,11 @@ public abstract class JedisCommandsTestBase { @Rule public RedisVersionRule versionRule = new RedisVersionRule( - HostAndPorts.getRedisEndpoint("standalone0").getHostAndPort(), - HostAndPorts.getRedisEndpoint("standalone0").getClientConfigBuilder().build()); + HostAndPorts.getRedisEndpoint("standalone0")); @Rule public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - HostAndPorts.getRedisEndpoint("standalone0").getHostAndPort(), - HostAndPorts.getRedisEndpoint("standalone0").getClientConfigBuilder().build()); + HostAndPorts.getRedisEndpoint("standalone0")); /** * Input data for parameterized tests. In principle all subclasses of this diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java index fd0a7a86c0..714110fc26 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ScriptingCommandsTest.java @@ -10,7 +10,7 @@ import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Before; diff --git a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java index 719014bdfc..7500b984c9 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java @@ -20,7 +20,7 @@ import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java index 7d559e1518..483a6aa4b9 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/BitCommandsTestBase.java @@ -9,8 +9,6 @@ import java.util.List; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersionRule; -import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.Protocol; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java index ca8be570ee..5f0df2a7a3 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterAllKindOfValuesCommandsTest.java @@ -10,8 +10,8 @@ import java.util.HashSet; import java.util.Set; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java index 505722574b..2515f5acfe 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java @@ -2,8 +2,8 @@ import static org.junit.Assert.assertEquals; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.*; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java index 81a6889dd5..d5024b1bb3 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterHashesCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.cluster; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java index ef24a93e3b..e1c9b3eb97 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterListCommandsTest.java @@ -11,8 +11,8 @@ import java.util.List; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java index b71a7fe663..d1b620a8c6 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSetCommandsTest.java @@ -6,8 +6,8 @@ import java.util.Set; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java index 095f4a24c7..600237571d 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterSortedSetCommandsTest.java @@ -11,8 +11,8 @@ import java.util.List; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java index 8b2d62f05c..a940e59d97 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterStringValuesCommandsTest.java @@ -6,8 +6,8 @@ import java.util.List; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java index ecef988fa7..9744244616 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/PipelineCommandsTestBase.java @@ -2,8 +2,8 @@ import java.util.Collection; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -31,13 +31,9 @@ public static Collection data() { protected final RedisProtocol protocol; @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - HostAndPorts.getStableClusterServers().get(0), - DefaultJedisClientConfig.builder().password("cluster").build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); /** * The RESP protocol is to be injected by the subclasses, usually via JUnit * parameterized tests, because most of the subclassed tests are meant to be diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java index 78627e1cf3..6d52e88b1f 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/StreamsPipelineCommandsTest.java @@ -29,7 +29,7 @@ import io.redis.test.annotations.SinceRedisVersion; import io.redis.test.utils.RedisVersion; -import io.redis.test.utils.RedisVersionUtil; +import redis.clients.jedis.util.RedisVersionUtil; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; @@ -254,13 +254,14 @@ public void xaddWithParamsMinId() { } @Test + @SinceRedisVersion(value = "7.0.0", message = "Added support for XADD ID auto sequence is introduced in 7.0.0") public void xaddParamsId() { String key = "kk"; Map map = singletonMap("ff", "vv"); pipe.xadd(key, XAddParams.xAddParams().id(new StreamEntryID(0, 1)), map); pipe.xadd(key, XAddParams.xAddParams().id(2, 3), map); - pipe.xadd(key, XAddParams.xAddParams().id("4-0"), map); + pipe.xadd(key, XAddParams.xAddParams().id(4), map); pipe.xadd(key, XAddParams.xAddParams().id("5-6"), map); pipe.xadd(key, XAddParams.xAddParams().id("7-8".getBytes()), map); pipe.xadd(key, XAddParams.xAddParams(), map); @@ -280,31 +281,6 @@ public void xaddParamsId() { greaterThan((StreamEntryID) results.get(4))); } - @Test - @SinceRedisVersion(value = "7.2.0", message = "Starting with Redis version 7.0.0: Added support for the -* explicit ID form.") - public void xaddParamsExplicitId() { - String key = "kk"; - Map map = singletonMap("ff", "vv"); - - pipe.xadd(key, XAddParams.xAddParams().id(new StreamEntryID(0, 1)), map); - pipe.xadd(key, XAddParams.xAddParams().id(2), map); - pipe.xadd(key, XAddParams.xAddParams().id(2), map); - pipe.xadd(key, XAddParams.xAddParams(), map); - - List results = pipe.syncAndReturnAll(); - - assertThat(results, contains( - equalTo(new StreamEntryID(0, 1)), - equalTo(new StreamEntryID(2, 0)), - equalTo(new StreamEntryID(2, 1)), - instanceOf(StreamEntryID.class) - )); - - assertThat((StreamEntryID) results.get(2), - greaterThan((StreamEntryID) results.get(1))); - } - - @Test public void xdel() { Map map1 = new HashMap<>(); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java index 1e2fc5d94d..c43a2b3667 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledAllKindOfValuesCommandsTest.java @@ -1,28 +1,23 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.HostAndPorts; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import redis.clients.jedis.DefaultJedisClientConfig; -import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.AllKindOfValuesCommandsTestBase; @RunWith(Parameterized.class) public class PooledAllKindOfValuesCommandsTest extends AllKindOfValuesCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledAllKindOfValuesCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java index b1428d46ca..e91b0ece06 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledBitCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -15,13 +15,9 @@ public class PooledBitCommandsTest extends BitCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort() - ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledBitCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java index 95f4020549..34e88a6a81 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledHashesCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -15,13 +15,9 @@ public class PooledHashesCommandsTest extends HashesCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledHashesCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java index 606e91bcc3..6626896095 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledListCommandsTest.java @@ -1,14 +1,13 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.commands.unified.ListCommandsTestBase; @@ -16,13 +15,9 @@ public class PooledListCommandsTest extends ListCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort() - ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledListCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java index 4ef5361caa..3da81a8e52 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledMiscellaneousTest.java @@ -9,8 +9,8 @@ import java.util.List; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -26,13 +26,9 @@ public class PooledMiscellaneousTest extends UnifiedJedisCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort() - ,PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledMiscellaneousTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java index f8a2aa05e6..d8ae1ffb92 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSetCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -15,13 +15,9 @@ public class PooledSetCommandsTest extends SetCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledSetCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java index 5499b0495f..584a8913b1 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledSortedSetCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -15,13 +15,9 @@ public class PooledSortedSetCommandsTest extends SortedSetCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledSortedSetCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java index ab8da3db7a..eea8c7c3a4 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/pooled/PooledStringValuesCommandsTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.commands.unified.pooled; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -14,13 +14,9 @@ @RunWith(Parameterized.class) public class PooledStringValuesCommandsTest extends StringValuesCommandsTestBase { @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public RedisVersionRule versionRule = new RedisVersionRule(PooledCommandsTestHelper.nodeInfo); @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - PooledCommandsTestHelper.nodeInfo.getHostAndPort(), - PooledCommandsTestHelper.nodeInfo.getClientConfigBuilder().build()); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(PooledCommandsTestHelper.nodeInfo); public PooledStringValuesCommandsTest(RedisProtocol protocol) { super(protocol); diff --git a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java index 4fdf76679b..614d5495b4 100644 --- a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java @@ -3,8 +3,8 @@ import java.util.function.Supplier; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.EnabledOnCommandRule; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.EnabledOnCommandRule; +import redis.clients.jedis.util.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.After; import org.junit.Before; diff --git a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java index 41d163e202..6d4c53a30b 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java @@ -5,11 +5,17 @@ import java.util.function.Supplier; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersionRule; +import org.junit.ClassRule; +import redis.clients.jedis.util.RedisVersionRule; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.junit.ClassRule; -import redis.clients.jedis.*; +import redis.clients.jedis.Connection; +import redis.clients.jedis.ConnectionPoolConfig; +import redis.clients.jedis.DefaultJedisClientConfig; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.HostAndPorts; +import redis.clients.jedis.JedisClientConfig; +import redis.clients.jedis.JedisCluster; @SinceRedisVersion(value = "7.4.0", message = "Jedis client-side caching is only supported with Redis 7.4 or later.") public class JedisClusterClientSideCacheTest extends UnifiedJedisClientSideCacheTestBase { @@ -26,16 +32,17 @@ public class JedisClusterClientSideCacheTest extends UnifiedJedisClientSideCache return poolConfig; }; - @ClassRule - public static RedisVersionRule versionRule = new RedisVersionRule(hnp.iterator().next(), clientConfig.get()); + @ClassRule + public static RedisVersionRule versionRule = new RedisVersionRule(hnp.iterator().next(), clientConfig.get()); - @Override - protected JedisCluster createRegularJedis() { + @Override + protected JedisCluster createRegularJedis() { return new JedisCluster(hnp, clientConfig.get()); - } + } + + @Override + protected JedisCluster createCachedJedis(CacheConfig cacheConfig) { + return new JedisCluster(hnp, clientConfig.get(), cacheConfig); + } - @Override - protected JedisCluster createCachedJedis(CacheConfig cacheConfig) { - return new JedisCluster(hnp, clientConfig.get(), cacheConfig); - } } diff --git a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java index ed1eaf1b93..65b7efab57 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTest.java @@ -1,7 +1,7 @@ package redis.clients.jedis.csc; import io.redis.test.annotations.SinceRedisVersion; -import io.redis.test.utils.RedisVersionRule; +import redis.clients.jedis.util.RedisVersionRule; import org.junit.BeforeClass; import org.junit.ClassRule; import redis.clients.jedis.HostAndPorts; diff --git a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java index d30ba58ba0..133efcb3fc 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/JedisPooledClientSideCacheTestBase.java @@ -2,8 +2,6 @@ import static org.junit.Assert.assertEquals; -import io.redis.test.utils.RedisVersionRule; -import org.junit.ClassRule; import org.junit.Test; import redis.clients.jedis.EndpointConfig; diff --git a/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java index 136448a73c..7a12394603 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisSentineledClientSideCacheTest.java @@ -9,30 +9,30 @@ import io.redis.test.utils.RedisVersion; import static org.junit.Assume.assumeTrue; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; +import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; public class JedisSentineledClientSideCacheTest extends UnifiedJedisClientSideCacheTestBase { - private static final String MASTER_NAME = "mymaster"; + private static final String MASTER_NAME = "mymaster"; - protected static final HostAndPort sentinel1 = HostAndPorts.getSentinelServers().get(1); - protected static final HostAndPort sentinel2 = HostAndPorts.getSentinelServers().get(3); + protected static final HostAndPort sentinel1 = HostAndPorts.getSentinelServers().get(1); + protected static final HostAndPort sentinel2 = HostAndPorts.getSentinelServers().get(3); - private static final Set sentinels = new HashSet<>(Arrays.asList(sentinel1, sentinel2)); + private static final Set sentinels = new HashSet<>(Arrays.asList(sentinel1, sentinel2)); - private static final JedisClientConfig masterClientConfig = DefaultJedisClientConfig.builder().resp3().password("foobared").build(); + private static final JedisClientConfig masterClientConfig = DefaultJedisClientConfig.builder().resp3().password("foobared").build(); - private static final JedisClientConfig sentinelClientConfig = DefaultJedisClientConfig.builder().resp3().build(); + private static final JedisClientConfig sentinelClientConfig = DefaultJedisClientConfig.builder().resp3().build(); - @Override - protected JedisSentineled createRegularJedis() { - return new JedisSentineled(MASTER_NAME, masterClientConfig, sentinels, sentinelClientConfig); - } + @Override + protected JedisSentineled createRegularJedis() { + return new JedisSentineled(MASTER_NAME, masterClientConfig, sentinels, sentinelClientConfig); + } - @Override - protected JedisSentineled createCachedJedis(CacheConfig cacheConfig) { - return new JedisSentineled(MASTER_NAME, masterClientConfig, cacheConfig, sentinels, sentinelClientConfig); - } + @Override + protected JedisSentineled createCachedJedis(CacheConfig cacheConfig) { + return new JedisSentineled(MASTER_NAME, masterClientConfig, cacheConfig, sentinels, sentinelClientConfig); + } @BeforeClass public static void prepare() { diff --git a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java index 8458e0ffdb..bf89e21b01 100644 --- a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java @@ -11,7 +11,7 @@ import java.nio.file.Path; import static org.junit.Assume.assumeTrue; -import static io.redis.test.utils.RedisVersionUtil.getRedisVersion; +import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; public class SSLJedisPooledClientSideCacheTest extends JedisPooledClientSideCacheTestBase { diff --git a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java b/src/test/java/redis/clients/jedis/util/EnabledOnCommandRule.java similarity index 99% rename from src/test/java/io/redis/test/utils/EnabledOnCommandRule.java rename to src/test/java/redis/clients/jedis/util/EnabledOnCommandRule.java index aa1d540188..b7bde2e51f 100644 --- a/src/test/java/io/redis/test/utils/EnabledOnCommandRule.java +++ b/src/test/java/redis/clients/jedis/util/EnabledOnCommandRule.java @@ -1,4 +1,4 @@ -package io.redis.test.utils; +package redis.clients.jedis.util; import io.redis.test.annotations.EnabledOnCommand; import org.junit.Assume; diff --git a/src/test/java/io/redis/test/utils/RedisVersionRule.java b/src/test/java/redis/clients/jedis/util/RedisVersionRule.java similarity index 93% rename from src/test/java/io/redis/test/utils/RedisVersionRule.java rename to src/test/java/redis/clients/jedis/util/RedisVersionRule.java index abafa6d520..7034710372 100644 --- a/src/test/java/io/redis/test/utils/RedisVersionRule.java +++ b/src/test/java/redis/clients/jedis/util/RedisVersionRule.java @@ -1,6 +1,8 @@ -package io.redis.test.utils; +package redis.clients.jedis.util; import io.redis.test.annotations.SinceRedisVersion; +import io.redis.test.utils.RedisInfo; +import io.redis.test.utils.RedisVersion; import org.junit.Assume; import org.junit.rules.TestRule; import org.junit.runner.Description; @@ -14,16 +16,14 @@ import java.lang.reflect.Method; -import static io.redis.test.utils.RedisVersionUtil.FORCE_REDIS_SERVER_VERSION_ENV; +import static redis.clients.jedis.util.RedisVersionUtil.FORCE_REDIS_SERVER_VERSION_ENV; +import static redis.clients.jedis.util.RedisVersionUtil.forcedVersion; public class RedisVersionRule implements TestRule { private static final Logger logger = LoggerFactory.getLogger(RedisVersionRule.class); private final HostAndPort hostPort; private final JedisClientConfig config; - private static final RedisVersion forcedVersion = System.getenv(FORCE_REDIS_SERVER_VERSION_ENV) != null - ? RedisVersion.of(System.getenv(FORCE_REDIS_SERVER_VERSION_ENV)) - : null; public RedisVersionRule(EndpointConfig endpoint) { diff --git a/src/test/java/io/redis/test/utils/RedisVersionUtil.java b/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java similarity index 89% rename from src/test/java/io/redis/test/utils/RedisVersionUtil.java rename to src/test/java/redis/clients/jedis/util/RedisVersionUtil.java index faeec309ec..fe7de68b5a 100644 --- a/src/test/java/io/redis/test/utils/RedisVersionUtil.java +++ b/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java @@ -1,16 +1,16 @@ -package io.redis.test.utils; +package redis.clients.jedis.util; +import io.redis.test.utils.RedisInfo; +import io.redis.test.utils.RedisVersion; import redis.clients.jedis.*; -import redis.clients.jedis.util.SafeEncoder; - -import java.util.Map; import static redis.clients.jedis.util.TlsUtil.createTrustAllSslSocketFactory; public class RedisVersionUtil { static final String FORCE_REDIS_SERVER_VERSION_ENV = "forceRedisServerVersion"; - private static final RedisVersion forcedVersion = System.getenv(FORCE_REDIS_SERVER_VERSION_ENV) != null + + static final RedisVersion forcedVersion = System.getenv(FORCE_REDIS_SERVER_VERSION_ENV) != null ? RedisVersion.of(System.getenv(FORCE_REDIS_SERVER_VERSION_ENV)) : null; From 551dd60f52e4252fbf42ed18f705c40f94e78895 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:35:27 +0600 Subject: [PATCH 36/44] Update ControlCommandsTest.java --- .../jedis/commands/jedis/ControlCommandsTest.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java index 2ffdbca1d0..a90699f19d 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java @@ -498,22 +498,18 @@ public void commandDocs() { } @Test + @SinceRedisVersion("7.0.0") public void commandGetKeys() { List keys = jedis.commandGetKeys("SORT", "mylist", "ALPHA", "STORE", "outlist"); assertEquals(2, keys.size()); - } - - @Test - @SinceRedisVersion("7.0.0") - public void commandGetKeysAndFlags() { List>> keySandFlags = jedis.commandGetKeysAndFlags("SET", "k1", "v1"); assertEquals("k1", keySandFlags.get(0).getKey()); assertEquals(2, keySandFlags.get(0).getValue().size()); } - @Test + @SinceRedisVersion("7.0.0") public void commandNoArgs() { Map infos = jedis.command(); @@ -535,6 +531,7 @@ public void commandNoArgs() { } @Test + @SinceRedisVersion("7.0.0") public void commandInfo() { Map infos = jedis.commandInfo("GET", "foo", "SET"); @@ -554,7 +551,7 @@ public void commandInfo() { } @Test // GitHub Issue #4020 - @SinceRedisVersion(value = "7.0.0", message = "In Redis 6.2.x ACL flags not empty") + @SinceRedisVersion("7.0.0") public void commandInfoAcl() { Map infos = jedis.commandInfo("ACL"); assertThat(infos, Matchers.aMapWithSize(1)); From 289c1eef3dc27943fbba5096514c63bae1654837 Mon Sep 17 00:00:00 2001 From: ggivo Date: Fri, 29 Nov 2024 09:16:28 +0200 Subject: [PATCH 37/44] Apply suggestions from code review Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- src/test/java/redis/clients/jedis/ACLJedisPoolTest.java | 2 +- .../java/redis/clients/jedis/ClusterPipeliningTest.java | 3 --- src/test/java/redis/clients/jedis/EndpointConfig.java | 2 +- src/test/java/redis/clients/jedis/JedisClusterTest.java | 1 - .../java/redis/clients/jedis/JedisClusterTestBase.java | 2 -- src/test/java/redis/clients/jedis/JedisTest.java | 1 - .../jedis/ClusterShardedPublishSubscribeCommandsTest.java | 7 ------- .../clients/jedis/commands/jedis/SortingCommandsTest.java | 1 - .../java/redis/clients/jedis/util/RedisVersionRule.java | 1 - 9 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java index a019d518d4..8bb1c0acbd 100644 --- a/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java +++ b/src/test/java/redis/clients/jedis/ACLJedisPoolTest.java @@ -28,7 +28,7 @@ public class ACLJedisPoolTest { private static final EndpointConfig endpointWithDefaultUser = HostAndPorts.getRedisEndpoint("standalone0"); @ClassRule - public static RedisVersionRule versionRule = new RedisVersionRule(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder().build()); + public static RedisVersionRule versionRule = new RedisVersionRule(endpoint); @Test public void checkConnections() { diff --git a/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java b/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java index 8b28e7b436..9cae9800f0 100644 --- a/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java +++ b/src/test/java/redis/clients/jedis/ClusterPipeliningTest.java @@ -741,7 +741,6 @@ public void clusterPipelineGeo() { assertTrue(r6.get().size() == 1 && r6.get().get(0).getMemberByString().equals("place1")); assertTrue(r7.get().size() == 1 && r7.get().get(0).getMemberByString().equals("place1")); - GeoRadiusResponse expectedResponse = new GeoRadiusResponse("place1".getBytes()); expectedResponse.setCoordinate(new GeoCoordinate(2.19093829393386841, 41.43379028184083523)); expectedResponse.setDistance(0.0881); @@ -750,8 +749,6 @@ public void clusterPipelineGeo() { assertThat(r8.get().get(0),isEqualToGeoRadiusResponse(expectedResponse)); assertThat(r9.get().get(0),isEqualToGeoRadiusResponse(expectedResponse)); - - assertEquals(Long.valueOf(1), r10.get()); assertTrue(r11.get().size() == 1 && r11.get().contains("place1")); assertTrue(r12.get().size() == 2 && r12.get().get(0).getMemberByString().equals("place2")); diff --git a/src/test/java/redis/clients/jedis/EndpointConfig.java b/src/test/java/redis/clients/jedis/EndpointConfig.java index cae5a2139c..27984577f3 100644 --- a/src/test/java/redis/clients/jedis/EndpointConfig.java +++ b/src/test/java/redis/clients/jedis/EndpointConfig.java @@ -50,11 +50,11 @@ public String getHost() { public int getPort() { return getHostAndPort().getPort(); } + public Boolean isTls() { return tls; } - public int getBdbId() { return bdbId; } public URI getURI() { diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index f5fdce46b3..32fce366f8 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -26,7 +26,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import io.redis.test.annotations.EnabledOnCommand; import io.redis.test.annotations.SinceRedisVersion; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.Test; diff --git a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java index 8720216fae..9fa2b945ab 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java @@ -30,8 +30,6 @@ public abstract class JedisClusterTestBase { public RedisVersionRule versionRule = new RedisVersionRule(nodeInfo1,DefaultJedisClientConfig.builder().password("cluster").build()); @Rule public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); - - @Before public void setUp() throws InterruptedException { node1 = new Jedis(nodeInfo1); diff --git a/src/test/java/redis/clients/jedis/JedisTest.java b/src/test/java/redis/clients/jedis/JedisTest.java index adab12acf4..7e353d3441 100644 --- a/src/test/java/redis/clients/jedis/JedisTest.java +++ b/src/test/java/redis/clients/jedis/JedisTest.java @@ -321,7 +321,6 @@ public void clientSetInfoDefault() { } @Test - @SinceRedisVersion(value = "7.2.0", message = "@see https://redis.io/docs/latest/commands/client-setinfo/") public void clientSetInfoDisabled() { try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder() .clientSetInfoConfig(ClientSetInfoConfig.DISABLED).build())) { diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java index 5a348cd77a..03d421893f 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java @@ -27,7 +27,6 @@ private void publishOne(final String channel, final String message) { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void subscribe() throws InterruptedException { cluster.ssubscribe(new JedisShardedPubSub() { @Override public void onSMessage(String channel, String message) { @@ -52,7 +51,6 @@ public void subscribe() throws InterruptedException { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void subscribeMany() { cluster.ssubscribe(new JedisShardedPubSub() { @Override public void onSMessage(String channel, String message) { @@ -67,7 +65,6 @@ public void subscribeMany() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubChannels() { cluster.ssubscribe(new JedisShardedPubSub() { private int count = 0; @@ -88,7 +85,6 @@ public void pubSubChannels() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubChannelsWithPattern() { cluster.ssubscribe(new JedisShardedPubSub() { private int count = 0; @@ -109,7 +105,6 @@ public void pubSubChannelsWithPattern() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void pubSubNumSub() { final Map expectedNumSub = new HashMap<>(); expectedNumSub.put("{testchannel}1", 1L); @@ -133,7 +128,6 @@ public void pubSubNumSub() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void binarySubscribe() { cluster.ssubscribe(new BinaryJedisShardedPubSub() { @Override public void onSMessage(byte[] channel, byte[] message) { @@ -156,7 +150,6 @@ public void binarySubscribe() { } @Test - @SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") public void binarySubscribeMany() { cluster.ssubscribe(new BinaryJedisShardedPubSub() { @Override public void onSMessage(byte[] channel, byte[] message) { diff --git a/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java index 4ce41722de..91410ce344 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/SortingCommandsTest.java @@ -11,7 +11,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import redis.clients.jedis.Protocol; import redis.clients.jedis.RedisProtocol; import redis.clients.jedis.params.SortingParams; diff --git a/src/test/java/redis/clients/jedis/util/RedisVersionRule.java b/src/test/java/redis/clients/jedis/util/RedisVersionRule.java index 7034710372..0f3c471bae 100644 --- a/src/test/java/redis/clients/jedis/util/RedisVersionRule.java +++ b/src/test/java/redis/clients/jedis/util/RedisVersionRule.java @@ -16,7 +16,6 @@ import java.lang.reflect.Method; -import static redis.clients.jedis.util.RedisVersionUtil.FORCE_REDIS_SERVER_VERSION_ENV; import static redis.clients.jedis.util.RedisVersionUtil.forcedVersion; public class RedisVersionRule implements TestRule { From bc9b0074c6c6bae0b9b67747561c88d6438ba50b Mon Sep 17 00:00:00 2001 From: ggivo Date: Fri, 29 Nov 2024 09:55:48 +0200 Subject: [PATCH 38/44] Addressing review comments --- ...lusterShardedPublishSubscribeCommandsTest.java | 2 +- .../clients/jedis/commands/jedis/ModuleTest.java | 2 +- .../jedis/commands/jedis/StreamsCommandsTest.java | 13 ++++++------- .../jedis/csc/ClientSideCacheTestBase.java | 7 +++---- .../redis/clients/jedis/util/TestEnvUtil.java | 6 +++--- .../java/redis/clients/jedis/util/TlsUtil.java | 15 --------------- 6 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java index 03d421893f..4eba70413c 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterShardedPublishSubscribeCommandsTest.java @@ -18,7 +18,7 @@ import redis.clients.jedis.util.JedisClusterCRC16; import redis.clients.jedis.util.SafeEncoder; -@SinceRedisVersion(value = "7.0.0", message = "SSUBSCRIBE") +@SinceRedisVersion(value = "7.0.0", message = "Sharded Pub/Sub") public class ClusterShardedPublishSubscribeCommandsTest extends ClusterJedisCommandsTestBase { private void publishOne(final String channel, final String message) { diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java index dc84ef2efe..139476e14e 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java @@ -49,7 +49,7 @@ public ModuleTest(RedisProtocol protocol) { @Test public void testModules() { try { - assertEquals("OK", jedis.moduleLoad(TestEnvUtil.testModuleSo())); + assertEquals("OK", jedis.moduleLoad(TestEnvUtil.testModuleSoPath())); List modules = jedis.moduleList(); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java index 7500b984c9..a50aafab2d 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/StreamsCommandsTest.java @@ -160,6 +160,7 @@ public void xaddWithParams() { } @Test + @SinceRedisVersion(value = "7.0.0") public void xaddParamsId() { StreamEntryID id; String key = "kk"; @@ -176,13 +177,11 @@ public void xaddParamsId() { assertEquals(2, id.getTime()); assertEquals(3, id.getSequence()); - // Starting with Redis version 7.0.0: Added support for the -* explicit ID form. - if (RedisVersionUtil.getRedisVersion(jedis).isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { - id = jedis.xadd(key, XAddParams.xAddParams().id(4), map); - assertNotNull(id); - assertEquals(4, id.getTime()); - assertEquals(0, id.getSequence()); - } + id = jedis.xadd(key, XAddParams.xAddParams().id(4), map); + assertNotNull(id); + assertEquals(4, id.getTime()); + assertEquals(0, id.getSequence()); + id = jedis.xadd(key, XAddParams.xAddParams().id("5-6"), map); assertNotNull(id); assertEquals(5, id.getTime()); diff --git a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java index 614d5495b4..5a422c3c5d 100644 --- a/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java +++ b/src/test/java/redis/clients/jedis/csc/ClientSideCacheTestBase.java @@ -22,11 +22,10 @@ public abstract class ClientSideCacheTestBase { protected Jedis control; @Rule - public RedisVersionRule versionRule = new RedisVersionRule( - HostAndPorts.getRedisEndpoint("standalone1")); + public RedisVersionRule versionRule = new RedisVersionRule( HostAndPorts.getRedisEndpoint("standalone1")); + @Rule - public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( - HostAndPorts.getRedisEndpoint("standalone1")); + public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(HostAndPorts.getRedisEndpoint("standalone1")); @Before public void setUp() throws Exception { diff --git a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java index ae72a70fcd..b42223e280 100644 --- a/src/test/java/redis/clients/jedis/util/TestEnvUtil.java +++ b/src/test/java/redis/clients/jedis/util/TestEnvUtil.java @@ -9,13 +9,13 @@ public class TestEnvUtil { public static final String ENV_LOCAL = "local"; private static final String TEST_ENV_PROVIDER = System.getenv().getOrDefault("TEST_ENV_PROVIDER", ENV_DOCKER); - private static final String TESTMODULE_SO = Optional.ofNullable(System.getenv("TESTMODULE_SO")) + private static final String TESTMODULE_SO_PATH = Optional.ofNullable(System.getenv("TESTMODULE_SO")) .orElseGet(() -> isContainerEnv() ? "/redis/work/modules/testmodule.so" : "/tmp/testmodule.so"); - public static String testModuleSo() { - return TESTMODULE_SO; + public static String testModuleSoPath() { + return TESTMODULE_SO_PATH; } public static boolean isContainerEnv() { diff --git a/src/test/java/redis/clients/jedis/util/TlsUtil.java b/src/test/java/redis/clients/jedis/util/TlsUtil.java index dedb89a57b..f014fc6161 100644 --- a/src/test/java/redis/clients/jedis/util/TlsUtil.java +++ b/src/test/java/redis/clients/jedis/util/TlsUtil.java @@ -268,19 +268,4 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) { throw new RuntimeException("Failed to create a trust-all SSL socket factory", e); } } - - public static void main(String[] args) { - try { - - String truststorePassword = null; - - String caCertPath = "./work/redis1-2-5-10-sentinel/work/tls/ca.crt"; - String truststorePath = "./work/redis1-2-5-10-sentinel/work/truststore.jceks"; - Path truststore = createAndSaveTruststore(caCertPath, truststorePath, "change_me"); - System.out.println("Truststore saved at: " + truststore.toAbsolutePath()); - - } catch (Exception e) { - e.printStackTrace(); - } - } } \ No newline at end of file From 4445bf6eb6588dd5b9e6e239c80371693bab9087 Mon Sep 17 00:00:00 2001 From: ggivo Date: Fri, 29 Nov 2024 10:03:44 +0200 Subject: [PATCH 39/44] Update src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- .../jedis/commands/jedis/AllKindOfValuesCommandsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java index 821f61babd..27ac71d43b 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/AllKindOfValuesCommandsTest.java @@ -635,7 +635,7 @@ public void restoreParams() { assertTrue(jedis2.pttl("foo") <= 1000); jedis2.restore("bar", System.currentTimeMillis() + 1000, serialized, RestoreParams.restoreParams().replace().absTtl()); - assertThat("ttl", jedis2.pttl("bar"), lessThanOrEqualTo(1000l + TIME_SKEW)); + assertThat(jedis2.pttl("bar"), lessThanOrEqualTo(1000l + TIME_SKEW)); jedis2.restore("bar1", 1000, serialized, RestoreParams.restoreParams().replace().idleTime(1000)); From a491286013348d5169b972cbb7ad2c329de55389 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:35:06 +0600 Subject: [PATCH 40/44] Undo JedisCommandsTestBase.java formatting only changes --- .../clients/jedis/commands/jedis/JedisCommandsTestBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java index b73e707f19..95b3be34a3 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/JedisCommandsTestBase.java @@ -37,6 +37,7 @@ public static Collection data() { protected final RedisProtocol protocol; protected Jedis jedis; + /** * The RESP protocol is to be injected by the subclasses, usually via JUnit * parameterized tests, because most of the subclassed tests are meant to be @@ -53,8 +54,7 @@ public JedisCommandsTestBase(RedisProtocol protocol) { @Before public void setUp() throws Exception { jedis = new Jedis(endpoint.getHostAndPort(), endpoint.getClientConfigBuilder() - .protocol(protocol) - .timeoutMillis(500).build()); + .protocol(protocol).timeoutMillis(500).build()); jedis.flushAll(); } From 6f299aa329591831c63e0ae743dd504f9daea0d9 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:48:27 +0600 Subject: [PATCH 41/44] Apply suggestions from code review --- src/main/java/redis/clients/jedis/resps/CommandInfo.java | 1 - src/test/java/redis/clients/jedis/JedisClusterTestBase.java | 1 + .../jedis/commands/jedis/ClusterJedisCommandsTestBase.java | 2 +- .../java/redis/clients/jedis/commands/jedis/ModuleTest.java | 2 +- .../commands/unified/cluster/ClusterBitCommandsTest.java | 4 ++-- .../commands/unified/cluster/ClusterCommandsTestHelper.java | 2 +- .../clients/jedis/csc/JedisClusterClientSideCacheTest.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/redis/clients/jedis/resps/CommandInfo.java b/src/main/java/redis/clients/jedis/resps/CommandInfo.java index c1360e97ec..7dd15c8684 100644 --- a/src/main/java/redis/clients/jedis/resps/CommandInfo.java +++ b/src/main/java/redis/clients/jedis/resps/CommandInfo.java @@ -2,7 +2,6 @@ import redis.clients.jedis.Builder; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java index 9fa2b945ab..05e8f3bb70 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTestBase.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTestBase.java @@ -30,6 +30,7 @@ public abstract class JedisClusterTestBase { public RedisVersionRule versionRule = new RedisVersionRule(nodeInfo1,DefaultJedisClientConfig.builder().password("cluster").build()); @Rule public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule(nodeInfo1, DefaultJedisClientConfig.builder().password("cluster").build()); + @Before public void setUp() throws InterruptedException { node1 = new Jedis(nodeInfo1); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java index 232e49b6b9..a0bdf33ac8 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ClusterJedisCommandsTestBase.java @@ -82,7 +82,7 @@ public void setUp() throws InterruptedException { public static void cleanUp() { int slotTest = JedisClusterCRC16.getSlot("test"); int slot51 = JedisClusterCRC16.getSlot("51"); - if (node3 != null ) { + if (node3 != null) { String node3Id = getNodeId(node3.clusterNodes()); node2.clusterSetSlotNode(slotTest, node3Id); node2.clusterSetSlotNode(slot51, node3Id); diff --git a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java index 139476e14e..2bf7c6da1d 100644 --- a/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java +++ b/src/test/java/redis/clients/jedis/commands/jedis/ModuleTest.java @@ -23,7 +23,7 @@ public class ModuleTest extends JedisCommandsTestBase { @BeforeClass public static void checkDockerEnvironment() { - Assume.assumeFalse("Module tests not supported against dockerised test env yet!",TestEnvUtil.isContainerEnv()); + Assume.assumeFalse("Module tests not supported against dockerised test env yet!", TestEnvUtil.isContainerEnv()); } static enum ModuleCommand implements ProtocolCommand { diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java index 2515f5acfe..fa98a7d106 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterBitCommandsTest.java @@ -19,8 +19,8 @@ public class ClusterBitCommandsTest extends BitCommandsTestBase { @Rule public RedisVersionRule versionRule = new RedisVersionRule( - HostAndPorts.getStableClusterServers().get(0) - ,DefaultJedisClientConfig.builder().password("cluster").build()); + HostAndPorts.getStableClusterServers().get(0), + DefaultJedisClientConfig.builder().password("cluster").build()); @Rule public EnabledOnCommandRule enabledOnCommandRule = new EnabledOnCommandRule( HostAndPorts.getStableClusterServers().get(0), diff --git a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java index 9fc35f96ab..6c8f3e25cc 100644 --- a/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java +++ b/src/test/java/redis/clients/jedis/commands/unified/cluster/ClusterCommandsTestHelper.java @@ -14,7 +14,7 @@ static JedisCluster getCleanCluster(RedisProtocol protocol) { clearClusterData(); return new JedisCluster( Collections.singleton(HostAndPorts.getStableClusterServers().get(0)), - DefaultJedisClientConfig.builder().password("cluster").protocol(protocol).build()); + DefaultJedisClientConfig.builder().password("cluster").protocol(protocol).build()); } static void clearClusterData() { diff --git a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java index 6d4c53a30b..ba48afbe6c 100644 --- a/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/JedisClusterClientSideCacheTest.java @@ -33,7 +33,7 @@ public class JedisClusterClientSideCacheTest extends UnifiedJedisClientSideCache }; @ClassRule - public static RedisVersionRule versionRule = new RedisVersionRule(hnp.iterator().next(), clientConfig.get()); + public static RedisVersionRule versionRule = new RedisVersionRule(hnp.iterator().next(), clientConfig.get()); @Override protected JedisCluster createRegularJedis() { From 09ffff5b3f2a708c52563f042bacf34d58f471ec Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 2 Dec 2024 11:31:34 +0200 Subject: [PATCH 42/44] Addressing review comments --- .../redis/clients/jedis/EndpointConfig.java | 13 +++++- .../redis/clients/jedis/SSLACLJedisTest.java | 13 +++--- .../redis/clients/jedis/SSLJedisTest.java | 2 +- .../SSLJedisPooledClientSideCacheTest.java | 2 +- .../clients/jedis/util/RedisVersionUtil.java | 9 ++-- src/test/resources/endpoints.json | 41 ++++++++++++------- src/test/resources/env/docker-compose.yml | 10 ++--- .../config/node-6379-6390/redis.conf | 0 .../config/node-6380/redis.conf | 0 .../config/node-6383-6391/redis.conf | 0 .../config/node-6386/redis.conf | 0 .../node-sentinel-26379-36379/redis.conf | 0 12 files changed, 56 insertions(+), 34 deletions(-) rename src/test/resources/env/{redis1-2-5-10-sentinel => redis1-2-5-8-sentinel}/config/node-6379-6390/redis.conf (100%) rename src/test/resources/env/{redis1-2-5-10-sentinel => redis1-2-5-8-sentinel}/config/node-6380/redis.conf (100%) rename src/test/resources/env/{redis1-2-5-10-sentinel => redis1-2-5-8-sentinel}/config/node-6383-6391/redis.conf (100%) rename src/test/resources/env/{redis1-2-5-10-sentinel => redis1-2-5-8-sentinel}/config/node-6386/redis.conf (100%) rename src/test/resources/env/{redis1-2-5-10-sentinel => redis1-2-5-8-sentinel}/config/node-sentinel-26379-36379/redis.conf (100%) diff --git a/src/test/java/redis/clients/jedis/EndpointConfig.java b/src/test/java/redis/clients/jedis/EndpointConfig.java index 27984577f3..447f0dcd67 100644 --- a/src/test/java/redis/clients/jedis/EndpointConfig.java +++ b/src/test/java/redis/clients/jedis/EndpointConfig.java @@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import redis.clients.jedis.util.JedisURIHelper; +import redis.clients.jedis.util.TlsUtil; import java.io.FileReader; import java.net.URI; @@ -17,14 +18,16 @@ public class EndpointConfig { private final String password; private final int bdbId; private final List endpoints; + private final String environment; - public EndpointConfig(HostAndPort hnp, String username, String password, boolean tls) { + public EndpointConfig(HostAndPort hnp, String username, String password, boolean tls, String environment) { this.tls = tls; this.username = username; this.password = password; this.bdbId = 0; this.endpoints = Collections.singletonList( URI.create(getURISchema(tls) + hnp.getHost() + ":" + hnp.getPort())); + this.environment = environment; } public HostAndPort getHostAndPort() { @@ -61,6 +64,10 @@ public URI getURI() { return endpoints.get(0); } + public String getEnvironment() { + return environment; + } + public class EndpointURIBuilder { private boolean tls; @@ -116,6 +123,10 @@ public DefaultJedisClientConfig.Builder getClientConfigBuilder() { DefaultJedisClientConfig.Builder builder = DefaultJedisClientConfig.builder() .password(password).ssl(tls); + if (tls & environment != null) { + builder.sslSocketFactory(TlsUtil.sslSocketFactoryForEnv(environment)); + } + if (username != null) { return builder.user(username); } diff --git a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java index 06b6fa1f79..6297298310 100644 --- a/src/test/java/redis/clients/jedis/SSLACLJedisTest.java +++ b/src/test/java/redis/clients/jedis/SSLACLJedisTest.java @@ -1,5 +1,6 @@ package redis.clients.jedis; +import static org.junit.Assume.assumeTrue; import static redis.clients.jedis.util.RedisVersionUtil.getRedisVersion; import static org.junit.Assert.*; import static redis.clients.jedis.util.TlsUtil.*; @@ -26,10 +27,10 @@ public class SSLACLJedisTest { @BeforeClass public static void prepare() { - Path trusStorePath = createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + Path trusStorePath = createAndSaveEnvTruststore("redis1-2-5-8-sentinel", "changeit"); TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); // Use to check if the ACL test should be ran. ACL are available only in 6.0 and later - org.junit.Assume.assumeTrue("Not running ACL test on this version of Redis", + assumeTrue("Not running ACL test on this version of Redis", getRedisVersion(endpoint).isGreaterThanOrEqualTo(RedisVersion.V6_0_0)); } @@ -42,7 +43,7 @@ public static void teardownTrustStore() { public void connectWithSsl() { try (Jedis jedis = new Jedis(endpoint.getHost(), endpoint.getPort(), DefaultJedisClientConfig.builder() - .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-8-sentinel")) .ssl(true) .build())) { jedis.auth(endpoint.getUsername(), endpoint.getPassword()); @@ -54,7 +55,7 @@ public void connectWithSsl() { public void connectWithConfig() { try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), DefaultJedisClientConfig.builder() - .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-8-sentinel")) .ssl(true).build())) { jedis.auth(endpoint.getUsername(), endpoint.getPassword()); assertEquals("PONG", jedis.ping()); @@ -81,13 +82,13 @@ public void connectWithUri() { endpointWithDefaultUser.getURIBuilder() .defaultCredentials().build(), DefaultJedisClientConfig.builder() - .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-8-sentinel")) .build())) { assertEquals("PONG", jedis.ping()); } try (Jedis jedis = new Jedis(endpoint.getURIBuilder().defaultCredentials().build(), DefaultJedisClientConfig.builder() - .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-10-sentinel")) + .sslSocketFactory(sslSocketFactoryForEnv("redis1-2-5-8-sentinel")) .build())) { assertEquals("PONG", jedis.ping()); } diff --git a/src/test/java/redis/clients/jedis/SSLJedisTest.java b/src/test/java/redis/clients/jedis/SSLJedisTest.java index 89a448fd30..8e0fed6252 100644 --- a/src/test/java/redis/clients/jedis/SSLJedisTest.java +++ b/src/test/java/redis/clients/jedis/SSLJedisTest.java @@ -19,7 +19,7 @@ public class SSLJedisTest { @BeforeClass public static void prepare() { - Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-8-sentinel", "changeit"); TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); } diff --git a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java index bf89e21b01..015abf2719 100644 --- a/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java +++ b/src/test/java/redis/clients/jedis/csc/SSLJedisPooledClientSideCacheTest.java @@ -17,7 +17,7 @@ public class SSLJedisPooledClientSideCacheTest extends JedisPooledClientSideCach @BeforeClass public static void prepare() { - Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-10-sentinel", "changeit"); + Path trusStorePath = TlsUtil.createAndSaveEnvTruststore("redis1-2-5-8-sentinel", "changeit"); TlsUtil.setCustomTrustStore(trusStorePath, "changeit"); endpoint = HostAndPorts.getRedisEndpoint("standalone0-tls"); diff --git a/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java b/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java index fe7de68b5a..480a89f3a3 100644 --- a/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java +++ b/src/test/java/redis/clients/jedis/util/RedisVersionUtil.java @@ -4,8 +4,6 @@ import io.redis.test.utils.RedisVersion; import redis.clients.jedis.*; -import static redis.clients.jedis.util.TlsUtil.createTrustAllSslSocketFactory; - public class RedisVersionUtil { static final String FORCE_REDIS_SERVER_VERSION_ENV = "forceRedisServerVersion"; @@ -51,10 +49,9 @@ public static RedisVersion getRedisVersion(EndpointConfig endpoint) { } DefaultJedisClientConfig.Builder builder = endpoint.getClientConfigBuilder(); - if (endpoint.isTls()) { - builder.sslSocketFactory(createTrustAllSslSocketFactory()); - } - try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), builder.build())) { + DefaultJedisClientConfig clientConfig = builder.build(); + + try (Jedis jedis = new Jedis(endpoint.getHostAndPort(), clientConfig)) { return getRedisVersion(jedis); } } diff --git a/src/test/resources/endpoints.json b/src/test/resources/endpoints.json index c1d905bfb8..75211f14fd 100644 --- a/src/test/resources/endpoints.json +++ b/src/test/resources/endpoints.json @@ -4,7 +4,8 @@ "tls": false, "endpoints": [ "redis://localhost:6379" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone0-tls": { "username": "default", @@ -12,7 +13,8 @@ "tls": true, "endpoints": [ "rediss://localhost:6390" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone0-acl": { "username": "acljedis", @@ -20,7 +22,8 @@ "tls": false, "endpoints": [ "redis://localhost:6379" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone0-acl-tls": { "username": "acljedis", @@ -28,7 +31,8 @@ "tls": true, "endpoints": [ "rediss://localhost:6390" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone1": { "username": "default", @@ -36,7 +40,8 @@ "tls": false, "endpoints": [ "redis://localhost:6380" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone2-primary": { "username": "default", @@ -44,7 +49,8 @@ "tls": false, "endpoints": [ "redis://localhost:6381" - ] + ], + "environment": "redis3-4-sentinel" }, "standalone3-replica-of-standalone2": { "username": "default", @@ -52,7 +58,8 @@ "tls": false, "endpoints": [ "redis://localhost:6382" - ] + ], + "environment": "redis3-4-sentinel" }, "standalone4-replica-of-standalone1": { "username": "default", @@ -60,7 +67,8 @@ "tls": false, "endpoints": [ "redis://localhost:6383" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone5-primary": { "username": "default", @@ -68,7 +76,8 @@ "tls": false, "endpoints": [ "redis://localhost:6384" - ] + ], + "environment": "redis6-7-sentinel" }, "standalone6-replica-of-standalone5": { "username": "default", @@ -76,7 +85,8 @@ "tls": false, "endpoints": [ "redis://localhost:6385" - ] + ], + "environment": "redis6-7-sentinel" }, "standalone7-with-lfu-policy": { "username": "default", @@ -84,19 +94,22 @@ "tls": false, "endpoints": [ "redis://localhost:6386" - ] + ], + "environment": "redis1-2-5-8-sentinel" }, "standalone9": { "tls": false, "endpoints": [ "redis://localhost:6388" - ] + ], + "environment": "redis10-11" }, "standalone10-replica-of-standalone9": { "tls": false, "endpoints": [ "redis://localhost:6389" - ] + ], + "environment": "redis10-11" }, "modules-docker": { "tls": false, @@ -104,4 +117,4 @@ "redis://localhost:6479" ] } -} \ No newline at end of file +} diff --git a/src/test/resources/env/docker-compose.yml b/src/test/resources/env/docker-compose.yml index c6bab9b2fd..0b81a666cd 100644 --- a/src/test/resources/env/docker-compose.yml +++ b/src/test/resources/env/docker-compose.yml @@ -1,9 +1,9 @@ services: - redis1-2-5-10-sentinel: + redis1-2-5-8-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 image: "${CLIENT_LIBS_TEST_IMAGE}:${REDIS_VERSION:-8.0-M01}" - container_name: redis1-2-5-10-sentinel + container_name: redis1-2-5-8-sentinel #network_mode: host environment: - REDIS_CLUSTER=no @@ -20,8 +20,8 @@ services: - "36379:36379" # sentinel tls command: ${ENABLE_MODULE_COMMAND_DIRECTIVE} volumes: - - ${REDIS_ENV_CONF_DIR}/redis1-2-5-10-sentinel/config:/redis/config:r - - ${REDIS_ENV_WORK_DIR}/redis1-2-5-10-sentinel/work:/redis/work:rw + - ${REDIS_ENV_CONF_DIR}/redis1-2-5-8-sentinel/config:/redis/config:r + - ${REDIS_ENV_WORK_DIR}/redis1-2-5-8-sentinel/work:/redis/work:rw redis3-4-sentinel: sysctls: - net.ipv6.conf.all.disable_ipv6=1 @@ -157,4 +157,4 @@ services: # command: redis-server /etc/redis.conf # volumes: # - "./redis_uds/config/node-0/redis.conf:/etc/redis.conf" -# - "./work/redis_uds/work:/tmp/docker/" \ No newline at end of file +# - "./work/redis_uds/work:/tmp/docker/" diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf b/src/test/resources/env/redis1-2-5-8-sentinel/config/node-6379-6390/redis.conf similarity index 100% rename from src/test/resources/env/redis1-2-5-10-sentinel/config/node-6379-6390/redis.conf rename to src/test/resources/env/redis1-2-5-8-sentinel/config/node-6379-6390/redis.conf diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf b/src/test/resources/env/redis1-2-5-8-sentinel/config/node-6380/redis.conf similarity index 100% rename from src/test/resources/env/redis1-2-5-10-sentinel/config/node-6380/redis.conf rename to src/test/resources/env/redis1-2-5-8-sentinel/config/node-6380/redis.conf diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf b/src/test/resources/env/redis1-2-5-8-sentinel/config/node-6383-6391/redis.conf similarity index 100% rename from src/test/resources/env/redis1-2-5-10-sentinel/config/node-6383-6391/redis.conf rename to src/test/resources/env/redis1-2-5-8-sentinel/config/node-6383-6391/redis.conf diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf b/src/test/resources/env/redis1-2-5-8-sentinel/config/node-6386/redis.conf similarity index 100% rename from src/test/resources/env/redis1-2-5-10-sentinel/config/node-6386/redis.conf rename to src/test/resources/env/redis1-2-5-8-sentinel/config/node-6386/redis.conf diff --git a/src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf b/src/test/resources/env/redis1-2-5-8-sentinel/config/node-sentinel-26379-36379/redis.conf similarity index 100% rename from src/test/resources/env/redis1-2-5-10-sentinel/config/node-sentinel-26379-36379/redis.conf rename to src/test/resources/env/redis1-2-5-8-sentinel/config/node-sentinel-26379-36379/redis.conf From eae2f4f1c494ebd3aab556d0e62332b38a2a4dbb Mon Sep 17 00:00:00 2001 From: ggivo Date: Mon, 2 Dec 2024 11:33:04 +0200 Subject: [PATCH 43/44] Update src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- .../jedis/commands/commandobjects/CommandObjectsTestBase.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java index fac2d9efc2..f8cd24724c 100644 --- a/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java +++ b/src/test/java/redis/clients/jedis/commands/commandobjects/CommandObjectsTestBase.java @@ -86,13 +86,11 @@ public void setUp() { commandExecutor.executeCommand(commandObjects.flushAll()), equalTo("OK")); - if ( RedisVersionUtil - .getRedisVersion(endpoint) + if (RedisVersionUtil.getRedisVersion(endpoint) .isGreaterThanOrEqualTo(RedisVersion.V7_0_0)) { assertThat( commandExecutor.executeCommand(commandObjects.functionFlush(FlushMode.SYNC)), equalTo("OK")); - } } From 5bf942e42ce4f6c21a201e2119c90675451d2363 Mon Sep 17 00:00:00 2001 From: ggivo Date: Wed, 4 Dec 2024 11:54:32 +0200 Subject: [PATCH 44/44] Update src/test/java/redis/clients/jedis/EndpointConfig.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- src/test/java/redis/clients/jedis/EndpointConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/EndpointConfig.java b/src/test/java/redis/clients/jedis/EndpointConfig.java index 447f0dcd67..866f9b67f9 100644 --- a/src/test/java/redis/clients/jedis/EndpointConfig.java +++ b/src/test/java/redis/clients/jedis/EndpointConfig.java @@ -123,7 +123,7 @@ public DefaultJedisClientConfig.Builder getClientConfigBuilder() { DefaultJedisClientConfig.Builder builder = DefaultJedisClientConfig.builder() .password(password).ssl(tls); - if (tls & environment != null) { + if (tls && environment != null) { builder.sslSocketFactory(TlsUtil.sslSocketFactoryForEnv(environment)); }