Merging upstream
This commit is contained in:
@@ -27,6 +27,10 @@ public class HostAndPortUtil {
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7381));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7382));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7383));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7384));
|
||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7385));
|
||||
|
||||
String envRedisHosts = System.getProperty("redis-hosts");
|
||||
String envSentinelHosts = System.getProperty("sentinel-hosts");
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package redis.clients.jedis.tests;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.util.ClusterNodeInformation;
|
||||
import redis.clients.util.ClusterNodeInformationParser;
|
||||
|
||||
public class JedisClusterNodeInformationParserTest extends Assert {
|
||||
private ClusterNodeInformationParser parser;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
parser = new ClusterNodeInformationParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseNodeMyself() {
|
||||
String nodeInfo = "9b0d2ab38ee31482c95fdb2c7847a0d40e88d518 :0 myself,master - 0 0 1 connected 0-5460";
|
||||
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||
ClusterNodeInformation clusterNodeInfo = parser
|
||||
.parse(nodeInfo, current);
|
||||
assertEquals(clusterNodeInfo.getNode(), current);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseNormalState() {
|
||||
String nodeInfo = "5f4a2236d00008fba7ac0dd24b95762b446767bd 192.168.0.3:7380 master - 0 1400598804016 2 connected 5461-10922";
|
||||
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||
ClusterNodeInformation clusterNodeInfo = parser
|
||||
.parse(nodeInfo, current);
|
||||
assertNotEquals(clusterNodeInfo.getNode(), current);
|
||||
assertEquals(clusterNodeInfo.getNode(), new HostAndPort("192.168.0.3",
|
||||
7380));
|
||||
|
||||
for (int slot = 5461; slot <= 10922; slot++) {
|
||||
assertTrue(clusterNodeInfo.getAvailableSlots().contains(slot));
|
||||
}
|
||||
|
||||
assertTrue(clusterNodeInfo.getSlotsBeingImported().isEmpty());
|
||||
assertTrue(clusterNodeInfo.getSlotsBeingMigrated().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSlotBeingMigrated() {
|
||||
String nodeInfo = "5f4a2236d00008fba7ac0dd24b95762b446767bd :0 myself,master - 0 0 1 connected 0-5459 [5460->-5f4a2236d00008fba7ac0dd24b95762b446767bd] [5461-<-5f4a2236d00008fba7ac0dd24b95762b446767bd]";
|
||||
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||
ClusterNodeInformation clusterNodeInfo = parser
|
||||
.parse(nodeInfo, current);
|
||||
assertEquals(clusterNodeInfo.getNode(), current);
|
||||
|
||||
for (int slot = 0; slot <= 5459; slot++) {
|
||||
assertTrue(clusterNodeInfo.getAvailableSlots().contains(slot));
|
||||
}
|
||||
|
||||
assertEquals(1, clusterNodeInfo.getSlotsBeingMigrated().size());
|
||||
assertTrue(clusterNodeInfo.getSlotsBeingMigrated().contains(5460));
|
||||
assertEquals(1, clusterNodeInfo.getSlotsBeingImported().size());
|
||||
assertTrue(clusterNodeInfo.getSlotsBeingImported().contains(5461));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package redis.clients.jedis.tests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
import redis.clients.jedis.tests.utils.JedisClusterTestUtil;
|
||||
|
||||
public class JedisClusterReplicateTest {
|
||||
private static Jedis node5;
|
||||
private static Jedis node6;
|
||||
|
||||
private HostAndPort nodeInfo5 = HostAndPortUtil.getClusterServers().get(4);
|
||||
private HostAndPort nodeInfo6 = HostAndPortUtil.getClusterServers().get(5);
|
||||
|
||||
private static int TIMEOUT = 15000; // cluster-node-timeout * 3
|
||||
|
||||
@Before
|
||||
public void setUp() throws InterruptedException {
|
||||
node5 = new Jedis(nodeInfo5.getHost(), nodeInfo5.getPort(), TIMEOUT);
|
||||
node5.connect();
|
||||
node5.flushAll();
|
||||
|
||||
node6 = new Jedis(nodeInfo6.getHost(), nodeInfo6.getPort(), TIMEOUT);
|
||||
node6.connect();
|
||||
// cannot flushall - it will be slave
|
||||
|
||||
// ---- configure cluster
|
||||
|
||||
// add nodes to cluster
|
||||
node5.clusterMeet("127.0.0.1", nodeInfo6.getPort());
|
||||
|
||||
JedisClusterTestUtil.assertNodeIsKnown(node5, JedisClusterTestUtil.getNodeId(node6.clusterNodes()), 1000);
|
||||
JedisClusterTestUtil.assertNodeIsKnown(node6, JedisClusterTestUtil.getNodeId(node5.clusterNodes()), 1000);
|
||||
|
||||
// split available slots across the three nodes
|
||||
int[] node5Slots = new int[JedisCluster.HASHSLOTS];
|
||||
for (int i = 0 ; i < JedisCluster.HASHSLOTS; i++) {
|
||||
node5Slots[i] = i;
|
||||
}
|
||||
|
||||
node5.clusterAddSlots(node5Slots);
|
||||
|
||||
JedisClusterTestUtil.waitForClusterReady(node5);
|
||||
|
||||
// replicate full 1on1
|
||||
node6.clusterReplicate(JedisClusterTestUtil.getNodeId(node5
|
||||
.clusterNodes()));
|
||||
|
||||
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||
replMap.put(node5, node6);
|
||||
|
||||
waitForReplicateReady(replMap, TIMEOUT);
|
||||
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||
}
|
||||
|
||||
private void waitForReplicateReady(Map<Jedis, Jedis> replMap, int timeoutMs) {
|
||||
int interval = 100;
|
||||
|
||||
for (int timeout = 0; timeout <= timeoutMs; timeout += interval) {
|
||||
for (Entry<Jedis, Jedis> entry : replMap.entrySet()) {
|
||||
Jedis master = entry.getKey();
|
||||
Jedis slave = entry.getValue();
|
||||
|
||||
String masterNodeId = JedisClusterTestUtil.getNodeId(master
|
||||
.clusterNodes());
|
||||
String slaveNodeId = JedisClusterTestUtil.getNodeId(slave
|
||||
.clusterNodes());
|
||||
|
||||
try {
|
||||
List<String> slaves = master.clusterSlaves(masterNodeId);
|
||||
|
||||
if (slaves.size() > 0 && slaves.get(0).contains(slaveNodeId)) {
|
||||
return;
|
||||
}
|
||||
} catch (JedisDataException e) {
|
||||
if (!e.getMessage().startsWith("ERR The specified node is not a master"))
|
||||
throw e;
|
||||
|
||||
// retry...
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new JedisException("there seems to replication error");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws InterruptedException {
|
||||
// clear all slots
|
||||
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
|
||||
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
|
||||
slotsToDelete[i] = i;
|
||||
}
|
||||
|
||||
node5.clusterDelSlots(slotsToDelete);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterReplicate() {
|
||||
// we're already replicate 1on1
|
||||
List<String> slaveInfos = node5.clusterSlaves(JedisClusterTestUtil
|
||||
.getNodeId(node5.clusterNodes()));
|
||||
assertEquals(1, slaveInfos.size());
|
||||
assertTrue(slaveInfos.get(0).contains(
|
||||
JedisClusterTestUtil.getNodeId(node6.clusterNodes())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterFailover() throws InterruptedException {
|
||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||
jedisClusterNode.add(new HostAndPort(nodeInfo5.getHost(), nodeInfo5.getPort()));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
|
||||
jc.set("51", "foo");
|
||||
// node5 is responsible of taking care of slot for key "51" (7186)
|
||||
|
||||
node6.clusterFailover();
|
||||
|
||||
try {
|
||||
// wait for failover
|
||||
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||
replMap.put(node6, node5);
|
||||
waitForReplicateReady(replMap, TIMEOUT);
|
||||
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||
|
||||
List<String> slaveInfos = node6.clusterSlaves(JedisClusterTestUtil
|
||||
.getNodeId(node6.clusterNodes()));
|
||||
assertEquals(1, slaveInfos.size());
|
||||
assertTrue(slaveInfos.get(0).contains(
|
||||
JedisClusterTestUtil.getNodeId(node5.clusterNodes())));
|
||||
} finally {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
// rollback
|
||||
node5.clusterFailover();
|
||||
|
||||
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||
replMap.put(node5, node6);
|
||||
waitForReplicateReady(replMap, TIMEOUT);
|
||||
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package redis.clients.jedis.tests;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
@@ -14,16 +16,19 @@ import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
import redis.clients.jedis.exceptions.*;
|
||||
import redis.clients.jedis.tests.utils.JedisClusterTestUtil;
|
||||
import redis.clients.util.JedisClusterCRC16;
|
||||
|
||||
public class JedisClusterTest extends Assert {
|
||||
private Jedis node1;
|
||||
private static Jedis node1;
|
||||
private static Jedis node2;
|
||||
private static Jedis node3;
|
||||
private static Jedis node4;
|
||||
|
||||
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
|
||||
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
|
||||
private HostAndPort nodeInfo3 = HostAndPortUtil.getClusterServers().get(2);
|
||||
private HostAndPort nodeInfo4 = HostAndPortUtil.getClusterServers().get(3);
|
||||
|
||||
@Before
|
||||
public void setUp() throws InterruptedException {
|
||||
@@ -38,6 +43,10 @@ public class JedisClusterTest extends Assert {
|
||||
node3 = new Jedis(nodeInfo3.getHost(), nodeInfo3.getPort());
|
||||
node3.connect();
|
||||
node3.flushAll();
|
||||
|
||||
node4 = new Jedis(nodeInfo4.getHost(), nodeInfo4.getPort());
|
||||
node4.connect();
|
||||
node4.flushAll();
|
||||
|
||||
// ---- configure cluster
|
||||
|
||||
@@ -64,29 +73,53 @@ public class JedisClusterTest extends Assert {
|
||||
node2.clusterAddSlots(node2Slots);
|
||||
node3.clusterAddSlots(node3Slots);
|
||||
|
||||
waitForClusterReady();
|
||||
JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
int slotTest = JedisClusterCRC16.getSlot("test");
|
||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||
String node3Id = getNodeId(node3.clusterNodes());
|
||||
|
||||
String node1Id = JedisClusterTestUtil.getNodeId(node1.clusterNodes());
|
||||
String node2Id = JedisClusterTestUtil.getNodeId(node2.clusterNodes());
|
||||
String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
|
||||
node2.clusterSetSlotNode(slotTest, node3Id);
|
||||
node2.clusterSetSlotNode(slot51, node3Id);
|
||||
node2.clusterDelSlots(slotTest, slot51);
|
||||
|
||||
// forget about all nodes
|
||||
node1.clusterForget(node2Id);
|
||||
node1.clusterForget(node3Id);
|
||||
node2.clusterForget(node1Id);
|
||||
node2.clusterForget(node3Id);
|
||||
node3.clusterForget(node1Id);
|
||||
node3.clusterForget(node2Id);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
public void tearDown() throws InterruptedException {
|
||||
// clear all slots
|
||||
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
|
||||
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
|
||||
slotsToDelete[i] = i;
|
||||
}
|
||||
|
||||
node1.clusterDelSlots(slotsToDelete);
|
||||
node2.clusterDelSlots(slotsToDelete);
|
||||
node3.clusterDelSlots(slotsToDelete);
|
||||
|
||||
clearAnyInconsistentMigration(node1);
|
||||
clearAnyInconsistentMigration(node2);
|
||||
clearAnyInconsistentMigration(node3);
|
||||
}
|
||||
|
||||
private void clearAnyInconsistentMigration(Jedis node) {
|
||||
// FIXME: it's too slow... apply pipeline if possible
|
||||
List<Integer> slots = getInconsistentSlots(node.clusterNodes());
|
||||
for (Integer slot : slots) {
|
||||
node.clusterSetSlotStable(slot);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = JedisMovedDataException.class)
|
||||
@@ -110,7 +143,7 @@ public class JedisClusterTest extends Assert {
|
||||
@Test(expected = JedisAskDataException.class)
|
||||
public void testThrowAskException() {
|
||||
int keySlot = JedisClusterCRC16.getSlot("test");
|
||||
String node3Id = getNodeId(node3.clusterNodes());
|
||||
String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
|
||||
node2.clusterSetSlotMigrating(keySlot, node3Id);
|
||||
node2.get("test");
|
||||
}
|
||||
@@ -120,7 +153,7 @@ public class JedisClusterTest extends Assert {
|
||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
assertEquals(jc.getClusterNodes().size(), 3);
|
||||
assertEquals(3, jc.getClusterNodes().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,7 +177,7 @@ public class JedisClusterTest extends Assert {
|
||||
node3.clusterDelSlots(slot51);
|
||||
node3.clusterAddSlots(slot51);
|
||||
|
||||
waitForClusterReady();
|
||||
JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
|
||||
jc.set("51", "foo");
|
||||
assertEquals("foo", jc.get("51"));
|
||||
}
|
||||
@@ -155,8 +188,8 @@ public class JedisClusterTest extends Assert {
|
||||
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||
node3.clusterSetSlotImporting(slot51, getNodeId(node2.clusterNodes()));
|
||||
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
|
||||
node3.clusterSetSlotImporting(slot51, JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
|
||||
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||
jc.set("51", "foo");
|
||||
assertEquals("foo", jc.get("51"));
|
||||
}
|
||||
@@ -176,7 +209,7 @@ public class JedisClusterTest extends Assert {
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||
// This will cause an infinite redirection loop
|
||||
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
|
||||
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||
jc.set("51", "foo");
|
||||
}
|
||||
|
||||
@@ -188,36 +221,181 @@ public class JedisClusterTest extends Assert {
|
||||
assertEquals(JedisClusterCRC16.getSlot("foo{bar}{zap}"), JedisClusterCRC16.getSlot("bar"));
|
||||
}
|
||||
|
||||
private static String getNodeId(String infoOutput) {
|
||||
for (String infoLine : infoOutput.split("\n")) {
|
||||
if (infoLine.contains("myself")) {
|
||||
return infoLine.split(" ")[0];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@Test
|
||||
public void testClusterForgetNode() throws InterruptedException {
|
||||
// at first, join node4 to cluster
|
||||
node1.clusterMeet("127.0.0.1", nodeInfo4.getPort());
|
||||
|
||||
String node7Id = JedisClusterTestUtil.getNodeId(node4.clusterNodes());
|
||||
|
||||
JedisClusterTestUtil.assertNodeIsKnown(node3, node7Id, 1000);
|
||||
JedisClusterTestUtil.assertNodeIsKnown(node2, node7Id, 1000);
|
||||
JedisClusterTestUtil.assertNodeIsKnown(node1, node7Id, 1000);
|
||||
|
||||
assertNodeHandshakeEnded(node3, 1000);
|
||||
assertNodeHandshakeEnded(node2, 1000);
|
||||
assertNodeHandshakeEnded(node1, 1000);
|
||||
|
||||
assertEquals(4, node1.clusterNodes().split("\n").length);
|
||||
assertEquals(4, node2.clusterNodes().split("\n").length);
|
||||
assertEquals(4, node3.clusterNodes().split("\n").length);
|
||||
|
||||
// do cluster forget
|
||||
node1.clusterForget(node7Id);
|
||||
node2.clusterForget(node7Id);
|
||||
node3.clusterForget(node7Id);
|
||||
|
||||
JedisClusterTestUtil.assertNodeIsUnknown(node1, node7Id, 1000);
|
||||
JedisClusterTestUtil.assertNodeIsUnknown(node2, node7Id, 1000);
|
||||
JedisClusterTestUtil.assertNodeIsUnknown(node3, node7Id, 1000);
|
||||
|
||||
assertEquals(3, node1.clusterNodes().split("\n").length);
|
||||
assertEquals(3, node2.clusterNodes().split("\n").length);
|
||||
assertEquals(3, node3.clusterNodes().split("\n").length);
|
||||
}
|
||||
|
||||
@Test(expected = JedisConnectionException.class)
|
||||
public void testIfPoolConfigAppliesToClusterPools() {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(0);
|
||||
config.setMaxWaitMillis(2000);
|
||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode, config);
|
||||
jc.set("52", "poolTestValue");
|
||||
}
|
||||
|
||||
private void waitForClusterReady() throws InterruptedException {
|
||||
boolean clusterOk = false;
|
||||
while (!clusterOk) {
|
||||
if (node1.clusterInfo().split("\n")[0].contains("ok")
|
||||
&& node2.clusterInfo().split("\n")[0].contains("ok")
|
||||
&& node3.clusterInfo().split("\n")[0].contains("ok")) {
|
||||
clusterOk = true;
|
||||
|
||||
@Test
|
||||
public void testClusterFlushSlots() {
|
||||
String slotRange = getNodeServingSlotRange(node1.clusterNodes());
|
||||
assertNotNull(slotRange);
|
||||
|
||||
try {
|
||||
node1.clusterFlushSlots();
|
||||
assertNull(getNodeServingSlotRange(node1.clusterNodes()));
|
||||
} finally {
|
||||
// rollback
|
||||
String[] rangeInfo = slotRange.split("-");
|
||||
int lower = Integer.parseInt(rangeInfo[0]);
|
||||
int upper = Integer.parseInt(rangeInfo[1]);
|
||||
|
||||
int[] node1Slots = new int[upper - lower + 1];
|
||||
for (int i = 0 ; lower <= upper ; ) {
|
||||
node1Slots[i++] = lower++;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
node1.clusterAddSlots(node1Slots);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterKeySlot() {
|
||||
// It assumes JedisClusterCRC16 is correctly implemented
|
||||
assertEquals(node1.clusterKeySlot("foo{bar}zap}").intValue(), JedisClusterCRC16.getSlot("foo{bar}zap"));
|
||||
assertEquals(node1.clusterKeySlot("{user1000}.following").intValue(), JedisClusterCRC16.getSlot("{user1000}.following"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterCountKeysInSlot() {
|
||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||
jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
|
||||
for (int index = 0 ; index < 5 ; index++) {
|
||||
jc.set("foo{bar}" + index, "hello");
|
||||
}
|
||||
|
||||
int slot = JedisClusterCRC16.getSlot("foo{bar}");
|
||||
assertEquals(5, node1.clusterCountKeysInSlot(slot).intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStableSlotWhenMigratingNodeOrImportingNodeIsNotSpecified() throws InterruptedException {
|
||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||
jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));
|
||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||
|
||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||
jc.set("51", "foo");
|
||||
// node2 is responsible of taking care of slot51 (7186)
|
||||
|
||||
node3.clusterSetSlotImporting(slot51, JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
|
||||
assertEquals("foo", jc.get("51"));
|
||||
node3.clusterSetSlotStable(slot51);
|
||||
assertEquals("foo", jc.get("51"));
|
||||
|
||||
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||
//assertEquals("foo", jc.get("51")); // it leads Max Redirections
|
||||
node2.clusterSetSlotStable(slot51);
|
||||
assertEquals("foo", jc.get("51"));
|
||||
}
|
||||
|
||||
private static String getNodeServingSlotRange(String infoOutput) {
|
||||
// f4f3dc4befda352a4e0beccf29f5e8828438705d 127.0.0.1:7380 master - 0 1394372400827 0 connected 5461-10922
|
||||
for (String infoLine : infoOutput.split("\n")) {
|
||||
if (infoLine.contains("myself")) {
|
||||
try {
|
||||
return infoLine.split(" ")[8];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Integer> getInconsistentSlots(String infoOuput) {
|
||||
for (String infoLine : infoOuput.split("\n")) {
|
||||
if (infoLine.contains("myself")) {
|
||||
return getSlotsBeingMigrated(infoLine);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Integer> getSlotsBeingMigrated(String infoLine) {
|
||||
List<Integer> inconsistentSlots = new ArrayList<Integer>();
|
||||
|
||||
String[] splitted = infoLine.split(" ");
|
||||
|
||||
if (splitted.length > 8) {
|
||||
for (int index = 8 ; index < splitted.length ; index++) {
|
||||
String info = splitted[index];
|
||||
Integer slot = getSlotFromMigrationInfo(info);
|
||||
if (slot != null) {
|
||||
inconsistentSlots.add(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inconsistentSlots;
|
||||
}
|
||||
|
||||
private Integer getSlotFromMigrationInfo(String info) {
|
||||
if (info.startsWith("[")) {
|
||||
if (info.contains("-<-")) {
|
||||
return Integer.parseInt(info.split("-<-")[0].substring(1));
|
||||
} else if (info.contains("->-")) {
|
||||
return Integer.parseInt(info.split("->-")[0].substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void assertNodeHandshakeEnded(Jedis node, int timeoutMs) {
|
||||
int sleepInterval = 100;
|
||||
for (int sleepTime = 0 ; sleepTime <= timeoutMs ; sleepTime += sleepInterval) {
|
||||
boolean isHandshaking = isAnyNodeHandshaking(node);
|
||||
if (!isHandshaking)
|
||||
return;
|
||||
|
||||
try {
|
||||
Thread.sleep(sleepInterval);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new JedisException("Node handshaking is not ended");
|
||||
}
|
||||
|
||||
private boolean isAnyNodeHandshaking(Jedis node) {
|
||||
String infoOutput = node.clusterNodes();
|
||||
for (String infoLine : infoOutput.split("\n")) {
|
||||
if (infoLine.contains("handshake")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -187,18 +187,48 @@ public class JedisPoolTest extends Assert {
|
||||
2000, "foobared");
|
||||
|
||||
Jedis jedis = pool.getResource();
|
||||
jedis.set("hello", "jedis");
|
||||
Transaction t = jedis.multi();
|
||||
t.set("hello", "world");
|
||||
pool.returnResource(jedis);
|
||||
try {
|
||||
jedis.set("hello", "jedis");
|
||||
Transaction t = jedis.multi();
|
||||
t.set("hello", "world");
|
||||
} finally {
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
Jedis jedis2 = pool.getResource();
|
||||
assertTrue(jedis == jedis2);
|
||||
assertEquals("jedis", jedis2.get("hello"));
|
||||
pool.returnResource(jedis2);
|
||||
try {
|
||||
assertTrue(jedis == jedis2);
|
||||
assertEquals("jedis", jedis2.get("hello"));
|
||||
} finally {
|
||||
jedis2.close();
|
||||
}
|
||||
|
||||
pool.destroy();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void checkResourceIsCloseable() {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
|
||||
2000, "foobared");
|
||||
|
||||
Jedis jedis = pool.getResource();
|
||||
try {
|
||||
jedis.set("hello", "jedis");
|
||||
} finally {
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
Jedis jedis2 = pool.getResource();
|
||||
try {
|
||||
assertEquals(jedis, jedis2);
|
||||
} finally {
|
||||
jedis2.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnNullObjectShouldNotFail() {
|
||||
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
|
||||
|
||||
@@ -79,6 +79,55 @@ public class JedisSentinelPoolTest extends JedisTestBase {
|
||||
pool.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkResourceIsCloseable() {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
|
||||
config, 1000, "foobared", 2);
|
||||
|
||||
Jedis jedis = pool.getResource();
|
||||
try {
|
||||
jedis.set("hello", "jedis");
|
||||
} finally {
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
Jedis jedis2 = pool.getResource();
|
||||
try {
|
||||
assertEquals(jedis, jedis2);
|
||||
} finally {
|
||||
jedis2.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnResourceWithNullResource() {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
|
||||
config, 1000, "foobared", 2);
|
||||
|
||||
Jedis nullJedis = null;
|
||||
pool.returnResource(nullJedis);
|
||||
pool.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnBrokenResourceWithNullResource() {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
|
||||
config, 1000, "foobared", 2);
|
||||
|
||||
Jedis nullJedis = null;
|
||||
pool.returnBrokenResource(nullJedis);
|
||||
pool.destroy();
|
||||
}
|
||||
|
||||
private void forceFailover(JedisSentinelPool pool)
|
||||
throws InterruptedException {
|
||||
|
||||
@@ -272,6 +272,26 @@ public class PipeliningTest extends Assert {
|
||||
assertEquals("world", r3.get());
|
||||
}
|
||||
|
||||
@Test(expected = JedisDataException.class)
|
||||
public void pipelineExecShoudThrowJedisDataExceptionWhenNotInMulti() {
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipeline.exec();
|
||||
}
|
||||
|
||||
@Test(expected = JedisDataException.class)
|
||||
public void pipelineDiscardShoudThrowJedisDataExceptionWhenNotInMulti() {
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipeline.discard();
|
||||
}
|
||||
|
||||
@Test(expected = JedisDataException.class)
|
||||
public void pipelineMultiShoudThrowJedisDataExceptionWhenAlreadyInMulti() {
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipeline.multi();
|
||||
pipeline.set("foo", "3");
|
||||
pipeline.multi();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscardInPipeline() {
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
|
||||
@@ -14,6 +14,7 @@ import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisShardInfo;
|
||||
import redis.clients.jedis.ShardedJedis;
|
||||
import redis.clients.jedis.ShardedJedisPipeline;
|
||||
import redis.clients.jedis.ShardedJedisPool;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
|
||||
@@ -233,4 +234,69 @@ public class ShardedJedisPoolTest extends Assert {
|
||||
assertEquals("PONG", jedis.ping());
|
||||
assertEquals("bar", jedis.get("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnResourceShouldResetState() throws URISyntaxException {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
|
||||
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||
shards.add(new JedisShardInfo(new URI(
|
||||
"redis://:foobared@localhost:6380")));
|
||||
shards.add(new JedisShardInfo(new URI(
|
||||
"redis://:foobared@localhost:6379")));
|
||||
|
||||
ShardedJedisPool pool = new ShardedJedisPool(config, shards);
|
||||
|
||||
ShardedJedis jedis = pool.getResource();
|
||||
jedis.set("pipelined", String.valueOf(0));
|
||||
jedis.set("pipelined2", String.valueOf(0));
|
||||
|
||||
ShardedJedisPipeline pipeline = jedis.pipelined();
|
||||
|
||||
pipeline.incr("pipelined");
|
||||
pipeline.incr("pipelined2");
|
||||
|
||||
jedis.resetState();
|
||||
|
||||
pipeline = jedis.pipelined();
|
||||
pipeline.incr("pipelined");
|
||||
pipeline.incr("pipelined2");
|
||||
List<Object> results = pipeline.syncAndReturnAll();
|
||||
|
||||
assertEquals(2, results.size());
|
||||
pool.returnResource(jedis);
|
||||
pool.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkResourceIsCloseable() throws URISyntaxException {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(1);
|
||||
config.setBlockWhenExhausted(false);
|
||||
|
||||
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||
shards.add(new JedisShardInfo(new URI(
|
||||
"redis://:foobared@localhost:6380")));
|
||||
shards.add(new JedisShardInfo(new URI(
|
||||
"redis://:foobared@localhost:6379")));
|
||||
|
||||
ShardedJedisPool pool = new ShardedJedisPool(config, shards);
|
||||
|
||||
ShardedJedis jedis = pool.getResource();
|
||||
try {
|
||||
jedis.set("hello", "jedis");
|
||||
} finally {
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
ShardedJedis jedis2 = pool.getResource();
|
||||
try {
|
||||
assertEquals(jedis, jedis2);
|
||||
} finally {
|
||||
jedis2.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -302,4 +302,25 @@ public class ShardedJedisTest extends Assert {
|
||||
assertEquals(jedisShardInfo.getName(), jedisShardInfo2.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCloseable() {
|
||||
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||
shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
|
||||
shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
|
||||
shards.get(0).setPassword("foobared");
|
||||
shards.get(1).setPassword("foobared");
|
||||
|
||||
ShardedJedis jedisShard = new ShardedJedis(shards);
|
||||
try {
|
||||
jedisShard.set("shard_closeable", "true");
|
||||
} finally {
|
||||
jedisShard.close();
|
||||
}
|
||||
|
||||
for (Jedis jedis : jedisShard.getAllShards()) {
|
||||
assertTrue(!jedis.isConnected());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import redis.clients.jedis.ScanResult;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.util.SafeEncoder;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||
|
||||
public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||
@@ -474,9 +475,16 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||
long status = jedis.pexpire("foo", 10000);
|
||||
assertEquals(0, status);
|
||||
|
||||
jedis.set("foo", "bar");
|
||||
status = jedis.pexpire("foo", 10000);
|
||||
jedis.set("foo1", "bar1");
|
||||
status = jedis.pexpire("foo1", 10000);
|
||||
assertEquals(1, status);
|
||||
|
||||
jedis.set("foo2", "bar2");
|
||||
status = jedis.pexpire("foo2", 200000000000L);
|
||||
assertEquals(1, status);
|
||||
|
||||
long pttl = jedis.pttl("foo2");
|
||||
assertTrue(pttl > 100000000000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -515,8 +523,14 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void scanMatch() {
|
||||
ScanParams params = new ScanParams();
|
||||
@@ -529,6 +543,19 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.match(bfoostar);
|
||||
|
||||
jedis.set(bfoo1, bbar);
|
||||
jedis.set(bfoo2, bbar);
|
||||
jedis.set(bfoo3, bbar);
|
||||
|
||||
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -543,5 +570,17 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||
ScanResult<String> result = jedis.scan(SCAN_POINTER_START, params);
|
||||
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.count(2);
|
||||
|
||||
jedis.set(bfoo1, bbar);
|
||||
jedis.set(bfoo2, bbar);
|
||||
jedis.set(bfoo3, bbar);
|
||||
|
||||
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package redis.clients.jedis.tests.commands;
|
||||
import org.junit.Test;
|
||||
|
||||
import redis.clients.jedis.BitOP;
|
||||
import redis.clients.jedis.BitPosParams;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class BitCommandsTest extends JedisCommandTestBase {
|
||||
@Test
|
||||
@@ -20,6 +22,111 @@ public class BitCommandsTest extends JedisCommandTestBase {
|
||||
assertTrue(bbit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitpos() {
|
||||
String foo = "foo";
|
||||
|
||||
jedis.set(foo, String.valueOf(0));
|
||||
|
||||
jedis.setbit(foo, 3, true);
|
||||
jedis.setbit(foo, 7, true);
|
||||
jedis.setbit(foo, 13, true);
|
||||
jedis.setbit(foo, 39, true);
|
||||
|
||||
/*
|
||||
* byte: 0 1 2 3 4
|
||||
* bit: 00010001 / 00000100 / 00000000 / 00000000 / 00000001
|
||||
*/
|
||||
long offset = jedis.bitpos(foo, true);
|
||||
assertEquals(2, offset);
|
||||
offset = jedis.bitpos(foo, false);
|
||||
assertEquals(0, offset);
|
||||
|
||||
offset = jedis.bitpos(foo, true, new BitPosParams(1));
|
||||
assertEquals(13, offset);
|
||||
offset = jedis.bitpos(foo, false, new BitPosParams(1));
|
||||
assertEquals(8, offset);
|
||||
|
||||
offset = jedis.bitpos(foo, true, new BitPosParams(2, 3));
|
||||
assertEquals(-1, offset);
|
||||
offset = jedis.bitpos(foo, false, new BitPosParams(2, 3));
|
||||
assertEquals(16, offset);
|
||||
|
||||
offset = jedis.bitpos(foo, true, new BitPosParams(3, 4));
|
||||
assertEquals(39, offset);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitposBinary() {
|
||||
// binary
|
||||
byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||
|
||||
jedis.set(bfoo, Protocol.toByteArray(0));
|
||||
|
||||
jedis.setbit(bfoo, 3, true);
|
||||
jedis.setbit(bfoo, 7, true);
|
||||
jedis.setbit(bfoo, 13, true);
|
||||
jedis.setbit(bfoo, 39, true);
|
||||
|
||||
/*
|
||||
* byte: 0 1 2 3 4
|
||||
* bit: 00010001 / 00000100 / 00000000 / 00000000 / 00000001
|
||||
*/
|
||||
long offset = jedis.bitpos(bfoo, true);
|
||||
assertEquals(2, offset);
|
||||
offset = jedis.bitpos(bfoo, false);
|
||||
assertEquals(0, offset);
|
||||
|
||||
offset = jedis.bitpos(bfoo, true, new BitPosParams(1));
|
||||
assertEquals(13, offset);
|
||||
offset = jedis.bitpos(bfoo, false, new BitPosParams(1));
|
||||
assertEquals(8, offset);
|
||||
|
||||
offset = jedis.bitpos(bfoo, true, new BitPosParams(2, 3));
|
||||
assertEquals(-1, offset);
|
||||
offset = jedis.bitpos(bfoo, false, new BitPosParams(2, 3));
|
||||
assertEquals(16, offset);
|
||||
|
||||
offset = jedis.bitpos(bfoo, true, new BitPosParams(3, 4));
|
||||
assertEquals(39, offset);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitposWithNoMatchingBitExist() {
|
||||
String foo = "foo";
|
||||
|
||||
jedis.set(foo, String.valueOf(0));
|
||||
for (int idx = 0; idx < 8; idx++) {
|
||||
jedis.setbit(foo, idx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* byte: 0
|
||||
* bit: 11111111
|
||||
*/
|
||||
long offset = jedis.bitpos(foo, false);
|
||||
// offset should be last index + 1
|
||||
assertEquals(8, offset);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitposWithNoMatchingBitExistWithinRange() {
|
||||
String foo = "foo";
|
||||
|
||||
jedis.set(foo, String.valueOf(0));
|
||||
for (int idx = 0; idx < 8 * 5; idx++) {
|
||||
jedis.setbit(foo, idx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* byte: 0 1 2 3 4
|
||||
* bit: 11111111 / 11111111 / 11111111 / 11111111 / 11111111
|
||||
*/
|
||||
long offset = jedis.bitpos(foo, false, new BitPosParams(2, 3));
|
||||
// offset should be -1
|
||||
assertEquals(-1, offset);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndgetrange() {
|
||||
jedis.set("key1", "Hello World");
|
||||
|
||||
@@ -13,12 +13,18 @@ import org.junit.Test;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||
|
||||
public class HashesCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
|
||||
final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C };
|
||||
|
||||
|
||||
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||
|
||||
@Test
|
||||
public void hset() {
|
||||
long status = jedis.hset("foo", "bar", "car");
|
||||
@@ -147,6 +153,25 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hincrByFloat() {
|
||||
Double value = jedis.hincrByFloat("foo", "bar", 1.5d);
|
||||
assertEquals((Double) 1.5d, value);
|
||||
value = jedis.hincrByFloat("foo", "bar", -1.5d);
|
||||
assertEquals((Double) 0d, value);
|
||||
value = jedis.hincrByFloat("foo", "bar", -10.7d);
|
||||
assertEquals(Double.compare(-10.7d, value), 0);
|
||||
|
||||
// Binary
|
||||
double bvalue = jedis.hincrByFloat(bfoo, bbar, 1.5d);
|
||||
assertEquals(Double.compare(1.5d, bvalue), 0);
|
||||
bvalue = jedis.hincrByFloat(bfoo, bbar, -1.5d);
|
||||
assertEquals(Double.compare(0d, bvalue), 0);
|
||||
bvalue = jedis.hincrByFloat(bfoo, bbar, -10.7d);
|
||||
assertEquals(Double.compare(-10.7d, value), 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hexists() {
|
||||
Map<String, String> hash = new HashMap<String, String>();
|
||||
@@ -300,6 +325,14 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
jedis.hset(bfoo, bbar, bcar);
|
||||
|
||||
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -315,6 +348,20 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.match(bbarstar);
|
||||
|
||||
jedis.hset(bfoo, bbar, bcar);
|
||||
jedis.hset(bfoo, bbar1, bcar);
|
||||
jedis.hset(bfoo, bbar2, bcar);
|
||||
jedis.hset(bfoo, bbar3, bcar);
|
||||
|
||||
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -330,5 +377,18 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
||||
SCAN_POINTER_START, params);
|
||||
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.count(2);
|
||||
|
||||
jedis.hset(bfoo, bbar, bcar);
|
||||
jedis.hset(bfoo, bbar1, bcar);
|
||||
jedis.hset(bfoo, bbar2, bcar);
|
||||
jedis.hset(bfoo, bbar3, bcar);
|
||||
|
||||
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package redis.clients.jedis.tests.commands;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import redis.clients.util.SafeEncoder;
|
||||
|
||||
public class HyperLogLogCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
@Test
|
||||
public void pfadd() {
|
||||
long status = jedis.pfadd("foo", "a");
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd("foo", "a");
|
||||
assertEquals(0, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfaddBinary() {
|
||||
byte[] bFoo = SafeEncoder.encode("foo");
|
||||
byte[] bBar = SafeEncoder.encode("bar");
|
||||
byte[] bBar2 = SafeEncoder.encode("bar2");
|
||||
|
||||
long status = jedis.pfadd(bFoo, bBar, bBar2);
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd(bFoo, bBar, bBar2);
|
||||
assertEquals(0, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfcount() {
|
||||
long status = jedis.pfadd("hll", "foo", "bar", "zap");
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd("hll", "zap", "zap", "zap");
|
||||
assertEquals(0, status);
|
||||
|
||||
status = jedis.pfadd("hll", "foo", "bar");
|
||||
assertEquals(0, status);
|
||||
|
||||
status = jedis.pfcount("hll");
|
||||
assertEquals(3, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfcounts() {
|
||||
long status = jedis.pfadd("hll_1", "foo", "bar", "zap");
|
||||
assertEquals(1, status);
|
||||
status = jedis.pfadd("hll_2", "foo", "bar", "zap");
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd("hll_3", "foo", "bar", "baz");
|
||||
assertEquals(1, status);
|
||||
status = jedis.pfcount("hll_1");
|
||||
assertEquals(3, status);
|
||||
status = jedis.pfcount("hll_2");
|
||||
assertEquals(3, status);
|
||||
status = jedis.pfcount("hll_3");
|
||||
assertEquals(3, status);
|
||||
|
||||
status = jedis.pfcount("hll_1", "hll_2");
|
||||
assertEquals(3, status);
|
||||
|
||||
status = jedis.pfcount("hll_1", "hll_2", "hll_3");
|
||||
assertEquals(4, status);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfcountBinary() {
|
||||
byte[] bHll = SafeEncoder.encode("hll");
|
||||
byte[] bFoo = SafeEncoder.encode("foo");
|
||||
byte[] bBar = SafeEncoder.encode("bar");
|
||||
byte[] bZap = SafeEncoder.encode("zap");
|
||||
|
||||
long status = jedis.pfadd(bHll, bFoo, bBar, bZap);
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd(bHll, bZap, bZap, bZap);
|
||||
assertEquals(0, status);
|
||||
|
||||
status = jedis.pfadd(bHll, bFoo, bBar);
|
||||
assertEquals(0, status);
|
||||
|
||||
status = jedis.pfcount(bHll);
|
||||
assertEquals(3, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfmerge() {
|
||||
long status = jedis.pfadd("hll1", "foo", "bar", "zap", "a");
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd("hll2", "a", "b", "c", "foo");
|
||||
assertEquals(1, status);
|
||||
|
||||
String mergeStatus = jedis.pfmerge("hll3", "hll1", "hll2");
|
||||
assertEquals("OK", mergeStatus);
|
||||
|
||||
status = jedis.pfcount("hll3");
|
||||
assertEquals(6, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pfmergeBinary() {
|
||||
byte[] bHll1 = SafeEncoder.encode("hll1");
|
||||
byte[] bHll2 = SafeEncoder.encode("hll2");
|
||||
byte[] bHll3 = SafeEncoder.encode("hll3");
|
||||
byte[] bFoo = SafeEncoder.encode("foo");
|
||||
byte[] bBar = SafeEncoder.encode("bar");
|
||||
byte[] bZap = SafeEncoder.encode("zap");
|
||||
byte[] bA = SafeEncoder.encode("a");
|
||||
byte[] bB = SafeEncoder.encode("b");
|
||||
byte[] bC = SafeEncoder.encode("c");
|
||||
|
||||
long status = jedis.pfadd(bHll1, bFoo, bBar, bZap, bA);
|
||||
assertEquals(1, status);
|
||||
|
||||
status = jedis.pfadd(bHll2, bA, bB, bC, bFoo);
|
||||
assertEquals(1, status);
|
||||
|
||||
String mergeStatus = jedis.pfmerge(bHll3, bHll1, bHll2);
|
||||
assertEquals("OK", mergeStatus);
|
||||
|
||||
status = jedis.pfcount("hll3");
|
||||
assertEquals(6, status);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.junit.Test;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||
|
||||
public class SetCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||
@@ -19,6 +20,11 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] bc = { 0x0C };
|
||||
final byte[] bd = { 0x0D };
|
||||
final byte[] bx = { 0x42 };
|
||||
|
||||
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||
|
||||
@Test
|
||||
public void sadd() {
|
||||
@@ -462,6 +468,14 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
jedis.sadd(bfoo, ba, bb);
|
||||
|
||||
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -474,6 +488,16 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.match(bbarstar);
|
||||
|
||||
jedis.sadd(bfoo, bbar1, bbar2, bbar3);
|
||||
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -486,5 +510,14 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
||||
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START, params);
|
||||
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.count(2);
|
||||
|
||||
jedis.sadd(bfoo, bbar1, bbar2, bbar3);
|
||||
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import redis.clients.jedis.Tuple;
|
||||
import redis.clients.jedis.ZParams;
|
||||
import redis.clients.util.SafeEncoder;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||
|
||||
public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||
@@ -19,6 +20,11 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||
final byte[] ba = { 0x0A };
|
||||
final byte[] bb = { 0x0B };
|
||||
final byte[] bc = { 0x0C };
|
||||
|
||||
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||
|
||||
@Test
|
||||
public void zadd() {
|
||||
@@ -899,6 +905,15 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
jedis.zadd(bfoo, 1, ba);
|
||||
jedis.zadd(bfoo, 1, bb);
|
||||
|
||||
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -913,6 +928,19 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||
|
||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.match(bbarstar);
|
||||
|
||||
jedis.zadd(bfoo, 2, bbar1);
|
||||
jedis.zadd(bfoo, 1, bbar2);
|
||||
jedis.zadd(bfoo, 11, bbar3);
|
||||
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -929,5 +957,17 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START, params);
|
||||
|
||||
assertFalse(result.getResult().isEmpty());
|
||||
|
||||
// binary
|
||||
params = new ScanParams();
|
||||
params.count(2);
|
||||
|
||||
jedis.zadd(bfoo, 2, bbar1);
|
||||
jedis.zadd(bfoo, 1, bbar2);
|
||||
jedis.zadd(bfoo, 11, bbar3);
|
||||
|
||||
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||
|
||||
assertFalse(bResult.getResult().isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,12 @@ public class StringValuesCommandsTest extends JedisCommandTestBase {
|
||||
assertEquals(4, value);
|
||||
}
|
||||
|
||||
@Test(expected = JedisDataException.class)
|
||||
public void incrByFloatWrongValue() {
|
||||
jedis.set("foo", "bar");
|
||||
jedis.incrByFloat("foo", 2d);
|
||||
}
|
||||
|
||||
@Test(expected = JedisDataException.class)
|
||||
public void decrWrongValue() {
|
||||
jedis.set("foo", "bar");
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package redis.clients.jedis.tests.utils;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
public class JedisClusterTestUtil {
|
||||
public static void waitForClusterReady(Jedis...nodes) throws InterruptedException {
|
||||
boolean clusterOk = false;
|
||||
while (!clusterOk) {
|
||||
boolean isOk = true;
|
||||
for (Jedis node : nodes) {
|
||||
if (!node.clusterInfo().split("\n")[0].contains("ok")) {
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isOk) {
|
||||
clusterOk = true;
|
||||
}
|
||||
|
||||
Thread.sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNodeId(String infoOutput) {
|
||||
for (String infoLine : infoOutput.split("\n")) {
|
||||
if (infoLine.contains("myself")) {
|
||||
return infoLine.split(" ")[0];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void assertNodeIsKnown(Jedis node, String targetNodeId, int timeoutMs) {
|
||||
assertNodeRecognizedStatus(node, targetNodeId, true, timeoutMs);
|
||||
}
|
||||
|
||||
public static void assertNodeIsUnknown(Jedis node, String targetNodeId, int timeoutMs) {
|
||||
assertNodeRecognizedStatus(node, targetNodeId, false, timeoutMs);
|
||||
}
|
||||
|
||||
private static void assertNodeRecognizedStatus(Jedis node, String targetNodeId, boolean shouldRecognized, int timeoutMs) {
|
||||
int sleepInterval = 100;
|
||||
for (int sleepTime = 0 ; sleepTime <= timeoutMs ; sleepTime += sleepInterval) {
|
||||
boolean known = isKnownNode(node, targetNodeId);
|
||||
if (shouldRecognized == known)
|
||||
return;
|
||||
|
||||
try {
|
||||
Thread.sleep(sleepInterval);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new JedisException("Node recognize check error");
|
||||
}
|
||||
|
||||
private static boolean isKnownNode(Jedis node, String nodeId) {
|
||||
String infoOutput = node.clusterNodes();
|
||||
for (String infoLine : infoOutput.split("\n")) {
|
||||
if (infoLine.contains(nodeId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user