Ejemplo n.º 1
0
public class ShardedJedisPipelineTest {
  private static HostAndPortUtil.HostAndPort redis1 = HostAndPortUtil.getRedisServers().get(0);
  private static HostAndPortUtil.HostAndPort redis2 = HostAndPortUtil.getRedisServers().get(1);

  private ShardedJedis jedis;

  @Before
  public void setUp() throws Exception {
    Jedis jedis = new Jedis(redis1.host, redis1.port);
    jedis.auth("foobared");
    jedis.flushAll();
    jedis.disconnect();
    jedis = new Jedis(redis2.host, redis2.port);
    jedis.auth("foobared");
    jedis.flushAll();
    jedis.disconnect();

    List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
    JedisShardInfo si1 = new JedisShardInfo(redis1.host, redis1.port);
    si1.setPassword("foobared");
    shards.add(si1);
    JedisShardInfo si2 = new JedisShardInfo(redis2.host, redis2.port);
    si2.setPassword("foobared");
    shards.add(si2);
    this.jedis = new ShardedJedis(shards);
  }

  @Test
  public void pipeline() throws UnsupportedEncodingException {
    ShardedJedisPipeline p = jedis.pipelined();
    p.set("foo", "bar");
    p.get("foo");
    List<Object> results = p.syncAndReturnAll();

    assertEquals(2, results.size());
    assertEquals("OK", results.get(0));
    assertEquals("bar", results.get(1));
  }

  @Test
  public void pipelineResponse() {
    jedis.set("string", "foo");
    jedis.lpush("list", "foo");
    jedis.hset("hash", "foo", "bar");
    jedis.zadd("zset", 1, "foo");
    jedis.sadd("set", "foo");

    ShardedJedisPipeline p = jedis.pipelined();
    Response<String> string = p.get("string");
    Response<String> list = p.lpop("list");
    Response<String> hash = p.hget("hash", "foo");
    Response<Set<String>> zset = p.zrange("zset", 0, -1);
    Response<String> set = p.spop("set");
    Response<Boolean> blist = p.exists("list");
    Response<Double> zincrby = p.zincrby("zset", 1, "foo");
    Response<Long> zcard = p.zcard("zset");
    p.lpush("list", "bar");
    Response<List<String>> lrange = p.lrange("list", 0, -1);
    Response<Map<String, String>> hgetAll = p.hgetAll("hash");
    p.sadd("set", "foo");
    Response<Set<String>> smembers = p.smembers("set");
    Response<Set<Tuple>> zrangeWithScores = p.zrangeWithScores("zset", 0, -1);
    p.sync();

    assertEquals("foo", string.get());
    assertEquals("foo", list.get());
    assertEquals("bar", hash.get());
    assertEquals("foo", zset.get().iterator().next());
    assertEquals("foo", set.get());
    assertFalse(blist.get());
    assertEquals(new Double(2), zincrby.get());
    assertEquals(new Long(1), zcard.get());
    assertEquals(1, lrange.get().size());
    assertNotNull(hgetAll.get().get("foo"));
    assertEquals(1, smembers.get().size());
    assertEquals(1, zrangeWithScores.get().size());
  }

  @Test(expected = JedisDataException.class)
  public void pipelineResponseWithinPipeline() {
    jedis.set("string", "foo");

    ShardedJedisPipeline p = jedis.pipelined();
    Response<String> string = p.get("string");
    string.get();
    p.sync();
  }

  @Test
  public void canRetrieveUnsetKey() {
    ShardedJedisPipeline p = jedis.pipelined();
    Response<String> shouldNotExist = p.get(UUID.randomUUID().toString());
    p.sync();
    assertNull(shouldNotExist.get());
  }
}
Ejemplo n.º 2
0
public class JedisClusterTest extends Assert {
  private static Jedis node1;
  private static Jedis node2;
  private static Jedis node3;
  private static Jedis node4;
  private static Jedis nodeSlave2;
  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);
  private HostAndPort nodeInfoSlave2 = HostAndPortUtil.getClusterServers().get(4);
  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();

    nodeSlave2 = new Jedis(nodeInfoSlave2.getHost(), nodeInfoSlave2.getPort());
    nodeSlave2.connect();
    nodeSlave2.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());

    JedisCluster jc2 = new JedisCluster(new HostAndPort("127.0.0.1", 7379));
    assertEquals(3, jc2.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"));

    JedisCluster jc2 = new JedisCluster(new HostAndPort("127.0.0.1", 7379));
    jc2.set("foo", "bar");
    jc2.set("test", "test");
    assertEquals("bar", node3.get("foo"));
    assertEquals("test", node2.get("test"));
  }

  @Test
  public void testReadonly() throws Exception {
    node1.clusterMeet(localHost, nodeInfoSlave2.getPort());
    JedisClusterTestUtil.waitForClusterReady(node1, node2, node3, nodeSlave2);

    for (String nodeInfo : node2.clusterNodes().split("\n")) {
      if (nodeInfo.contains("myself")) {
        nodeSlave2.clusterReplicate(nodeInfo.split(" ")[0]);
        break;
      }
    }
    try {
      nodeSlave2.get("test");
      fail();
    } catch (JedisMovedDataException e) {
    }
    nodeSlave2.readonly();
    nodeSlave2.get("test");

    nodeSlave2.clusterReset(Reset.SOFT);
    nodeSlave2.flushDB();
  }

  /** 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 = 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() throws IOException {
    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 testJedisClusterTimeout() {
    Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
    jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));

    JedisCluster jc = new JedisCluster(jedisClusterNode, 4000);

    for (JedisPool pool : jc.getClusterNodes().values()) {
      Jedis jedis = pool.getResource();
      assertEquals(jedis.getClient().getConnectionTimeout(), 4000);
      assertEquals(jedis.getClient().getSoTimeout(), 4000);
      jedis.close();
    }
  }

  @Test
  public void testJedisClusterRunsWithMultithreaded()
      throws InterruptedException, ExecutionException, IOException {
    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();
  }

  @Test(timeout = 2000)
  public void testReturnConnectionOnJedisConnectionException() throws InterruptedException {
    Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
    jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(1);
    JedisCluster jc = new JedisCluster(jedisClusterNode, config);

    Jedis j = jc.getClusterNodes().get("127.0.0.1:7380").getResource();
    ClientKillerUtil.tagClient(j, "DEAD");
    ClientKillerUtil.killClient(j, "DEAD");
    j.close();

    jc.get("test");
  }

  @Test(expected = JedisClusterMaxRedirectionsException.class, timeout = 2000)
  public void testReturnConnectionOnRedirection() {
    Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
    jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(1);
    JedisCluster jc = new JedisCluster(jedisClusterNode, 0, 2, config);

    // This will cause an infinite redirection between node 2 and 3
    node3.clusterSetSlotMigrating(15363, JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
    jc.get("e");
  }

  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;
  }
}
Ejemplo n.º 3
0
public class PipeliningTest extends Assert {
  private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);

  private Jedis jedis;

  @Before
  public void setUp() throws Exception {
    jedis = new Jedis(hnp.getHost(), hnp.getPort(), 500);
    jedis.connect();
    jedis.auth("foobared");
    jedis.flushAll();
  }

  @Test
  public void pipeline() throws UnsupportedEncodingException {
    Pipeline p = jedis.pipelined();
    p.set("foo", "bar");
    p.get("foo");
    List<Object> results = p.syncAndReturnAll();

    assertEquals(2, results.size());
    assertEquals("OK", results.get(0));
    assertEquals("bar", results.get(1));
  }

  @Test
  public void pipelineResponse() {
    jedis.set("string", "foo");
    jedis.lpush("list", "foo");
    jedis.hset("hash", "foo", "bar");
    jedis.zadd("zset", 1, "foo");
    jedis.sadd("set", "foo");
    jedis.setrange("setrange", 0, "0123456789");
    byte[] bytesForSetRange = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    jedis.setrange("setrangebytes".getBytes(), 0, bytesForSetRange);

    Pipeline p = jedis.pipelined();
    Response<String> string = p.get("string");
    Response<String> list = p.lpop("list");
    Response<String> hash = p.hget("hash", "foo");
    Response<Set<String>> zset = p.zrange("zset", 0, -1);
    Response<String> set = p.spop("set");
    Response<Boolean> blist = p.exists("list");
    Response<Double> zincrby = p.zincrby("zset", 1, "foo");
    Response<Long> zcard = p.zcard("zset");
    p.lpush("list", "bar");
    Response<List<String>> lrange = p.lrange("list", 0, -1);
    Response<Map<String, String>> hgetAll = p.hgetAll("hash");
    p.sadd("set", "foo");
    Response<Set<String>> smembers = p.smembers("set");
    Response<Set<Tuple>> zrangeWithScores = p.zrangeWithScores("zset", 0, -1);
    Response<String> getrange = p.getrange("setrange", 1, 3);
    Response<byte[]> getrangeBytes = p.getrange("setrangebytes".getBytes(), 6, 8);
    p.sync();

    assertEquals("foo", string.get());
    assertEquals("foo", list.get());
    assertEquals("bar", hash.get());
    assertEquals("foo", zset.get().iterator().next());
    assertEquals("foo", set.get());
    assertEquals(false, blist.get());
    assertEquals(Double.valueOf(2), zincrby.get());
    assertEquals(Long.valueOf(1), zcard.get());
    assertEquals(1, lrange.get().size());
    assertNotNull(hgetAll.get().get("foo"));
    assertEquals(1, smembers.get().size());
    assertEquals(1, zrangeWithScores.get().size());
    assertEquals("123", getrange.get());
    byte[] expectedGetRangeBytes = {6, 7, 8};
    assertArrayEquals(expectedGetRangeBytes, getrangeBytes.get());
  }

  @Test
  public void pipelineResponseWithData() {
    jedis.zadd("zset", 1, "foo");

    Pipeline p = jedis.pipelined();
    Response<Double> score = p.zscore("zset", "foo");
    p.sync();

    assertNotNull(score.get());
  }

  @Test
  public void pipelineBinarySafeHashCommands() {
    jedis.hset("key".getBytes(), "f1".getBytes(), "v111".getBytes());
    jedis.hset("key".getBytes(), "f22".getBytes(), "v2222".getBytes());

    Pipeline p = jedis.pipelined();
    Response<Map<byte[], byte[]>> fmap = p.hgetAll("key".getBytes());
    Response<Set<byte[]>> fkeys = p.hkeys("key".getBytes());
    Response<List<byte[]>> fordered = p.hmget("key".getBytes(), "f22".getBytes(), "f1".getBytes());
    Response<List<byte[]>> fvals = p.hvals("key".getBytes());
    p.sync();

    assertNotNull(fmap.get());
    // we have to do these strange contortions because byte[] is not a very
    // good key
    // for a java Map. It only works with equality (you need the exact key
    // object to retrieve
    // the value) I recommend we switch to using ByteBuffer or something
    // similar:
    // http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java
    Map<byte[], byte[]> map = fmap.get();
    Set<byte[]> mapKeys = map.keySet();
    Iterator<byte[]> iterMap = mapKeys.iterator();
    byte[] firstMapKey = iterMap.next();
    byte[] secondMapKey = iterMap.next();
    assertFalse(iterMap.hasNext());
    verifyHasBothValues(firstMapKey, secondMapKey, "f1".getBytes(), "f22".getBytes());
    byte[] firstMapValue = map.get(firstMapKey);
    byte[] secondMapValue = map.get(secondMapKey);
    verifyHasBothValues(firstMapValue, secondMapValue, "v111".getBytes(), "v2222".getBytes());

    assertNotNull(fkeys.get());
    Iterator<byte[]> iter = fkeys.get().iterator();
    byte[] firstKey = iter.next();
    byte[] secondKey = iter.next();
    assertFalse(iter.hasNext());
    verifyHasBothValues(firstKey, secondKey, "f1".getBytes(), "f22".getBytes());

    assertNotNull(fordered.get());
    assertArrayEquals("v2222".getBytes(), fordered.get().get(0));
    assertArrayEquals("v111".getBytes(), fordered.get().get(1));

    assertNotNull(fvals.get());
    assertEquals(2, fvals.get().size());
    byte[] firstValue = fvals.get().get(0);
    byte[] secondValue = fvals.get().get(1);
    verifyHasBothValues(firstValue, secondValue, "v111".getBytes(), "v2222".getBytes());
  }

  private void verifyHasBothValues(
      byte[] firstKey, byte[] secondKey, byte[] value1, byte[] value2) {
    assertFalse(Arrays.equals(firstKey, secondKey));
    assertTrue(Arrays.equals(firstKey, value1) || Arrays.equals(firstKey, value2));
    assertTrue(Arrays.equals(secondKey, value1) || Arrays.equals(secondKey, value2));
  }

  @Test
  public void pipelineSelect() {
    Pipeline p = jedis.pipelined();
    p.select(1);
    p.sync();
  }

  @Test
  public void pipelineResponseWithoutData() {
    jedis.zadd("zset", 1, "foo");

    Pipeline p = jedis.pipelined();
    Response<Double> score = p.zscore("zset", "bar");
    p.sync();

    assertNull(score.get());
  }

  @Test(expected = JedisDataException.class)
  public void pipelineResponseWithinPipeline() {
    jedis.set("string", "foo");

    Pipeline p = jedis.pipelined();
    Response<String> string = p.get("string");
    string.get();
    p.sync();
  }

  @Test
  public void pipelineWithPubSub() {
    Pipeline pipelined = jedis.pipelined();
    Response<Long> p1 = pipelined.publish("foo", "bar");
    Response<Long> p2 = pipelined.publish("foo".getBytes(), "bar".getBytes());
    pipelined.sync();
    assertEquals(0, p1.get().longValue());
    assertEquals(0, p2.get().longValue());
  }

  @Test
  public void canRetrieveUnsetKey() {
    Pipeline p = jedis.pipelined();
    Response<String> shouldNotExist = p.get(UUID.randomUUID().toString());
    p.sync();
    assertNull(shouldNotExist.get());
  }

  @Test
  public void piplineWithError() {
    Pipeline p = jedis.pipelined();
    p.set("foo", "bar");
    Response<Set<String>> error = p.smembers("foo");
    Response<String> r = p.get("foo");
    p.sync();
    try {
      error.get();
      fail();
    } catch (JedisDataException e) {
      // that is fine we should be here
    }
    assertEquals(r.get(), "bar");
  }

  @Test
  public void multi() {
    Pipeline p = jedis.pipelined();
    p.multi();
    Response<Long> r1 = p.hincrBy("a", "f1", -1);
    Response<Long> r2 = p.hincrBy("a", "f1", -2);
    Response<List<Object>> r3 = p.exec();
    List<Object> result = p.syncAndReturnAll();

    assertEquals(new Long(-1), r1.get());
    assertEquals(new Long(-3), r2.get());

    assertEquals(4, result.size());

    assertEquals("OK", result.get(0));
    assertEquals("QUEUED", result.get(1));
    assertEquals("QUEUED", result.get(2));

    // 4th result is a list with the results from the multi
    @SuppressWarnings("unchecked")
    List<Object> multiResult = (List<Object>) result.get(3);
    assertEquals(new Long(-1), multiResult.get(0));
    assertEquals(new Long(-3), multiResult.get(1));

    assertEquals(new Long(-1), r3.get().get(0));
    assertEquals(new Long(-3), r3.get().get(1));
  }

  @Test
  public void multiWithSync() {
    jedis.set("foo", "314");
    jedis.set("bar", "foo");
    jedis.set("hello", "world");
    Pipeline p = jedis.pipelined();
    Response<String> r1 = p.get("bar");
    p.multi();
    Response<String> r2 = p.get("foo");
    p.exec();
    Response<String> r3 = p.get("hello");
    p.sync();

    // before multi
    assertEquals("foo", r1.get());
    // It should be readable whether exec's response was built or not
    assertEquals("314", r2.get());
    // after multi
    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();
    pipeline.multi();
    pipeline.set("foo", "bar");
    Response<String> discard = pipeline.discard();
    Response<String> get = pipeline.get("foo");
    pipeline.sync();
    discard.get();
    get.get();
  }

  @Test
  public void testEval() {
    String script = "return 'success!'";

    Pipeline p = jedis.pipelined();
    Response<String> result = p.eval(script);
    p.sync();

    assertEquals("success!", result.get());
  }

  @Test
  public void testEvalKeyAndArg() {
    String key = "test";
    String arg = "3";
    String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";

    Pipeline p = jedis.pipelined();
    p.set(key, "0");
    Response<String> result0 = p.eval(script, Arrays.asList(key), Arrays.asList(arg));
    p.incr(key);
    Response<String> result1 = p.eval(script, Arrays.asList(key), Arrays.asList(arg));
    Response<String> result2 = p.get(key);
    p.sync();

    assertNull(result0.get());
    assertNull(result1.get());
    assertEquals("13", result2.get());
  }

  @Test
  public void testEvalsha() {
    String script = "return 'success!'";
    String sha1 = jedis.scriptLoad(script);

    assertTrue(jedis.scriptExists(sha1));

    Pipeline p = jedis.pipelined();
    Response<String> result = p.evalsha(sha1);
    p.sync();

    assertEquals("success!", result.get());
  }

  @Test
  public void testEvalshaKeyAndArg() {
    String key = "test";
    String arg = "3";
    String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";
    String sha1 = jedis.scriptLoad(script);

    assertTrue(jedis.scriptExists(sha1));

    Pipeline p = jedis.pipelined();
    p.set(key, "0");
    Response<String> result0 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg));
    p.incr(key);
    Response<String> result1 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg));
    Response<String> result2 = p.get(key);
    p.sync();

    assertNull(result0.get());
    assertNull(result1.get());
    assertEquals("13", result2.get());
  }
}