diff --git a/pom.xml b/pom.xml index 49a7370a5d..346a9e17e7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-redis - 3.2.0-SNAPSHOT + 3.2.0-GH-2612-SNAPSHOT Spring Data Redis Spring Data module for Redis @@ -25,7 +25,7 @@ 1.4.20 2.11.1 6.2.6.RELEASE - 4.4.4 + 5.0.1 1.01 4.1.96.Final spring.data.redis diff --git a/src/main/java/org/springframework/data/redis/connection/FutureResult.java b/src/main/java/org/springframework/data/redis/connection/FutureResult.java index e869f77147..0ff9dabb7a 100644 --- a/src/main/java/org/springframework/data/redis/connection/FutureResult.java +++ b/src/main/java/org/springframework/data/redis/connection/FutureResult.java @@ -21,22 +21,25 @@ import org.springframework.lang.Nullable; /** - * The result of an asynchronous operation + * Result of an asynchronous operation * + * @param The data type of the object that holds the future result (usually type of the + * {@link java.util.concurrent.Future} or response wrapper). * @author Jennifer Hickey * @author Christoph Strobl * @author Mark Paluch - * @param The data type of the object that holds the future result (usually type of the - * {@link java.util.concurrent.Future} or response wrapper). + * @author John Blum */ public abstract class FutureResult { - private T resultHolder; + private boolean status = false; + + private final T resultHolder; + private final Supplier defaultConversionResult; - private boolean status = false; - @SuppressWarnings("rawtypes") // + @SuppressWarnings("rawtypes") protected Converter converter; /** @@ -71,6 +74,7 @@ public FutureResult(T resultHolder, @Nullable Converter converter) { * @param defaultConversionResult must not be {@literal null}. * @since 2.1 */ + @SuppressWarnings("rawtypes") public FutureResult(T resultHolder, @Nullable Converter converter, Supplier defaultConversionResult) { this.resultHolder = resultHolder; @@ -78,16 +82,6 @@ public FutureResult(T resultHolder, @Nullable Converter converter, Supplier d this.defaultConversionResult = defaultConversionResult; } - /** - * Get the object holding the actual result. - * - * @return never {@literal null}. - * @since 1.1 - */ - public T getResultHolder() { - return resultHolder; - } - /** * Converts the given result if a converter is specified, else returns the result * @@ -98,11 +92,9 @@ public T getResultHolder() { @Nullable public Object convert(@Nullable Object result) { - if (result == null) { - return computeDefaultResult(null); - } + Object resolvedResult = result != null ? getConverter().convert(result) : null; - return computeDefaultResult(converter.convert(result)); + return computeDefaultResult(resolvedResult); } @Nullable @@ -112,7 +104,17 @@ private Object computeDefaultResult(@Nullable Object source) { @SuppressWarnings("rawtypes") public Converter getConverter() { - return converter; + return this.converter; + } + + /** + * Get the object holding the actual result. + * + * @return never {@literal null}. + * @since 1.1 + */ + public T getResultHolder() { + return this.resultHolder; } /** @@ -121,7 +123,7 @@ public Converter getConverter() { * @return true if this is a status result (i.e. OK) */ public boolean isStatus() { - return status; + return this.status; } /** @@ -144,4 +146,5 @@ public void setStatus(boolean status) { * @since 2.1 */ public abstract boolean conversionRequired(); + } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java index 06bbf2a569..f53c6cbbb6 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java @@ -30,13 +30,15 @@ import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** + * Cluster {@link RedisHashCommands} implementation for Jedis. + * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum * @since 2.0 */ class JedisClusterHashCommands implements RedisHashCommands { @@ -160,10 +162,10 @@ public Entry hRandFieldWithValues(byte[] key) { Assert.notNull(key, "Key must not be null"); try { - Map map = connection.getCluster().hrandfieldWithValues(key, 1); - return map.isEmpty() ? null : map.entrySet().iterator().next(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + List> mapEntryList = connection.getCluster().hrandfieldWithValues(key, 1); + return mapEntryList.isEmpty() ? null : mapEntryList.get(0); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -185,10 +187,9 @@ public List hRandField(byte[] key, long count) { public List> hRandFieldWithValues(byte[] key, long count) { try { - Map map = connection.getCluster().hrandfieldWithValues(key, count); - return Streamable.of(() -> map.entrySet().iterator()).toList(); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return connection.getCluster().hrandfieldWithValues(key, count); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java index 43b83bf874..0acc10af59 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java @@ -15,12 +15,11 @@ */ package org.springframework.data.redis.connection.jedis; -import redis.clients.jedis.Jedis; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.concurrent.TimeUnit; @@ -38,9 +37,14 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import redis.clients.jedis.Jedis; + /** + * {@link RedisClusterServerCommands} implementation for Jedis. + * * @author Mark Paluch * @author Dennis Neufeld + * @author John Blum * @since 2.0 */ class JedisClusterServerCommands implements RedisClusterServerCommands { @@ -82,7 +86,8 @@ public Long lastSave() { return null; } - Collections.sort(result, Collections.reverseOrder()); + result.sort(Collections.reverseOrder()); + return result.get(0); } @@ -221,7 +226,7 @@ public Properties info(RedisClusterNode node, String section) { public void shutdown() { connection.getClusterCommandExecutor().executeCommandOnAllNodes((JedisClusterCommandCallback) jedis -> { jedis.shutdown(); - return null; + return "success"; }); } @@ -229,12 +234,12 @@ public void shutdown() { public void shutdown(RedisClusterNode node) { executeCommandOnSingleNode(jedis -> { jedis.shutdown(); - return null; + return "success"; }, node); } @Override - public void shutdown(ShutdownOption option) { + public void shutdown(@Nullable ShutdownOption option) { if (option == null) { shutdown(); @@ -249,21 +254,26 @@ public Properties getConfig(String pattern) { Assert.notNull(pattern, "Pattern must not be null"); - List>> mapResult = connection.getClusterCommandExecutor() - .executeCommandOnAllNodes((JedisClusterCommandCallback>) client -> client.configGet(pattern)) + JedisClusterCommandCallback> command = jedis -> jedis.configGet(pattern); + + List>> nodeResults = connection.getClusterCommandExecutor() + .executeCommandOnAllNodes(command) .getResults(); - List result = new ArrayList<>(); - for (NodeResult> entry : mapResult) { + Properties nodesConfiguration = new Properties(); + + for (NodeResult> nodeResult : nodeResults) { + + String prefix = nodeResult.getNode().asString(); - String prefix = entry.getNode().asString(); - int i = 0; - for (String value : entry.getValue()) { - result.add((i++ % 2 == 0 ? (prefix + ".") : "") + value); + for (Entry entry : nodeResult.getValue().entrySet()) { + String newKey = prefix.concat(".").concat(entry.getKey()); + String value = entry.getValue(); + nodesConfiguration.setProperty(newKey, value); } } - return Converters.toProperties(result); + return nodesConfiguration; } @Override @@ -271,10 +281,10 @@ public Properties getConfig(RedisClusterNode node, String pattern) { Assert.notNull(pattern, "Pattern must not be null"); + JedisClusterCommandCallback command = client -> Converters.toProperties(client.configGet(pattern)); + return connection.getClusterCommandExecutor() - .executeCommandOnSingleNode( - (JedisClusterCommandCallback) client -> Converters.toProperties(client.configGet(pattern)), - node) + .executeCommandOnSingleNode(command, node) .getValue(); } @@ -322,19 +332,19 @@ public void rewriteConfig(RedisClusterNode node) { @Override public Long time(TimeUnit timeUnit) { - return convertListOfStringToTime( - connection.getClusterCommandExecutor() - .executeCommandOnArbitraryNode((JedisClusterCommandCallback>) Jedis::time).getValue(), - timeUnit); + JedisClusterCommandCallback> command = Jedis::time; + + return convertListOfStringToTime(connection.getClusterCommandExecutor() + .executeCommandOnArbitraryNode(command).getValue(), timeUnit); } @Override public Long time(RedisClusterNode node, TimeUnit timeUnit) { - return convertListOfStringToTime( - connection.getClusterCommandExecutor() - .executeCommandOnSingleNode((JedisClusterCommandCallback>) Jedis::time, node).getValue(), - timeUnit); + JedisClusterCommandCallback> command = Jedis::time; + + return convertListOfStringToTime(connection.getClusterCommandExecutor() + .executeCommandOnSingleNode(command, node).getValue(), timeUnit); } @Override @@ -343,8 +353,9 @@ public void killClient(String host, int port) { Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'"); String hostAndPort = String.format("%s:%s", host, port); - connection.getClusterCommandExecutor() - .executeCommandOnAllNodes((JedisClusterCommandCallback) client -> client.clientKill(hostAndPort)); + JedisClusterCommandCallback command = jedis -> jedis.clientKill(hostAndPort); + + connection.getClusterCommandExecutor().executeCommandOnAllNodes(command); } @Override @@ -360,21 +371,26 @@ public String getClientName() { @Override public List getClientList() { + JedisClusterCommandCallback command = Jedis::clientList; + Collection map = connection.getClusterCommandExecutor() - .executeCommandOnAllNodes((JedisClusterCommandCallback) Jedis::clientList).resultsAsList(); + .executeCommandOnAllNodes(command).resultsAsList(); ArrayList result = new ArrayList<>(); + for (String infos : map) { result.addAll(JedisConverters.toListOfRedisClientInformation(infos)); } + return result; } @Override public List getClientList(RedisClusterNode node) { - return JedisConverters - .toListOfRedisClientInformation(executeCommandOnSingleNode(Jedis::clientList, node).getValue()); + JedisClusterCommandCallback command = Jedis::clientList; + + return JedisConverters.toListOfRedisClientInformation(executeCommandOnSingleNode(command, node).getValue()); } @Override @@ -403,8 +419,10 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable Migrate RedisClusterNode node = connection.getTopologyProvider().getTopology().lookup(target.getHost(), target.getPort()); - executeCommandOnSingleNode(client -> client.migrate(target.getHost(), target.getPort(), key, dbIndex, timeoutToUse), - node); + JedisClusterCommandCallback command = jedis -> + jedis.migrate(target.getHost(), target.getPort(), key, dbIndex, timeoutToUse); + + executeCommandOnSingleNode(command, node); } private Long convertListOfStringToTime(List serverTimeInformation, TimeUnit timeUnit) { @@ -416,12 +434,11 @@ private Long convertListOfStringToTime(List serverTimeInformation, TimeU return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1), timeUnit); } - private NodeResult executeCommandOnSingleNode(JedisClusterCommandCallback cmd, RedisClusterNode node) { - return connection.getClusterCommandExecutor().executeCommandOnSingleNode(cmd, node); + private NodeResult executeCommandOnSingleNode(JedisClusterCommandCallback command, RedisClusterNode node) { + return connection.getClusterCommandExecutor().executeCommandOnSingleNode(command, node); } - private MultiNodeResult executeCommandOnAllNodes(JedisClusterCommandCallback cmd) { - return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd); + private MultiNodeResult executeCommandOnAllNodes(JedisClusterCommandCallback command) { + return connection.getClusterCommandExecutor().executeCommandOnAllNodes(command); } - } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStreamCommands.java index 11223cb2d5..3e76aea917 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStreamCommands.java @@ -15,14 +15,14 @@ */ package org.springframework.data.redis.connection.jedis; -import static org.springframework.data.redis.connection.jedis.StreamConverters.*; - import redis.clients.jedis.BuilderFactory; import redis.clients.jedis.params.XAddParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XPendingParams; import redis.clients.jedis.params.XReadGroupParams; import redis.clients.jedis.params.XReadParams; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -42,10 +42,15 @@ import org.springframework.data.redis.connection.stream.StreamInfo; import org.springframework.data.redis.connection.stream.StreamOffset; import org.springframework.data.redis.connection.stream.StreamReadOptions; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** + * {@link RedisStreamCommands} implementation for Jedis. + * * @author Dengliming + * @author John Blum * @since 2.3 */ class JedisClusterStreamCommands implements RedisStreamCommands { @@ -65,9 +70,9 @@ public Long xAck(byte[] key, String group, RecordId... recordIds) { try { return connection.getCluster().xack(key, JedisConverters.toBytes(group), - entryIdsToBytes(Arrays.asList(recordIds))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + StreamConverters.entryIdsToBytes(Arrays.asList(recordIds))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -80,10 +85,10 @@ public RecordId xAdd(MapRecord record, XAddOptions optio XAddParams params = StreamConverters.toXAddParams(record.getId(), options); try { - return RecordId - .of(JedisConverters.toString(connection.getCluster().xadd(record.getStream(), record.getValue(), params))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return RecordId.of(JedisConverters.toString(connection.getCluster() + .xadd(record.getStream(), record.getValue(), params))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -94,20 +99,24 @@ public List xClaimJustId(byte[] key, String group, String newOwner, XC Assert.notNull(group, "Group must not be null"); Assert.notNull(newOwner, "NewOwner must not be null"); - long minIdleTime = options.getMinIdleTime() == null ? -1L : options.getMinIdleTime().toMillis(); + long minIdleTime = nullSafeMilliseconds(options.getMinIdleTime()); XClaimParams xClaimParams = StreamConverters.toXClaimParams(options); + try { List ids = connection.getCluster().xclaimJustId(key, JedisConverters.toBytes(group), - JedisConverters.toBytes(newOwner), minIdleTime, xClaimParams, entryIdsToBytes(options.getIds())); + JedisConverters.toBytes(newOwner), minIdleTime, xClaimParams, + StreamConverters.entryIdsToBytes(options.getIds())); List recordIds = new ArrayList<>(ids.size()); + ids.forEach(it -> recordIds.add(RecordId.of(JedisConverters.toString(it)))); return recordIds; - } catch (Exception ex) { - throw convertJedisAccessException(ex); + + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -118,14 +127,16 @@ public List xClaim(byte[] key, String group, String newOwner, XClaim Assert.notNull(group, "Group must not be null"); Assert.notNull(newOwner, "NewOwner must not be null"); - long minIdleTime = options.getMinIdleTime() == null ? -1L : options.getMinIdleTime().toMillis(); + long minIdleTime = nullSafeMilliseconds(options.getMinIdleTime()); XClaimParams xClaimParams = StreamConverters.toXClaimParams(options); + try { - return convertToByteRecord(key, connection.getCluster().xclaim(key, JedisConverters.toBytes(group), - JedisConverters.toBytes(newOwner), minIdleTime, xClaimParams, entryIdsToBytes(options.getIds()))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return StreamConverters.convertToByteRecord(key, connection.getCluster().xclaim(key, + JedisConverters.toBytes(group), JedisConverters.toBytes(newOwner), minIdleTime, xClaimParams, + StreamConverters.entryIdsToBytes(options.getIds()))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -136,9 +147,9 @@ public Long xDel(byte[] key, RecordId... recordIds) { Assert.notNull(recordIds, "recordIds must not be null"); try { - return connection.getCluster().xdel(key, entryIdsToBytes(Arrays.asList(recordIds))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return connection.getCluster().xdel(key, StreamConverters.entryIdsToBytes(Arrays.asList(recordIds))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -157,8 +168,8 @@ public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, try { return connection.getCluster().xgroupCreate(key, JedisConverters.toBytes(groupName), JedisConverters.toBytes(readOffset.getOffset()), mkStream); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -171,8 +182,8 @@ public Boolean xGroupDelConsumer(byte[] key, Consumer consumer) { try { return connection.getCluster().xgroupDelConsumer(key, JedisConverters.toBytes(consumer.getGroup()), JedisConverters.toBytes(consumer.getName())) != 0L; - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -184,20 +195,21 @@ public Boolean xGroupDestroy(byte[] key, String groupName) { try { return connection.getCluster().xgroupDestroy(key, JedisConverters.toBytes(groupName)) != 0L; - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @Override + @SuppressWarnings("unchecked") public StreamInfo.XInfoStream xInfo(byte[] key) { Assert.notNull(key, "Key must not be null"); try { - return StreamInfo.XInfoStream.fromList((List) connection.getCluster().xinfoStream(key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return StreamInfo.XInfoStream.fromList((List) connection.getCluster().xinfoStream(key)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -208,8 +220,8 @@ public StreamInfo.XInfoGroups xInfoGroups(byte[] key) { try { return StreamInfo.XInfoGroups.fromList(connection.getCluster().xinfoGroups(key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -222,8 +234,8 @@ public StreamInfo.XInfoConsumers xInfoConsumers(byte[] key, String groupName) { try { return StreamInfo.XInfoConsumers.fromList(groupName, connection.getCluster().xinfoConsumers(key, JedisConverters.toBytes(groupName))); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -234,8 +246,8 @@ public Long xLen(byte[] key) { try { return connection.getCluster().xlen(key); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -252,13 +264,14 @@ public PendingMessagesSummary xPending(byte[] key, String groupName) { Object response = connection.getCluster().xpending(key, group); return StreamConverters.toPendingMessagesSummary(groupName, response); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @Override + @SuppressWarnings("unchecked") public PendingMessages xPending(byte[] key, String groupName, XPendingOptions options) { Assert.notNull(key, "Key must not be null"); @@ -269,14 +282,25 @@ public PendingMessages xPending(byte[] key, String groupName, XPendingOptions op try { - List response = connection.getCluster().xpending(key, group, - JedisConverters.toBytes(getLowerValue(range)), JedisConverters.toBytes(getUpperValue(range)), - options.getCount().intValue(), JedisConverters.toBytes(options.getConsumerName())); + @SuppressWarnings("all") + XPendingParams pendingParams = new XPendingParams( + JedisConverters.toBytes(StreamConverters.getLowerValue(range)), + JedisConverters.toBytes(StreamConverters.getUpperValue(range)), + options.getCount().intValue()); + + String consumerName = options.getConsumerName(); + + if (StringUtils.hasText(consumerName)) { + pendingParams = pendingParams.consumer(consumerName); + } + + List response = connection.getCluster().xpending(key, group, pendingParams); return StreamConverters.toPendingMessages(groupName, range, BuilderFactory.STREAM_PENDING_ENTRY_LIST.build(response)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -290,14 +314,16 @@ public List xRange(byte[] key, Range range, Limit limit) { int count = limit.isUnlimited() ? Integer.MAX_VALUE : limit.getCount(); try { - return convertToByteRecord(key, connection.getCluster().xrange(key, JedisConverters.toBytes(getLowerValue(range)), - JedisConverters.toBytes(getUpperValue(range)), count)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return StreamConverters.convertToByteRecord(key, connection.getCluster().xrange(key, + JedisConverters.toBytes(StreamConverters.getLowerValue(range)), + JedisConverters.toBytes(StreamConverters.getUpperValue(range)), count)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @Override + @SuppressWarnings("unchecked") public List xRead(StreamReadOptions readOptions, StreamOffset... streams) { Assert.notNull(readOptions, "StreamReadOptions must not be null"); @@ -307,19 +333,20 @@ public List xRead(StreamReadOptions readOptions, StreamOffset xread = connection.getCluster().xread(xReadParams, toStreamOffsets(streams)); + List xread = connection.getCluster().xread(xReadParams, StreamConverters.toStreamOffsets(streams)); if (xread == null) { return Collections.emptyList(); } return StreamConverters.convertToByteRecords(xread); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @Override + @SuppressWarnings("unchecked") public List xReadGroup(Consumer consumer, StreamReadOptions readOptions, StreamOffset... streams) { @@ -332,15 +359,15 @@ public List xReadGroup(Consumer consumer, StreamReadOptions readOpti try { List xread = connection.getCluster().xreadGroup(JedisConverters.toBytes(consumer.getGroup()), - JedisConverters.toBytes(consumer.getName()), xReadParams, toStreamOffsets(streams)); + JedisConverters.toBytes(consumer.getName()), xReadParams, StreamConverters.toStreamOffsets(streams)); if (xread == null) { return Collections.emptyList(); } return StreamConverters.convertToByteRecords(xread); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -354,10 +381,11 @@ public List xRevRange(byte[] key, Range range, Limit limit) int count = limit.isUnlimited() ? Integer.MAX_VALUE : limit.getCount(); try { - return convertToByteRecord(key, connection.getCluster().xrevrange(key, - JedisConverters.toBytes(getUpperValue(range)), JedisConverters.toBytes(getLowerValue(range)), count)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return StreamConverters.convertToByteRecord(key, connection.getCluster().xrevrange(key, + JedisConverters.toBytes(StreamConverters.getUpperValue(range)), + JedisConverters.toBytes(StreamConverters.getLowerValue(range)), count)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -373,13 +401,16 @@ public Long xTrim(byte[] key, long count, boolean approximateTrimming) { try { return connection.getCluster().xtrim(key, count, approximateTrimming); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } - private DataAccessException convertJedisAccessException(Exception ex) { - return connection.convertJedisAccessException(ex); + private DataAccessException convertJedisAccessException(Exception cause) { + return connection.convertJedisAccessException(cause); } + private long nullSafeMilliseconds(@Nullable Duration duration) { + return duration != null ? duration.toMillis() : -1L; + } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java index 4d0923e43d..a63acfedca 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java @@ -20,6 +20,7 @@ import redis.clients.jedis.params.ZParams; import redis.clients.jedis.params.ZRangeParams; import redis.clients.jedis.resps.ScanResult; +import redis.clients.jedis.util.KeyValue; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -34,7 +35,6 @@ import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.convert.SetConverter; import org.springframework.data.redis.connection.zset.Aggregate; -import org.springframework.data.redis.connection.zset.DefaultTuple; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.Cursor; @@ -46,18 +46,22 @@ import org.springframework.util.Assert; /** + * Cluster {@link RedisZSetCommands} implementation for Jedis. + * * @author Christoph Strobl * @author Mark Paluch * @author Clement Ong * @author Andrey Shlykov * @author Jens Deppe * @author Shyngys Sapraliyev + * @author John Blum * @since 2.0 */ class JedisClusterZSetCommands implements RedisZSetCommands { - private static final SetConverter TUPLE_SET_CONVERTER = new SetConverter<>( - JedisConverters::toTuple); + private static final SetConverter TUPLE_SET_CONVERTER = + new SetConverter<>(JedisConverters::toTuple); + private final JedisClusterConnection connection; JedisClusterZSetCommands(JedisClusterConnection connection) { @@ -349,8 +353,8 @@ public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { try { return toTuple(connection.getCluster().bzpopmin(JedisConverters.toSeconds(timeout, unit), key)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -816,11 +820,10 @@ public Set zDiff(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return connection.getCluster().zdiff(sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(connection.getCluster().zdiff(sets)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -833,11 +836,10 @@ public Set zDiffWithScores(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return JedisConverters.toTupleSet(connection.getCluster().zdiffWithScores(sets)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster().zdiffWithScores(sets))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -870,11 +872,10 @@ public Set zInter(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return connection.getCluster().zinter(new ZParams(), sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(connection.getCluster().zinter(new ZParams(), sets)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -887,11 +888,11 @@ public Set zInterWithScores(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return JedisConverters.toTupleSet(connection.getCluster().zinterWithScores(new ZParams(), sets)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() + .zinterWithScores(new ZParams(), sets))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -907,12 +908,11 @@ public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]. .format("The number of weights (%d) must match the number of source sets (%d)", weights.size(), sets.length)); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return JedisConverters - .toTupleSet(connection.getCluster().zinterWithScores(toZParams(aggregate, weights), sets)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() + .zinterWithScores(toZParams(aggregate, weights), sets))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -969,11 +969,10 @@ public Set zUnion(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return connection.getCluster().zunion(new ZParams(), sets); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(connection.getCluster().zunion(new ZParams(), sets)); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -986,11 +985,11 @@ public Set zUnionWithScores(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return JedisConverters.toTupleSet(connection.getCluster().zunionWithScores(new ZParams(), sets)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() + .zunionWithScores(new ZParams(), sets))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -1006,12 +1005,11 @@ public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]. .format("The number of weights (%d) must match the number of source sets (%d)", weights.size(), sets.length)); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { - try { - return JedisConverters - .toTupleSet(connection.getCluster().zunionWithScores(toZParams(aggregate, weights), sets)); - } catch (Exception ex) { - throw convertJedisAccessException(ex); + return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() + .zunionWithScores(toZParams(aggregate, weights), sets))); + } catch (Exception cause) { + throw convertJedisAccessException(cause); } } @@ -1126,21 +1124,14 @@ private static ZParams toZParams(Aggregate aggregate, Weights weights) { return new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); } - /** - * Workaround for broken Jedis BZPOP signature. - * - * @param bytes - * @return - */ @Nullable - @SuppressWarnings("unchecked") - private static Tuple toTuple(@Nullable List bytes) { + private static Tuple toTuple(@Nullable KeyValue keyValue) { - if (bytes == null || bytes.isEmpty()) { - return null; + if (keyValue != null) { + redis.clients.jedis.resps.Tuple tuple = keyValue.getValue(); + return tuple != null ? JedisConverters.toTuple(tuple) : null; } - return new DefaultTuple((byte[]) bytes.get(1), Double.parseDouble(new String((byte[]) bytes.get(2)))); + return null; } - } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index eaa1b5ba4e..32ee6f6df4 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -59,9 +59,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import redis.clients.jedis.BuilderFactory; import redis.clients.jedis.CommandArguments; import redis.clients.jedis.CommandObject; @@ -130,6 +127,7 @@ public class JedisConnection extends AbstractRedisConnection { private final Log LOGGER = LogFactory.getLog(getClass()); + @SuppressWarnings("rawtypes") private List pipelinedResults = new ArrayList<>(); private final @Nullable Pool pool; @@ -211,7 +209,7 @@ private Object doInvoke(boolean status, Function directFunction, Function> pipelineFunction, Converter converter, Supplier nullDefault) { - return doWithJedis(it -> { + return doWithJedis(jedis -> { if (isQueueing()) { @@ -227,7 +225,7 @@ private Object doInvoke(boolean status, Function directFunction, return null; } - Object result = directFunction.apply(getJedis()); + Object result = directFunction.apply(jedis); if (result == null) { return nullDefault.get(); @@ -348,7 +346,6 @@ public void close() throws DataAccessException { jedis.close(); } else { - doExceptionThrowingOperationSafely(jedis::quit, "Failed to quit during close"); doExceptionThrowingOperationSafely(jedis::disconnect, "Failed to disconnect during close"); } } @@ -381,7 +378,7 @@ public void openPipeline() { } if (pipeline == null) { - pipeline = jedis.pipelined(); + pipeline = getJedis().pipelined(); } } @@ -414,7 +411,8 @@ private List convertPipelineResults() { Object data = result.get(); if (!result.isStatus()) { - results.add(result.conversionRequired() ? result.convert(data) : data); + Object resolvedData = result.conversionRequired() ? result.convert(data) : data; + results.add(resolvedData); } } catch (JedisDataException e) { DataAccessException dataAccessException = convertJedisAccessException(e); @@ -480,6 +478,7 @@ public void discard() { public List exec() { try { + if (transaction == null) { throw new InvalidDataAccessApiUsageException("No ongoing transaction; Did you forget to call multi"); } @@ -489,6 +488,7 @@ public List exec() { return !CollectionUtils.isEmpty(results) ? new TransactionResultConverter<>(txResults, JedisExceptionConverter.INSTANCE).convert(results) : results; + } catch (Exception cause) { throw convertJedisAccessException(cause); } finally { @@ -551,17 +551,20 @@ JedisInvoker invokeStatus() { } JedisResult newJedisResult(Response response) { - return JedisResultBuilder. forResponse(response).build(); + return JedisResultBuilder.forResponse(response).build(); } JedisResult newJedisResult(Response response, Converter converter, Supplier defaultValue) { - return JedisResultBuilder. forResponse(response).mappedWith(converter) - .convertPipelineAndTxResults(convertPipelineAndTxResults).mapNullTo(defaultValue).build(); + return JedisResultBuilder.forResponse(response) + .convertPipelineAndTxResults(this.convertPipelineAndTxResults) + .mapNullTo(defaultValue) + .mappedWith(converter) + .build(); } JedisStatusResult newStatusResult(Response response) { - return JedisResultBuilder. forResponse(response).buildStatusResult(); + return JedisResultBuilder.forResponse(response).buildStatusResult(); } @Override diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java index 88b8a5eb4d..7abc23019e 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java @@ -35,6 +35,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -87,6 +88,8 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import redis.clients.jedis.util.SafeEncoder; + /** * Jedis type converters. * @@ -114,12 +117,22 @@ abstract class JedisConverters extends Converters { MINUS_BYTES = toBytes("-"); POSITIVE_INFINITY_BYTES = toBytes("+inf"); NEGATIVE_INFINITY_BYTES = toBytes("-inf"); + + } + + @Nullable + static Set toSet(@Nullable List list) { + return list != null ? new LinkedHashSet<>(list) : null; } - public static Converter stringToBytes() { + static Converter stringToBytes() { return JedisConverters::toBytes; } + static ListConverter stringListToByteList() { + return new ListConverter<>(stringToBytes()); + } + /** * {@link ListConverter} converting jedis {@link redis.clients.jedis.resps.Tuple} to {@link Tuple}. * @@ -129,16 +142,16 @@ static ListConverter tuplesToTuples() { return new ListConverter<>(JedisConverters::toTuple); } - static ListConverter stringListToByteList() { - return new ListConverter<>(stringToBytes()); + static Tuple toTuple(redis.clients.jedis.resps.Tuple source) { + return new DefaultTuple(source.getBinaryElement(), source.getScore()); } - static Set toTupleSet(Set source) { - return new SetConverter<>(JedisConverters::toTuple).convert(source); + static List toTupleList(List source) { + return tuplesToTuples().convert(source); } - public static Tuple toTuple(redis.clients.jedis.resps.Tuple source) { - return new DefaultTuple(source.getBinaryElement(), source.getScore()); + static Set toTupleSet(Set source) { + return new SetConverter<>(JedisConverters::toTuple).convert(source); } /** @@ -255,6 +268,7 @@ public static byte[][] toByteArrays(Map source) { public static SortingParams toSortingParams(@Nullable SortParameters params) { SortingParams jedisParams = null; + if (params != null) { jedisParams = new SortingParams(); byte[] byPattern = params.getByPattern(); @@ -278,6 +292,7 @@ public static SortingParams toSortingParams(@Nullable SortParameters params) { jedisParams.alpha(); } } + return jedisParams; } @@ -386,8 +401,10 @@ public static SetParams toSetCommandExPxArgument(Expiration expiration, SetParam * @since 2.6 */ static GetExParams toGetExParams(Expiration expiration) { + return toGetExParams(expiration, new GetExParams()); + } - GetExParams params = new GetExParams(); + static GetExParams toGetExParams(Expiration expiration, GetExParams params) { if (expiration.isPersistent()) { return params.persist(); @@ -584,18 +601,14 @@ static ZAddParams toZAddParams(ZAddArgs source) { return new ZAddParams(); } - ZAddParams target = new ZAddParams() { - - { - if (source.contains(ZAddArgs.Flag.GT)) { - addParam("gt"); - } - if (source.contains(ZAddArgs.Flag.LT)) { - addParam("lt"); - } - } - }; + ZAddParams target = new ZAddParams(); + if (source.contains(ZAddArgs.Flag.GT)) { + target.gt(); + } + if (source.contains(ZAddArgs.Flag.LT)) { + target.lt(); + } if (source.contains(ZAddArgs.Flag.XX)) { target.xx(); } @@ -605,6 +618,7 @@ static ZAddParams toZAddParams(ZAddArgs source) { if (source.contains(ZAddArgs.Flag.CH)) { target.ch(); } + return target; } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java index 4efaf0c85c..419d19d3f8 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java @@ -37,8 +37,11 @@ import org.springframework.util.Assert; /** + * {@link RedisHashCommands} implementation for Jedis. + * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum * @since 2.0 */ class JedisHashCommands implements RedisHashCommands { @@ -122,7 +125,7 @@ public Entry hRandFieldWithValues(byte[] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(Jedis::hrandfieldWithValues, PipelineBinaryCommands::hrandfieldWithValues, key, 1L) - .get(it -> it.isEmpty() ? null : it.entrySet().iterator().next()); + .get(mapEntryList -> mapEntryList.isEmpty() ? null : mapEntryList.get(0)); } @Nullable @@ -141,12 +144,16 @@ public List> hRandFieldWithValues(byte[] key, long count) Assert.notNull(key, "Key must not be null"); return connection.invoke() - .from(Jedis::hrandfieldWithValues, PipelineBinaryCommands::hrandfieldWithValues, key, count).get(it -> { + .from(Jedis::hrandfieldWithValues, PipelineBinaryCommands::hrandfieldWithValues, key, count) + .get(mapEntryList -> { + + List> convertedMapEntryList = new ArrayList<>(mapEntryList.size()); + + mapEntryList.forEach(entry -> + convertedMapEntryList.add(Converters.entryOf(entry.getKey(), entry.getValue()))); - List> entries = new ArrayList<>(it.size()); - it.forEach((k, v) -> entries.add(Converters.entryOf(k, v))); + return convertedMapEntryList; - return entries; }); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java index 805efabe4b..b049274240 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java @@ -17,7 +17,6 @@ import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; -import redis.clients.jedis.Queable; import redis.clients.jedis.Response; import redis.clients.jedis.Transaction; import redis.clients.jedis.commands.DatabasePipelineCommands; @@ -47,7 +46,7 @@ * composing a functional pipeline to transform the result using a {@link Converter}. *

* Usage example: - * + *

*

  * JedisInvoker invoker = …;
  *
@@ -62,6 +61,7 @@
  *
  * @author Mark Paluch
  * @author Christoph Strobl
+ * @author John Blum
  * @since 2.5
  */
 class JedisInvoker {
@@ -82,7 +82,7 @@  R just(ConnectionFunction0 function) {
 
 		Assert.notNull(function, "ConnectionFunction must not be null");
 
-		return synchronizer.invoke(function::apply, it -> {
+		return synchronizer.invoke(function::apply, responseCommands -> {
 			throw new InvalidDataAccessApiUsageException("Operation not supported by Jedis in pipelining/transaction mode");
 		}, Converters.identityConverter(), () -> null);
 	}
@@ -115,7 +115,8 @@  R just(ConnectionFunction1 function, PipelineFunction1 pip
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return synchronizer.invoke(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1));
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1));
 	}
 
 	/**
@@ -133,7 +134,8 @@  R just(ConnectionFunction2 function, PipelineFunction2 function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2));
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1, t2),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2));
 	}
 
 	/**
@@ -152,7 +154,8 @@  R just(ConnectionFunction3 function, PipelineFunc
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return synchronizer.invoke(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3));
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1, t2, t3),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3));
 	}
 
 	/**
@@ -172,7 +175,7 @@  R just(ConnectionFunction4 function,
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return synchronizer.invoke(it -> function.apply(it, t1, t2, t3, t4),
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1, t2, t3, t4),
 				it -> pipelineFunction.apply(it, t1, t2, t3, t4));
 	}
 
@@ -194,7 +197,7 @@  R just(ConnectionFunction5 functi
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return synchronizer.invoke(it -> function.apply(it, t1, t2, t3, t4, t5),
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1, t2, t3, t4, t5),
 				it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5));
 	}
 
@@ -217,8 +220,8 @@  R just(ConnectionFunction6 function.apply(it, t1, t2, t3, t4, t5, t6),
-				it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6));
+		return synchronizer.invoke(jedis -> function.apply(jedis, t1, t2, t3, t4, t5, t6),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4, t5, t6));
 	}
 
 	/**
@@ -265,7 +268,7 @@  SingleInvocationSpec from(ConnectionFunction1 function, Pipeli
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return from(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1));
+		return from(jedis -> function.apply(jedis, t1), responseCommands -> pipelineFunction.apply(responseCommands, t1));
 	}
 
 	/**
@@ -283,7 +286,8 @@  SingleInvocationSpec from(ConnectionFunction2 function
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return from(it -> function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2));
+		return from(jedis -> function.apply(jedis, t1, t2),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2));
 	}
 
 	/**
@@ -302,7 +306,8 @@  SingleInvocationSpec from(ConnectionFunction3
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return from(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3));
+		return from(jedis -> function.apply(jedis, t1, t2, t3),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3));
 	}
 
 	/**
@@ -322,7 +327,8 @@  SingleInvocationSpec from(ConnectionFunction4 function.apply(it, t1, t2, t3, t4), it -> pipelineFunction.apply(it, t1, t2, t3, t4));
+		return from(jedis -> function.apply(jedis, t1, t2, t3, t4),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4));
 	}
 
 	/**
@@ -343,7 +349,8 @@  SingleInvocationSpec from(ConnectionFunction5 function.apply(it, t1, t2, t3, t4, t5), it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5));
+		return from(jedis -> function.apply(jedis, t1, t2, t3, t4, t5),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4, t5));
 	}
 
 	/**
@@ -365,8 +372,8 @@  SingleInvocationSpec from(ConnectionFunction6 function.apply(it, t1, t2, t3, t4, t5, t6),
-				it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6));
+		return from(jedis -> function.apply(jedis, t1, t2, t3, t4, t5, t6),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4, t5, t6));
 	}
 
 	/**
@@ -414,7 +421,8 @@ , E, T1> ManyInvocationSpec fromMany(ConnectionFuncti
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1), it -> pipelineFunction.apply(it, t1));
+		return fromMany(jedis -> function.apply(jedis, t1),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1));
 	}
 
 	/**
@@ -432,7 +440,8 @@ , E, T1, T2> ManyInvocationSpec fromMany(ConnectionFu
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1, t2), it -> pipelineFunction.apply(it, t1, t2));
+		return fromMany(jedis -> function.apply(jedis, t1, t2),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2));
 	}
 
 	/**
@@ -451,7 +460,8 @@ , E, T1, T2, T3> ManyInvocationSpec fromMany(Connecti
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1, t2, t3), it -> pipelineFunction.apply(it, t1, t2, t3));
+		return fromMany(jedis -> function.apply(jedis, t1, t2, t3),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3));
 	}
 
 	/**
@@ -472,7 +482,8 @@ , E, T1, T2, T3, T4> ManyInvocationSpec fromMany(
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1, t2, t3, t4), it -> pipelineFunction.apply(it, t1, t2, t3, t4));
+		return fromMany(jedis -> function.apply(jedis, t1, t2, t3, t4),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4));
 	}
 
 	/**
@@ -494,7 +505,8 @@ , E, T1, T2, T3, T4, T5> ManyInvocationSpec fromMany(
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1, t2, t3, t4, t5), it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5));
+		return fromMany(jedis -> function.apply(jedis, t1, t2, t3, t4, t5),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4, t5));
 	}
 
 	/**
@@ -517,8 +529,8 @@ , E, T1, T2, T3, T4, T5, T6> ManyInvocationSpec fromM
 		Assert.notNull(function, "ConnectionFunction must not be null");
 		Assert.notNull(pipelineFunction, "PipelineFunction must not be null");
 
-		return fromMany(it -> function.apply(it, t1, t2, t3, t4, t5, t6),
-				it -> pipelineFunction.apply(it, t1, t2, t3, t4, t5, t6));
+		return fromMany(jedis -> function.apply(jedis, t1, t2, t3, t4, t5, t6),
+				responseCommands -> pipelineFunction.apply(responseCommands, t1, t2, t3, t4, t5, t6));
 	}
 
 	/**
@@ -937,10 +949,7 @@ static class DefaultSingleInvocationSpec implements SingleInvocationSpec {
 
 		@Override
 		public  T get(Converter converter) {
-
-			Assert.notNull(converter, "Converter must not be null");
-
-			return synchronizer.invoke(parentFunction, parentPipelineFunction, converter, () -> null);
+			return getOrElse(converter, () -> null);
 		}
 
 		@Nullable
@@ -959,6 +968,7 @@ static class DefaultManyInvocationSpec implements ManyInvocationSpec {
 		private final Function>> parentPipelineFunction;
 		private final Synchronizer synchronizer;
 
+		@SuppressWarnings({ "rawtypes", "unchecked" })
 		DefaultManyInvocationSpec(Function> parentFunction,
 				Function>> parentPipelineFunction,
 				Synchronizer synchronizer) {
@@ -969,6 +979,7 @@ static class DefaultManyInvocationSpec implements ManyInvocationSpec {
 		}
 
 		@Override
+		@SuppressWarnings("all")
 		public  List toList(Converter converter) {
 
 			Assert.notNull(converter, "Converter must not be null");
@@ -981,15 +992,17 @@ public  List toList(Converter converter) {
 
 				List result = new ArrayList<>(source.size());
 
-				for (S s : source) {
-					result.add(converter.convert(s));
+				for (S element : source) {
+					result.add(converter.convert(element));
 				}
 
 				return result;
+
 			}, Collections::emptyList);
 		}
 
 		@Override
+		@SuppressWarnings("all")
 		public  Set toSet(Converter converter) {
 
 			Assert.notNull(converter, "Converter must not be null");
@@ -1002,11 +1015,12 @@ public  Set toSet(Converter converter) {
 
 				Set result = new LinkedHashSet<>(source.size());
 
-				for (S s : source) {
-					result.add(converter.convert(s));
+				for (S element : source) {
+					result.add(converter.convert(element));
 				}
 
 				return result;
+
 			}, Collections::emptySet);
 		}
 	}
@@ -1020,6 +1034,7 @@ interface Synchronizer {
 		@Nullable
 		@SuppressWarnings({ "unchecked", "rawtypes" })
 		default  T invoke(Function callFunction, Function> pipelineFunction) {
+
 			return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, Converters.identityConverter(),
 					() -> null);
 		}
@@ -1046,15 +1061,13 @@ interface ResponseCommands extends PipelineBinaryCommands, DatabasePipelineComma
 	/**
 	 * Create a proxy to invoke methods dynamically on {@link Pipeline} or {@link Transaction} as those share many
 	 * commands that are not defined on a common super-type.
-	 *
-	 * @param pipelineOrTransaction
-	 * @return
 	 */
-	static ResponseCommands createCommands(Queable pipelineOrTransaction) {
+	static ResponseCommands createCommands(Object pipelineOrTransaction) {
 
 		ProxyFactory proxyFactory = new ProxyFactory(pipelineOrTransaction);
+
 		proxyFactory.addInterface(ResponseCommands.class);
+
 		return (ResponseCommands) proxyFactory.getProxy(JedisInvoker.class.getClassLoader());
 	}
-
 }
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java
index 3f96bb0b91..7e7e95e425 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java
@@ -24,24 +24,21 @@
 import org.springframework.lang.Nullable;
 
 /**
- * Jedis specific {@link FutureResult} implementation. 
+ * {@link FutureResult} implementation for Jedis. * + * @param The data type of the object that holds the future result (usually of type Future). + * @param The data type of the result type. * @author Costin Leau * @author Jennifer Hickey * @author Christoph Strobl * @author Mark Paluch - * @param The data type of the object that holds the future result (usually of type Future). - * @param The data type of the result type. + * @author John Blum * @since 2.1 */ class JedisResult extends FutureResult> { private final boolean convertPipelineAndTxResults; - JedisResult(Response resultHolder) { - this(resultHolder, false, null); - } - JedisResult(Response resultHolder, boolean convertPipelineAndTxResults, @Nullable Converter converter) { this(resultHolder, () -> null, convertPipelineAndTxResults, converter); } @@ -50,6 +47,7 @@ class JedisResult extends FutureResult> { @Nullable Converter converter) { super(resultHolder, converter, defaultReturnValue); + this.convertPipelineAndTxResults = convertPipelineAndTxResults; } @@ -61,7 +59,7 @@ public T get() { } public boolean conversionRequired() { - return convertPipelineAndTxResults; + return this.convertPipelineAndTxResults; } /** @@ -69,10 +67,10 @@ public boolean conversionRequired() { */ static class JedisStatusResult extends JedisResult { - @SuppressWarnings("unchecked") JedisStatusResult(Response resultHolder, Converter converter) { super(resultHolder, false, converter); + setStatus(true); } } @@ -86,9 +84,12 @@ static class JedisStatusResult extends JedisResult { */ static class JedisResultBuilder { - private final Response response; - private Converter converter; private boolean convertPipelineAndTxResults = false; + + private Converter converter; + + private final Response response; + private Supplier nullValueDefault = () -> null; @SuppressWarnings("unchecked") @@ -119,6 +120,7 @@ static JedisResultBuilder forResponse(Response response) { JedisResultBuilder mappedWith(Converter converter) { this.converter = converter; + return this; } @@ -131,12 +133,14 @@ JedisResultBuilder mappedWith(Converter converter) { JedisResultBuilder mapNullTo(Supplier supplier) { this.nullValueDefault = supplier; + return this; } JedisResultBuilder convertPipelineAndTxResults(boolean flag) { - convertPipelineAndTxResults = flag; + this.convertPipelineAndTxResults = flag; + return this; } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java index 1aab87de0a..a19247a8d1 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java @@ -22,6 +22,7 @@ import redis.clients.jedis.params.ZParams; import redis.clients.jedis.params.ZRangeParams; import redis.clients.jedis.resps.ScanResult; +import redis.clients.jedis.util.KeyValue; import java.util.LinkedHashSet; import java.util.List; @@ -31,7 +32,6 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.zset.Aggregate; -import org.springframework.data.redis.connection.zset.DefaultTuple; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.Cursor; @@ -42,11 +42,14 @@ import org.springframework.util.Assert; /** + * {@link RedisZSetCommands} implementation for Jedis. + * * @author Christoph Strobl * @author Clement Ong * @author Mark Paluch * @author Andrey Shlykov * @author Shyngys Sapraliyev + * @author John Blum * @since 2.0 */ class JedisZSetCommands implements RedisZSetCommands { @@ -74,8 +77,10 @@ public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(tuples, "Tuples must not be null"); - return connection.invoke().just(Jedis::zadd, PipelineBinaryCommands::zadd, key, JedisConverters.toTupleMap(tuples), - JedisConverters.toZAddParams(args)); + Long count = connection.invoke().just(Jedis::zadd, PipelineBinaryCommands::zadd, key, + JedisConverters.toTupleMap(tuples), JedisConverters.toZAddParams(args)); + + return count != null ? count : 0L; } @Override @@ -424,7 +429,7 @@ public Set zDiff(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); - return connection.invoke().just(Jedis::zdiff, PipelineBinaryCommands::zdiff, sets); + return connection.invoke().fromMany(Jedis::zdiff, PipelineBinaryCommands::zdiff, sets).toSet(); } @Override @@ -450,7 +455,7 @@ public Set zInter(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); - return connection.invoke().just(Jedis::zinter, PipelineBinaryCommands::zinter, new ZParams(), sets); + return connection.invoke().fromMany(Jedis::zinter, PipelineBinaryCommands::zinter, new ZParams(), sets).toSet(); } @Override @@ -504,7 +509,7 @@ public Set zUnion(byte[]... sets) { Assert.notNull(sets, "Sets must not be null"); - return connection.invoke().just(Jedis::zunion, PipelineBinaryCommands::zunion, new ZParams(), sets); + return connection.invoke().fromMany(Jedis::zunion, PipelineBinaryCommands::zunion, new ZParams(), sets).toSet(); } @Override @@ -772,21 +777,8 @@ static ZRangeParams toZRangeParams(Protocol.Keyword by, byte[] min, byte[] max, return zRangeParams; } - /** - * Workaround for broken Jedis BZPOP signature. - * - * @param bytes - * @return - */ @Nullable - @SuppressWarnings("unchecked") - private static Tuple toTuple(List bytes) { - - if (bytes.isEmpty()) { - return null; - } - - return new DefaultTuple((byte[]) bytes.get(1), Double.parseDouble(new String((byte[]) bytes.get(2)))); + private static Tuple toTuple(@Nullable KeyValue keyValue) { + return keyValue != null ? JedisConverters.toTuple(keyValue.getValue()) : null; } - } diff --git a/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java b/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java index eb2c198e8e..34e8e88454 100644 --- a/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java +++ b/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java @@ -18,23 +18,27 @@ import java.util.Arrays; import org.springframework.lang.Nullable; +import org.springframework.util.ObjectUtils; /** * Default implementation for {@link Tuple} interface. * * @author Costin Leau * @author Christoph Strobl + * @author John Blum */ public class DefaultTuple implements Tuple { + private static final Double ZERO = 0.0d; + private final Double score; private final byte[] value; /** - * Constructs a new DefaultTuple instance. + * Constructs a new {@link DefaultTuple}. * - * @param value - * @param score + * @param value {@link byte[]} of the member's raw value. + * @param score {@link Double score} of the raw value used in sorting. */ public DefaultTuple(byte[] value, Double score) { @@ -43,29 +47,25 @@ public DefaultTuple(byte[] value, Double score) { } public Double getScore() { - return score; + return this.score; } public byte[] getValue() { - return value; + return this.value; } public boolean equals(@Nullable Object obj) { - if (this == obj) + + if (this == obj) { return true; - if (obj == null) - return false; - if (!(obj instanceof DefaultTuple)) - return false; - DefaultTuple other = (DefaultTuple) obj; - if (score == null) { - if (other.score != null) - return false; - } else if (!score.equals(other.score)) - return false; - if (!Arrays.equals(value, other.value)) + } + + if (!(obj instanceof DefaultTuple that)) { return false; - return true; + } + + return ObjectUtils.nullSafeEquals(this.score, that.score) + && Arrays.equals(this.value, that.value); } public int hashCode() { @@ -76,19 +76,21 @@ public int hashCode() { return result; } - public int compareTo(Double o) { - Double d = (score == null ? Double.valueOf(0.0d) : score); - Double a = (o == null ? Double.valueOf(0.0d) : o); - return d.compareTo(a); + public int compareTo(Double value) { + + Double ourScore = getScore(); + Double thisScore = ourScore != null ? ourScore : ZERO; + Double thatScore = value != null ? value : ZERO; + + return thisScore.compareTo(thatScore); } @Override public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getSimpleName()); - sb.append(" [score=").append(score); - sb.append(", value=").append(value == null ? "null" : new String(value)); - sb.append(']'); - return sb.toString(); + + return getClass().getSimpleName() + + " { score=" + getScore() + + ", value=" + Arrays.toString(getValue()) + + " }"; } } diff --git a/src/main/java/org/springframework/data/redis/connection/zset/Tuple.java b/src/main/java/org/springframework/data/redis/connection/zset/Tuple.java index 19c05a3385..4f35b6c25f 100644 --- a/src/main/java/org/springframework/data/redis/connection/zset/Tuple.java +++ b/src/main/java/org/springframework/data/redis/connection/zset/Tuple.java @@ -20,6 +20,17 @@ */ public interface Tuple extends Comparable { + /** + * Create a new {@link Tuple} with the {@link byte[] raw value} and given {@link Double score}. + * + * @param value {@link byte[]} of the member's raw value. + * @param score {@link Double score} given to the {@code value} used in sorting. + * @return a {@link Tuple} capturing the {@link byte[] value} with its {@link Double score}. + */ + static Tuple of(byte[] value, Double score) { + return new DefaultTuple(value, score); + } + /** * @return the raw value of the member. */ @@ -30,14 +41,4 @@ public interface Tuple extends Comparable { */ Double getScore(); - /** - * Create a new {@link Tuple}. - * - * @param value - * @param score - * @return - */ - static Tuple of(byte[] value, Double score) { - return new DefaultTuple(value, score); - } } diff --git a/src/main/java/org/springframework/data/redis/core/types/Expiration.java b/src/main/java/org/springframework/data/redis/core/types/Expiration.java index c5df3ae8f7..d24a60fc89 100644 --- a/src/main/java/org/springframework/data/redis/core/types/Expiration.java +++ b/src/main/java/org/springframework/data/redis/core/types/Expiration.java @@ -16,7 +16,6 @@ package org.springframework.data.redis.core.types; import java.time.Duration; -import java.util.Objects; import java.util.concurrent.TimeUnit; import org.springframework.lang.Nullable; diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java index b6b12293eb..bb07bd98e8 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java @@ -111,6 +111,8 @@ */ public abstract class AbstractConnectionIntegrationTests { + private static final byte[] EMPTY_ARRAY = new byte[0]; + private static final Point POINT_ARIGENTO = new Point(13.583333, 37.316667); private static final Point POINT_CATANIA = new Point(15.087269, 37.502669); private static final Point POINT_PALERMO = new Point(13.361389, 38.115556); @@ -119,17 +121,18 @@ public abstract class AbstractConnectionIntegrationTests { private static final GeoLocation CATANIA = new GeoLocation<>("catania", POINT_CATANIA); private static final GeoLocation PALERMO = new GeoLocation<>("palermo", POINT_PALERMO); - protected StringRedisConnection connection; - protected RedisSerializer serializer = RedisSerializer.java(); - private RedisSerializer stringSerializer = RedisSerializer.string(); + protected List actual = new ArrayList<>(); - private static final byte[] EMPTY_ARRAY = new byte[0]; + protected RedisConnection byteConnection; - protected List actual = new ArrayList<>(); + protected StringRedisConnection connection; - @Autowired @EnabledOnRedisDriver.DriverQualifier protected RedisConnectionFactory connectionFactory; + @Autowired + @EnabledOnRedisDriver.DriverQualifier + protected RedisConnectionFactory connectionFactory; - protected RedisConnection byteConnection; + protected RedisSerializer serializer = RedisSerializer.java(); + private RedisSerializer stringSerializer = RedisSerializer.string(); private boolean isJedisOrLettuceConnection(RedisConnectionFactory connectionFactory) { return ConnectionUtils.isJedis(connectionFactory) || ConnectionUtils.isLettuce(connectionFactory); @@ -154,20 +157,21 @@ public void setUp() { @AfterEach public void tearDown() { - try { - // since we use more than one db we're required to flush them all + try { + // Since we use more than one db we're required to flush them all connection.flushAll(); - } catch (Exception e) { - // Connection may be closed in certain cases, like after pub/sub - // tests + } catch (Exception ignore) { + // Connection may be closed in certain cases, like after pub/sub tests } + connection.close(); connection = null; } @Test public void testSelect() { + // Make sure this doesn't throw Exception connection.select(1); } @@ -181,6 +185,7 @@ void testExpire() { verifyResults(Arrays.asList(true, true)); KeyExpired keyExpired = new KeyExpired("exp"); + await().atMost(Duration.ofMillis(3000L)).until(keyExpired::passes); } @@ -203,9 +208,11 @@ void testExpireAt() { actual.add(connection.set("exp2", "true")); actual.add(connection.expireAt("exp2", System.currentTimeMillis() / 1000 + 1)); + verifyResults(Arrays.asList(true, true)); KeyExpired keyExpired = new KeyExpired("exp2"); + await().atMost(Duration.ofMillis(3000L)).until(keyExpired::passes); } @@ -214,16 +221,18 @@ void testPExpire() { actual.add(connection.set("exp", "true")); actual.add(connection.pExpire("exp", 100)); + verifyResults(Arrays.asList(true, true)); KeyExpired keyExpired = new KeyExpired("exp"); + await().atMost(Duration.ofMillis(1000L)).until(keyExpired::passes); } @Test void testPExpireKeyNotExists() { actual.add(connection.pExpire("nonexistent", 100)); - verifyResults(Arrays.asList(new Object[] { false })); + verifyResults(Collections.singletonList(false)); } @LongRunningTest @@ -231,36 +240,47 @@ void testPExpireAt() { actual.add(connection.set("exp2", "true")); actual.add(connection.pExpireAt("exp2", System.currentTimeMillis() + 200)); + verifyResults(Arrays.asList(true, true)); KeyExpired keyExpired = new KeyExpired("exp2"); + await().atMost(Duration.ofMillis(1000L)).until(keyExpired::passes); } @LongRunningTest void testPExpireAtKeyNotExists() { actual.add(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200)); - verifyResults(Arrays.asList(new Object[] { false })); + verifyResults(Collections.singletonList(false)); } @Test public void testScriptLoadEvalSha() { + getResults(); + String sha1 = connection.scriptLoad("return KEYS[1]"); + initConnection(); actual.add(connection.evalSha(sha1, ReturnType.VALUE, 2, "key1", "key2")); + assertThat(new String((byte[]) getResults().get(0))).isEqualTo("key1"); } @SuppressWarnings("unchecked") @Test public void testEvalShaArrayStrings() { + getResults(); + String sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}"); + initConnection(); actual.add(connection.evalSha(sha1, ReturnType.MULTI, 1, "key1", "arg1")); + List results = getResults(); List scriptResults = (List) results.get(0); + assertThat(Arrays.asList(new String(scriptResults.get(0)), new String(scriptResults.get(1)))) .isEqualTo(Arrays.asList("key1", "arg1")); } @@ -268,18 +288,24 @@ public void testEvalShaArrayStrings() { @SuppressWarnings("unchecked") @Test public void testEvalShaArrayBytes() { + getResults(); + byte[] sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}").getBytes(); + initConnection(); actual.add(byteConnection.evalSha(sha1, ReturnType.MULTI, 1, "key1".getBytes(), "arg1".getBytes())); + List results = getResults(); List scriptResults = (List) results.get(0); + assertThat(Arrays.asList(new String(scriptResults.get(0)), new String(scriptResults.get(1)))) .isEqualTo(Arrays.asList("key1", "arg1")); } @Test public void testEvalShaArrayError() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.evalSha("notasha", ReturnType.MULTI, 1, "key1", "arg1"); getResults(); @@ -288,6 +314,7 @@ public void testEvalShaArrayError() { @Test public void testEvalShaNotFound() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); getResults(); @@ -296,25 +323,31 @@ public void testEvalShaNotFound() { @Test public void testEvalReturnString() { + actual.add(connection.eval("return KEYS[1]", ReturnType.VALUE, 1, "foo")); + byte[] result = (byte[]) getResults().get(0); + assertThat(new String(result)).isEqualTo("foo"); } @Test public void testEvalReturnNumber() { actual.add(connection.eval("return 10", ReturnType.INTEGER, 0)); - verifyResults(Arrays.asList(new Object[] { 10L })); + verifyResults(Collections.singletonList(10L)); } @Test public void testEvalReturnSingleOK() { + actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0)); - assertThat(getResults()).isEqualTo(Arrays.asList("OK")); + + assertThat(getResults()).isEqualTo(Collections.singletonList("OK")); } @Test public void testEvalReturnSingleError() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); getResults(); @@ -324,20 +357,23 @@ public void testEvalReturnSingleError() { @Test public void testEvalReturnFalse() { actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { false })); + verifyResults(Collections.singletonList(false)); } @Test public void testEvalReturnTrue() { actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { true })); + verifyResults(Collections.singletonList(true)); } @SuppressWarnings("unchecked") @Test public void testEvalReturnArrayStrings() { + actual.add(connection.eval("return {KEYS[1],ARGV[1]}", ReturnType.MULTI, 1, "foo", "bar")); + List result = (List) getResults().get(0); + assertThat(Arrays.asList(new String(result.get(0)), new String(result.get(1)))) .isEqualTo(Arrays.asList("foo", "bar")); } @@ -345,11 +381,12 @@ public void testEvalReturnArrayStrings() { @Test public void testEvalReturnArrayNumbers() { actual.add(connection.eval("return {1,2}", ReturnType.MULTI, 1, "foo", "bar")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(1L, 2L) })); + verifyResults(Collections.singletonList(Arrays.asList(1L, 2L))); } @Test public void testEvalArrayScriptError() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { // Syntax error connection.eval("return {1,2", ReturnType.MULTI, 1, "foo", "bar"); @@ -360,9 +397,12 @@ public void testEvalArrayScriptError() { @SuppressWarnings("unchecked") @Test public void testEvalReturnArrayOKs() { + actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", ReturnType.MULTI, 0)); + List result = (List) getResults().get(0); + assertThat(Arrays.asList(new String(result.get(0)), new String(result.get(1)))) .isEqualTo(Arrays.asList("OK", "OK")); } @@ -370,32 +410,41 @@ public void testEvalReturnArrayOKs() { @Test public void testEvalReturnArrayFalses() { actual.add(connection.eval("return { false, false}", ReturnType.MULTI, 0)); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(null, null) })); + verifyResults(Collections.singletonList(Arrays.asList(null, null))); } @Test public void testEvalReturnArrayTrues() { actual.add(connection.eval("return { true, true}", ReturnType.MULTI, 0)); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(1L, 1L) })); + verifyResults(Collections.singletonList(Arrays.asList(1L, 1L))); } @Test public void testScriptExists() { + getResults(); + String sha1 = connection.scriptLoad("return 'foo'"); + initConnection(); + actual.add(connection.scriptExists(sha1, "98777234")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(true, false) })); + + verifyResults(Collections.singletonList(Arrays.asList(true, false))); } @Test public void testScriptFlush() { + getResults(); + String sha1 = connection.scriptLoad("return KEYS[1]"); + connection.scriptFlush(); initConnection(); actual.add(connection.scriptExists(sha1)); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(false) })); + + verifyResults(Collections.singletonList(Collections.singletonList(false))); } @LongRunningTest @@ -405,6 +454,7 @@ void testPersist() { actual.add(connection.expire("exp3", 30)); actual.add(connection.persist("exp3")); actual.add(connection.ttl("exp3")); + verifyResults(Arrays.asList(true, true, true, -1L)); } @@ -417,6 +467,7 @@ void testSetEx() { verifyResults(Arrays.asList(true, "yep")); KeyExpired keyExpired = new KeyExpired("expy"); + await().atMost(Duration.ofMillis(2500L)).until(keyExpired::passes); } @@ -429,25 +480,26 @@ void testPsetEx() { verifyResults(Arrays.asList(true, "yep")); KeyExpired keyExpired = new KeyExpired("expy"); + await().atMost(Duration.ofMillis(2500L)).until(keyExpired::passes); } @LongRunningTest public void testBRPopTimeout() { actual.add(connection.bRPop(1, "alist")); - verifyResults(Arrays.asList(new Object[] { null })); + verifyResults(Collections.singletonList(null)); } @LongRunningTest public void testBLPopTimeout() { actual.add(connection.bLPop(1, "alist")); - verifyResults(Arrays.asList(new Object[] { null })); + verifyResults(Collections.singletonList(null)); } @LongRunningTest public void testBRPopLPushTimeout() { actual.add(connection.bRPopLPush(1, "alist", "foo")); - verifyResults(Arrays.asList(new Object[] { null })); + verifyResults(Collections.singletonList(null)); } @Test @@ -458,6 +510,7 @@ void testSetAndGet() { actual.add(connection.set(key.getBytes(), value.getBytes())); actual.add(connection.get(key)); + verifyResults(Arrays.asList(true, value)); } @@ -469,23 +522,29 @@ public void testPingPong() { @Test void testBitSet() { + String key = "bitset-test"; + actual.add(connection.setBit(key, 0, true)); actual.add(connection.setBit(key, 0, false)); actual.add(connection.setBit(key, 1, true)); actual.add(connection.getBit(key, 0)); actual.add(connection.getBit(key, 1)); - verifyResults(Arrays.asList(new Object[] { false, true, false, false, true })); + + verifyResults(Arrays.asList(false, true, false, false, true)); } @Test void testBitCount() { + String key = "bitset-test"; + actual.add(connection.setBit(key, 0, false)); actual.add(connection.setBit(key, 1, true)); actual.add(connection.setBit(key, 2, true)); actual.add(connection.bitCount(key)); - verifyResults(Arrays.asList(new Object[] { false, false, false, 2L })); + + verifyResults(Arrays.asList(false, false, false, 2L)); } @Test @@ -493,6 +552,7 @@ void testBitCountInterval() { actual.add(connection.set("mykey", "foobar")); actual.add(connection.bitCount("mykey", 1, 1)); + verifyResults(Arrays.asList(Boolean.TRUE, 6L)); } @@ -509,6 +569,7 @@ void testBitOpAnd() { actual.add(connection.set("key2", "bar")); actual.add(connection.bitOp(BitOperation.AND, "key3", "key1", "key2")); actual.add(connection.get("key3")); + verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 3L, "bab")); } @@ -519,6 +580,7 @@ void testBitOpOr() { actual.add(connection.set("key2", "ugh")); actual.add(connection.bitOp(BitOperation.OR, "key3", "key1", "key2")); actual.add(connection.get("key3")); + verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 3L, "woo")); } @@ -528,6 +590,7 @@ void testBitOpXOr() { actual.add(connection.set("key1", "abcd")); actual.add(connection.set("key2", "efgh")); actual.add(connection.bitOp(BitOperation.XOR, "key3", "key1", "key2")); + verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 4L)); } @@ -536,11 +599,13 @@ void testBitOpNot() { actual.add(connection.set("key1", "abcd")); actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1")); + verifyResults(Arrays.asList(Boolean.TRUE, 4L)); } @Test void testBitOpNotMultipleSources() { + assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); } @@ -553,6 +618,7 @@ public void testCopy() { actual.add(connection.copy("foo", "baz", false)); verifyResults(Arrays.asList(true, true)); + assertThat(connection.get("baz")).isEqualTo("bar"); assertThat(connection.exists("foo")).isTrue(); } @@ -561,31 +627,38 @@ public void testCopy() { public void testInfo() { actual.add(connection.info()); - List results = getResults(); - Properties info = (Properties) results.get(0); + + Properties info = (Properties) getResults().get(0); + assertThat(info.size() >= 5).as("at least 5 settings should be present").isTrue(); + String version = info.getProperty("redis_version"); + assertThat(version).isNotNull(); } @Test public void testInfoBySection() { + actual.add(connection.info("server")); - List results = getResults(); - Properties info = (Properties) results.get(0); + + Properties info = (Properties) getResults().get(0); + assertThat(info.size() >= 5).as("at least 5 settings should be present").isTrue(); + String version = info.getProperty("redis_version"); + assertThat(version).isNotNull(); } @Test @Disabled("DATAREDIS-525") public void testNullKey() { + try { connection.decr((String) null); fail("Decrement should fail with null key"); - } catch (Exception ex) { - // expected + } catch (Exception expected) { } } @@ -594,12 +667,13 @@ public void testNullKey() { public void testNullValue() { byte[] key = UUID.randomUUID().toString().getBytes(); + connection.append(key, EMPTY_ARRAY); + try { connection.append(key, null); fail("Append should fail with null value"); - } catch (DataAccessException ex) { - // expected + } catch (DataAccessException expected) { } } @@ -608,58 +682,65 @@ public void testNullValue() { public void testHashNullKey() { byte[] key = UUID.randomUUID().toString().getBytes(); + try { connection.hExists(key, null); fail("hExists should fail with null key"); - } catch (DataAccessException ex) { - // expected + } catch (DataAccessException expected) { } } @Test @Disabled("DATAREDIS-525") public void testHashNullValue() { + byte[] key = UUID.randomUUID().toString().getBytes(); byte[] field = "random".getBytes(); connection.hSet(key, field, EMPTY_ARRAY); + try { connection.hSet(key, field, null); fail("hSet should fail with null value"); - } catch (DataAccessException ex) { - // expected + } catch (DataAccessException expected) { } } @Test void testNullSerialization() { + String[] keys = new String[] { "~", "[" }; + actual.add(connection.mGet(keys)); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(null, null) })); + + verifyResults(Arrays.asList(Arrays.asList(null, null))); + StringRedisTemplate stringTemplate = new StringRedisTemplate(connectionFactory); List multiGet = stringTemplate.opsForValue().multiGet(Arrays.asList(keys)); + assertThat(multiGet).isEqualTo(Arrays.asList(null, null)); } @Test void testAppend() { + actual.add(connection.set("a", "b")); actual.add(connection.append("a", "c")); actual.add(connection.get("a")); - verifyResults(Arrays.asList(new Object[] { Boolean.TRUE, 2L, "bc" })); + + verifyResults(Arrays.asList(Boolean.TRUE, 2L, "bc")); } @LongRunningTest public void testPubSubWithNamedChannels() throws Exception { - final String expectedChannel = "channel1"; - final String expectedMessage = "msg"; - final BlockingDeque messages = new LinkedBlockingDeque<>(); - MessageListener listener = (message, pattern) -> { - messages.add(message); - }; + String expectedChannel = "channel1"; + String expectedMessage = "msg"; + BlockingDeque messages = new LinkedBlockingDeque<>(); + + MessageListener listener = (message, pattern) -> messages.add(message); - Thread th = new Thread(() -> { + Thread thread = new Thread(() -> { // sync to let the registration happen await().atMost(Duration.ofMillis(2000L)).until(connection::isSubscribed); @@ -669,8 +750,10 @@ public void testPubSubWithNamedChannels() throws Exception { // open a new connection RedisConnection connection2 = connectionFactory.getConnection(); + connection2.publish(expectedChannel.getBytes(), expectedMessage.getBytes()); connection2.close(); + // In some clients, unsubscribe happens async of message // receipt, so not all // messages may be received if unsubscribing now. @@ -681,11 +764,13 @@ public void testPubSubWithNamedChannels() throws Exception { } }); - th.start(); + thread.start(); connection.subscribe(listener, expectedChannel.getBytes()); // Not all providers block on subscribe, give some time for messages to // be received + Message message = messages.poll(5, TimeUnit.SECONDS); + assertThat(message).isNotNull(); assertThat(new String(message.getBody())).isEqualTo(expectedMessage); assertThat(new String(message.getChannel())).isEqualTo(expectedChannel); @@ -693,16 +778,18 @@ public void testPubSubWithNamedChannels() throws Exception { @LongRunningTest public void testPubSubWithPatterns() throws Exception { - final String expectedPattern = "channel*"; - final String expectedMessage = "msg"; - final BlockingDeque messages = new LinkedBlockingDeque<>(); - final MessageListener listener = (message, pattern) -> { + String expectedPattern = "channel*"; + String expectedMessage = "msg"; + BlockingDeque messages = new LinkedBlockingDeque<>(); + + MessageListener listener = (message, pattern) -> { assertThat(new String(pattern)).isEqualTo(expectedPattern); messages.add(message); }; - Thread th = new Thread(() -> { + Thread thread = new Thread(() -> { + // sync to let the registration happen await().atMost(Duration.ofMillis(2000L)).until(connection::isSubscribed); @@ -712,9 +799,11 @@ public void testPubSubWithPatterns() throws Exception { // open a new connection RedisConnection connection2 = connectionFactory.getConnection(); + connection2.publish("channel1".getBytes(), expectedMessage.getBytes()); connection2.publish("channel2".getBytes(), expectedMessage.getBytes()); connection2.close(); + // In some clients, unsubscribe happens async of message // receipt, so not all // messages may be received if unsubscribing now. @@ -725,20 +814,25 @@ public void testPubSubWithPatterns() throws Exception { } }); - th.start(); + thread.start(); connection.pSubscribe(listener, expectedPattern); + // Not all providers block on subscribe (Lettuce does not), give some // time for messages to be received Message message = messages.poll(5, TimeUnit.SECONDS); + assertThat(message).isNotNull(); assertThat(new String(message.getBody())).isEqualTo(expectedMessage); + message = messages.poll(5, TimeUnit.SECONDS); + assertThat(message).isNotNull(); assertThat(new String(message.getBody())).isEqualTo(expectedMessage); } @Test public void exceptionExecuteNative() { + assertThatExceptionOfType(DataAccessException.class).isThrownBy(() -> { connection.execute("set", "foo"); getResults(); @@ -758,8 +852,8 @@ void testExecute() { void testExecuteNoArgs() { actual.add(connection.execute("PING")); - List results = getResults(); - assertThat(stringSerializer.deserialize((byte[]) results.get(0))).isEqualTo("PONG"); + + assertThat(stringSerializer.deserialize((byte[]) getResults().get(0))).isEqualTo("PONG"); } @SuppressWarnings("unchecked") @@ -770,14 +864,16 @@ public void testMultiExec() { connection.set("key", "value"); connection.get("key"); actual.add(connection.exec()); - List results = getResults(); - List execResults = (List) results.get(0); + + List execResults = (List) getResults().get(0); + assertThat(execResults).isEqualTo(Arrays.asList(true, "value")); assertThat(connection.get("key")).isEqualTo("value"); } @Test public void testMultiAlreadyInTx() { + connection.multi(); // Ensure it's OK to call multi twice testMultiExec(); @@ -785,6 +881,7 @@ public void testMultiAlreadyInTx() { @Test public void testExecWithoutMulti() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.exec(); }); @@ -792,6 +889,7 @@ public void testExecWithoutMulti() { @Test public void testErrorInTx() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.multi(); connection.set("foo", "bar"); @@ -804,15 +902,21 @@ public void testErrorInTx() { @Test public void testMultiDiscard() { + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.set("testitnow", "willdo"); connection.multi(); connection.set("testitnow2", "notok"); connection.discard(); actual.add(connection.get("testitnow")); + List results = getResults(); + assertThat(results).isEqualTo(Arrays.asList("willdo")); + initConnection(); + // Ensure we can run a new tx after discarding previous one testMultiExec(); } @@ -823,9 +927,12 @@ public void testWatch() throws Exception { actual.add(connection.set("testitnow", "willdo")); connection.watch("testitnow".getBytes()); - // Give some time for watch to be asynch executed in extending tests + + // Give some time for watch to be async executed in extending tests Thread.sleep(200); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.set("testitnow", "something"); conn2.close(); connection.multi(); @@ -833,21 +940,22 @@ public void testWatch() throws Exception { actual.add(connection.exec()); actual.add(connection.get("testitnow")); - verifyResults(Arrays.asList(new Object[] { true, null, "something" })); + verifyResults(Arrays.asList(true, null, "something")); } @LongRunningTest public void testUnwatch() throws Exception { actual.add(connection.set("testitnow", "willdo")); - connection.watch("testitnow".getBytes()); connection.unwatch(); connection.multi(); // Give some time for unwatch to be asynch executed Thread.sleep(200); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.set("testitnow", "something"); connection.set("testitnow", "somethingelse"); @@ -859,39 +967,47 @@ public void testUnwatch() throws Exception { @Test void testSort() { + actual.add(connection.rPush("sortlist", "foo")); actual.add(connection.rPush("sortlist", "bar")); actual.add(connection.rPush("sortlist", "baz")); actual.add(connection.sort("sortlist", new DefaultSortParameters(null, Order.ASC, true))); + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("bar", "baz", "foo"))); } @Test void testSortStore() { + actual.add(connection.rPush("sortlist", "foo")); actual.add(connection.rPush("sortlist", "bar")); actual.add(connection.rPush("sortlist", "baz")); actual.add(connection.sort("sortlist", new DefaultSortParameters(null, Order.ASC, true), "newlist")); actual.add(connection.lRange("newlist", 0, 9)); + verifyResults(Arrays.asList(1L, 2L, 3L, 3L, Arrays.asList("bar", "baz", "foo"))); } @Test void testSortNullParams() { + actual.add(connection.rPush("sortlist", "5")); actual.add(connection.rPush("sortlist", "2")); actual.add(connection.rPush("sortlist", "3")); actual.add(connection.sort("sortlist", null)); + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("2", "3", "5"))); } @Test void testSortStoreNullParams() { + actual.add(connection.rPush("sortlist", "9")); actual.add(connection.rPush("sortlist", "3")); actual.add(connection.rPush("sortlist", "5")); actual.add(connection.sort("sortlist", null, "newlist")); actual.add(connection.lRange("newlist", 0, 9)); + verifyResults(Arrays.asList(1L, 2L, 3L, 3L, Arrays.asList("3", "5", "9"))); } @@ -900,28 +1016,33 @@ public void testDbSize() { actual.add(connection.set("dbparam", "foo")); actual.add(connection.dbSize()); + assertThat((Long) getResults().get(1) > 0).isTrue(); } @Test public void testFlushDb() { + connection.flushDb(); actual.add(connection.dbSize()); + verifyResults(Arrays.asList(new Object[] { 0L })); } - @SuppressWarnings("unchecked") @Test // DATAREDIS-661 public void testGetConfig() { + actual.add(connection.getConfig("*")); + Properties config = (Properties) getResults().get(0); + assertThat(!config.isEmpty()).isTrue(); } @Test public void testEcho() { actual.add(connection.echo("Hello World")); - verifyResults(Arrays.asList(new Object[] { "Hello World" })); + verifyResults(Collections.singletonList("Hello World")); } @Test @@ -930,6 +1051,7 @@ void testExists() { actual.add(connection.set("existent", "true")); actual.add(connection.exists("existent")); actual.add(connection.exists("nonexistent")); + verifyResults(Arrays.asList(true, true, false)); } @@ -939,25 +1061,21 @@ void testExistsWithMultipleKeys() { actual.add(connection.set("exist-1", "true")); actual.add(connection.set("exist-2", "true")); actual.add(connection.set("exist-3", "true")); - actual.add(connection.exists("exist-1", "exist-2", "exist-3", "nonexistent")); - verifyResults(Arrays.asList(new Object[] { true, true, true, 3L })); + verifyResults(Arrays.asList(true, true, true, 3L)); } @Test // DATAREDIS-529 void testExistsWithMultipleKeysNoneExists() { - actual.add(connection.exists("no-exist-1", "no-exist-2")); - - verifyResults(Arrays.asList(new Object[] { 0L })); + verifyResults(Collections.singletonList(0L)); } @Test // DATAREDIS-529 void testExistsSameKeyMultipleTimes() { actual.add(connection.set("existent", "true")); - actual.add(connection.exists("existent", "existent")); verifyResults(Arrays.asList(true, 2L)); @@ -969,6 +1087,7 @@ void testKeys() { actual.add(connection.set("keytest", "true")); actual.add(connection.keys("key*")); + assertThat(((Collection) getResults().get(1)).contains("keytest")).isTrue(); } @@ -977,8 +1096,8 @@ void testRandomKey() { actual.add(connection.set("some", "thing")); actual.add(connection.randomKey()); - List results = getResults(); - assertThat(results.get(1)).isNotNull(); + + assertThat(getResults().get(1)).isNotNull(); } @Test @@ -988,6 +1107,7 @@ void testRename() { connection.rename("renametest", "newrenametest"); actual.add(connection.get("newrenametest")); actual.add(connection.exists("renametest")); + verifyResults(Arrays.asList(true, "testit", false)); } @@ -998,13 +1118,16 @@ void testRenameNx() { actual.add(connection.renameNX("nxtest", "newnxtest")); actual.add(connection.get("newnxtest")); actual.add(connection.exists("nxtest")); + verifyResults(Arrays.asList(true, true, "testit", false)); } @Test void testTtl() { + actual.add(connection.set("whatup", "yo")); actual.add(connection.ttl("whatup")); + verifyResults(Arrays.asList(true, -1L)); } @@ -1026,6 +1149,7 @@ void testPTtlNoExpire() { actual.add(connection.set("whatup", "yo")); actual.add(connection.pTtl("whatup")); + verifyResults(Arrays.asList(true, -1L)); } @@ -1036,9 +1160,7 @@ void testPTtl() { actual.add(connection.pExpire("whatup", TimeUnit.SECONDS.toMillis(10))); actual.add(connection.pTtl("whatup")); - List results = getResults(); - - assertThat((Long) results.get(2) > -1).isTrue(); + assertThat((Long) getResults().get(2) > -1).isTrue(); } @Test // DATAREDIS-526 @@ -1059,7 +1181,9 @@ void testDumpAndRestore() { connection.set("testing", "12"); actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); actual.add(connection.del("testing")); @@ -1067,7 +1191,7 @@ void testDumpAndRestore() { connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); actual.add(connection.get("testing")); - verifyResults(Arrays.asList(new Object[] { 1L, null, "12" })); + verifyResults(Arrays.asList(1L, null, "12")); } @Test @@ -1078,6 +1202,7 @@ void testDumpNonExistentKey() { @Test public void testRestoreBadData() { + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { // Use something other than dump-specific serialization connection.restore("testing".getBytes(), 0, "foo".getBytes()); @@ -1090,8 +1215,11 @@ public void testRestoreExistingKey() { actual.add(connection.set("testing", "12")); actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + assertThatExceptionOfType(RedisSystemException.class).isThrownBy(() -> { connection.restore("testing".getBytes(), 0, (byte[]) results.get(1)); getResults(); @@ -1107,8 +1235,10 @@ void testRestoreExistingKeyWithReplaceOption() { connection.restore("testing".getBytes(), 0, (byte[]) getResults().get(1), true); initConnection(); + actual.add(connection.get("testing")); - verifyResults(Arrays.asList(new Object[] { "12" })); + + verifyResults(Arrays.asList("12")); } @LongRunningTest @@ -1118,13 +1248,17 @@ void testRestoreTtl() { actual.add(connection.dump("testing".getBytes())); List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); actual.add(connection.get("testing")); connection.restore("testing".getBytes(), 100L, (byte[]) results.get(1)); + verifyResults(Arrays.asList(1L, null)); KeyExpired keyExpired = new KeyExpired("testing"); + await().atMost(Duration.ofMillis(400L)).until(keyExpired::passes); } @@ -1134,6 +1268,7 @@ void testDel() { actual.add(connection.set("testing", "123")); actual.add(connection.del("testing")); actual.add(connection.exists("testing")); + verifyResults(Arrays.asList(true, 1L, false)); } @@ -1141,10 +1276,9 @@ void testDel() { void unlinkReturnsNrOfKeysRemoved() { actual.add(connection.set("unlink.this", "Can't track this")); - actual.add(connection.unlink("unlink.this", "unlink.that")); - verifyResults(Arrays.asList(new Object[] { true, 1L })); + verifyResults(Arrays.asList(true, 1L)); } @Test // DATAREDIS-693 @@ -1160,10 +1294,8 @@ void testUnlinkBatch() { @Test // DATAREDIS-693 void unlinkReturnsZeroIfNoKeysRemoved() { - actual.add(connection.unlink("unlink.this")); - - verifyResults(Arrays.asList(new Object[] { 0L })); + verifyResults(Collections.singletonList(0L)); } @Test @@ -1171,6 +1303,7 @@ void testType() { actual.add(connection.set("something", "yo")); actual.add(connection.type("something")); + verifyResults(Arrays.asList(true, DataType.STRING)); } @@ -1204,6 +1337,7 @@ void testGetSet() { actual.add(connection.set("testGS", "1")); actual.add(connection.getSet("testGS", "2")); actual.add(connection.get("testGS")); + verifyResults(Arrays.asList(true, "1", "2")); } @@ -1211,11 +1345,13 @@ void testGetSet() { void testMSet() { Map vals = new HashMap<>(); + vals.put("color", "orange"); vals.put("size", "1"); actual.add(connection.mSetString(vals)); actual.add(connection.mGet("color", "size")); + verifyResults(Arrays.asList(true, Arrays.asList("orange", "1"))); } @@ -1223,10 +1359,13 @@ void testMSet() { void testMSetNx() { Map vals = new HashMap<>(); + vals.put("height", "5"); vals.put("width", "1"); + actual.add(connection.mSetNXString(vals)); actual.add(connection.mGet("height", "width")); + verifyResults(Arrays.asList(true, Arrays.asList("5", "1"))); } @@ -1234,11 +1373,15 @@ void testMSetNx() { void testMSetNxFailure() { actual.add(connection.set("height", "2")); + Map vals = new HashMap<>(); + vals.put("height", "5"); vals.put("width", "1"); + actual.add(connection.mSetNXString(vals)); actual.add(connection.mGet("height", "width")); + verifyResults(Arrays.asList(true, false, Arrays.asList("2", null))); } @@ -1249,7 +1392,8 @@ void testSetNx() { actual.add(connection.get("notaround")); actual.add(connection.setNX("notaround", "55")); actual.add(connection.get("notaround")); - verifyResults(Arrays.asList(new Object[] { true, "54", false, "54" })); + + verifyResults(Arrays.asList(true, "54", false, "54")); } @Test @@ -1259,6 +1403,7 @@ void testGetRangeSetRange() { actual.add(connection.getRange("rangekey", 0L, 2L)); connection.setRange("rangekey", "ck", 2); actual.add(connection.get("rangekey")); + verifyResults(Arrays.asList(true, "sup", "suckrcalifrag")); } @@ -1268,6 +1413,7 @@ void testDecrByIncrBy() { actual.add(connection.set("tdb", "4")); actual.add(connection.decrBy("tdb", 3L)); actual.add(connection.incrBy("tdb", 7L)); + verifyResults(Arrays.asList(Boolean.TRUE, 1L, 8L)); } @@ -1287,10 +1433,12 @@ void testIncrDecrByLong() { String key = "test.count"; long largeNumber = 0x123456789L; // > 32bits + actual.add(connection.set(key, "0")); actual.add(connection.incrBy(key, largeNumber)); actual.add(connection.decrBy(key, largeNumber)); actual.add(connection.decrBy(key, 2 * largeNumber)); + verifyResults(Arrays.asList(Boolean.TRUE, largeNumber, 0L, -2 * largeNumber)); } @@ -1301,20 +1449,22 @@ void testHashIncrDecrByLong() { String hkey = "hashkey"; long largeNumber = 0x123456789L; // > 32bits + actual.add(connection.hSet(key, hkey, "0")); actual.add(connection.hIncrBy(key, hkey, largeNumber)); - // assertEquals(largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); actual.add(connection.hIncrBy(key, hkey, -2 * largeNumber)); - // assertEquals(-largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); - verifyResults(Arrays.asList(new Object[] { true, largeNumber, -largeNumber })); + + verifyResults(Arrays.asList(true, largeNumber, -largeNumber)); } @Test // GH-2048 @EnabledOnCommand("HRANDFIELD") + @SuppressWarnings({ "unchecked" }) void testHRandField() { String key = "hash"; Map hash = new HashMap<>(); + hash.put("key1", "val1"); hash.put("key2", "val2"); hash.put("key3", "val3"); @@ -1326,6 +1476,7 @@ void testHRandField() { actual.add(connection.hRandField(key, -10)); List results = getResults(); + assertThat((String) results.get(0)).isIn(hash.keySet()); assertThat((List) results.get(1)).hasSize(2); assertThat((List) results.get(2)).hasSize(10); @@ -1337,6 +1488,7 @@ void testHRandFieldWithValues() { String key = "hash"; Map hash = new HashMap<>(); + hash.put("key1", "val1"); hash.put("key2", "val2"); hash.put("key3", "val3"); @@ -1348,6 +1500,7 @@ void testHRandFieldWithValues() { actual.add(connection.hRandFieldWithValues(key, -10)); List results = getResults(); + assertThat(results.get(0)).isNotNull(); assertThat((List) results.get(1)).hasSize(2); @@ -1363,6 +1516,7 @@ void testIncDecr() { actual.add(connection.get("incrtest")); actual.add(connection.decr("incrtest")); actual.add(connection.get("incrtest")); + verifyResults(Arrays.asList(Boolean.TRUE, 1L, "1", 0L, "0")); } @@ -1371,6 +1525,7 @@ void testStrLen() { actual.add(connection.set("strlentest", "cat")); actual.add(connection.strLen("strlentest")); + verifyResults(Arrays.asList(Boolean.TRUE, 3L)); } @@ -1378,71 +1533,89 @@ void testStrLen() { @Test public void testBLPop() { + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.lPush("poplist", "foo"); conn2.lPush("poplist", "bar"); + actual.add(connection.bLPop(100, "poplist", "otherlist")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList("poplist", "bar") })); + + verifyResults(Collections.singletonList(Arrays.asList("poplist", "bar"))); } @Test public void testBRPop() { + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.rPush("rpoplist", "bar"); conn2.rPush("rpoplist", "foo"); + actual.add(connection.bRPop(1, "rpoplist")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList("rpoplist", "foo") })); + + verifyResults(Collections.singletonList(Arrays.asList("rpoplist", "foo"))); } @Test void testLInsert() { + actual.add(connection.rPush("MyList", "hello")); actual.add(connection.rPush("MyList", "world")); actual.add(connection.lInsert("MyList", Position.AFTER, "hello", "big")); actual.add(connection.lRange("MyList", 0, -1)); actual.add(connection.lInsert("MyList", Position.BEFORE, "big", "very")); actual.add(connection.lRange("MyList", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("hello", "big", "world"), 4L, Arrays.asList("hello", "very", "big", "world"))); } @Test void testLPop() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.lPop("PopList")); - verifyResults(Arrays.asList(new Object[] { 1L, 2L, "hello" })); + + verifyResults(Arrays.asList(1L, 2L, "hello")); } @Test // GH-1987 @EnabledOnRedisVersion("6.2") void testLPopWithCount() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPush("PopList", "42")); actual.add(connection.lPop("PopList", 2)); - verifyResults(Arrays.asList(new Object[] { 1L, 2L, 3L, Arrays.asList("hello", "world") })); + + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("hello", "world"))); } @Test void testLRem() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "big")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPush("PopList", "hello")); actual.add(connection.lRem("PopList", 2, "hello")); actual.add(connection.lRange("PopList", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, 3L, 4L, 2L, Arrays.asList("big", "world"))); } @Test void testLLen() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "big")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPush("PopList", "hello")); actual.add(connection.lLen("PopList")); - verifyResults(Arrays.asList(new Object[] { 1L, 2L, 3L, 4L, 4L })); + + verifyResults(Arrays.asList(1L, 2L, 3L, 4L, 4L)); } @Test // GH-2039 @@ -1466,12 +1639,9 @@ void testBLMove() { actual.add(connection.rPush("From", "hello")); actual.add(connection.rPush("From", "big")); - actual.add( - connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); - actual.add( - connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); - actual.add( - connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); + actual.add(connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); + actual.add(connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); + actual.add(connection.bLMove("From", "To", RedisListCommands.Direction.LEFT, RedisListCommands.Direction.RIGHT, 0.01d)); actual.add(connection.lRange("From", 0, -1)); actual.add(connection.lRange("To", 0, -1)); @@ -1480,113 +1650,139 @@ void testBLMove() { @Test void testLSet() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "big")); actual.add(connection.rPush("PopList", "world")); connection.lSet("PopList", 1, "cruel"); actual.add(connection.lRange("PopList", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("hello", "cruel", "world"))); } @Test void testLTrim() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "big")); actual.add(connection.rPush("PopList", "world")); connection.lTrim("PopList", 1, -1); actual.add(connection.lRange("PopList", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("big", "world"))); } @Test void testRPop() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPop("PopList")); - verifyResults(Arrays.asList(new Object[] { 1L, 2L, "world" })); + + verifyResults(Arrays.asList(1L, 2L, "world")); } @Test // GH-1987 @EnabledOnRedisVersion("6.2") void testRPopWithCount() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPush("PopList", "42")); actual.add(connection.rPop("PopList", 2)); - verifyResults(Arrays.asList(new Object[] { 1L, 2L, 3L, Arrays.asList("42", "world") })); + + verifyResults(Arrays.asList(1L, 2L, 3L, Arrays.asList("42", "world"))); } @Test void testRPopLPush() { + actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPush("pop2", "hey")); actual.add(connection.rPopLPush("PopList", "pop2")); actual.add(connection.lRange("PopList", 0, -1)); actual.add(connection.lRange("pop2", 0, -1)); - verifyResults(Arrays.asList(1L, 2L, 1L, "world", Arrays.asList("hello"), Arrays.asList("world", "hey"))); + + verifyResults(Arrays.asList(1L, 2L, 1L, "world", Collections.singletonList("hello"), Arrays.asList("world", "hey"))); } @Test public void testBRPopLPush() { + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection()); + conn2.rPush("PopList", "hello"); conn2.rPush("PopList", "world"); conn2.rPush("pop2", "hey"); + actual.add(connection.bRPopLPush(1, "PopList", "pop2")); - List results = getResults(); - assertThat(results).isEqualTo(Arrays.asList("world")); - assertThat(connection.lRange("PopList", 0, -1)).isEqualTo(Arrays.asList("hello")); + + assertThat(getResults()).isEqualTo(Collections.singletonList("world")); + assertThat(connection.lRange("PopList", 0, -1)).isEqualTo(Collections.singletonList("hello")); assertThat(connection.lRange("pop2", 0, -1)).isEqualTo(Arrays.asList("world", "hey")); } @Test void testLPushX() { + actual.add(connection.rPush("mylist", "hi")); actual.add(connection.lPushX("mylist", "foo")); actual.add(connection.lRange("mylist", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, Arrays.asList("foo", "hi"))); } @Test void testRPushMultiple() { + actual.add(connection.rPush("mylist", "hi", "foo")); actual.add(connection.lRange("mylist", 0, -1)); + verifyResults(Arrays.asList(2L, Arrays.asList("hi", "foo"))); } @Test void testRPushX() { + actual.add(connection.rPush("mylist", "hi")); actual.add(connection.rPushX("mylist", "foo")); actual.add(connection.lRange("mylist", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, Arrays.asList("hi", "foo"))); } @Test void testLIndex() { + actual.add(connection.lPush("testylist", "foo")); actual.add(connection.lIndex("testylist", 0)); - verifyResults(Arrays.asList(new Object[] { 1L, "foo" })); + + verifyResults(Arrays.asList(1L, "foo")); } @Test void testLPush() { + actual.add(connection.lPush("testlist", "bar")); actual.add(connection.lPush("testlist", "baz")); actual.add(connection.lRange("testlist", 0, -1)); + verifyResults(Arrays.asList(1L, 2L, Arrays.asList("baz", "bar"))); } @Test void testLPushMultiple() { + actual.add(connection.lPush("testlist", "bar", "baz")); actual.add(connection.lRange("testlist", 0, -1)); + verifyResults(Arrays.asList(2L, Arrays.asList("baz", "bar"))); } @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPos() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1597,6 +1793,7 @@ void lPos() { @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosRank() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1607,6 +1804,7 @@ void lPosRank() { @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosNegativeRank() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1617,6 +1815,7 @@ void lPosNegativeRank() { @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosCount() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1627,6 +1826,7 @@ void lPosCount() { @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosRankCount() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1637,6 +1837,7 @@ void lPosRankCount() { @Test // DATAREDIS-1196, GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosCountZero() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1647,6 +1848,7 @@ void lPosCountZero() { @Test // GH-1957 @EnabledOnCommand("LPOS") + @SuppressWarnings("unchecked") void lPosNonExisting() { actual.add(connection.rPush("mylist", "a", "b", "c", "1", "2", "3", "c", "c")); @@ -1663,7 +1865,8 @@ void testSAdd() { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, new HashSet<>(Arrays.asList("foo", "bar")) })); + + verifyResults(Arrays.asList(1L, 1L, new HashSet<>(Arrays.asList("foo", "bar")))); } @Test @@ -1672,7 +1875,8 @@ void testSAddMultiple() { actual.add(connection.sAdd("myset", "foo", "bar")); actual.add(connection.sAdd("myset", "baz")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 2L, 1L, new HashSet<>(Arrays.asList("foo", "bar", "baz")) })); + + verifyResults(Arrays.asList(2L, 1L, new HashSet<>(Arrays.asList("foo", "bar", "baz")))); } @Test @@ -1681,7 +1885,8 @@ void testSCard() { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sCard("myset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 2L })); + + verifyResults(Arrays.asList(1L, 1L, 2L)); } @Test @@ -1691,7 +1896,8 @@ void testSDiff() { actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sDiff("myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, new HashSet<>(Collections.singletonList("foo")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, new HashSet<>(Collections.singletonList("foo")))); } @Test @@ -1702,7 +1908,8 @@ void testSDiffStore() { actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sDiffStore("thirdset", "myset", "otherset")); actual.add(connection.sMembers("thirdset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, 1L, new HashSet<>(Collections.singletonList("foo")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 1L, new HashSet<>(Collections.singletonList("foo")))); } @Test @@ -1712,17 +1919,20 @@ void testSInter() { actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sInter("myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, new HashSet<>(Collections.singletonList("bar")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, new HashSet<>(Collections.singletonList("bar")))); } @Test void testSInterStore() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sInterStore("thirdset", "myset", "otherset")); actual.add(connection.sMembers("thirdset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, 1L, new HashSet<>(Collections.singletonList("bar")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 1L, new HashSet<>(Collections.singletonList("bar")))); } @Test @@ -1732,7 +1942,8 @@ void testSIsMember() { actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sIsMember("myset", "foo")); actual.add(connection.sIsMember("myset", "baz")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, true, false })); + + verifyResults(Arrays.asList(1L, 1L, true, false)); } @Test // GH-2037 @@ -1742,7 +1953,8 @@ void testSMIsMember() { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sMIsMember("myset", "foo", "bar", "baz")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, Arrays.asList(true, true, false) })); + + verifyResults(Arrays.asList(1L, 1L, Arrays.asList(true, true, false))); } @Test @@ -1752,7 +1964,8 @@ void testSMove() { actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sMove("myset", "otherset", "foo")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, true })); + + verifyResults(Arrays.asList(1L, 1L, 1L, true)); } @Test @@ -1761,10 +1974,12 @@ void testSPop() { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sPop("myset")); + assertThat(new HashSet<>(Arrays.asList("foo", "bar")).contains((String) getResults().get(2))).isTrue(); } @Test // DATAREDIS-688 + @SuppressWarnings("unchecked") void testSPopWithCount() { actual.add(connection.sAdd("myset", "foo")); @@ -1777,9 +1992,11 @@ void testSPopWithCount() { @Test void testSRandMember() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sRandMember("myset")); + assertThat(new HashSet<>(Arrays.asList("foo", "bar")).contains(getResults().get(2))).isTrue(); } @@ -1792,18 +2009,21 @@ void testSRandMemberKeyNotExists() { @SuppressWarnings("rawtypes") @Test void testSRandMemberCount() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("myset", "baz")); actual.add(connection.sRandMember("myset", 2)); + assertThat(((Collection) getResults().get(3)).size() == 2).isTrue(); } - @SuppressWarnings("rawtypes") @Test void testSRandMemberCountNegative() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sRandMember("myset", -2)); + assertThat(getResults().get(1)).isEqualTo(Arrays.asList("foo", "foo")); } @@ -1816,67 +2036,82 @@ void testSRandMemberCountKeyNotExists() { @Test void testSRem() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sRem("myset", "foo")); actual.add(connection.sRem("myset", "baz")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, 0L, new HashSet<>(Collections.singletonList("bar")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 0L, new HashSet<>(Collections.singletonList("bar")))); } @Test void testSRemMultiple() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("myset", "baz")); actual.add(connection.sRem("myset", "foo", "nope", "baz")); actual.add(connection.sMembers("myset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, 2L, new HashSet<>(Collections.singletonList("bar")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 2L, new HashSet<>(Collections.singletonList("bar")))); } @Test void testSUnion() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sAdd("otherset", "baz")); actual.add(connection.sUnion("myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L, 1L, 1L, new HashSet<>(Arrays.asList("foo", "bar", "baz")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 1L, new HashSet<>(Arrays.asList("foo", "bar", "baz")))); } @Test void testSUnionStore() { + actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("otherset", "bar")); actual.add(connection.sAdd("otherset", "baz")); actual.add(connection.sUnionStore("thirdset", "myset", "otherset")); actual.add(connection.sMembers("thirdset")); - verifyResults( - Arrays.asList(new Object[] { 1L, 1L, 1L, 1L, 3L, new HashSet<>(Arrays.asList("foo", "bar", "baz")) })); + + verifyResults(Arrays.asList(1L, 1L, 1L, 1L, 3L, new HashSet<>(Arrays.asList("foo", "bar", "baz")))); } // ZSet @Test void testZAddAndZRange() { + actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("James", "Bob")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList("James", "Bob")))); } @Test void testZAddMultiple() { + Set strTuples = new HashSet<>(); + strTuples.add(new DefaultStringTuple("Bob".getBytes(), "Bob", 2.0)); strTuples.add(new DefaultStringTuple("James".getBytes(), "James", 1.0)); + Set tuples = new HashSet<>(); + tuples.add(new DefaultTuple("Joe".getBytes(), 2.5)); + actual.add(connection.zAdd("myset", strTuples)); actual.add(connection.zAdd("myset".getBytes(), tuples)); actual.add(connection.zRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { 2L, 1L, new LinkedHashSet<>(Arrays.asList("James", "Bob", "Joe")) })); + + verifyResults(Arrays.asList(2L, 1L, new LinkedHashSet<>(Arrays.asList("James", "Bob", "Joe")))); } @Test // GH-1794 @@ -1904,10 +2139,12 @@ void testZAddMultipleNX() { actual.add(connection.zAdd("myset", 1, "James")); Set strTuples = new HashSet<>(); + strTuples.add(new DefaultStringTuple("Bob".getBytes(), "Bob", 2.0)); strTuples.add(new DefaultStringTuple("James".getBytes(), "James", 1.0)); actual.add(connection.zAdd("myset", strTuples, ZAddArgs.ifNotExists())); + verifyResults(Arrays.asList(true, 1L)); } @@ -1917,28 +2154,34 @@ void testZAddMultipleXX() { actual.add(connection.zAdd("myset", 1, "James")); Set strTuples = new HashSet<>(); + strTuples.add(new DefaultStringTuple("Bob".getBytes(), "Bob", 2.0)); strTuples.add(new DefaultStringTuple("James".getBytes(), "James", 2.0)); actual.add(connection.zAdd("myset", strTuples, ZAddArgs.ifNotExists())); + verifyResults(Arrays.asList(true, 1L)); } @Test void testZCard() { + actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zCard("myset")); - verifyResults(Arrays.asList(new Object[] { true, true, 2L })); + + verifyResults(Arrays.asList(true, true, 2L)); } @Test void testZCount() { + actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 4, "Joe")); actual.add(connection.zCount("myset", 1, 2)); - verifyResults(Arrays.asList(new Object[] { true, true, true, 2L })); + + verifyResults(Arrays.asList(true, true, true, 2L)); } @Test // DATAREDIS-729 @@ -1951,7 +2194,6 @@ void zLexCountTest() { actual.add(connection.zAdd("myzset", 0, "e")); actual.add(connection.zAdd("myzset", 0, "f")); actual.add(connection.zAdd("myzset", 0, "g")); - actual.add(connection.zLexCount("myzset", Range.unbounded())); actual.add(connection.zLexCount("myzset", Range.leftUnbounded(Bound.exclusive("c")))); actual.add(connection.zLexCount("myzset", Range.leftUnbounded(Bound.inclusive("c")))); @@ -1969,13 +2211,13 @@ void zLexCountTest() { @Test // GH-2007 @EnabledOnCommand("ZPOPMIN") + @SuppressWarnings("unchecked") void zPopMin() { actual.add(connection.zAdd("myzset", 1, "a")); actual.add(connection.zAdd("myzset", 2, "b")); actual.add(connection.zAdd("myzset", 3, "c")); actual.add(connection.zAdd("myzset", 4, "d")); - actual.add(connection.zPopMin("myzset")); actual.add(connection.bZPopMin("myzset", 1, TimeUnit.SECONDS)); actual.add(connection.zPopMin("myzset", 2)); @@ -1985,20 +2227,20 @@ void zPopMin() { assertThat(results.get(4)).isEqualTo(new DefaultStringTuple("a".getBytes(), "a", 1D)); assertThat(results.get(5)).isEqualTo(new DefaultStringTuple("b".getBytes(), "b", 2D)); - assertThat((Collection) results.get(6)).containsExactly(new DefaultStringTuple("c".getBytes(), "c", 3D), + assertThat((Collection) results.get(6)).containsExactly(new DefaultStringTuple("c".getBytes(), "c", 3D), new DefaultStringTuple("d".getBytes(), "d", 4D)); assertThat(results.get(7)).isNull(); } @Test // GH-2007 @EnabledOnCommand("ZPOPMAX") + @SuppressWarnings("unchecked") void zPopMax() { actual.add(connection.zAdd("myzset", 1, "a")); actual.add(connection.zAdd("myzset", 2, "b")); actual.add(connection.zAdd("myzset", 3, "c")); actual.add(connection.zAdd("myzset", 4, "d")); - actual.add(connection.zPopMax("myzset")); actual.add(connection.bZPopMax("myzset", 1, TimeUnit.SECONDS)); actual.add(connection.zPopMax("myzset", 2)); @@ -2008,7 +2250,7 @@ void zPopMax() { assertThat(results.get(4)).isEqualTo(new DefaultStringTuple("d".getBytes(), "d", 4D)); assertThat(results.get(5)).isEqualTo(new DefaultStringTuple("c".getBytes(), "c", 3D)); - assertThat((Collection) results.get(6)).containsExactly(new DefaultStringTuple("b".getBytes(), "b", 2D), + assertThat((Collection) results.get(6)).containsExactly(new DefaultStringTuple("b".getBytes(), "b", 2D), new DefaultStringTuple("a".getBytes(), "a", 1D)); assertThat(results.get(7)).isNull(); } @@ -2021,8 +2263,8 @@ void testZIncrBy() { actual.add(connection.zAdd("myset", 4, "Joe")); actual.add(connection.zIncrBy("myset", 2, "Joe")); actual.add(connection.zRangeByScore("myset", 6, 6)); - verifyResults( - Arrays.asList(new Object[] { true, true, true, 6d, new LinkedHashSet<>(Collections.singletonList("Joe")) })); + + verifyResults(Arrays.asList(true, true, true, 6d, new LinkedHashSet<>(Collections.singletonList("Joe")))); } @Test // GH-2041 @@ -2036,8 +2278,9 @@ void testZDiff() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zDiff("myset", "otherset")); actual.add(connection.zDiffWithScores("myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, Collections.singleton("Joe"), - Collections.singleton(new DefaultStringTuple("Joe", 4)) })); + + verifyResults(Arrays.asList(true, true, true, true, true, Collections.singleton("Joe"), + Collections.singleton(new DefaultStringTuple("Joe", 4)))); } @Test // GH-2041 @@ -2051,7 +2294,8 @@ void testZDiffStore() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zDiffStore("thirdset", "myset", "otherset")); actual.add(connection.zRange("thirdset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 1L, Collections.singleton("Joe") })); + + verifyResults(Arrays.asList(true, true, true, true, true, 1L, Collections.singleton("Joe"))); } @Test // GH-2042 @@ -2065,9 +2309,9 @@ void testZInter() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zInter("myset", "otherset")); actual.add(connection.zInterWithScores("myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, - new LinkedHashSet<>(Arrays.asList("Bob", "James")), - new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 3d), new DefaultStringTuple("James", 5))) })); + + verifyResults(Arrays.asList(true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")), + new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 3d), new DefaultStringTuple("James", 5))))); } @Test // GH-2042 @@ -2082,9 +2326,8 @@ void testZInterAggWeights() { actual.add(connection.zInter("myset", "otherset")); actual.add(connection.zInterWithScores(Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, - new LinkedHashSet<>(Arrays.asList("Bob", "James")), - new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 4d), new DefaultStringTuple("James", 12d))) })); + verifyResults(Arrays.asList(true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")), + new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 4d), new DefaultStringTuple("James", 12d))))); } @Test @@ -2097,8 +2340,8 @@ void testZInterStore() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zInterStore("thirdset", "myset", "otherset")); actual.add(connection.zRange("thirdset", 0, -1)); - verifyResults(Arrays - .asList(new Object[] { true, true, true, true, true, 2L, new LinkedHashSet<>(Arrays.asList("Bob", "James")) })); + + verifyResults(Arrays.asList(true, true, true, true, true, 2L, new LinkedHashSet<>(Arrays.asList("Bob", "James")))); } @Test @@ -2110,11 +2353,11 @@ void testZInterStoreAggWeights() { actual.add(connection.zAdd("otherset", 1, "Bob")); actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zInterStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); - actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 2L, + + verifyResults(Arrays.asList(true, true, true, true, true, 2L, new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("James".getBytes(), "James", 12d))) })); + new DefaultStringTuple("James".getBytes(), "James", 12d))))); } @Test // GH-2049 @@ -2129,12 +2372,13 @@ void testZRandMember() { List results = getResults(); assertThat(results.get(2)).isNotNull(); - assertThat(new LinkedHashSet<>((Collection) results.get(3))) + assertThat(new LinkedHashSet<>((Collection) results.get(3))) .isEqualTo(new LinkedHashSet<>(Arrays.asList("Bob", "James"))); } @Test // GH-2049 @EnabledOnCommand("ZRANDMEMBER") + @SuppressWarnings({ "unchecked" }) void testZRandMemberWithScore() { actual.add(connection.zAdd("myset", 2, "Bob")); @@ -2145,7 +2389,7 @@ void testZRandMemberWithScore() { List results = getResults(); assertThat(results.get(2)).isNotNull(); - assertThat(new LinkedHashSet<>((Collection) results.get(3))) + assertThat(new LinkedHashSet<>((Collection>>) results.get(3))) .isEqualTo(new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), new DefaultStringTuple("James".getBytes(), "James", 1d)))); } @@ -2156,9 +2400,10 @@ void testZRangeWithScores() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeWithScores("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("James".getBytes(), "James", 1d), - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))) })); + new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))))); } @Test @@ -2167,7 +2412,8 @@ void testZRangeByScore() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScore("myset", 1, 1)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("James")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Collections.singletonList("James")))); } @Test @@ -2176,7 +2422,8 @@ void testZRangeByScoreOffsetCount() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScore("myset", 1d, 3d, 1, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("Bob")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Collections.singletonList("Bob")))); } @Test @@ -2185,8 +2432,9 @@ void testZRangeByScoreWithScores() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScoreWithScores("myset", 2d, 5d)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))) })); + + verifyResults(Arrays.asList(true, true, + new LinkedHashSet<>(Collections.singletonList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))))); } @Test @@ -2195,8 +2443,9 @@ void testZRangeByScoreWithScoresOffsetCount() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRangeByScoreWithScores("myset", 1d, 5d, 0, 1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("James".getBytes(), "James", 1d))) })); + + verifyResults(Arrays.asList(true, true, + new LinkedHashSet<>(Collections.singletonList(new DefaultStringTuple("James".getBytes(), "James", 1d))))); } @Test @@ -2205,7 +2454,8 @@ void testZRevRange() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRevRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")))); } @Test @@ -2214,9 +2464,10 @@ void testZRevRangeWithScores() { actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRevRangeWithScores("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d))) })); + new DefaultStringTuple("James".getBytes(), "James", 1d))))); } @Test @@ -2225,7 +2476,8 @@ void testZRevRangeByScoreOffsetCount() { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScore("myset", 0d, 3d, 0, 5)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")))); } @Test @@ -2234,7 +2486,8 @@ void testZRevRangeByScore() { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScore("myset", 0d, 3d)); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James")))); } @Test @@ -2243,8 +2496,9 @@ void testZRevRangeByScoreWithScoresOffsetCount() { actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); actual.add(connection.zRevRangeByScoreWithScores("myset", 0d, 3d, 0, 1)); - verifyResults(Arrays.asList(new Object[] { true, true, - new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))) })); + + verifyResults(Arrays.asList(true, true, + new LinkedHashSet<>(Collections.singletonList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d))))); } @Test @@ -2254,9 +2508,10 @@ void testZRevRangeByScoreWithScores() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 3, "Joe")); actual.add(connection.zRevRangeByScoreWithScores("myset", 0d, 2d)); - verifyResults(Arrays.asList(new Object[] { true, true, true, + + verifyResults(Arrays.asList(true, true, true, new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d))) })); + new DefaultStringTuple("James".getBytes(), "James", 1d))))); } @Test @@ -2266,7 +2521,8 @@ void testZRank() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRank("myset", "James")); actual.add(connection.zRank("myset", "Bob")); - verifyResults(Arrays.asList(new Object[] { true, true, 0L, 1L })); + + verifyResults(Arrays.asList(true, true, 0L, 1L)); } @Test @@ -2276,7 +2532,8 @@ void testZRem() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRem("myset", "James")); actual.add(connection.zRange("myset", 0L, -1L)); - verifyResults(Arrays.asList(new Object[] { true, true, 1L, new LinkedHashSet<>(Arrays.asList("Bob")) })); + + verifyResults(Arrays.asList(true, true, 1L, new LinkedHashSet<>(Collections.singletonList("Bob")))); } @Test @@ -2288,8 +2545,8 @@ void testZRemMultiple() { actual.add(connection.zAdd("myset", 2.5, "Jen")); actual.add(connection.zRem("myset", "James", "Jen")); actual.add(connection.zRange("myset", 0L, -1L)); - verifyResults( - Arrays.asList(new Object[] { true, true, true, true, 2L, new LinkedHashSet<>(Arrays.asList("Joe", "Bob")) })); + + verifyResults(Arrays.asList(true, true, true, true, 2L, new LinkedHashSet<>(Arrays.asList("Joe", "Bob")))); } @Test @@ -2299,7 +2556,8 @@ void testZRemRangeByRank() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRemRange("myset", 0L, 3L)); actual.add(connection.zRange("myset", 0L, -1L)); - verifyResults(Arrays.asList(new Object[] { true, true, 2L, new LinkedHashSet(0) })); + + verifyResults(Arrays.asList(true, true, 2L, new LinkedHashSet<>(0))); } @Test // GH-1816 @@ -2316,8 +2574,8 @@ void testZRemRangeByLex() { actual.add(connection.zAdd("myset", 0, "ALPHA")); actual.add(connection.zAdd("myset", 0, "alpha")); actual.add(connection.zRemRangeByLex("myset", Range.closed("alpha", "omega"))); - actual.add(connection.zRange("myset", 0L, -1L)); + verifyResults(Arrays.asList(true, true, true, true, true, true, true, true, true, true, 6L, new LinkedHashSet<>(Arrays.asList("ALPHA", "aaaa", "zap", "zip")))); } @@ -2329,8 +2587,8 @@ void testZRemRangeByScore() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zRemRangeByScore("myset", 0d, 1d)); actual.add(connection.zRange("myset", 0L, -1L)); - verifyResults( - Arrays.asList(new Object[] { true, true, 1L, new LinkedHashSet<>(Collections.singletonList("Bob")) })); + + verifyResults(Arrays.asList(true, true, 1L, new LinkedHashSet<>(Collections.singletonList("Bob")))); } @Test @@ -2340,7 +2598,8 @@ void testZRevRank() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 3, "Joe")); actual.add(connection.zRevRank("myset", "Joe")); - verifyResults(Arrays.asList(new Object[] { true, true, true, 0L })); + + verifyResults(Arrays.asList(true, true, true, 0L)); } @Test @@ -2350,7 +2609,8 @@ void testZScore() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 3, "Joe")); actual.add(connection.zScore("myset", "Joe")); - verifyResults(Arrays.asList(new Object[] { true, true, true, 3d })); + + verifyResults(Arrays.asList(true, true, true, 3d)); } @Test @@ -2361,12 +2621,14 @@ void testZMScore() { actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 3, "Joe")); actual.add(connection.zMScore("myset", "James", "Joe", "Dave")); - verifyResults(Arrays.asList(new Object[] { true, true, true, Arrays.asList(1d, 3d, null) })); + + verifyResults(Arrays.asList(true, true, true, Arrays.asList(1d, 3d, null))); } @Test // GH-2042 @EnabledOnCommand("ZUNION") void testZUnion() { + actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 4, "Joe")); @@ -2374,15 +2636,16 @@ void testZUnion() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zUnion("myset", "otherset")); actual.add(connection.zUnionWithScores("myset", "otherset")); - verifyResults(Arrays - .asList(new Object[] { true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")), + + verifyResults(Arrays.asList(true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")), new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 3d), new DefaultStringTuple("James", 5), - new DefaultStringTuple("Joe", 4))) })); + new DefaultStringTuple("Joe", 4))))); } @Test // GH-2042 @EnabledOnCommand("ZUNION") void testZUnionAggWeights() { + actual.add(connection.zAdd("myset", 2, "Bob")); actual.add(connection.zAdd("myset", 1, "James")); actual.add(connection.zAdd("myset", 4, "Joe")); @@ -2391,10 +2654,9 @@ void testZUnionAggWeights() { actual.add(connection.zUnion("myset", "otherset")); actual.add(connection.zUnionWithScores(Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); - verifyResults(Arrays - .asList(new Object[] { true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")), + verifyResults(Arrays.asList(true, true, true, true, true, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")), new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 4d), new DefaultStringTuple("Joe", 8d), - new DefaultStringTuple("James", 12d))) })); + new DefaultStringTuple("James", 12d))))); } @Test @@ -2407,8 +2669,8 @@ void testZUnionStore() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zUnionStore("thirdset", "myset", "otherset")); actual.add(connection.zRange("thirdset", 0, -1)); - verifyResults(Arrays.asList( - new Object[] { true, true, true, true, true, 3L, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")) })); + + verifyResults(Arrays.asList(true, true, true, true, true, 3L, new LinkedHashSet<>(Arrays.asList("Bob", "James", "Joe")))); } @Test @@ -2421,105 +2683,131 @@ void testZUnionStoreAggWeights() { actual.add(connection.zAdd("otherset", 4, "James")); actual.add(connection.zUnionStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", "otherset")); actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 3L, + + verifyResults(Arrays.asList(true, true, true, true, true, 3L, new LinkedHashSet<>(Arrays.asList(new DefaultStringTuple("Bob", 4d), new DefaultStringTuple("Joe", 8d), - new DefaultStringTuple("James", 12d))) })); + new DefaultStringTuple("James", 12d))))); } // Hash Ops @Test void testHSetGet() { + String hash = getClass() + ":hashtest"; String key1 = UUID.randomUUID().toString(); String key2 = UUID.randomUUID().toString(); String value1 = "foo"; String value2 = "bar"; + actual.add(connection.hSet(hash, key1, value1)); actual.add(connection.hSet(hash, key2, value2)); actual.add(connection.hGet(hash, key1)); actual.add(connection.hGetAll(hash)); + Map expected = new HashMap<>(); + expected.put(key1, value1); expected.put(key2, value2); + verifyResults(Arrays.asList(true, true, value1, expected)); } @Test void testHSetNX() { + actual.add(connection.hSetNX("myhash", "key1", "foo")); actual.add(connection.hSetNX("myhash", "key1", "bar")); actual.add(connection.hGet("myhash", "key1")); - verifyResults(Arrays.asList(new Object[] { true, false, "foo" })); + + verifyResults(Arrays.asList(true, false, "foo")); } @Test void testHDel() { + actual.add(connection.hSet("test", "key", "val")); actual.add(connection.hDel("test", "key")); actual.add(connection.hDel("test", "foo")); actual.add(connection.hExists("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 1L, 0L, false })); + + verifyResults(Arrays.asList(true, 1L, 0L, false)); } @Test void testHDelMultiple() { + actual.add(connection.hSet("test", "key", "val")); actual.add(connection.hSet("test", "foo", "bar")); actual.add(connection.hDel("test", "key", "foo")); actual.add(connection.hExists("test", "key")); actual.add(connection.hExists("test", "foo")); - verifyResults(Arrays.asList(new Object[] { true, true, 2L, false, false })); + + verifyResults(Arrays.asList(true, true, 2L, false, false)); } @Test void testHIncrBy() { + actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hIncrBy("test", "key", 3L)); actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 5L, "5" })); + + verifyResults(Arrays.asList(true, 5L, "5")); } @Test @DisabledOnOs(value = MAC, architectures = "aarch64") void testHIncrByDouble() { + actual.add(connection.hSet("test", "key", "2.9")); actual.add(connection.hIncrBy("test", "key", 3.5)); actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 6.4d, "6.4" })); + + verifyResults(Arrays.asList(true, 6.4d, "6.4")); } @Test void testHKeys() { + actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hSet("test", "key2", "2")); actual.add(connection.hKeys("test")); - verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet<>(Arrays.asList("key", "key2")) })); + + verifyResults(Arrays.asList(true, true, new LinkedHashSet<>(Arrays.asList("key", "key2")))); } @Test void testHLen() { + actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hSet("test", "key2", "2")); actual.add(connection.hLen("test")); - verifyResults(Arrays.asList(new Object[] { true, true, 2L })); + + verifyResults(Arrays.asList(true, true, 2L)); } @Test void testHMGetSet() { + Map tuples = new HashMap<>(); + tuples.put("key", "foo"); tuples.put("key2", "bar"); + connection.hMSet("test", tuples); actual.add(connection.hMGet("test", "key", "key2")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList("foo", "bar") })); + + verifyResults(Collections.singletonList(Arrays.asList("foo", "bar"))); } @Test void testHVals() { + actual.add(connection.hSet("test", "key", "foo")); actual.add(connection.hSet("test", "key2", "bar")); actual.add(connection.hVals("test")); + verifyResults(Arrays.asList(true, true, Arrays.asList("foo", "bar"))); } @@ -2530,7 +2818,9 @@ public void testMove() { actual.add(connection.move("foo", 1)); verifyResults(Arrays.asList(true, true)); + connection.select(1); + try { assertThat(connection.get("foo")).isEqualTo("bar"); } finally { @@ -2542,9 +2832,10 @@ public void testMove() { @Test public void testLastSave() { + actual.add(connection.lastSave()); - List results = getResults(); - assertThat(results.get(0)).isNotNull(); + + assertThat(getResults().get(0)).isNotNull(); } @Test // DATAREDIS-206, DATAREDIS-513 @@ -2553,6 +2844,7 @@ public void testGetTimeShouldRequestServerTime() { actual.add(connection.time()); List results = getResults(); + assertThat(results).isNotEmpty(); assertThat(results.get(0)).isNotNull(); assertThat((Long) results.get(0) > 0).isTrue(); @@ -2566,16 +2858,14 @@ public void testGetTimeShouldRequestServerTimeAsMicros() { actual.add(connection.time(TimeUnit.HOURS)); List results = getResults(); + assertThat(results).isNotEmpty(); assertThat(results.get(0)).isNotNull(); Instant now = Instant.now(); Instant reference = Instant.parse("1970-01-01T00:00:00.0Z"); - Instant micros = reference.plus(Duration.ofNanos(TimeUnit.MICROSECONDS.toNanos((Long) results.get(0)))); - Instant seconds = reference.plus(Duration.ofNanos(TimeUnit.SECONDS.toNanos((Long) results.get(1)))); - Instant hours = reference.plus(Duration.ofNanos(TimeUnit.HOURS.toNanos((Long) results.get(2)))); assertThat(micros).isCloseTo(now, within(1, ChronoUnit.MINUTES)); @@ -2594,13 +2884,16 @@ public void testListClientsContainsAtLeastOneElement() { actual.add(connection.getClientList()); List results = getResults(); + assertThat(results.get(0)).isNotNull(); List firstEntry = (List) results.get(0); + assertThat(firstEntry.size()).isNotEqualTo(0); assertThat(firstEntry.get(0)).isInstanceOf(RedisClientInfo.class); RedisClientInfo info = (RedisClientInfo) firstEntry.get(0); + assertThat(info.getDatabaseId()).isNotNull(); } @@ -2618,6 +2911,7 @@ void scanShouldReadEntireValueRange() { connection.set("spring", "data"); int itemCount = 22; + for (int i = 0; i < itemCount; i++) { connection.set(("key_" + i), ("foo_" + i)); } @@ -2625,6 +2919,7 @@ void scanShouldReadEntireValueRange() { Cursor cursor = connection.scan(scanOptions().count(20).match("ke*").build()); int i = 0; + while (cursor.hasNext()) { byte[] value = cursor.next(); assertThat(new String(value)).doesNotContain("spring"); @@ -2647,15 +2942,19 @@ void scanWithType() { connection.sAdd("set", "foo"); Cursor cursor = connection.scan(KeyScanOptions.scanOptions().type("set").build()); + assertThat(toList(cursor)).hasSize(1).contains("set"); cursor = connection.scan(KeyScanOptions.scanOptions().type("string").match("k*").build()); + assertThat(toList(cursor)).hasSize(1).contains("key"); cursor = connection.scan(KeyScanOptions.scanOptions().match("k*").build()); + assertThat(toList(cursor)).hasSize(1).contains("key"); cursor = connection.scan(KeyScanOptions.scanOptions().build()); + assertThat(toList(cursor)).contains("key", "list", "set"); } @@ -2671,13 +2970,14 @@ public void scanShouldReadEntireValueRangeWhenIdividualScanIterationsReturnEmpty Cursor cursor = connection.scan(ScanOptions.scanOptions().match("key*9").count(10).build()); - int i = 0; + int count = 0; + while (cursor.hasNext()) { assertThat(new String(cursor.next())).contains("key:"); - i++; + count++; } - assertThat(i).isEqualTo(10); + assertThat(count).isEqualTo(10); } @Test // DATAREDIS-306 @@ -2698,6 +2998,7 @@ void zScanShouldReadEntireValueRange() { Cursor tuples = connection.zScan("myset", ScanOptions.NONE); int count = 0; + while (tuples.hasNext()) { StringTuple tuple = tuples.next(); @@ -2727,13 +3028,14 @@ void sScanShouldReadEntireValueRange() { Cursor cursor = connection.sScan("sscankey", scanOptions().count(2).match("fo*").build()); - int i = 0; + int count = 0; + while (cursor.hasNext()) { assertThat(cursor.next()).doesNotContain("bar"); - i++; + count++; } - assertThat(i).isEqualTo(6); + assertThat(count).isEqualTo(6); } @Test // DATAREDIS-305 @@ -2748,7 +3050,6 @@ void hScanShouldReadEntireValueRange() { } connection.hSet("hscankey", "bar", "foobar"); - connection.hSet("hscankey", "foo-1", "v-1"); connection.hSet("hscankey", "foo-2", "v-2"); connection.hSet("hscankey", "foo-3", "v-3"); @@ -2756,7 +3057,8 @@ void hScanShouldReadEntireValueRange() { Cursor> cursor = connection.hScan("hscankey", scanOptions().count(2).match("fo*").build()); - int i = 0; + int count = 0; + while (cursor.hasNext()) { String key = cursor.next().getKey(); @@ -2764,10 +3066,10 @@ void hScanShouldReadEntireValueRange() { assertThat(key).doesNotContain("bar"); assertThat(key).contains("foo"); - i++; + count++; } - assertThat(i).isEqualTo(3); + assertThat(count).isEqualTo(3); } @Test // DATAREDIS-308 @@ -2775,8 +3077,7 @@ void pfAddShouldAddToNonExistingKeyCorrectly() { actual.add(connection.pfAdd("hll", "a", "b", "c")); - List results = getResults(); - assertThat(results.get(0)).isEqualTo(1L); + assertThat(getResults().get(0)).isEqualTo(1L); } @Test // DATAREDIS-308 @@ -2787,6 +3088,7 @@ void pfAddShouldReturnZeroWhenValueAlreadyExists() { actual.add(connection.pfAdd("hll2", "e")); List results = getResults(); + assertThat(results.get(0)).isEqualTo(1L); assertThat(results.get(1)).isEqualTo(1L); assertThat(results.get(2)).isEqualTo(0L); @@ -2799,6 +3101,7 @@ void pfCountShouldReturnCorrectly() { actual.add(connection.pfCount("hll")); List results = getResults(); + assertThat(results.get(0)).isEqualTo(1L); assertThat(results.get(1)).isEqualTo(3L); } @@ -2811,6 +3114,7 @@ void pfCountWithMultipleKeysShouldReturnCorrectly() { actual.add(connection.pfCount("hll", "hll2")); List results = getResults(); + assertThat(results.get(0)).isEqualTo(1L); assertThat(results.get(1)).isEqualTo(1L); assertThat(results.get(2)).isEqualTo(6L); @@ -2832,16 +3136,13 @@ void zRangeByLexTest() { actual.add(connection.zAdd("myzset", 0, "e")); actual.add(connection.zAdd("myzset", 0, "f")); actual.add(connection.zAdd("myzset", 0, "g")); - actual.add(connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")))); actual.add(connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.exclusive("c")))); actual.add(connection.zRangeByLex("myzset", Range.rightOpen("aaa", "g"))); actual.add(connection.zRangeByLex("myzset", Range.rightUnbounded(Bound.inclusive("e")))); - actual.add(connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")), Limit.unlimited())); actual.add(connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")), Limit.limit().count(1))); - actual.add( - connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")), Limit.limit().count(1).offset(1))); + actual.add(connection.zRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")), Limit.limit().count(1).offset(1))); List results = getResults(); @@ -2865,16 +3166,13 @@ public void zRevRangeByLexTest() { actual.add(connection.zAdd("myzset", 0, "e")); actual.add(connection.zAdd("myzset", 0, "f")); actual.add(connection.zAdd("myzset", 0, "g")); - actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")))); actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.exclusive("c")))); actual.add(connection.zRevRangeByLex("myzset", Range.rightOpen("aaa", "g"))); actual.add(connection.zRevRangeByLex("myzset", Range.rightUnbounded(Bound.inclusive("e")))); - actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("c")), Limit.unlimited())); actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("d")), Limit.limit().count(2))); - actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("d")), - Limit.limit().count(2).offset(1))); + actual.add(connection.zRevRangeByLex("myzset", Range.leftUnbounded(Bound.inclusive("d")), Limit.limit().count(2).offset(1))); List results = getResults(); @@ -2899,12 +3197,13 @@ void setWithExpirationAndNullOpionShouldThrowException() { void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "foo", Expiration.milliseconds(500), SetOption.upsert())); + actual.add(connection.set(key, "foo", Expiration.milliseconds(500), SetOption.upsert())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(500d, Offset.offset(499d)); @@ -2914,14 +3213,15 @@ void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() { void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.upsert())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(result.get(2)).isEqualTo(Boolean.TRUE); @@ -2933,14 +3233,15 @@ void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() { void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifAbsent())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.FALSE); assertThat(result.get(2)).isEqualTo(Boolean.TRUE); @@ -2952,13 +3253,14 @@ void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() { void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifAbsent())); + actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifAbsent())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(500d, Offset.offset(499d)); @@ -2969,14 +3271,15 @@ void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() { void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifPresent())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(result.get(2)).isEqualTo(Boolean.TRUE); @@ -2988,13 +3291,14 @@ void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() { void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifPresent())); + actual.add(connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifPresent())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.FALSE); assertThat(result.get(1)).isEqualTo(Boolean.FALSE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(-2, Offset.offset(0d)); @@ -3004,6 +3308,7 @@ void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() { void setWithNullExpirationAndUpsertOpionShouldThrowException() { String key = "exp-" + UUID.randomUUID(); + assertThatIllegalArgumentException().isThrownBy(() -> connection.set(key, "foo", null, SetOption.upsert())); } @@ -3011,12 +3316,13 @@ void setWithNullExpirationAndUpsertOpionShouldThrowException() { void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "foo", Expiration.persistent(), SetOption.upsert())); + actual.add(connection.set(key, "foo", Expiration.persistent(), SetOption.upsert())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(-1, Offset.offset(0d)); @@ -3026,9 +3332,9 @@ void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() { void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.upsert())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); @@ -3046,14 +3352,15 @@ void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() { void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifAbsent())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.FALSE); assertThat(result.get(2)).isEqualTo(Boolean.TRUE); @@ -3065,13 +3372,14 @@ void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() { void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifAbsent())); + actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifAbsent())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(-1, Offset.offset(0d)); @@ -3082,14 +3390,15 @@ void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() { void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() { String key = "exp-" + UUID.randomUUID(); + actual.add(connection.set(key, "spring")); actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifPresent())); - actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.TRUE); assertThat(result.get(1)).isEqualTo(Boolean.TRUE); assertThat(result.get(2)).isEqualTo(Boolean.TRUE); @@ -3101,13 +3410,14 @@ void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() { void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() { String key = "exp-" + UUID.randomUUID(); - actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifPresent())); + actual.add(connection.set(key, "data", Expiration.persistent(), SetOption.ifPresent())); actual.add(connection.exists(key)); actual.add(connection.pTtl(key)); actual.add(connection.get(key)); List result = getResults(); + assertThat(result.get(0)).isEqualTo(Boolean.FALSE); assertThat(result.get(1)).isEqualTo(Boolean.FALSE); assertThat(((Long) result.get(2)).doubleValue()).isCloseTo(-2, Offset.offset(0d)); @@ -3117,30 +3427,32 @@ void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() { void geoAddSingleGeoLocation() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, PALERMO)); - List result = getResults(); - assertThat(result.get(0)).isEqualTo(1L); + assertThat(getResults().get(0)).isEqualTo(1L); } @Test // DATAREDIS-438 void geoAddMultipleGeoLocations() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, ARIGENTO, CATANIA, PALERMO))); - List result = getResults(); - assertThat(result.get(0)).isEqualTo(3L); + assertThat(getResults().get(0)).isEqualTo(3L); } @Test // DATAREDIS-438 void geoDist() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoDist(key, PALERMO.getName(), CATANIA.getName())); List result = getResults(); + assertThat(((Distance) result.get(1)).getValue()).isCloseTo(166274.15156960033D, Offset.offset(0.005)); assertThat(((Distance) result.get(1)).getUnit()).isEqualTo("m"); } @@ -3149,110 +3461,123 @@ void geoDist() { void geoDistNotExisting() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoDist(key, "Spring", "Data")); - List result = getResults(); - assertThat(result.get(1)).isNull(); + assertThat(getResults().get(1)).isNull(); } @Test // DATAREDIS-438 void geoDistWithMetric() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoDist(key, PALERMO.getName(), CATANIA.getName(), Metrics.KILOMETERS)); List result = getResults(); + assertThat(((Distance) result.get(1)).getValue()).isCloseTo(166.27415156960033D, Offset.offset(0.005)); assertThat(((Distance) result.get(1)).getUnit()).isEqualTo("km"); } @Test // DATAREDIS-438 @EnabledOnRedisDriver({ RedisDriver.JEDIS }) + @SuppressWarnings("unchecked") void geoHash() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoHash(key, PALERMO.getName(), CATANIA.getName())); List result = getResults(); + assertThat(((List) result.get(1)).get(0)).isEqualTo("sqc8b49rny0"); assertThat(((List) result.get(1)).get(1)).isEqualTo("sqdtr74hyu0"); } @Test // DATAREDIS-438 @EnabledOnRedisDriver({ RedisDriver.JEDIS }) + @SuppressWarnings("unchecked") void geoHashNonExisting() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoHash(key, PALERMO.getName(), ARIGENTO.getName(), CATANIA.getName())); List result = getResults(); + assertThat(((List) result.get(1)).get(0)).isEqualTo("sqc8b49rny0"); assertThat(((List) result.get(1)).get(1)).isNull(); assertThat(((List) result.get(1)).get(2)).isEqualTo("sqdtr74hyu0"); } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoPosition() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoPos(key, PALERMO.getName(), CATANIA.getName())); List result = getResults(); + assertThat(((List) result.get(1)).get(0).getX()).isCloseTo(POINT_PALERMO.getX(), Offset.offset(0.005)); assertThat(((List) result.get(1)).get(0).getY()).isCloseTo(POINT_PALERMO.getY(), Offset.offset(0.005)); - assertThat(((List) result.get(1)).get(1).getX()).isCloseTo(POINT_CATANIA.getX(), Offset.offset(0.005)); assertThat(((List) result.get(1)).get(1).getY()).isCloseTo(POINT_CATANIA.getY(), Offset.offset(0.005)); } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoPositionNonExisting() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); + actual.add(connection.geoAdd(key, Arrays.asList(PALERMO, CATANIA))); actual.add(connection.geoPos(key, PALERMO.getName(), ARIGENTO.getName(), CATANIA.getName())); List result = getResults(); + assertThat(((List) result.get(1)).get(0).getX()).isCloseTo(POINT_PALERMO.getX(), Offset.offset(0.005)); assertThat(((List) result.get(1)).get(0).getY()).isCloseTo(POINT_PALERMO.getY(), Offset.offset(0.005)); - assertThat(((List) result.get(1)).get(1)).isNull(); - assertThat(((List) result.get(1)).get(2).getX()).isCloseTo(POINT_CATANIA.getX(), Offset.offset(0.005)); assertThat(((List) result.get(1)).get(2).getY()).isCloseTo(POINT_CATANIA.getY(), Offset.offset(0.005)); } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoRadiusShouldReturnMembersCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)))); actual.add(connection.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(150D, KILOMETERS)))); List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent()).hasSize(3); assertThat(((GeoResults>) results.get(2)).getContent()).hasSize(2); } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoRadiusShouldReturnDistanceCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().includeDistance())); List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent()).hasSize(3); assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getValue()) .isCloseTo(130.423D, Offset.offset(0.005)); @@ -3261,28 +3586,30 @@ void geoRadiusShouldReturnDistanceCorrectly() { } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoRadiusShouldApplyLimit() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoRadius(key, new Circle(new Point(15D, 37D), new Distance(200D, KILOMETERS)), newGeoRadiusArgs().limit(2))); - List results = getResults(); - assertThat(((GeoResults>) results.get(1)).getContent()).hasSize(2); + assertThat(((GeoResults>) getResults().get(1)).getContent()).hasSize(2); } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoRadiusByMemberShouldReturnMembersCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoRadiusByMember(key, PALERMO.getName(), new Distance(100, KILOMETERS), newGeoRadiusArgs().sortAscending())); List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent().get(0).getContent().getName()) .isEqualTo(PALERMO.getName()); assertThat(((GeoResults>) results.get(1)).getContent().get(1).getContent().getName()) @@ -3290,15 +3617,17 @@ void geoRadiusByMemberShouldReturnMembersCorrectly() { } @Test // DATAREDIS-438 + @SuppressWarnings("unchecked") void geoRadiusByMemberShouldReturnDistanceCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoRadiusByMember(key, PALERMO.getName(), new Distance(100, KILOMETERS), newGeoRadiusArgs().includeDistance())); List results = getResults(); + assertThat(((GeoResults>) results.get(1)).getContent()).hasSize(2); assertThat(((GeoResults>) results.get(1)).getContent().get(0).getDistance().getValue()) .isCloseTo(90.978D, Offset.offset(0.005)); @@ -3307,6 +3636,7 @@ void geoRadiusByMemberShouldReturnDistanceCorrectly() { } @Test // DATAREDIS-438 + @SuppressWarnings({ "unchecked" }) void geoRadiusByMemberShouldApplyLimit() { String key = "geo-" + UUID.randomUUID(); @@ -3321,16 +3651,17 @@ void geoRadiusByMemberShouldApplyLimit() { @Test // GH-2043 @EnabledOnCommand("GEOSEARCH") + @SuppressWarnings("unchecked") void geoSearchByMemberShouldReturnMembersCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoSearch(key, GeoReference.fromMember(PALERMO), GeoShape.byRadius(new Distance(200, KILOMETERS)), newGeoSearchArgs().limit(2))); - List results = getResults(); - List>> content = ((GeoResults>) results.get(1)).getContent(); + List>> content = ((GeoResults>) getResults().get(1)).getContent(); + assertThat(content).hasSize(2); assertThat(content.get(0).getDistance()).isEqualTo(new Distance(0, KILOMETERS)); assertThat(content.get(0).getContent().getPoint()).isNull(); @@ -3338,16 +3669,17 @@ void geoSearchByMemberShouldReturnMembersCorrectly() { @Test // GH-2043 @EnabledOnCommand("GEOSEARCH") + @SuppressWarnings("unchecked") void geoSearchByPointShouldReturnMembersCorrectly() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoSearch(key, GeoReference.fromCoordinate(PALERMO), GeoShape.byRadius(new Distance(200, KILOMETERS)), newGeoSearchArgs().limit(2))); - List results = getResults(); - List>> content = ((GeoResults>) results.get(1)).getContent(); + List>> content = ((GeoResults>) getResults().get(1)).getContent(); + assertThat(content).hasSize(2); assertThat(content.get(0).getDistance()).isEqualTo(new Distance(0, KILOMETERS)); assertThat(content.get(0).getContent().getPoint()).isNull(); @@ -3355,18 +3687,18 @@ void geoSearchByPointShouldReturnMembersCorrectly() { @Test // GH-2043 @EnabledOnCommand("GEOSEARCH") + @SuppressWarnings("unchecked") void geoSearchShouldConsiderDistanceCorrectly() { String key = "geo-" + UUID.randomUUID(); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoSearch(key, GeoReference.fromMember(PALERMO), + GeoShape.byRadius(new Distance(200, KILOMETERS)), + newGeoSearchArgs().limit(2).includeDistance().includeCoordinates())); - actual.add( - connection.geoSearch(key, GeoReference.fromMember(PALERMO), - GeoShape.byRadius(new Distance(200, KILOMETERS)), - newGeoSearchArgs().limit(2).includeDistance().includeCoordinates())); + List>> content = ((GeoResults>) getResults().get(1)).getContent(); - List results = getResults(); - List>> content = ((GeoResults>) results.get(1)).getContent(); assertThat(content).hasSize(2); assertThat(content.get(0).getDistance()).isNotNull(); assertThat(content.get(0).getContent().getPoint()).isNotNull(); @@ -3377,8 +3709,8 @@ void geoSearchShouldConsiderDistanceCorrectly() { void geoSearchStoreByMemberShouldStoreResult() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoSearchStore("georesults", key, GeoReference.fromMember(PALERMO), GeoShape.byRadius(new Distance(200, KILOMETERS)), newGeoSearchStoreArgs().limit(2).storeDistance())); @@ -3386,6 +3718,7 @@ void geoSearchStoreByMemberShouldStoreResult() { actual.add(connection.zScore("georesults", ARIGENTO.getName())); List results = getResults(); + assertThat(results.get(1)).isEqualTo(2L); assertThat((Double) results.get(2)).isLessThan(1); assertThat((Double) results.get(3)).isGreaterThan(1); @@ -3396,8 +3729,8 @@ void geoSearchStoreByMemberShouldStoreResult() { void geoSearchStoreByPointShouldStoreResult() { String key = "geo-" + UUID.randomUUID(); - actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); + actual.add(connection.geoAdd(key, Arrays.asList(ARIGENTO, CATANIA, PALERMO))); actual.add(connection.geoSearchStore("georesults", key, GeoReference.fromCoordinate(PALERMO), GeoShape.byRadius(new Distance(200, KILOMETERS)), newGeoSearchStoreArgs().limit(2).storeDistance())); @@ -3405,6 +3738,7 @@ void geoSearchStoreByPointShouldStoreResult() { actual.add(connection.zScore("georesults", ARIGENTO.getName())); List results = getResults(); + assertThat(results.get(1)).isEqualTo(2L); assertThat((Double) results.get(2)).isLessThan(1); assertThat((Double) results.get(3)).isGreaterThan(1); @@ -3417,7 +3751,7 @@ void hStrLenReturnsFieldLength() { actual.add(connection.hSet("hash-hstrlen", "key-2", "value-2")); actual.add(connection.hStrLen("hash-hstrlen", "key-2")); - verifyResults(Arrays.asList(new Object[] { Boolean.TRUE, Boolean.TRUE, Long.valueOf("value-2".length()) })); + verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, (long) "value-2".length())); } @Test // DATAREDIS-698 @@ -3426,15 +3760,13 @@ void hStrLenReturnsZeroWhenFieldDoesNotExist() { actual.add(connection.hSet("hash-hstrlen", "key-1", "value-1")); actual.add(connection.hStrLen("hash-hstrlen", "key-2")); - verifyResults(Arrays.asList(new Object[] { Boolean.TRUE, 0L })); + verifyResults(Arrays.asList(Boolean.TRUE, 0L)); } @Test // DATAREDIS-698 void hStrLenReturnsZeroWhenKeyDoesNotExist() { - actual.add(connection.hStrLen("hash-no-exist", "key-2")); - - verifyResults(Arrays.asList(new Object[] { 0L })); + verifyResults(Collections.singletonList(0L)); } @Test // DATAREDIS-694 @@ -3443,15 +3775,13 @@ void touchReturnsNrOfKeysTouched() { actual.add(connection.set("touch.this", "Can't touch this; - oh-oh oh oh oh-oh-oh")); actual.add(connection.touch("touch.this", "touch.that")); - verifyResults(Arrays.asList(new Object[] { Boolean.TRUE, 1L })); + verifyResults(Arrays.asList(Boolean.TRUE, 1L)); } @Test // DATAREDIS-694 void touchReturnsZeroIfNoKeysTouched() { - actual.add(connection.touch("touch.this", "touch.that")); - - verifyResults(Arrays.asList(new Object[] { 0L })); + verifyResults(Collections.singletonList(0L)); } @Test // DATAREDIS-697 @@ -3460,7 +3790,7 @@ void bitPosShouldReturnPositionCorrectly() { actual.add(connection.set("bitpos-1".getBytes(), HexStringUtils.hexToBytes("fff000"))); actual.add(connection.bitPos("bitpos-1", false)); - verifyResults(Arrays.asList(new Object[] { true, 12L })); + verifyResults(Arrays.asList(true, 12L)); } @Test // DATAREDIS-697 @@ -3470,25 +3800,22 @@ void bitPosShouldReturnPositionInRangeCorrectly() { actual.add(connection.bitPos("bitpos-1", true, org.springframework.data.domain.Range.of(Bound.inclusive(2L), Bound.unbounded()))); - verifyResults(Arrays.asList(new Object[] { true, 16L })); + verifyResults(Arrays.asList(true, 16L)); } @Test // DATAREDIS-716 void encodingReturnsCorrectly() { actual.add(connection.set("encode.this", "1000")); - actual.add(connection.encodingOf("encode.this")); - verifyResults(Arrays.asList(new Object[] { true, RedisValueEncoding.INT })); + verifyResults(Arrays.asList(true, RedisValueEncoding.INT)); } @Test // DATAREDIS-716 void encodingReturnsVacantWhenKeyDoesNotExist() { - actual.add(connection.encodingOf("encode.this")); - - verifyResults(Arrays.asList(new Object[] { RedisValueEncoding.VACANT })); + verifyResults(Collections.singletonList(RedisValueEncoding.VACANT)); } @Test // DATAREDIS-716 @@ -3496,17 +3823,14 @@ void idletimeReturnsCorrectly() { actual.add(connection.set("idle.this", "1000")); actual.add(connection.get("idle.this")); - actual.add(connection.idletime("idle.this")); - verifyResults(Arrays.asList(new Object[] { true, "1000", Duration.ofSeconds(0) })); + verifyResults(Arrays.asList(true, "1000", Duration.ofSeconds(0))); } @Test // DATAREDIS-716 void idldetimeReturnsNullWhenKeyDoesNotExist() { - actual.add(connection.idletime("idle.this")); - verifyResults(Arrays.asList(new Object[] { null })); } @@ -3514,51 +3838,50 @@ void idldetimeReturnsNullWhenKeyDoesNotExist() { void refcountReturnsCorrectly() { actual.add(connection.lPush("refcount.this", "1000")); - actual.add(connection.refcount("refcount.this")); - verifyResults(Arrays.asList(new Object[] { 1L, 1L })); + verifyResults(Arrays.asList(1L, 1L)); } @Test // DATAREDIS-716 void refcountReturnsNullWhenKeyDoesNotExist() { - actual.add(connection.refcount("refcount.this")); - verifyResults(Arrays.asList(new Object[] { null })); } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitFieldSetShouldWorkCorrectly() { actual.add(connection.bitfield(KEY_1, create().set(INT_8).valueAt(BitFieldSubCommands.Offset.offset(0L)).to(10L))); actual.add(connection.bitfield(KEY_1, create().set(INT_8).valueAt(BitFieldSubCommands.Offset.offset(0L)).to(20L))); List results = getResults(); + assertThat((List) results.get(0)).containsExactly(0L); assertThat((List) results.get(1)).containsExactly(10L); } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitFieldGetShouldWorkCorrectly() { actual.add(connection.bitfield(KEY_1, create().get(INT_8).valueAt(BitFieldSubCommands.Offset.offset(0L)))); - List results = getResults(); - assertThat((List) results.get(0)).containsExactly(0L); + assertThat((List) getResults().get(0)).containsExactly(0L); } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitFieldIncrByShouldWorkCorrectly() { - actual - .add(connection.bitfield(KEY_1, create().incr(INT_8).valueAt(BitFieldSubCommands.Offset.offset(100L)).by(1L))); + actual.add(connection.bitfield(KEY_1, create().incr(INT_8).valueAt(BitFieldSubCommands.Offset.offset(100L)).by(1L))); - List results = getResults(); - assertThat((List) results.get(0)).containsExactly(1L); + assertThat((List) getResults().get(0)).containsExactly(1L); } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitFieldIncrByWithOverflowShouldWorkCorrectly() { actual.add(connection.bitfield(KEY_1, @@ -3571,6 +3894,7 @@ void bitFieldIncrByWithOverflowShouldWorkCorrectly() { create().incr(unsigned(2)).valueAt(BitFieldSubCommands.Offset.offset(102L)).overflow(FAIL).by(1L))); List results = getResults(); + assertThat((List) results.get(0)).containsExactly(1L); assertThat((List) results.get(1)).containsExactly(2L); assertThat((List) results.get(2)).containsExactly(3L); @@ -3578,6 +3902,7 @@ void bitFieldIncrByWithOverflowShouldWorkCorrectly() { } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitfieldShouldAllowMultipleSubcommands() { actual.add(connection.bitfield(KEY_1, @@ -3587,6 +3912,7 @@ void bitfieldShouldAllowMultipleSubcommands() { } @Test // DATAREDIS-562 + @SuppressWarnings("unchecked") void bitfieldShouldWorkUsingNonZeroBasedOffset() { actual.add(connection.bitfield(KEY_1, @@ -3597,6 +3923,7 @@ void bitfieldShouldWorkUsingNonZeroBasedOffset() { .valueAt(BitFieldSubCommands.Offset.offset(1L).multipliedByTypeLength()))); List results = getResults(); + assertThat((List) results.get(0)).containsExactly(0L, 0L); assertThat((List) results.get(1)).containsExactly(100L, -56L); } @@ -3609,6 +3936,7 @@ void xAddShouldCreateStream() { actual.add(connection.type(KEY_1)); List results = getResults(); + assertThat(results).hasSize(2); assertThat(((RecordId) results.get(0)).getValue()).contains("-"); assertThat(results.get(1)).isEqualTo(DataType.STREAM); @@ -3619,15 +3947,14 @@ void xAddShouldCreateStream() { void xAddShouldTrimStreamExactly() { RedisStreamCommands.XAddOptions xAddOptions = RedisStreamCommands.XAddOptions.maxlen(1); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); actual.add(connection.xLen(KEY_1)); List results = getResults(); + assertThat(results).hasSize(4); assertThat(((RecordId) results.get(0)).getValue()).contains("-"); assertThat((Long) results.get(3)).isEqualTo(1); @@ -3638,15 +3965,14 @@ void xAddShouldTrimStreamExactly() { void xAddShouldTrimStreamApprox() { RedisStreamCommands.XAddOptions xAddOptions = RedisStreamCommands.XAddOptions.maxlen(1).approximateTrimming(true); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); - actual.add( - connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); + actual.add(connection.xAdd(StringRecord.of(Collections.singletonMap(KEY_2, VALUE_2)).withStreamKey(KEY_1), xAddOptions)); actual.add(connection.xLen(KEY_1)); List results = getResults(); + assertThat(results).hasSize(4); assertThat(((RecordId) results.get(0)).getValue()).contains("-"); assertThat((Long) results.get(3)).isBetween(1L, 3L); @@ -3654,14 +3980,13 @@ void xAddShouldTrimStreamApprox() { @Test // DATAREDIS-864 @EnabledOnCommand("XADD") + @SuppressWarnings("unchecked") public void xReadShouldReadMessage() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); actual.add(connection.xReadAsString(StreamOffset.create(KEY_1, ReadOffset.from("0")))); - List results = getResults(); - - List> messages = (List) results.get(1); + List> messages = (List>) getResults().get(1); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); @@ -3669,6 +3994,7 @@ public void xReadShouldReadMessage() { @Test // DATAREDIS-864 @EnabledOnCommand("XADD") + @SuppressWarnings({ "rawtypes", "unchecked" }) public void xReadGroupShouldReadMessage() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); @@ -3679,39 +4005,36 @@ public void xReadGroupShouldReadMessage() { StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); List results = getResults(); - List> messages = (List) results.get(2); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); - assertThat((List) results.get(3)).isEmpty(); } @Test // DATAREDIS-864 @EnabledOnCommand("XADD") + @SuppressWarnings({ "rawtypes", "unchecked" }) public void xGroupCreateShouldWorkWithAndWithoutExistingStream() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group", true)); actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); - actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); List results = getResults(); - List> messages = (List) results.get(2); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); - assertThat((List) results.get(3)).isEmpty(); } @Test // DATAREDIS-864 @EnabledOnCommand("XADD") + @SuppressWarnings({ "unchecked" }) void xRangeShouldReportMessages() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); @@ -3719,19 +4042,20 @@ void xRangeShouldReportMessages() { actual.add(connection.xRange(KEY_1, org.springframework.data.domain.Range.unbounded())); List results = getResults(); + assertThat(results).hasSize(3); - List> messages = (List) results.get(2); + List> messages = (List>) results.get(2); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); - assertThat(messages.get(1).getStream()).isEqualTo(KEY_1); assertThat(messages.get(1).getValue()).isEqualTo(Collections.singletonMap(KEY_3, VALUE_3)); } @Test // DATAREDIS-864 @EnabledOnCommand("XADD") + @SuppressWarnings({ "unchecked" }) public void xRevRangeShouldReportMessages() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); @@ -3739,20 +4063,21 @@ public void xRevRangeShouldReportMessages() { actual.add(connection.xRevRange(KEY_1, org.springframework.data.domain.Range.unbounded())); List results = getResults(); + assertThat(results).hasSize(3); assertThat(((RecordId) results.get(0)).getValue()).contains("-"); - List> messages = (List) results.get(2); + List> messages = (List>) results.get(2); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_3, VALUE_3)); - assertThat(messages.get(1).getStream()).isEqualTo(KEY_1); assertThat(messages.get(1).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); } @Test // DATAREDIS-1207 @EnabledOnCommand("XADD") + @SuppressWarnings({ "unchecked" }) public void xRevRangeShouldWorkWithBoundedRange() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); @@ -3760,14 +4085,14 @@ public void xRevRangeShouldWorkWithBoundedRange() { actual.add(connection.xRevRange(KEY_1, org.springframework.data.domain.Range.closed("0-0", "+"))); List results = getResults(); + assertThat(results).hasSize(3); - List> messages = (List) results.get(2); - assertThat(messages).hasSize(2); + List> messages = (List>) results.get(2); + assertThat(messages).hasSize(2); assertThat(messages.get(0).getStream()).isEqualTo(KEY_1); assertThat(messages.get(0).getValue()).isEqualTo(Collections.singletonMap(KEY_3, VALUE_3)); - assertThat(messages.get(1).getStream()).isEqualTo(KEY_1); assertThat(messages.get(1).getValue()).isEqualTo(Collections.singletonMap(KEY_2, VALUE_2)); } @@ -3780,11 +4105,12 @@ void xPendingShouldLoadOverviewCorrectly() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xPending(KEY_1, "my-group")); List results = getResults(); + assertThat(results).hasSize(4); + PendingMessagesSummary info = (PendingMessagesSummary) results.get(3); assertThat(info.getGroupName()).isEqualTo("my-group"); @@ -3802,7 +4128,9 @@ void xPendingShouldLoadEmptyOverviewCorrectly() { actual.add(connection.xPending(KEY_1, "my-group")); List results = getResults(); + assertThat(results).hasSize(3); + PendingMessagesSummary info = (PendingMessagesSummary) results.get(2); assertThat(info.getGroupName()).isEqualTo("my-group"); @@ -3819,11 +4147,12 @@ public void xPendingShouldLoadPendingMessages() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xPending(KEY_1, "my-group", org.springframework.data.domain.Range.unbounded(), 10L)); List results = getResults(); + assertThat(results).hasSize(4); + PendingMessages pending = (PendingMessages) results.get(3); assertThat(pending.size()).isOne(); @@ -3841,11 +4170,12 @@ public void xPendingShouldWorkWithBoundedRange() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xPending(KEY_1, "my-group", org.springframework.data.domain.Range.closed("0-0", "+"), 10L)); List results = getResults(); + assertThat(results).hasSize(4); + PendingMessages pending = (PendingMessages) results.get(3); assertThat(pending.size()).isOne(); @@ -3863,12 +4193,13 @@ public void xPendingShouldLoadPendingMessagesForConsumer() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xPending(KEY_1, "my-group", "my-consumer", org.springframework.data.domain.Range.unbounded(), 10L)); List results = getResults(); + assertThat(results).hasSize(4); + PendingMessages pending = (PendingMessages) results.get(3); assertThat(pending.size()).isOne(); @@ -3886,12 +4217,13 @@ public void xPendingShouldLoadPendingMessagesForNonExistingConsumer() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xPending(KEY_1, "my-group", "my-consumer-2", org.springframework.data.domain.Range.unbounded(), 10L)); List results = getResults(); + assertThat(results).hasSize(4); + PendingMessages pending = (PendingMessages) results.get(3); assertThat(pending.size()).isZero(); @@ -3903,11 +4235,12 @@ void xPendingShouldLoadEmptyPendingMessages() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); - actual.add(connection.xPending(KEY_1, "my-group", org.springframework.data.domain.Range.unbounded(), 10L)); List results = getResults(); + assertThat(results).hasSize(3); + PendingMessages pending = (PendingMessages) results.get(2); assertThat(pending.size()).isZero(); @@ -3915,6 +4248,7 @@ void xPendingShouldLoadEmptyPendingMessages() { @Test // DATAREDIS-1084 @EnabledOnCommand("XADD") + @SuppressWarnings({ "unchecked" }) public void xClaim() throws InterruptedException { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); @@ -3930,6 +4264,7 @@ public void xClaim() throws InterruptedException { XClaimOptions.minIdle(Duration.ofMillis(1)).ids(messages.get(0).getId()))); List> claimed = (List>) getResults().get(3); + assertThat(claimed).containsAll(messages); } @@ -3943,11 +4278,12 @@ public void xinfo() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xInfo(KEY_1)); List results = getResults(); + assertThat(results).hasSize(6); + RecordId firstRecord = (RecordId) results.get(1); RecordId lastRecord = (RecordId) results.get(2); XInfoStream info = (XInfoStream) results.get(5); @@ -3967,11 +4303,12 @@ public void xinfoNoGroup() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_3, VALUE_3))); - actual.add(connection.xInfo(KEY_1)); List results = getResults(); + assertThat(results).hasSize(3); + RecordId firstRecord = (RecordId) results.get(0); RecordId lastRecord = (RecordId) results.get(1); XInfoStream info = (XInfoStream) results.get(2); @@ -3994,11 +4331,12 @@ public void xinfoGroups() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xInfoGroups(KEY_1)); List results = getResults(); + assertThat(results).hasSize(5); + RecordId lastRecord = (RecordId) results.get(1); XInfoGroups info = (XInfoGroups) results.get(4); @@ -4015,11 +4353,12 @@ public void xinfoGroupsNoGroup() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_3, VALUE_3))); - actual.add(connection.xInfoGroups(KEY_1)); List results = getResults(); + assertThat(results).hasSize(3); + XInfoGroups info = (XInfoGroups) results.get(2); assertThat(info.size()).isZero(); @@ -4032,15 +4371,15 @@ public void xinfoGroupsNoConsumer() { actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2))); actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_3, VALUE_3))); actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); - actual.add(connection.xInfoGroups(KEY_1)); List results = getResults(); + assertThat(results).hasSize(4); + XInfoGroups info = (XInfoGroups) results.get(3); assertThat(info.size()).isOne(); - assertThat(info.get(0).groupName()).isEqualTo("my-group"); assertThat(info.get(0).consumerCount()).isZero(); assertThat(info.get(0).pendingCount()).isZero(); @@ -4056,11 +4395,12 @@ public void xinfoConsumers() { actual.add(connection.xGroupCreate(KEY_1, ReadOffset.from("0"), "my-group")); actual.add(connection.xReadGroupAsString(Consumer.from("my-group", "my-consumer"), StreamOffset.create(KEY_1, ReadOffset.lastConsumed()))); - actual.add(connection.xInfoConsumers(KEY_1, "my-group")); List results = getResults(); + assertThat(results).hasSize(5); + XInfoConsumers info = (XInfoConsumers) results.get(4); assertThat(info.size()).isOne(); @@ -4080,23 +4420,30 @@ public void xinfoConsumersNoConsumer() { actual.add(connection.xInfoConsumers(KEY_1, "my-group")); List results = getResults(); + assertThat(results).hasSize(4); + XInfoConsumers info = (XInfoConsumers) results.get(3); assertThat(info.size()).isZero(); } @Test //GH-2345 + @SuppressWarnings({ "unchecked" }) public void zRangeStoreByScoreStoresKeys() { + String dstKey = KEY_2; String srcKey = KEY_1; + actual.add(connection.zAdd(srcKey, 1, VALUE_1)); actual.add(connection.zAdd(srcKey, 2, VALUE_2)); actual.add(connection.zAdd(srcKey, 3, VALUE_3)); actual.add(connection.zAdd(srcKey, 4, VALUE_4)); actual.add(connection.zRangeStoreByScore(dstKey, srcKey, Range.closed(3, 4))); actual.add(connection.zRange(dstKey, 0, -1)); + List result = getResults(); + assertThat(result.get(0)).isEqualTo(true); assertThat(result.get(1)).isEqualTo(true); assertThat(result.get(2)).isEqualTo(true); @@ -4106,16 +4453,21 @@ public void zRangeStoreByScoreStoresKeys() { } @Test // GH-2345 + @SuppressWarnings({ "unchecked" }) public void zRangeStoreRevByScoreStoresKeys() { + String dstKey = KEY_2; String srcKey = KEY_1; + actual.add(connection.zAdd(srcKey, 1, VALUE_1)); actual.add(connection.zAdd(srcKey, 2, VALUE_2)); actual.add(connection.zAdd(srcKey, 3, VALUE_3)); actual.add(connection.zAdd(srcKey, 4, VALUE_4)); actual.add(connection.zRangeStoreRevByScore(dstKey, srcKey, Range.closed(3, 4))); actual.add(connection.zRange(dstKey, 0, -1)); + List result = getResults(); + assertThat(result.get(0)).isEqualTo(true); assertThat(result.get(1)).isEqualTo(true); assertThat(result.get(2)).isEqualTo(true); @@ -4125,16 +4477,21 @@ public void zRangeStoreRevByScoreStoresKeys() { } @Test //GH-2345 + @SuppressWarnings({ "unchecked" }) public void zRangeStoreByLexStoresKeys() { + String dstKey = KEY_2; String srcKey = KEY_1; + actual.add(connection.zAdd(srcKey, 0, VALUE_3)); actual.add(connection.zAdd(srcKey, 0, VALUE_1)); actual.add(connection.zAdd(srcKey, 0, VALUE_4)); actual.add(connection.zAdd(srcKey, 0, VALUE_2)); actual.add(connection.zRangeStoreByLex(dstKey, srcKey, Range.rightUnbounded(Bound.inclusive(VALUE_3)))); actual.add(connection.zRange(dstKey, 0, -1)); + List result = getResults(); + assertThat(result.get(0)).isEqualTo(true); assertThat(result.get(1)).isEqualTo(true); assertThat(result.get(2)).isEqualTo(true); @@ -4144,16 +4501,21 @@ public void zRangeStoreByLexStoresKeys() { } @Test // GH-2345 + @SuppressWarnings({ "unchecked" }) public void zRangeStoreRevByLexStoresKeys() { + String dstKey = KEY_2; String srcKey = KEY_1; + actual.add(connection.zAdd(srcKey, 0, VALUE_3)); actual.add(connection.zAdd(srcKey, 0, VALUE_1)); actual.add(connection.zAdd(srcKey, 0, VALUE_4)); actual.add(connection.zAdd(srcKey, 0, VALUE_2)); actual.add(connection.zRangeStoreRevByLex(dstKey, srcKey, Range.rightUnbounded(Bound.inclusive(VALUE_3)))); actual.add(connection.zRange(dstKey, 0, -1)); + List result = getResults(); + assertThat(result.get(0)).isEqualTo(true); assertThat(result.get(1)).isEqualTo(true); assertThat(result.get(2)).isEqualTo(true); @@ -4175,15 +4537,15 @@ protected void initConnection() { } protected class KeyExpired implements TestCondition { - private String key; + + private final String key; KeyExpired(String key) { this.key = key; } public boolean passes() { - return (!connection.exists(key)); + return !connection.exists(key); } } - } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java index 78ffeb756e..13621d31fc 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java @@ -2279,7 +2279,7 @@ public void zPopMinShouldWorkCorrectly() { @EnabledOnCommand("BZPOPMIN") public void bzPopMinShouldWorkCorrectly() { - assertThat(clusterConnection.bZPopMin(KEY_1_BYTES, 10, TimeUnit.MILLISECONDS)).isNull(); + assertThat(clusterConnection.zSetCommands().zCard(KEY_1_BYTES)).isZero(); nativeConnection.zadd(KEY_1_BYTES, 10D, VALUE_1_BYTES); nativeConnection.zadd(KEY_1_BYTES, 20D, VALUE_2_BYTES); @@ -2306,7 +2306,7 @@ public void zPopMaxShouldWorkCorrectly() { @EnabledOnCommand("BZPOPMAX") public void bzPopMaxShouldWorkCorrectly() { - assertThat(clusterConnection.bZPopMax(KEY_1_BYTES, 10, TimeUnit.MILLISECONDS)).isNull(); + assertThat(clusterConnection.zSetCommands().zCard(KEY_1_BYTES)).isZero(); nativeConnection.zadd(KEY_1_BYTES, 10D, VALUE_1_BYTES); nativeConnection.zadd(KEY_1_BYTES, 20D, VALUE_2_BYTES); diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java index 2a39274473..51edd0ded0 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTests.java @@ -25,7 +25,6 @@ import redis.clients.jedis.params.ScanParams; import redis.clients.jedis.resps.ScanResult; -import java.io.IOException; import java.util.Collections; import java.util.Map.Entry; @@ -43,7 +42,10 @@ import org.springframework.data.redis.core.ScanOptions; /** + * Unit tests for {@link JedisConnection}. + * * @author Christoph Strobl + * @author John Blum */ class JedisConnectionUnitTests { @@ -165,11 +167,11 @@ public void scanShouldKeepTheConnectionOpen() { connection.scan(ScanOptions.NONE); - verify(jedisSpy, never()).quit(); + verify(jedisSpy, never()).disconnect(); } @Test // DATAREDIS-531, GH-2006 - public void scanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException { + public void scanShouldCloseTheConnectionWhenCursorIsClosed() { doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).scan(any(byte[].class), any(ScanParams.class)); @@ -177,7 +179,7 @@ public void scanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException Cursor cursor = connection.scan(ScanOptions.NONE); cursor.close(); - verify(jedisSpy, times(1)).quit(); + verify(jedisSpy, times(1)).disconnect(); } @Test // DATAREDIS-531 @@ -188,11 +190,11 @@ public void sScanShouldKeepTheConnectionOpen() { connection.sScan("foo".getBytes(), ScanOptions.NONE); - verify(jedisSpy, never()).quit(); + verify(jedisSpy, never()).disconnect(); } @Test // DATAREDIS-531 - public void sScanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException { + public void sScanShouldCloseTheConnectionWhenCursorIsClosed() { doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).sscan(any(byte[].class), any(byte[].class), any(ScanParams.class)); @@ -200,7 +202,7 @@ public void sScanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException Cursor cursor = connection.sScan("foo".getBytes(), ScanOptions.NONE); cursor.close(); - verify(jedisSpy, times(1)).quit(); + verify(jedisSpy, times(1)).disconnect(); } @Test // DATAREDIS-531 @@ -211,11 +213,11 @@ public void zScanShouldKeepTheConnectionOpen() { connection.zScan("foo".getBytes(), ScanOptions.NONE); - verify(jedisSpy, never()).quit(); + verify(jedisSpy, never()).disconnect(); } @Test // DATAREDIS-531 - public void zScanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException { + public void zScanShouldCloseTheConnectionWhenCursorIsClosed() { doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).zscan(any(byte[].class), any(byte[].class), any(ScanParams.class)); @@ -223,7 +225,7 @@ public void zScanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException Cursor cursor = connection.zScan("foo".getBytes(), ScanOptions.NONE); cursor.close(); - verify(jedisSpy, times(1)).quit(); + verify(jedisSpy, times(1)).disconnect(); } @Test // DATAREDIS-531 @@ -234,19 +236,20 @@ public void hScanShouldKeepTheConnectionOpen() { connection.hScan("foo".getBytes(), ScanOptions.NONE); - verify(jedisSpy, never()).quit(); + verify(jedisSpy, never()).disconnect(); } @Test // DATAREDIS-531 - public void hScanShouldCloseTheConnectionWhenCursorIsClosed() throws IOException { + public void hScanShouldCloseTheConnectionWhenCursorIsClosed() { doReturn(new ScanResult<>("0", Collections. emptyList())).when(jedisSpy).hscan(any(byte[].class), any(byte[].class), any(ScanParams.class)); Cursor> cursor = connection.hScan("foo".getBytes(), ScanOptions.NONE); + cursor.close(); - verify(jedisSpy, times(1)).quit(); + verify(jedisSpy, times(1)).disconnect(); } @Test // DATAREDIS-714 @@ -369,7 +372,5 @@ public void hScanShouldCloseTheConnectionWhenCursorIsClosed() { assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(() -> super.hScanShouldCloseTheConnectionWhenCursorIsClosed()); } - } - } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java index eb37cf171d..7cbc1b6e92 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java @@ -16,7 +16,15 @@ package org.springframework.data.redis.connection.jedis; import static org.assertj.core.api.Assertions.*; - +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import redis.clients.jedis.Protocol; import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; @@ -35,12 +43,15 @@ import org.springframework.data.redis.connection.RedisStringCommands.SetOption; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.RedisClientInfo; +import org.springframework.lang.Nullable; +import org.springframework.test.util.ReflectionTestUtils; /** * Unit tests for {@link JedisConverters}. * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ class JedisConvertersUnitTests { @@ -212,15 +223,31 @@ void toSetCommandExPxOptionShouldReturnEXforMilliseconds() { @Test // GH-2050 void convertsExpirationToSetPXAT() { - assertThat(JedisConverters.toSetCommandExPxArgument(Expiration.unixTimestamp(10, TimeUnit.MILLISECONDS))) - .extracting(SetParams::toString).isEqualTo(SetParams.setParams().pxAt(10).toString()); + SetParams mockSetParams = mock(SetParams.class); + + doReturn(mockSetParams).when(mockSetParams).pxAt(anyLong()); + + Expiration expiration = Expiration.unixTimestamp(10, TimeUnit.MILLISECONDS); + + assertThat(JedisConverters.toSetCommandExPxArgument(expiration, mockSetParams)).isNotNull(); + + verify(mockSetParams, times(1)).pxAt(eq(10L)); + verifyNoMoreInteractions(mockSetParams); } @Test // GH-2050 void convertsExpirationToSetEXAT() { - assertThat(JedisConverters.toSetCommandExPxArgument(Expiration.unixTimestamp(1, TimeUnit.MINUTES))) - .extracting(SetParams::toString).isEqualTo(SetParams.setParams().exAt(60).toString()); + SetParams mockSetParams = mock(SetParams.class); + + doReturn(mockSetParams).when(mockSetParams).exAt(anyLong()); + + Expiration expiration = Expiration.unixTimestamp(1, TimeUnit.MINUTES); + + assertThat(JedisConverters.toSetCommandExPxArgument(expiration, mockSetParams)).isNotNull(); + + verify(mockSetParams, times(1)).exAt(eq(60L)); + verifyNoMoreInteractions(mockSetParams); } @Test // DATAREDIS-316, DATAREDIS-749 @@ -241,43 +268,91 @@ void toSetCommandNxXxOptionShouldReturnEmptyArrayforUpsert() { @Test // GH-2050 void convertsExpirationToGetExEX() { - assertThat(JedisConverters.toGetExParams(Expiration.seconds(10))).extracting(GetExParams::toString) - .isEqualTo(new GetExParams().ex(10).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).ex(anyLong()); + + Expiration expiration = Expiration.seconds(10); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).ex(eq(10L)); + verifyNoMoreInteractions(mockGetExParams); } @Test // GH-2050 void convertsExpirationWithTimeUnitToGetExEX() { - assertThat(JedisConverters.toGetExParams(Expiration.from(1, TimeUnit.MINUTES))).extracting(GetExParams::toString) - .isEqualTo(new GetExParams().ex(60).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).ex(anyLong()); + + Expiration expiration = Expiration.from(1, TimeUnit.MINUTES); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).ex(eq(60L)); // seconds + verifyNoMoreInteractions(mockGetExParams); } @Test // GH-2050 void convertsExpirationToGetExPEX() { - assertThat(JedisConverters.toGetExParams(Expiration.milliseconds(10))).extracting(GetExParams::toString) - .isEqualTo(new GetExParams().px(10).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).px(anyLong()); + + Expiration expiration = Expiration.milliseconds(10L); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).px(eq(10L)); + verifyNoMoreInteractions(mockGetExParams); } @Test // GH-2050 void convertsExpirationToGetExEXAT() { - assertThat(JedisConverters.toGetExParams(Expiration.unixTimestamp(10, TimeUnit.SECONDS))) - .extracting(GetExParams::toString).isEqualTo(new GetExParams().exAt(10).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).exAt(anyLong()); + + Expiration expiration = Expiration.unixTimestamp(10, TimeUnit.SECONDS); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).exAt(eq(10L)); + verifyNoMoreInteractions(mockGetExParams); } @Test // GH-2050 void convertsExpirationWithTimeUnitToGetExEXAT() { - assertThat(JedisConverters.toGetExParams(Expiration.unixTimestamp(1, TimeUnit.MINUTES))) - .extracting(GetExParams::toString).isEqualTo(new GetExParams().exAt(60).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).exAt(anyLong()); + + Expiration expiration = Expiration.unixTimestamp(1, TimeUnit.MINUTES); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).exAt(eq(60L)); + verifyNoMoreInteractions(mockGetExParams); } @Test // GH-2050 void convertsExpirationToGetExPXAT() { - assertThat(JedisConverters.toGetExParams(Expiration.unixTimestamp(10, TimeUnit.MILLISECONDS))) - .extracting(GetExParams::toString).isEqualTo(new GetExParams().pxAt(10).toString()); + GetExParams mockGetExParams = mock(GetExParams.class); + + doReturn(mockGetExParams).when(mockGetExParams).pxAt(anyLong()); + + Expiration expiration = Expiration.unixTimestamp(10, TimeUnit.MILLISECONDS); + + assertThat(JedisConverters.toGetExParams(expiration, mockGetExParams)).isNotNull(); + + verify(mockGetExParams, times(1)).pxAt(eq(10L)); + verifyNoMoreInteractions(mockGetExParams); } private void verifyRedisServerInfo(RedisServer server, Map values) { @@ -289,18 +364,22 @@ private void verifyRedisServerInfo(RedisServer server, Map value private static String toString(SetParams setParams) { - StringBuilder builder = new StringBuilder(); + StringBuilder stringBuilder = new StringBuilder(); - for (byte[] parameter : setParams.getByteParams()) { + stringBuilder.append(toString((Protocol.Keyword) ReflectionTestUtils.getField(setParams, "existance"))); + stringBuilder.append(toString((Protocol.Keyword) ReflectionTestUtils.getField(setParams, "expiration"))); - if (builder.length() != 0) { - builder.append(' '); - } + Long expirationValue = (Long) ReflectionTestUtils.getField(setParams, "expirationValue"); - builder.append(new String(parameter)); + if (expirationValue != null) { + stringBuilder.append(" ").append(expirationValue); } - return builder.toString(); + return stringBuilder.toString().trim(); + } + + private static String toString(@Nullable Enum value) { + return value != null ? value.name().toLowerCase() : ""; } private Map getRedisServerInfoMap(String name, int port) { diff --git a/src/test/java/org/springframework/data/redis/core/DefaultStreamOperationsIntegrationTests.java b/src/test/java/org/springframework/data/redis/core/DefaultStreamOperationsIntegrationTests.java index 58e3ee3c31..b8963b5618 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultStreamOperationsIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultStreamOperationsIntegrationTests.java @@ -78,10 +78,11 @@ public DefaultStreamOperationsIntegrationTests(RedisTemplate redisTemplate public static Collection testParams() { List params = new ArrayList<>(); + params.addAll(AbstractOperationsTestParams .testParams(JedisConnectionFactoryExtension.getConnectionFactory(RedisStanalone.class))); - if(RedisDetector.isClusterAvailable()) { + if (RedisDetector.isClusterAvailable()) { params.addAll(AbstractOperationsTestParams .testParams(JedisConnectionFactoryExtension.getConnectionFactory(RedisCluster.class))); } @@ -89,7 +90,7 @@ public static Collection testParams() { params.addAll(AbstractOperationsTestParams .testParams(LettuceConnectionFactoryExtension.getConnectionFactory(RedisStanalone.class))); - if(RedisDetector.isClusterAvailable()) { + if (RedisDetector.isClusterAvailable()) { params.addAll(AbstractOperationsTestParams .testParams(LettuceConnectionFactoryExtension.getConnectionFactory(RedisCluster.class))); } @@ -398,11 +399,11 @@ void pendingShouldReadMessageDetails() { K key = keyFactory.instance(); HK hashKey = hashKeyFactory.instance(); - HV value = hashValueFactory.instance(); + HV hashValue = hashValueFactory.instance(); - RecordId messageId = streamOps.add(key, Collections.singletonMap(hashKey, value)); - streamOps.createGroup(key, ReadOffset.from("0-0"), "my-group"); + RecordId messageId = streamOps.add(key, Collections.singletonMap(hashKey, hashValue)); + streamOps.createGroup(key, ReadOffset.from("0-0"), "my-group"); streamOps.read(Consumer.from("my-group", "my-consumer"), StreamOffset.create(key, ReadOffset.lastConsumed())); diff --git a/src/test/java/org/springframework/data/redis/test/extension/JedisExtension.java b/src/test/java/org/springframework/data/redis/test/extension/JedisExtension.java index d438926b3d..e5440dfdb6 100644 --- a/src/test/java/org/springframework/data/redis/test/extension/JedisExtension.java +++ b/src/test/java/org/springframework/data/redis/test/extension/JedisExtension.java @@ -45,7 +45,7 @@ * callbacks. The following resource types are supported by this extension: *
    *
  • {@link Jedis} (singleton)
  • - *
  • {@link JediCluster} (singleton)
  • + *
  • {@link JedisCluster} (singleton)
  • *
* *
@@ -66,6 +66,7 @@
  * is managed by this extension.
  *
  * @author Mark Paluch
+ * @author John Blum
  * @see ParameterResolver
  * @see BeforeEachCallback
  */
@@ -86,18 +87,14 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon
 	}
 
 	/**
-	 * Attempt to resolve the {@code requestedResourceType}.
-	 *
-	 * @param extensionContext
-	 * @param requestedResourceType
-	 * @param 
-	 * @return
+	 * Attempt to resolve the {@link Class requestedResourceType}.
 	 */
+	@SuppressWarnings("unchecked")
 	public  T resolve(ExtensionContext extensionContext, Class requestedResourceType) {
 
 		ExtensionContext.Store store = getStore(extensionContext);
 
-		return (T) store.getOrComputeIfAbsent(requestedResourceType, it -> findSupplier(requestedResourceType).get());
+		return (T) store.getOrComputeIfAbsent(requestedResourceType, it -> doGetInstance(requestedResourceType));
 	}
 
 	@Override
@@ -111,6 +108,10 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte
 		return store.getOrComputeIfAbsent(parameter.getType(), it -> doGetInstance(parameterizedType));
 	}
 
+	private Object doGetInstance(Type parameterizedType) {
+		return findSupplier(parameterizedType).get();
+	}
+
 	@SuppressWarnings("unchecked")
 	private static Supplier findSupplier(Type type) {
 
@@ -120,30 +121,26 @@ private static Supplier findSupplier(Type type) {
 
 			ResolvableType providedType = ResolvableType.forType(it.getClass()).as(Supplier.class).getGeneric(0);
 
-			if (requested.isAssignableFrom(providedType)) {
-				return true;
-			}
-			return false;
+			return requested.isAssignableFrom(providedType);
+
 		}).findFirst().orElseThrow(() -> new NoSuchElementException("Cannot find a factory for " + type));
 
 		return (Supplier) supplier;
 	}
 
-	private Object doGetInstance(Type parameterizedType) {
-		return findSupplier(parameterizedType).get();
-	}
-
 	private ExtensionContext.Store getStore(ExtensionContext extensionContext) {
 		return extensionContext.getStore(NAMESPACE);
 	}
 
 	static class ResourceFunction {
 
+		final Function function;
+
 		final ResolvableType dependsOn;
 		final ResolvableType provides;
-		final Function function;
 
 		public ResourceFunction(ResolvableType dependsOn, ResolvableType provides, Function function) {
+
 			this.dependsOn = dependsOn;
 			this.provides = provides;
 			this.function = (Function) function;
@@ -155,9 +152,11 @@ enum JedisSupplier implements Supplier {
 		INSTANCE;
 
 		final Lazy lazy = Lazy.of(() -> {
+
 			Jedis client = new Jedis(SettingsUtils.getHost(), SettingsUtils.getPort());
 
-			ShutdownQueue.INSTANCE.register(client);
+			ShutdownQueue.register(client);
+
 			return client;
 		});
 
@@ -172,9 +171,13 @@ enum JedisClusterSupplier implements Supplier {
 		INSTANCE;
 
 		final Lazy lazy = Lazy.of(() -> {
-			JedisCluster client = new JedisCluster(new HostAndPort(SettingsUtils.getHost(), SettingsUtils.getClusterPort()));
 
-			ShutdownQueue.INSTANCE.register(client);
+			HostAndPort hostAndPort = new HostAndPort(SettingsUtils.getHost(), SettingsUtils.getClusterPort());
+
+			JedisCluster client = new JedisCluster(hostAndPort);
+
+			ShutdownQueue.register(client);
+
 			return client;
 		});
 
@@ -183,5 +186,4 @@ public JedisCluster get() {
 			return lazy.get();
 		}
 	}
-
 }