diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java index 245ffc77bcb0d..74f344693b5f5 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/client/deployment/devmode/IncrementResource.java @@ -18,7 +18,7 @@ public IncrementResource(RedisDataSource ds) { @GET public int increment() { - return (int) commands.incrby("counter", INCREMENT); + return (int) commands.incrby("counter-dev-mode", INCREMENT); } } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchArgs.java index e4ebbe5e86c93..2070507f362c3 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchArgs.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchArgs.java @@ -212,12 +212,12 @@ public List toArgs(Codec codec) { if (radius > 0) { list.add("BYRADIUS"); list.add(Double.toString(radius)); - list.add(unit.name()); + list.add(unit.toString()); } else { list.add("BYBOX"); list.add(Double.toString(width)); list.add(Double.toString(height)); - list.add(unit.name()); + list.add(unit.toString()); } if (direction != null) { diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchStoreArgs.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchStoreArgs.java index 661956928331c..5443316b8ff13 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchStoreArgs.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoSearchStoreArgs.java @@ -174,12 +174,12 @@ public List toArgs(Codec codec) { if (radius > 0) { list.add("BYRADIUS"); list.add(Double.toString(radius)); - list.add(unit.name()); + list.add(unit.toString()); } else { list.add("BYBOX"); list.add(Double.toString(width)); list.add(Double.toString(height)); - list.add(unit.name()); + list.add(unit.toString()); } if (direction != null) { diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoUnit.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoUnit.java index 129c6669d73a0..7670e433d6bff 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoUnit.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/geo/GeoUnit.java @@ -1,5 +1,7 @@ package io.quarkus.redis.datasource.geo; +import java.util.Locale; + public enum GeoUnit { /** @@ -21,4 +23,9 @@ public enum GeoUnit { * mile. */ MI; + + public String toString() { + // Redis 6 requires lower case, uppercase has only been added in Redis 7. + return name().toLowerCase(Locale.ROOT); + } } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java index e710bb1fb2091..9550a98db6542 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java @@ -103,7 +103,7 @@ Uni _geodist(K key, V from, V to, GeoUnit unit) { .put(marshaller.encode(key)) .put(marshaller.encode(from)) .put(marshaller.encode(to)) - .put(unit.name())); + .put(unit.toString())); } Uni _geohash(K key, V... members) { @@ -142,7 +142,7 @@ Uni _georadius(K key, double longitude, double latitude, double radius return execute(RedisCommand.of(Command.GEORADIUS) .put(marshaller.encode(key)).put(longitude).put(latitude).put(radius) - .put(unit.name())); + .put(unit.toString())); } Uni _georadius(K key, double longitude, double latitude, double radius, GeoUnit unit, @@ -155,7 +155,7 @@ Uni _georadius(K key, double longitude, double latitude, double radius nonNull(geoArgs, "geoArgs"); return execute(RedisCommand.of(Command.GEORADIUS) .put(marshaller.encode(key)).put(longitude).put(latitude).put(radius) - .put(unit.name()) + .put(unit.toString()) .putArgs(geoArgs)); } @@ -169,7 +169,7 @@ Uni _georadius(K key, double longitude, double latitude, double radius nonNull(geoArgs, "geoArgs"); return execute(RedisCommand.of(Command.GEORADIUS) .put(marshaller.encode(key)).put(longitude).put(latitude).put(radius) - .put(unit.name()) + .put(unit.toString()) .putArgs(geoArgs, keyCodec)); } @@ -180,7 +180,7 @@ Uni _georadiusbymember(K key, V member, double distance, GeoUnit unit, nonNull(unit, "unit"); nonNull(geoArgs, "geoArgs"); return execute(RedisCommand.of(Command.GEORADIUSBYMEMBER).put(marshaller.encode(key)).put(marshaller.encode(member)) - .put(distance).put(unit.name()) + .put(distance).put(unit.toString()) .putArgs(geoArgs)); } @@ -190,7 +190,7 @@ Uni _georadiusbymember(K key, V member, double distance, GeoUnit unit) positive(distance, "distance"); nonNull(unit, "unit"); return execute(RedisCommand.of(Command.GEORADIUSBYMEMBER).put(marshaller.encode(key)) - .put(marshaller.encode(member)).put(distance).put(unit.name())); + .put(marshaller.encode(member)).put(distance).put(unit.toString())); } Uni _georadiusbymember(K key, V member, double distance, GeoUnit unit, GeoRadiusStoreArgs geoArgs) { @@ -201,7 +201,7 @@ Uni _georadiusbymember(K key, V member, double distance, GeoUnit unit, nonNull(geoArgs, "geoArgs"); return execute(RedisCommand.of(Command.GEORADIUSBYMEMBER).put(marshaller.encode(key)) .put(marshaller.encode(member)) - .put(distance).put(unit.name()) + .put(distance).put(unit.toString()) .putArgs(geoArgs, keyCodec)); } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/DatasourceTestBase.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/DatasourceTestBase.java index b2fc89e096926..60380b44dd6d5 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/DatasourceTestBase.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/DatasourceTestBase.java @@ -8,8 +8,10 @@ import org.testcontainers.utility.DockerImageName; import io.vertx.mutiny.core.Vertx; +import io.vertx.mutiny.redis.client.Command; import io.vertx.mutiny.redis.client.Redis; import io.vertx.mutiny.redis.client.RedisAPI; +import io.vertx.mutiny.redis.client.Request; public class DatasourceTestBase { @@ -20,7 +22,7 @@ public class DatasourceTestBase { public static RedisAPI api; static GenericContainer server = new GenericContainer<>( - DockerImageName.parse("redis:7-alpine")) + DockerImageName.parse(System.getProperty("redis.base.image", "redis:7-alpine"))) .withExposedPorts(6379); @BeforeAll @@ -39,4 +41,12 @@ static void cleanup() { vertx.closeAndAwait(); } + public static String getRedisVersion() { + String info = redis.send(Request.cmd(Command.INFO)).await().indefinitely().toString(); + // Look for the redis_version line + return info.lines().filter(s -> s.startsWith("redis_version")).findAny() + .map(line -> line.split(":")[1]) + .orElseThrow(); + } + } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java index 613f41a0a5754..4164db8eb88df 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/KeyCommandsTest.java @@ -129,6 +129,7 @@ void expire() { } @Test + @RequiresRedis7OrHigher void expireWithArgs() { assertThat(keys.expire(key, 10, new ExpireArgs().xx())).isFalse(); strings.set(key, Person.person7); @@ -153,6 +154,7 @@ void expireat() { } @Test + @RequiresRedis7OrHigher void expireatWithArgs() { Date expiration = new Date(System.currentTimeMillis() + 10000); assertThat(keys.expireat(key, expiration.toInstant().getEpochSecond(), new ExpireArgs().xx())).isFalse(); @@ -217,6 +219,7 @@ void pexpire() { } @Test + @RequiresRedis7OrHigher void pexpireWithArgs() { assertThat(keys.pexpire(key, 5000, new ExpireArgs().xx())).isFalse(); strings.set(key, Person.person7); @@ -230,6 +233,7 @@ void pexpireWithArgs() { } @Test + @RequiresRedis7OrHigher void pexpireWithDuration() { assertThat(keys.pexpire(key, Duration.ofSeconds(5))).isFalse(); strings.set(key, Person.person7); @@ -253,6 +257,7 @@ void pexpireat() { } @Test + @RequiresRedis7OrHigher void pexpireatWithArgs() { Instant expiration = new Date(System.currentTimeMillis() + 5000).toInstant(); assertThat(keys.pexpireat(key, expiration.getEpochSecond(), new ExpireArgs().xx())).isFalse(); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ListCommandTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ListCommandTest.java index 1bfd7a616181c..a9453a3651698 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ListCommandTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/ListCommandTest.java @@ -42,6 +42,7 @@ void blpop() { } @Test + @RequiresRedis7OrHigher void blmpop() { lists.rpush("two", Person.person1, Person.person2, Person.person3); assertThat(lists.blmpop(Duration.ofSeconds(1), Position.RIGHT, "one", "two")) @@ -54,6 +55,7 @@ void blmpop() { } @Test + @RequiresRedis7OrHigher void blmpopMany() { lists.rpush("two", Person.person1, Person.person2, Person.person3); assertThat(lists.blmpop(Duration.ofSeconds(1), Position.RIGHT, 2, "one", "two")) @@ -130,6 +132,7 @@ void lpop() { } @Test + @RequiresRedis7OrHigher void lmpop() { assertThat(lists.lmpop(Position.RIGHT, key)).isNull(); lists.rpush(key, Person.person1, Person.person2); @@ -138,6 +141,7 @@ void lmpop() { } @Test + @RequiresRedis7OrHigher void lmpopMany() { assertThat(lists.lmpop(Position.RIGHT, 2, key)).isEmpty(); lists.rpush(key, Person.person1, Person.person2); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/Redis7OrHigherCondition.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/Redis7OrHigherCondition.java new file mode 100644 index 0000000000000..bcdbc6a6fb5f4 --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/Redis7OrHigherCondition.java @@ -0,0 +1,35 @@ +package io.quarkus.redis.datasource; + +import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled; +import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled; + +import java.util.Optional; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +class Redis7OrHigherCondition implements ExecutionCondition { + + private static final ConditionEvaluationResult ENABLED_BY_DEFAULT = enabled("@RequiresRedis7OrHigher is not present"); + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + Optional optional = AnnotationUtils.findAnnotation(context.getElement(), + RequiresRedis7OrHigher.class); + + if (optional.isPresent()) { + String version = DatasourceTestBase.getRedisVersion(); + + return isRedis7orHigher(version) ? enabled("Redis " + version + " >= 7") + : disabled("Disabled, Redis " + version + " < 7"); + } + + return ENABLED_BY_DEFAULT; + } + + public static boolean isRedis7orHigher(String version) { + return Integer.parseInt(version.split("\\.")[0]) >= 7; + } +} diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/RequiresRedis7OrHigher.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/RequiresRedis7OrHigher.java new file mode 100644 index 0000000000000..a2300b4e2a1fa --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/RequiresRedis7OrHigher.java @@ -0,0 +1,18 @@ +package io.quarkus.redis.datasource; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@ExtendWith(Redis7OrHigherCondition.class) +@interface RequiresRedis7OrHigher { + + // Important the class must extend DatasourceTestBase. +} diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SetCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SetCommandsTest.java index 021c697c902fe..6918ef84c2b9d 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SetCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SetCommandsTest.java @@ -71,6 +71,7 @@ void sdiffstore() { } @Test + @RequiresRedis7OrHigher // because of sintercard void sinter() { populate(); assertThat(sets.sinter("key1", "key2", "key3")).isEqualTo(Set.of(person3)); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java index 9e6d105c80da8..ed1d232ce4bd4 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java @@ -231,6 +231,7 @@ void zincrby() { } @Test + @RequiresRedis7OrHigher void zintercard() { setOfPlaces.zadd("zset1", Map.of(Place.crussol, 1.0, Place.grignan, 2.0)); setOfPlaces.zadd("zset2", Map.of(Place.crussol, 2.0, Place.grignan, 1.0)); @@ -729,6 +730,7 @@ public void zmscore() { } @Test + @RequiresRedis7OrHigher public void zmpopMin() { assertThat(setOfPlaces.zmpopMin("zset1")).isEqualTo(null); @@ -749,6 +751,7 @@ public void zmpopMin() { } @Test + @RequiresRedis7OrHigher public void zmpopMax() { assertThat(setOfPlaces.zmpopMax("zset1")).isEqualTo(null); @@ -769,6 +772,7 @@ public void zmpopMax() { } @Test + @RequiresRedis7OrHigher public void bzmpopMin() { assertThat(setOfPlaces.bzmpopMin(Duration.ofSeconds(1), "zset1")).isEqualTo(null); @@ -791,6 +795,7 @@ public void bzmpopMin() { } @Test + @RequiresRedis7OrHigher public void bzmpopMax() { assertThat(setOfPlaces.bzmpopMax(Duration.ofSeconds(1), "zset1")).isEqualTo(null); diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java index e5a0a1572984a..f7d583e131664 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/StringCommandsTest.java @@ -251,6 +251,7 @@ void strlen() { } @Test + @RequiresRedis7OrHigher void lcs() { strings.mset(Map.of("key1", "ohmytext", "key2", "mynewtext")); assertThat(strings.lcs("key1", "key2")).isEqualTo("mytext");