ClusterBinaryValuesCommandsTest.java
package redis.clients.jedis.commands.unified.cluster;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.stream.Stream;
import io.redis.test.annotations.EnabledOnCommand;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedClass;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import redis.clients.jedis.RedisProtocol;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.commands.unified.BinaryValuesCommandsTestBase;
import redis.clients.jedis.exceptions.JedisClusterOperationException;
import redis.clients.jedis.params.MSetExParams;
import redis.clients.jedis.util.SafeEncoder;
@ParameterizedClass
@MethodSource("redis.clients.jedis.commands.CommandsTestsParameters#respVersions")
public class ClusterBinaryValuesCommandsTest extends BinaryValuesCommandsTestBase {
public ClusterBinaryValuesCommandsTest(RedisProtocol protocol) {
super(protocol);
}
@Override
protected UnifiedJedis createTestClient() {
return ClusterCommandsTestHelper.getCleanCluster(protocol);
}
@AfterEach
public void tearDown() {
ClusterCommandsTestHelper.clearClusterData();
}
@Disabled
@Override
public void mget() {
}
@Disabled
@Override
public void mset() {
}
@Disabled
@Override
public void msetnx() {
}
static Stream<Arguments> msetexCrossSlotParams() {
return Stream.of(Arguments.of("unconditional", MSetExParams.setParams().ex(60)),
Arguments.of("NX", MSetExParams.setParams().nx().ex(60)),
Arguments.of("XX", MSetExParams.setParams().xx().ex(60)));
}
@ParameterizedTest(name = "MSETEX {0} rejects cross-slot binary keys")
@MethodSource("msetexCrossSlotParams")
@EnabledOnCommand("MSETEX")
public void msetexRejectsCrossSlotKeysBeforeWrites(String condition, MSetExParams params) {
byte[] existing = SafeEncoder.encode("{a}msetex:existing");
byte[] missing = SafeEncoder.encode("{b}msetex:missing");
byte[] oldValue = { 0, (byte) 0xff };
byte[] newValue = { 1, (byte) 0xfe };
jedis.set(existing, oldValue);
assertThrows(JedisClusterOperationException.class,
() -> jedis.msetex(params, missing, newValue, existing, newValue));
assertArrayEquals(oldValue, jedis.get(existing));
assertEquals(-1L, jedis.ttl(existing));
assertNull(jedis.get(missing));
}
static Stream<Arguments> msetexSameSlotConditions() {
return Stream.of(Arguments.of("NX", MSetExParams.setParams().nx().ex(60)),
Arguments.of("XX", MSetExParams.setParams().xx().ex(60)));
}
@ParameterizedTest(name = "MSETEX {0} checks all same-slot binary keys")
@MethodSource("msetexSameSlotConditions")
@EnabledOnCommand("MSETEX")
public void msetexSameSlotConditionFailureLeavesKeysUnchanged(String condition,
MSetExParams params) {
byte[] existing = SafeEncoder.encode("{a}msetex:existing");
byte[] missing = SafeEncoder.encode("{a}msetex:missing");
byte[] oldValue = { 0, (byte) 0xff };
byte[] newValue = { 1, (byte) 0xfe };
jedis.set(existing, oldValue);
assertFalse(jedis.msetex(params, missing, newValue, existing, newValue));
assertArrayEquals(oldValue, jedis.get(existing));
assertEquals(-1L, jedis.ttl(existing));
assertNull(jedis.get(missing));
}
@Test
@EnabledOnCommand("MSETEX")
public void msetexSameSlotWithoutConditionSetsAllKeys() {
byte[] k1 = SafeEncoder.encode("{a}msetex:first");
byte[] k2 = SafeEncoder.encode("{a}msetex:second");
byte[] v1 = { 0, (byte) 0xff };
byte[] v2 = { 1, (byte) 0xfe };
assertTrue(jedis.msetex(MSetExParams.setParams().ex(60), k1, v1, k2, v2));
assertArrayEquals(v1, jedis.get(k1));
assertArrayEquals(v2, jedis.get(k2));
assertTrue(jedis.ttl(k1) > 0);
assertTrue(jedis.ttl(k2) > 0);
}
}