Package redis.clients.jedis.tests

Source Code of redis.clients.jedis.tests.JedisClusterTest

package redis.clients.jedis.tests;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
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.JedisCluster.Reset;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterException;
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.jedis.tests.utils.JedisClusterTestUtil;
import redis.clients.util.JedisClusterCRC16;

public class JedisClusterTest extends Assert {
    private static Jedis node1;
    private static Jedis node2;
    private static Jedis node3;
    private static Jedis node4;
    private String localHost = "127.0.0.1";

    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);
    protected Logger log = Logger.getLogger(getClass().getName());

    @Before
    public void setUp() throws InterruptedException {
  node1 = new Jedis(nodeInfo1.getHost(), nodeInfo1.getPort());
  node1.connect();
  node1.flushAll();

  node2 = new Jedis(nodeInfo2.getHost(), nodeInfo2.getPort());
  node2.connect();
  node2.flushAll();

  node3 = new Jedis(nodeInfo3.getHost(), nodeInfo3.getPort());
  node3.connect();
  node3.flushAll();

  node4 = new Jedis(nodeInfo4.getHost(), nodeInfo4.getPort());
  node4.connect();
  node4.flushAll();

  // ---- configure cluster

  // add nodes to cluster
  node1.clusterMeet(localHost, nodeInfo2.getPort());
  node1.clusterMeet(localHost, nodeInfo3.getPort());

  // split available slots across the three nodes
  int slotsPerNode = JedisCluster.HASHSLOTS / 3;
  int[] node1Slots = new int[slotsPerNode];
  int[] node2Slots = new int[slotsPerNode + 1];
  int[] node3Slots = new int[slotsPerNode];
  for (int i = 0, slot1 = 0, slot2 = 0, slot3 = 0; i < JedisCluster.HASHSLOTS; i++) {
      if (i < slotsPerNode) {
    node1Slots[slot1++] = i;
      } else if (i > slotsPerNode * 2) {
    node3Slots[slot3++] = i;
      } else {
    node2Slots[slot2++] = i;
      }
  }

  node1.clusterAddSlots(node1Slots);
  node2.clusterAddSlots(node2Slots);
  node3.clusterAddSlots(node3Slots);

  JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
    }

    @AfterClass
    public static void cleanUp() {
  node1.flushDB();
  node2.flushDB();
  node3.flushDB();
  node4.flushDB();
  node1.clusterReset(Reset.SOFT);
  node2.clusterReset(Reset.SOFT);
  node3.clusterReset(Reset.SOFT);
  node4.clusterReset(Reset.SOFT);
    }

    @After
    public void tearDown() throws InterruptedException {
  cleanUp();
    }

    @Test(expected = JedisMovedDataException.class)
    public void testThrowMovedException() {
  node1.set("foo", "bar");
    }

    @Test
    public void testMovedExceptionParameters() {
  try {
      node1.set("foo", "bar");
  } catch (JedisMovedDataException jme) {
      assertEquals(12182, jme.getSlot());
      assertEquals(new HostAndPort("127.0.0.1", 7381),
        jme.getTargetNode());
      return;
  }
  fail();
    }

    @Test(expected = JedisAskDataException.class)
    public void testThrowAskException() {
  int keySlot = JedisClusterCRC16.getSlot("test");
  String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
  node2.clusterSetSlotMigrating(keySlot, node3Id);
  node2.get("test");
    }

    @Test
    public void testDiscoverNodesAutomatically() {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  assertEquals(3, jc.getClusterNodes().size());
    }

    @Test
    public void testCalculateConnectionPerSlot() {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  jc.set("foo", "bar");
  jc.set("test", "test");
  assertEquals("bar", node3.get("foo"));
  assertEquals("test", node2.get("test"));
    }

    /**
     * slot->nodes 15363 node3 e
     */
    @Test
    public void testMigrate() {
  log.info("test migrate slot");
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(nodeInfo1);
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
  String node2Id = JedisClusterTestUtil.getNodeId(node2.clusterNodes());
  node3.clusterSetSlotMigrating(15363, node2Id);
  node2.clusterSetSlotImporting(15363, node3Id);
  try {
      node2.set("e", "e");
  } catch (JedisMovedDataException jme) {
      assertEquals(15363, jme.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo3.getPort()),
        jme.getTargetNode());
  }

  try {
      node3.set("e", "e");
  } catch (JedisAskDataException jae) {
      assertEquals(15363, jae.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo2.getPort()),
        jae.getTargetNode());
  }

  jc.set("e", "e");

  try {
      node2.get("e");
  } catch (JedisMovedDataException jme) {
      assertEquals(15363, jme.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo3.getPort()),
        jme.getTargetNode());
  }
  try {
      node3.get("e");
  } catch (JedisAskDataException jae) {
      assertEquals(15363, jae.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo2.getPort()),
        jae.getTargetNode());
  }

  assertEquals("e", jc.get("e"));

  node2.clusterSetSlotNode(15363, node2Id);
  node3.clusterSetSlotNode(15363, node2Id);
  // assertEquals("e", jc.get("e"));
  assertEquals("e", node2.get("e"));

  // assertEquals("e", node3.get("e"));

    }

    @Test
    public void testMigrateToNewNode() throws InterruptedException {
  log.info("test migrate slot to new node");
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(nodeInfo1);
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  node4.clusterMeet(localHost, nodeInfo1.getPort());

  String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
  String node4Id = JedisClusterTestUtil.getNodeId(node4.clusterNodes());
  JedisClusterTestUtil.waitForClusterReady(node4);
  node3.clusterSetSlotMigrating(15363, node4Id);
  node4.clusterSetSlotImporting(15363, node3Id);
  try {
      node4.set("e", "e");
  } catch (JedisMovedDataException jme) {
      assertEquals(15363, jme.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo3.getPort()),
        jme.getTargetNode());
  }

  try {
      node3.set("e", "e");
  } catch (JedisAskDataException jae) {
      assertEquals(15363, jae.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo4.getPort()),
        jae.getTargetNode());
  }

  jc.set("e", "e");

  try {
      node4.get("e");
  } catch (JedisMovedDataException jme) {
      assertEquals(15363, jme.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo3.getPort()),
        jme.getTargetNode());
  }
  try {
      node3.get("e");
  } catch (JedisAskDataException jae) {
      assertEquals(15363, jae.getSlot());
      assertEquals(new HostAndPort(localHost, nodeInfo4.getPort()),
        jae.getTargetNode());
  }

  assertEquals("e", jc.get("e"));

  node4.clusterSetSlotNode(15363, node4Id);
  node3.clusterSetSlotNode(15363, node4Id);
  // assertEquals("e", jc.get("e"));
  assertEquals("e", node4.get("e"));

  // assertEquals("e", node3.get("e"));

    }

    @Test
    public void testRecalculateSlotsWhenMoved() throws InterruptedException {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  int slot51 = JedisClusterCRC16.getSlot("51");
  node2.clusterDelSlots(slot51);
  node3.clusterDelSlots(slot51);
  node3.clusterAddSlots(slot51);

  JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
  jc.set("51", "foo");
  assertEquals("foo", jc.get("51"));
    }

    @Test
    public void testAskResponse() throws InterruptedException {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  int slot51 = JedisClusterCRC16.getSlot("51");
  node3.clusterSetSlotImporting(slot51,
    JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
  node2.clusterSetSlotMigrating(slot51,
    JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
  jc.set("51", "foo");
  assertEquals("foo", jc.get("51"));
    }

    @Test(expected = JedisClusterException.class)
    public void testThrowExceptionWithoutKey() {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  jc.ping();
    }

    @Test(expected = JedisClusterMaxRedirectionsException.class)
    public void testRedisClusterMaxRedirections() {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  JedisCluster jc = new JedisCluster(jedisClusterNode);
  int slot51 = JedisClusterCRC16.getSlot("51");
  // This will cause an infinite redirection loop
  node2.clusterSetSlotMigrating(slot51,
    JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
  jc.set("51", "foo");
    }

    @Test
    public void testRedisHashtag() {
  assertEquals(JedisClusterCRC16.getSlot("{bar"),
    JedisClusterCRC16.getSlot("foo{{bar}}zap"));
  assertEquals(JedisClusterCRC16.getSlot("{user1000}.following"),
    JedisClusterCRC16.getSlot("{user1000}.followers"));
  assertNotEquals(JedisClusterCRC16.getSlot("foo{}{bar}"),
    JedisClusterCRC16.getSlot("bar"));
  assertEquals(JedisClusterCRC16.getSlot("foo{bar}{zap}"),
    JedisClusterCRC16.getSlot("bar"));
    }

    @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
    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++;
      }
      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"));
    }

    @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");
    }

    @Test
    public void testCloseable() {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1
    .getPort()));

  JedisCluster jc = null;
  try {
      jc = new JedisCluster(jedisClusterNode);
      jc.set("51", "foo");
  } finally {
      if (jc != null) {
    jc.close();
      }
  }

  Iterator<JedisPool> poolIterator = jc.getClusterNodes().values()
    .iterator();
  while (poolIterator.hasNext()) {
      JedisPool pool = poolIterator.next();
      try {
    pool.getResource();
    fail("JedisCluster's internal pools should be already destroyed");
      } catch (JedisConnectionException e) {
    // ok to go...
      }
  }
    }

    @Test
    public void testJedisClusterRunsWithMultithreaded()
      throws InterruptedException, ExecutionException {
  Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
  jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
  final JedisCluster jc = new JedisCluster(jedisClusterNode);
  jc.set("foo", "bar");

  ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 0,
    TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
  List<Future<String>> futures = new ArrayList<Future<String>>();
  for (int i = 0; i < 50; i++) {
      executor.submit(new Callable<String>() {
    @Override
    public String call() throws Exception {
        // FIXME : invalidate slot cache from JedisCluster to test
        // random connection also does work
        return jc.get("foo");
    }
      });
  }

  for (Future<String> future : futures) {
      String value = future.get();
      assertEquals("bar", value);
  }

  jc.close();
    }

    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 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;
    }

}
TOP

Related Classes of redis.clients.jedis.tests.JedisClusterTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.