ClusterCommandsTest.java
package redis.clients.jedis.commands.jedis;
import java.util.List;
import java.util.Map;
import io.redis.test.annotations.SinceRedisVersion;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.args.ClusterResetType;
import redis.clients.jedis.HostAndPorts;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.resps.ClusterShardInfo;
import redis.clients.jedis.resps.ClusterShardNodeInfo;
import redis.clients.jedis.util.JedisClusterCRC16;
import redis.clients.jedis.util.JedisClusterTestUtil;
import redis.clients.jedis.util.RedisVersionCondition;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ClusterCommandsTest {
private static Jedis node1;
private static Jedis node2;
private static HostAndPort nodeInfo1 = HostAndPorts.getClusterServers().get(0);
private static HostAndPort nodeInfo2 = HostAndPorts.getClusterServers().get(1);
@RegisterExtension
public RedisVersionCondition versionCondition = new RedisVersionCondition(nodeInfo1,
DefaultJedisClientConfig.builder().password("cluster").build());
@BeforeEach
public void setUp() throws Exception {
node1 = new Jedis(nodeInfo1);
node1.auth("cluster");
node1.flushAll();
node2 = new Jedis(nodeInfo2);
node2.auth("cluster");
node2.flushAll();
}
@AfterEach
public void tearDown() {
node1.disconnect();
node2.disconnect();
}
@BeforeAll
public static void resetRedisBefore() {
removeSlots();
}
@AfterAll
public static void resetRedisAfter() {
removeSlots();
}
public static void removeSlots() {
try (Jedis node = new Jedis(nodeInfo1)) {
node.auth("cluster");
node.clusterReset(ClusterResetType.SOFT);
}
try (Jedis node = new Jedis(nodeInfo2)) {
node.auth("cluster");
node.clusterReset(ClusterResetType.SOFT);
}
}
@Test
public void testClusterSoftReset() {
node1.clusterMeet("127.0.0.1", nodeInfo2.getPort());
assertTrue(node1.clusterNodes().split("\n").length > 1);
node1.clusterReset(ClusterResetType.SOFT);
assertEquals(1, node1.clusterNodes().split("\n").length);
}
@Test
public void testClusterHardReset() {
String nodeId = JedisClusterTestUtil.getNodeId(node1.clusterNodes());
node1.clusterReset(ClusterResetType.HARD);
String newNodeId = JedisClusterTestUtil.getNodeId(node1.clusterNodes());
assertNotEquals(nodeId, newNodeId);
}
@Test
public void clusterSetSlotImporting() {
node2.clusterAddSlots(6000);
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotImporting(6000, nodeId);
assertEquals("OK", status);
node2.clusterDelSlots(6000);
}
@Test
public void clusterNodes() {
String nodes = node1.clusterNodes();
assertTrue(nodes.split("\n").length > 0);
}
//
// @Test
// public void clusterMeet() {
// String status = node1.clusterMeet("127.0.0.1", nodeInfo2.getPort());
// assertEquals("OK", status);
// }
@Test
public void clusterAddSlotsAndDelSlots() {
assertEquals("OK", node1.clusterAddSlots(1, 2, 3, 4, 5));
assertEquals("OK", node1.clusterDelSlots(1, 2, 3, 4, 5));
}
@Test
public void clusterInfo() {
String info = node1.clusterInfo();
assertNotNull(info);
}
@Test
@SinceRedisVersion("7.0.0")
public void addAndDelSlotsRange() {
// test add
assertEquals("OK", node1.clusterAddSlotsRange(100, 105));
String clusterNodes = node1.clusterNodes();
assertTrue(clusterNodes.contains("connected 100-105"));
assertEquals("OK", node1.clusterAddSlotsRange(110, 120));
clusterNodes = node1.clusterNodes();
assertTrue(clusterNodes.contains("connected 100-105 110-120"));
// test del
assertEquals("OK", node1.clusterDelSlotsRange(100, 105));
clusterNodes = node1.clusterNodes();
assertTrue(clusterNodes.contains("connected 110-120"));
assertEquals("OK", node1.clusterDelSlotsRange(110, 120));
}
@Test
public void clusterGetKeysInSlot() {
node1.clusterAddSlots(500);
List<String> keys = node1.clusterGetKeysInSlot(500, 1);
assertEquals(0, keys.size());
node1.clusterDelSlots(500);
}
@Test
public void clusterGetKeysInSlotBinary() {
node1.clusterAddSlots(501);
List<byte[]> keys = node1.clusterGetKeysInSlotBinary(501, 1);
assertEquals(0, keys.size());
node1.clusterDelSlots(501);
}
@Test
public void clusterSetSlotNode() {
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotNode(10000, nodeId);
assertEquals("OK", status);
}
@Test
public void clusterSetSlotMigrating() {
node1.clusterAddSlots(5000);
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotMigrating(5000, nodeId);
assertEquals("OK", status);
node1.clusterDelSlots(5000);
}
@Test
public void clusterSlots() {
// please see cluster slot output format from below commit
// @see: https://github.com/antirez/redis/commit/e14829de3025ffb0d3294e5e5a1553afd9f10b60
assertEquals("OK", node1.clusterAddSlots(3000, 3001, 3002));
List<Object> slots = node1.clusterSlots();
assertNotNull(slots);
assertTrue(slots.size() > 0);
for (Object slotInfoObj : slots) {
assertNotNull(slotInfoObj);
List<Object> slotInfo = (List<Object>) slotInfoObj;
assertTrue(slotInfo.size() >= 2);
assertInstanceOf(Long.class, slotInfo.get(0));
assertInstanceOf(Long.class, slotInfo.get(1));
if (slotInfo.size() > 2) {
// assigned slots
assertInstanceOf(List.class, slotInfo.get(2));
}
}
node1.clusterDelSlots(3000, 3001, 3002);
}
@Test
@SinceRedisVersion("7.0.0")
public void clusterShards() {
assertEquals("OK", node1.clusterAddSlots(3100, 3101, 3102, 3105));
List<ClusterShardInfo> shards = node1.clusterShards();
assertNotNull(shards);
assertTrue(shards.size() > 0);
for (ClusterShardInfo shardInfo : shards) {
assertNotNull(shardInfo);
assertTrue(shardInfo.getSlots().size() > 1);
for (List<Long> slotRange : shardInfo.getSlots()) {
assertEquals(2, slotRange.size());
}
for (ClusterShardNodeInfo nodeInfo : shardInfo.getNodes()) {
assertNotNull(nodeInfo.getId());
assertNotNull(nodeInfo.getEndpoint());
assertNotNull(nodeInfo.getIp());
assertNull(nodeInfo.getHostname());
assertNotNull(nodeInfo.getPort());
assertNotNull(nodeInfo.getTlsPort()); // currently we are always starting Redis server with `tls-port`
assertNotNull(nodeInfo.getRole());
assertNotNull(nodeInfo.getReplicationOffset());
assertNotNull(nodeInfo.getHealth());
}
}
node1.clusterDelSlots(3100, 3101, 3102, 3105);
}
@Test
@SinceRedisVersion("7.0.0")
public void clusterLinks() throws InterruptedException {
List<Map<String, Object>> links = node1.clusterLinks();
assertNotNull(links);
assertEquals(0, links.size());
}
@Test
public void testClusterKeySlot() {
// It assumes JedisClusterCRC16 is correctly implemented
assertEquals(JedisClusterCRC16.getSlot("{user1000}.following"),
node1.clusterKeySlot("{user1000}.following"));
assertEquals(JedisClusterCRC16.getSlot("foo{bar}{zap}"),
node1.clusterKeySlot("foo{bar}{zap}"));
assertEquals(JedisClusterCRC16.getSlot("foo{}{bar}"),
node1.clusterKeySlot("foo{}{bar}"));
assertEquals(JedisClusterCRC16.getSlot("foo{{bar}}zap"),
node1.clusterKeySlot("foo{{bar}}zap"));
}
@Test
public void clusterCountFailureReports() {
assertEquals(0, node1.clusterCountFailureReports(node1.clusterMyId()));
}
@Test
public void clusterMyId() {
MatcherAssert.assertThat(node1.clusterMyId(), Matchers.not(Matchers.isEmptyOrNullString()));
}
@Test
@SinceRedisVersion("7.2.0")
public void clusterMyShardId() {
MatcherAssert.assertThat(node1.clusterMyShardId(), Matchers.not(Matchers.isEmptyOrNullString()));
}
@Test
public void testClusterEpoch() {
try {
assertEquals("OK", node1.clusterSetConfigEpoch(1));
} catch (JedisDataException jde) {
assertEquals("ERR The user can assign a config epoch only when the node does not know any other node.", jde.getMessage());
}
}
@Test
public void ClusterBumpEpoch() {
MatcherAssert.assertThat(node1.clusterBumpEpoch(), Matchers.matchesPattern("^BUMPED|STILL [0-9]+$"));
}
}