Package org.jredis.ri.alphazero

Source Code of org.jredis.ri.alphazero.JRedisFutureProviderTestsBase

/*
*   Copyright 2009 Joubin Houshyar
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*   
*   http://www.apache.org/licenses/LICENSE-2.0
*   
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

package org.jredis.ri.alphazero;

import static org.jredis.ri.alphazero.support.DefaultCodec.toStr;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.jredis.ClientRuntimeException;
import org.jredis.JRedisFuture;
import org.jredis.ObjectInfo;
import org.jredis.Query;
import org.jredis.RedisException;
import org.jredis.RedisType;
import org.jredis.ZSetEntry;
import org.jredis.protocol.Command;
import org.jredis.protocol.ResponseStatus;
import org.jredis.ri.JRedisTestSuiteBase;
import org.jredis.ri.alphazero.support.Convert;
import org.jredis.ri.alphazero.support.DefaultCodec;
import org.jredis.ri.alphazero.support.Log;
import org.testng.annotations.Test;

/**
* [TODO: cleanup the unit test comments]
*
* Provides the comprehensive set of tests of all {@link JRedisFuture} methods.
*
* @author  Joubin Houshyar (alphazero@sensesay.net)
* @version alpha.0, Oct 10, 2009
* @since   alpha.0
*
*/

public abstract class JRedisFutureProviderTestsBase extends JRedisTestSuiteBase<JRedisFuture> {

  // ------------------------------------------------------------------------
  // Properties
  // ------------------------------------------------------------------------

  /** JRedis Command being tested -- for log info */
  private String cmd;
 
  // ------------------------------------------------------------------------
  // The Tests
  // ======================================================= JRedisFuture ===
  /*
   * We define and run provider agnostic tests here.  This means we run a set
   * of JRedisFuture interface method tests that every connected JRedisFuture
   * implementation should be able to support.
   *
   * The following commands are omitted:
   * 1 - QUIT: since we may be testing a multi-connection provier
   * 2 - SHUTDOWN: for the same reason as QUIT
   * 3 - MOVE and SELECT
   */
  // ------------------------------------------------------------------------


//  @Test
//  public void testTemplate() throws InterruptedException {
//    cmd = Command.PING.code + " | " + Command.SETNX.code + " byte[] | " + Command.GET;
//    Log.log("TEST: %s command", cmd);
//   
//    try {
//      provider.flushdb();
//      try {
//      }
//      catch(ExecutionException e){
//        Throwable cause = e.getCause();
//        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
//      }
//    }
//    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e);  }
//  }

  @Test
  public void testSrandmember () throws InterruptedException {
    cmd = Command.SRANDMEMBER.code + " String | " + Command.SMEMBERS;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
     
      List<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        saddResponses.add (provider.sadd(setkey, stringList.get(i)));
     
      Future<List<byte[]>>  smembersResponse = provider.smembers(setkey);
      Future<byte[]>        srandmemberResponse = provider.srandmember(setkey);
     
      try {
       
        for(Future<Boolean> resp : saddResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random element should have been true");
       
        List<String>  members = toStr(smembersResponse.get());
        assertEquals(members.size(), SMALL_CNT, "set members count should be SMALL_CNT");
       
        String randmember = toStr(srandmemberResponse.get());
       
        boolean found = false;
        for(String m : members) {
          if(m.equals(randmember)) {
            found = true;
            break;
          }
        }
        assertTrue(found, "random member should have been part of the members list");

        // edge cases
       
        // empty set
        String emptyset = "empty-set";
        provider.sadd(emptyset, "delete-me");
        provider.srem(emptyset, "delete-me");
        assertEquals(provider.smembers(emptyset).get(), Collections.EMPTY_LIST, "smembers should return an empty list");
        assertEquals(provider.srandmember(emptyset).get(), null, "random member of empty set should be null");
       
        // non existent key
        String nonsuch = "no-such-key";
        assertEquals(provider.smembers(nonsuch).get(), Collections.EMPTY_LIST, "members of non existent key set should be empty");
        assertEquals (provider.srandmember(nonsuch).get(), null, "random member of non existent key set should be null");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }


  @Test
  public void testSmoveStringByteArray() throws InterruptedException{
    cmd = Command.SMOVE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    provider.flushdb();
   
    String srckey = keys.get(0);
    String destkey = keys.get(1);
   
    List<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<MEDIUM_CNT; i++)
      saddResponses.add (provider.sadd(srckey, dataList.get(i)));
   
    List<Future<Boolean>> smoveResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<MEDIUM_CNT; i++)
      smoveResponses.add (provider.smove(srckey, destkey, dataList.get(i)));
   
    try {
      try {
        for(Future<Boolean> resp : saddResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random element should have been true");
       
        for(Future<Boolean> resp : smoveResponses)
          assertTrue (resp.get().booleanValue(), "smove of element should have been true");
       
        for(int i=0;i<MEDIUM_CNT; i++){
          assertTrue  (provider.sismember(destkey, dataList.get(i)).get(), "@ [" + i +"] should be a member of the dest after move");
          assertFalse (provider.sismember(srckey, dataList.get(i)).get(), "@ [" + i +"] should NOT be a member of the src after move");
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testScard() throws InterruptedException {
    cmd = Command.SCARD.code + " Java Object";
    Log.log("TEST: %s command", cmd);

    provider.flushdb();
   
    String setkey = keys.get(0);
 
    List<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<MEDIUM_CNT; i++)
      saddResponses.add (provider.sadd(setkey, objectList.get(i)));
   
    Future<Long> scardResp = provider.scard(setkey);
   
    try {
      provider.flushdb();
      try {
        for(Future<Boolean> resp : saddResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random object should have been true");
       
        assertEquals (scardResp.get().longValue(), MEDIUM_CNT, "scard value should have been MEDIUM_CNT");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testZcard() throws InterruptedException {
    cmd = Command.ZCARD.code + " Java Object";
    Log.log("TEST: %s command", cmd);

    provider.flushdb();
   
    String setkey = keys.get(0);
 
    List<Future<Boolean>> zaddResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<MEDIUM_CNT; i++)
      zaddResponses.add (provider.zadd(setkey, i, objectList.get(i)));
   
    Future<Long> zcardResp = provider.zcard(setkey);
   
    try {
      provider.flushdb();
      try {
        for(Future<Boolean> resp : zaddResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random object should have been true");
       
        assertEquals (zcardResp.get().longValue(), MEDIUM_CNT, "zcard value should have been MEDIUM_CNT");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testSismemberStringByteArray() throws InterruptedException {
    cmd = Command.SISMEMBER.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    String setkey = keys.get(0);
   
    provider.flushdb();
   
    List<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<SMALL_CNT; i++)
      saddResponses.add (provider.sadd(setkey, dataList.get(i)));
   
    List<Future<Boolean>> sismemberResponses = new ArrayList<Future<Boolean>>();
    for(int i=0;i<SMALL_CNT; i++)
      saddResponses.add (provider.sismember(setkey, dataList.get(i)));
   
   
    try {
      try {
        for(Future<Boolean> resp : saddResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random element should have been true");
       
        for(Future<Boolean> resp : sismemberResponses)
          assertTrue (resp.get().booleanValue(), "set membership test should have been true");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testSmembers() throws InterruptedException{
    cmd = Command.SMEMBERS.code + " byte[] | " + Command.SADD + "| " + Command.SCARD;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
     
      String setkey = keys.get(0);
      List<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        saddResponses.add (provider.sadd(setkey, dataList.get(i)));
     
      Future<Long> scardResp = provider.scard(setkey);
      Future<List<byte[]>> smembersResp = provider.smembers(setkey);     

      String setkey2 = keys.get(2);
      provider.sadd(setkey2, dataList.get(0));
      provider.srem(setkey2, dataList.get(0));
      Future<Long> scardResp2 = provider.scard(setkey2);
      Future<List<byte[]>> smembersResp2 = provider.smembers(setkey2);     
     
     
      try {
        for(Future<Boolean> resp : saddResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random element should have been true");
       
        List<byte[]> members = smembersResp.get();
        assertTrue(members.size() == SMALL_CNT, "smembers should have returned a list of SMALL_CNT size");
        assertTrue(members.size() == scardResp.get().longValue(), "smembers should have returned a list of scard size");
       
        List<byte[]> members2 = smembersResp2.get();
        assertEquals(scardResp2.get().longValue(), 0, "setkey2 should be zero");
        assertEquals(members2, Collections.EMPTY_LIST, "smembers should have returned empty");
//        assertTrue(members2.size() == scardResp2.get().longValue(), "smembers should have returned a list of scard size");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testZremStringByteArray() throws InterruptedException{
    cmd = Command.ZADD.code + " byte[] | " + Command.ZREM.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      List<Future<Boolean>> expectedOKRemResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKRemResponses.add (provider.zrem(setkey, dataList.get(i)));
     

      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        for(Future<Boolean> resp : expectedOKRemResponses)
          assertTrue (resp.get().booleanValue(), "zadd of existing element should have been false");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testZaddStringByteArray() throws InterruptedException{
    cmd = Command.ZADD.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, random.nextDouble(), dataList.get(i)));
     
      List<Future<Boolean>> expectedErrorResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedErrorResponses.add (provider.zadd(setkey, random.nextDouble(), dataList.get(i)));
     

      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        for(Future<Boolean> resp : expectedErrorResponses)
          assertFalse (resp.get().booleanValue(), "zadd of existing element should have been false");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testZscoreAndZincrbyStringByteArray() throws InterruptedException{
    cmd = Command.ZSCORE.code + " byte[] | " + Command.ZINCRBY.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, doubleList.get(i), dataList.get(i)));
     
      List<Future<Double>> scores = new ArrayList<Future<Double>>();
      for(int i=0;i<SMALL_CNT; i++)
        scores.add (provider.zscore(setkey, dataList.get(i)));
     
      double increment = 0.05;
      List<Future<Double>> incrementedScores = new ArrayList<Future<Double>>();
      for(int i=0;i<SMALL_CNT; i++)
        incrementedScores.add (provider.zincrby(setkey, increment, dataList.get(i)));
     
      Future<Double>  noneSuchKeyScore = provider.zscore(setkey, "no such member");
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        int i=0;
        for(Future<Double> score : scores){
          assertEquals (score.get(), doubleList.get(i), "zscore of element should have been " + doubleList.get(i));
          i++;
       
       
        i=0;
        for(Future<Double> score : incrementedScores){
          assertEquals (score.get(), doubleList.get(i) + increment, "zincr of element should be " + doubleList.get(i) + increment);
          i++;
       
       
        assertNull(noneSuchKeyScore.get(), "zscore of none existent member of sorted set should be null");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testZrangebyscoreStringByteArray() throws InterruptedException{
    cmd = Command.ZRANGEBYSCORE.code + " byte[] | " + Command.ZSCORE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<List<byte[]>> frRange = provider.zrangebyscore(setkey, 0, SMALL_CNT);
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        List<byte[]> range = frRange.get();
        assertTrue(range.size() > 0, "should have non empty results for range by score here");
       
        for(int i=0;i<SMALL_CNT-1; i++){
          assertEquals(range.get(i), dataList.get(i), "expected value in the range by score missing");
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testZremrangebyscoreStringByteArray() throws InterruptedException{
    cmd = Command.ZREMRANGEBYSCORE.code + " byte[] | " + Command.ZSCORE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<Long> frRemCnt = provider.zremrangebyscore(setkey, 0, SMALL_CNT);
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        long remCnt = frRemCnt.get().longValue();
        assertTrue(remCnt > 0, "should have non-zero number of rem cnt for zremrangebyscore");
        assertEquals(remCnt, SMALL_CNT+1, "should have specific number of rem cnt for zremrangebyscore");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testZcountStringByteArray() throws InterruptedException{
    cmd = Command.ZCOUNT.code + " byte[] | " + Command.ZADD.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<Long> frCount = provider.zcount(setkey, 0, SMALL_CNT);
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        long remCnt = frCount.get().longValue();
        assertTrue(remCnt > 0, "should have non-zero number of rem cnt for zremrangebyscore");
        assertEquals(remCnt, SMALL_CNT+1, "should have specific number for zcount");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testZremrangebyrankStringByteArray() throws InterruptedException{
    cmd = Command.ZREMRANGEBYRANK.code + " byte[] | " + Command.ZSCORE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<Long> frRemCnt = provider.zremrangebyrank(setkey, 0, SMALL_CNT);
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        long remCnt = frRemCnt.get().longValue();
        assertTrue(remCnt > 0, "should have non-zero number of rem cnt for zremrangebyrank");
        assertEquals(remCnt, SMALL_CNT+1, "should have specific number of rem cnt for zremrangebyrank");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testZrankStringByteArray() throws InterruptedException{
    cmd = Command.ZRANK.code;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
     
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      List<Future<Long>> rankingResps = new ArrayList<Future<Long>>();
      for(int i=0;i<SMALL_CNT; i++)
        rankingResps.add(provider.zrank(setkey, dataList.get(i)));

      Future<Long>  frRankForMissingElement = provider.zrank(setkey, dataList.get(SMALL_CNT+1));
      Future<Long>  frRankForNoSuchSet = provider.zrank("no-such-set", dataList.get(0));
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        int i=0;
        for(Future<Long> resp : rankingResps)
          assertEquals (resp.get().longValue(), i++, "zrank of element");
       
        assertEquals (frRankForMissingElement.get().longValue(), -1, "zrank against non-existent member should be -1");
        assertEquals (frRankForNoSuchSet.get().longValue(), -1, "zrank against non-existent key should be -1");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
 
  @Test
  public void testZrevrankStringByteArray() throws InterruptedException{
    cmd = Command.ZREVRANK.code;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
     
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<=SMALL_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      List<Future<Long>> rankingResps = new ArrayList<Future<Long>>();
      for(int i=0;i<=SMALL_CNT; i++)
        rankingResps.add(provider.zrevrank(setkey, dataList.get(i)));

      Future<Long>  frRankForMissingElement = provider.zrevrank(setkey, dataList.get(SMALL_CNT+1));
      Future<Long>  frRankForNoSuchSet = provider.zrevrank("no-such-set", dataList.get(0));
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        int i=0;
        for(Future<Long> resp : rankingResps)
          assertEquals (resp.get().longValue(), SMALL_CNT - i++, "zrevrank of element");
       
        assertEquals (frRankForMissingElement.get().longValue(), -1, "zrevrank against non-existent member should be -1");
        assertEquals (frRankForNoSuchSet.get().longValue(), -1, "zrevrank against non-existent key should be -1");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testZrangeWithscoresStringByteArray() throws InterruptedException{
    cmd = Command.ZRANGE$OPTS.code + " byte[] | " + Command.ZSCORE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<List<byte[]>> frZValues = provider.zrange(setkey, 0, SMALL_CNT);
      Future<List<ZSetEntry>> frSubset = provider.zrangeSubset(setkey, 0, SMALL_CNT);
     
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        List<byte[]> zvalues = frZValues.get();
        List<ZSetEntry> zsubset = frSubset.get();
        for(int i=0;i<SMALL_CNT; i++){
          assertEquals(zsubset.get(i).getValue(), dataList.get(i), "value of element from zrange_withscore");
          assertEquals(zsubset.get(i).getValue(), zvalues.get(i), "value of element from zrange_withscore compared with zscore with same range query");
          assertEquals (zsubset.get(i).getScore(), (double)i, "score of element from zrange_withscore");
          assertTrue(zsubset.get(i).getScore() <= zsubset.get(i+1).getScore(), "range member score should be smaller or equal to previous range member.  idx: " + i);
          if(i>0) assertTrue(zsubset.get(i).getScore() >= zsubset.get(i-1).getScore(), "range member score should be bigger or equal to previous range member.  idx: " + i);
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testZrevrangeWithscoresStringByteArray() throws InterruptedException{
    cmd = Command.ZREVRANGE$OPTS.code + " byte[] | " + Command.ZSCORE.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<MEDIUM_CNT; i++)
        expectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));
     
      Future<List<byte[]>> frZValues = provider.zrevrange(setkey, 0, SMALL_CNT);
      Future<List<ZSetEntry>> frSubset = provider.zrevrangeSubset(setkey, 0, SMALL_CNT);
     
      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "zadd of random element should have been true");
       
        List<byte[]> zvalues = frZValues.get();
        List<ZSetEntry> zsubset = frSubset.get();
        for(int i=0;i<SMALL_CNT; i++){
          assertEquals(zsubset.get(i).getValue(), dataList.get(MEDIUM_CNT-i-1), "value of element from zrange_withscore");
          assertEquals(zsubset.get(i).getValue(), zvalues.get(i), "value of element from zrange_withscore compared with zscore with same range query");
          assertEquals (zsubset.get(i).getScore(), (double)MEDIUM_CNT-i-1, "score of element from zrange_withscore");
          assertTrue(zsubset.get(i).getScore() >= zsubset.get(i+1).getScore(), "range member score should be smaller or equal to previous range member.  idx: " + i);
          if(i>0) assertTrue(zsubset.get(i).getScore() <= zsubset.get(i-1).getScore(), "range member score should be bigger or equal to previous range member.  idx: " + i);
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testSaddStringByteArray() throws InterruptedException{
    cmd = Command.SADD.code + " byte[]";
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
      String setkey = keys.get(0);
      List<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedOKResponses.add (provider.sadd(setkey, dataList.get(i)));
     
      List<Future<Boolean>> expectedErrorResponses = new ArrayList<Future<Boolean>>();
      for(int i=0;i<SMALL_CNT; i++)
        expectedErrorResponses.add (provider.sadd(setkey, dataList.get(i)));
     

      try {
        for(Future<Boolean> resp : expectedOKResponses)
          assertTrue (resp.get().booleanValue(), "sadd of random element should have been true");
       
        for(Future<Boolean> resp : expectedErrorResponses)
          assertFalse (resp.get().booleanValue(), "sadd of existing element should have been false");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testSort() throws InterruptedException{
    cmd = Command.SORT.code;
    Log.log("TEST: %s command", cmd);

    final String setkey = "set-key";
    final String listkey = "list-key";
    try {
      provider.flushdb();
     
      for(int i=0; i<MEDIUM_CNT; i++){
        provider.sadd(setkey, stringList.get(i));
        provider.lpush(listkey, stringList.get(i));
      }
     
      int cnt1 = MEDIUM_CNT, cnt2 = 9, cnt3 = 1;
      Future<List<byte[]>> sortListResp1 = provider.sort(listkey).ALPHA().LIMIT(0, cnt1).DESC().execAsync();
      Future<List<byte[]>> sortListResp2 = provider.sort(listkey).ALPHA().LIMIT(10, cnt2).DESC().execAsync();
      Future<List<byte[]>> sortListResp3 = provider.sort(listkey).ALPHA().LIMIT(MEDIUM_CNT-1, cnt3).DESC().execAsync();
     
      Future<List<byte[]>> sortSetResp = provider.sort(setkey).ALPHA().LIMIT(0, 555).DESC().execAsync();
     
      try {
        assertEquals(sortListResp1.get().size(), cnt1, "expecting sort results of size MEDIUM_CNT");
        assertEquals(sortListResp2.get().size(), cnt2, "expecting sort results of size 9");
        assertEquals(sortListResp3.get().size(), cnt3, "expecting sort results of size 1");
       
        Log.log("TEST: SORTED LIST ");
        for(String s : toStr(sortListResp1.get()))
          System.out.format("[t.1] %s\n", s);
       
        Log.log("TEST: SORTED LIST ");
        for(String s : toStr(sortListResp2.get()))
          System.out.format("[t.1] %s\n", s);
       
        Log.log("TEST: SORTED LIST ");
        for(String s : toStr(sortListResp3.get()))
          System.out.format("[t.1] %s\n", s);
       
        Log.log("TEST: SORTED SET ");
        for(String s : toStr(sortSetResp.get()))
          System.out.format("%s\n", s);
       
        String destKey = String.format("%s_store", listkey);
        List<byte[]> ssres = provider.sort(listkey).ALPHA().LIMIT(0, MEDIUM_CNT).DESC().STORE(destKey).execAsync().get();
        assertNotNull(ssres, "result of srot with STORE should be non-null");
        assertEquals(ssres.size(), 1, "result of sort with STORE should be a list of single entry (the stored list's size)");
        long sortedListSize = Query.Support.unpackValue(ssres);
        assertEquals(sortedListSize, MEDIUM_CNT);
        RedisType type = provider.type(destKey).get();
        assertEquals(type, RedisType.list, "dest key of SORT .. STORE should be a LIST");
        long sslistSize = provider.llen(destKey).get();
        assertEquals(sslistSize, sortedListSize, "result of SORT ... STORE and LLEN of destkey list should be same");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
   
    // force errors
   
    // count can't be zero
    Runnable invalidLimitSpec = new Runnable() {
      public void run() {
        try { provider.sort(listkey).ALPHA().LIMIT(0, 0).DESC().exec(); }
                catch (Throwable t) { throw new RuntimeException ("", t); }
      }
    };
    assertDidRaiseRuntimeError(invalidLimitSpec, RuntimeException.class);
   
    // LIMIT from must be positive, {0...n}
    Runnable invalidLimitSpec2 = new Runnable() {
      public void run() {
        try { provider.sort(listkey).ALPHA().LIMIT(-1, 1).DESC().exec(); }
                catch (Throwable t) { throw new RuntimeException ("", t); }
      }
    };
    assertDidRaiseRuntimeError(invalidLimitSpec2, RuntimeException.class);
   
  }
 
  @Test
  public void testLsetStringIntByteArray() throws InterruptedException {
    cmd = Command.LSET.code + " byte[] | " + Command.LLEN;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
     
      // prep a MEDIUM list
      String listkey = keys.get(0);
      for(int i=0; i<SMALL_CNT; i++)
        provider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved
      Future<Long> llenResp = provider.llen(listkey);
     
      // now we'll change their values
      for(int i=0; i<SMALL_CNT; i++)
        provider.lset(listkey, i, dataList.get(SMALL_CNT+i));
      Future<List<byte[]>>  lrangeResp1 = provider.lrange(listkey, 0, LARGE_CNT);
     
      // now we'll change their values using the negative index mode
      int lim = SMALL_CNT*-1;
      for(int i=-1; i>lim; i--)
        provider.lset(listkey, i, dataList.get(i*-1));
      Future<List<byte[]>>  lrangeResp2 = provider.lrange(listkey, 0, LARGE_CNT);

      // test edge conditions
      // out of range
      Future<ResponseStatus> expectedErrorResp =  provider.lset(listkey, SMALL_CNT, dataList.get(0));

      try {
        assertTrue (llenResp.get().longValue() == SMALL_CNT, "list length should be SMALL_CNT");
       
        for(int i=0; i<SMALL_CNT; i++)
          assertEquals (dataList.get(SMALL_CNT+i), lrangeResp1.get().get(i), "after LSET the expected and range item differ at idx: " + i);

        for(int i=0; i<SMALL_CNT; i++)
          assertEquals (dataList.get(SMALL_CNT-i), lrangeResp2.get().get(i), "after LSET the expected and range item differ at idx: " + i);
       
        boolean expectedError = false;
        try {
          Log.log("Expecting an out of range ERROR for LSET here..");
                  expectedErrorResp.get(); // wait for response
        }
              catch (ExecutionException e) {
                expectedError = true;
                Throwable cause = e.getCause();
                if(cause instanceof RedisException)
                  Log.log("%s (as excepted)", cause);
                else
                  fail("FAULT: the cause of ExecutionException was expected to be a RedisException");
              }
        assertTrue(expectedError, "was expecting a Expecting an out of range ERROR for LSET here");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLremStringByteArrayInt() throws InterruptedException {
    cmd = Command.LREM.code + " byte[] | " + Command.LLEN;
    Log.log("TEST: %s command", cmd);

    try {
      provider.flushdb();
     
      // prep a MEDIUM list
      String listkey = keys.get(0);
      for(int i=0; i<MEDIUM_CNT; i++)
        provider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved
     
      Future<Long> llenResp = provider.llen(listkey);
     
      // everysingle one of these should work and remove exactly 1 item
      Future<Long> lremResp1 = provider.lrem(listkey, dataList.get(0), 0);
      Future<Long> lremResp2 = provider.lrem(listkey, dataList.get(1), -1);
      Future<Long> lremResp3 = provider.lrem(listkey, dataList.get(2), 1);
      Future<Long> lremResp4 = provider.lrem(listkey, dataList.get(3), 2);
      Future<Long> lremResp5 = provider.lrem(listkey, dataList.get(4), -2);
     
      // everysingle one of these should work and remove NOTHING
      Future<Long> lremResp6 = provider.lrem(listkey, dataList.get(0), 0);
      Future<Long> lremResp7 = provider.lrem(listkey, dataList.get(1), -1);
      Future<Long> lremResp8 = provider.lrem(listkey, dataList.get(2), 1);
      Future<Long> lremResp9 = provider.lrem(listkey, dataList.get(3), 2);
      Future<Long> lremResp10 = provider.lrem(listkey, dataList.get(4), -2);
     
      try {
        long listcnt = llenResp.get();
        assertTrue (listcnt == MEDIUM_CNT, "list length should be MEDIUM_CNT");
       
        assertEquals(1, lremResp1.get().longValue());
        assertEquals(1, lremResp2.get().longValue());
        assertEquals(1, lremResp3.get().longValue());
        assertEquals(1, lremResp4.get().longValue());
        assertEquals(1, lremResp5.get().longValue());
        assertEquals(0, lremResp6.get().longValue());
        assertEquals(0, lremResp7.get().longValue());
        assertEquals(0, lremResp8.get().longValue());
        assertEquals(0, lremResp9.get().longValue());
        assertEquals(0, lremResp10.get().longValue());
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLrange() throws InterruptedException {
    cmd = Command.LRANGE.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
     
      // prep a MEDIUM list
      String listkey = keys.get(0);
      for(int i=0; i<MEDIUM_CNT; i++)
        provider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved
     
      Future<Long> llenResp = provider.llen(listkey);
      Future<List<byte[]>>  lrangeResp = provider.lrange(listkey, 0, MEDIUM_CNT-1);

      try {
//        provider.ping().get();
        // sanity check
        long listcnt = llenResp.get();
        assertTrue (listcnt == MEDIUM_CNT, "list length should be MEDIUM_CNT");
       
        List<byte[]> items = lrangeResp.get();
        assertEquals (items.size(), MEDIUM_CNT, "list range 0->MEDIUM_CNT length should be MEDIUM_CNT");
        for(int i=0; i<MEDIUM_CNT; i++)
          assertEquals(items.get(i), dataList.get(i),
              "nth items of range 0->CNT should be the same as nth dataitem, where n is " + i);
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testSubstr() throws InterruptedException {
    cmd = Command.SUBSTR.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
     
      String key = keys.get(0);
      byte[] value = dataList.get(0);
      provider.set(key, value);
     
      List<Future<byte[]>> frBytesRespList = new ArrayList<Future<byte[]>>();
      for(int i=0; i<value.length; i++){
        frBytesRespList.add(provider.substr(key, i, i));
      }
     
      Future<byte[]> frFullValue1 = provider.substr(key, 0, -1);
      Future<byte[]> frFullValue2 = provider.substr(key, 0, value.length);
      Future<byte[]> frExpectedNull = provider.substr(key, -1, 0);

      try {
        assertEquals(frFullValue1.get(), value, "full range substr should be equal to value");
        assertEquals(frFullValue2.get(), value, "full range substr should be equal to value");
        assertEquals(frExpectedNull.get(), new byte[0], "substr with -1 from idx should be zero-length array");
        for(int i=0; i<value.length; i++){
          assertTrue(frBytesRespList.get(i).get().length == 1, "checking size: using substr to iterate over value bytes @ idx " + i);
          assertEquals(frBytesRespList.get(i).get()[0], value[i], "checking value: using substr to iterate over value bytes @ idx " + i);
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testRpop() throws InterruptedException {
    cmd = Command.RPOP.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      // prep a small list
      String listkey = keys.get(0);
      for(int i=0; i<SMALL_CNT; i++)
        provider.lpush(listkey, dataList.get(i));
     
      Future<Long> llenResp = provider.llen(listkey);
     
      List<Future<byte[]>>  rpops = new ArrayList<Future<byte[]>>();
      for(int i=0; i<SMALL_CNT; i++)
        rpops.add(provider.rpop(listkey));
     
      try {
        long listcnt = llenResp.get();
        // sanity check
        assertTrue (listcnt == SMALL_CNT, "list length should be SMALL_CNT");
       
        for(int i=0; i<SMALL_CNT; i++)
          assertEquals(rpops.get(i).get(), dataList.get(i),
              "nth popped tail should be the same as nth dataitem, where n is " + i);
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLpop() throws InterruptedException {
    cmd = Command.LPOP.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      // prep a small list
      String listkey = keys.get(0);
      for(int i=0; i<SMALL_CNT; i++)
        provider.rpush(listkey, dataList.get(i));
     
      Future<Long> llenResp = provider.llen(listkey);
      List<Future<byte[]>>  lpops = new ArrayList<Future<byte[]>>();
      for(int i=0; i<SMALL_CNT; i++)
        lpops.add(provider.lpop(listkey));
     
      try {
        long listcnt = llenResp.get();
        // sanity check
        assertTrue (listcnt == SMALL_CNT, "list length should be SMALL_CNT");
       
        for(int i=0; i<SMALL_CNT; i++)
          assertEquals(lpops.get(i).get(), dataList.get(i),
              "nth popped head should be the same as nth dataitem, where n is " + i);
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLindex() throws InterruptedException {
    cmd = Command.LINDEX.code;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      // prep a small list
      String listkey = keys.get(0);
      for(int i=0; i<SMALL_CNT; i++)
        provider.rpush(listkey, dataList.get(i));
     
      try {
        for(int i=0; i<SMALL_CNT; i++)
          assertEquals (provider.lindex(listkey, i).get(), dataList.get(i), "list items should match ref data");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLtrim() throws InterruptedException {
    cmd = Command.LTRIM.code + " | " + Command.LLEN.code + " | " + Command.LRANGE.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      // prep a small list
      String listkey = keys.get(0);
      for(int i=0; i<SMALL_CNT; i++)
        provider.rpush(listkey, dataList.get(i));
     
      Future<Long> llenResp = provider.llen(listkey);
      try {
        long listcnt = llenResp.get();
        // sanity check
        assertTrue (listcnt == SMALL_CNT, "list length should be SMALL_CNT");
       
        provider.ltrim(listkey, 0,listcnt-1)// trim nothing
        assertTrue (provider.llen(listkey).get() == listcnt, "trim from end to end - no delta expected");
       
        provider.ltrim(listkey, 1, listcnt-1);   // remove the head
        assertTrue (provider.llen(listkey).get() == listcnt-1, "trim head - len should be --1 expected");
       
        listcnt = provider.llen(listkey).get();
        assertEquals(listcnt, SMALL_CNT - 1, "list length should be SMALL_CNT - 1");
        for(int i=0; i<SMALL_CNT-1; i++)
          assertEquals(provider.lindex(listkey, i).get(), dataList.get(i+1), "list items should match ref data shifted by 1 after removing head");
       
        provider.ltrim(listkey, -2, -1);
        assertTrue (provider.llen(listkey).get() == 2, "list length should be 2");
       
        provider.ltrim(listkey, 0, 0);
        assertTrue (provider.llen(listkey).get() == 1, "list length should be 1");

        byte[] lastItem = provider.lpop(listkey).get();
        assertNotNull(lastItem, "last item should not have been null");
        assertTrue (provider.llen(listkey).get() == 0, "expecting empty list after trims and pop");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testLpushStringByteArray() throws InterruptedException {
    cmd = Command.LPUSH.code + " byte[] | " + Command.LLEN + " | " + Command.LRANGE;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      boolean expected = false;
      try {
        byte[] nil = null;
        provider.lpush("foo", nil);
      }
      catch(IllegalArgumentException e) { expected = true; }
      assertTrue(expected, "expecting exception for null value to RPUSH");
     
      String listkey = this.keys.get(0);
      for(int i=0; i<SMALL_CNT; i++){
        provider.lpush(listkey, dataList.get(i));
      }
      Future<Long> llenResp = provider.llen(listkey);
      Future<List<byte[]>> lrangeResp = provider.lrange(listkey, 0, SMALL_CNT);

      try {
        // use LLEN: size should be small count
        assertTrue(llenResp.get()==SMALL_CNT, "LLEN after LPUSH is wrong");
       
        // use LRANGE 0 cnt: equal size and data should be same in order
        List<byte[]> range = lrangeResp.get();
        assertTrue(range.size()==SMALL_CNT, "range size after LPUSH is wrong");
        for(int i=0; i<SMALL_CNT; i++){
          int r = SMALL_CNT - i - 1;
          assertEquals (dataList.get(i), range.get(r), "range and reference list differ at i: " + i);
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testLpoppushStringByteArray() throws InterruptedException {
    cmd = Command.RPOPLPUSH.code;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      String listkey = this.keys.get(0);
      for(int i=0; i<SMALL_CNT; i++){
        provider.lpush(listkey, dataList.get(i));
      }
     
      Future<Long> llenRespBefore = provider.llen(listkey);
      List<Future<byte[]>> poppushResponses = new ArrayList<Future<byte[]>>();
     
      for(int i=0; i<SMALL_CNT; i++){
        poppushResponses.add(provider.rpoplpush (listkey, listkey));
      }
     
      Future<Long> llenRespAfter = provider.llen(listkey);
      try {
        // use LLEN: size should be small count
        assertTrue(llenRespBefore.get()==SMALL_CNT, "LLEN after LPUSH is wrong");
       
        for(int i=0; i<SMALL_CNT; i++){
          assertEquals (poppushResponses.get(i).get(), dataList.get(i), "RPOPLPUSH result and reference list differ at i: " + i);
        }
       
        // use LLEN: size should be small count
        assertTrue(llenRespAfter.get()==SMALL_CNT, "LLEN after RPOPLPUSH is wrong");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testRpushStringByteArray() throws InterruptedException {
    cmd = Command.RPUSH.code + " byte[] | " + Command.LLEN + " | " + Command.LRANGE;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();

      boolean expected = false;
      try {
        byte[] nil = null;
        provider.rpush("foo", nil);
      }
      catch(IllegalArgumentException e) { expected = true; }
      assertTrue(expected, "expecting exception for null value to RPUSH");
     
      String listkey = this.keys.get(0);
      for(int i=0; i<SMALL_CNT; i++){
        provider.rpush(listkey, dataList.get(i));
      }
     
      Future<Long> llenResp = provider.llen(listkey);
      Future<List<byte[]>> lrangeResp = provider.lrange(listkey, 0, SMALL_CNT);
     
      try {
        // use LLEN: size should be small count
        assertTrue(llenResp.get()==SMALL_CNT, "LLEN after RPUSH is wrong");
       
        // use LRANGE 0 cnt: equal size and data should be same in order
        List<byte[]> range = lrangeResp.get();
        assertTrue(range.size()==SMALL_CNT, "range size after RPUSH is wrong");
        for(int i=0; i<SMALL_CNT; i++){
          assertEquals (dataList.get(i), range.get(i), "range and reference list differ at i: " + i);
        }
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  @Test
  public void testMget() throws InterruptedException {
    cmd = Command.MGET.code ;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      for(int i=0; i<SMALL_CNT; i++){
        provider.set (keys.get(i), dataList.get(i));
      }
      Future<List<byte[]>> mgetResp1 = provider.mget(keys.get(0));
      Future<List<byte[]>> mgetResp2 = provider.mget(keys.get(0), keys.get(1));
      Future<List<byte[]>> mgetResp3 = provider.mget(keys.get(0), keys.get(1), keys.get(2));
      Future<List<byte[]>> mgetResp4 = provider.mget("foo", "bar", "paz");
     
      try {
        List<byte[]>  values = null;
       
        values = mgetResp1.get();
        assertEquals(values.size(), 1, "one value expected");
        for(int i=0; i<1; i++)
          assertEquals(values.get(i), dataList.get(i));
       
        values = mgetResp2.get();
        assertEquals(values.size(), 2, "2 values expected");
        for(int i=0; i<2; i++)
          assertEquals(values.get(i), dataList.get(i));
       
        values = mgetResp3.get();
        assertEquals(values.size(), 3, "3 values expected");
        for(int i=0; i<3; i++)
          assertEquals(values.get(i), dataList.get(i));
       
        values = mgetResp4.get();
        assertEquals(values.size(), 3, "3 values expected");
        for(int i=0; i<3; i++)
          assertEquals(values.get(i), null, "nonexistent key value in list should be null");
       
        // edge cases
        // all should through exceptions
        boolean didRaiseEx;
        didRaiseEx = false;
        try {
          String[] keys = null;
          provider.mget(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }

        didRaiseEx = false;
        try {
          String[] keys = new String[0];
          provider.mget(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }

        didRaiseEx = false;
        try {
          String[] keys = new String[3];
          keys[0] = stringList.get(0);
          keys[1] = null;
          keys[2] = stringList.get(2);
          provider.mget(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testDel() throws InterruptedException {
    cmd = Command.DEL.code;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
     
      String key = this.keys.get(0);
      provider.set (key, dataList.get(0));
      Future<Boolean> existsResp1 = provider.exists(key);
      Future<Long> delResp = provider.del(key);
      Future<Boolean> existsResp2 = provider.exists(key);

      try {
        assertEquals(delResp.get().longValue(), 1, "one key should been deleted");
        assertTrue (existsResp1.get(), "After set key should exist");
        assertFalse (existsResp2.get(), "After del key should not exist");
       
        // delete many keys
        provider.flushdb();
        for(int i=0; i<SMALL_CNT; i++) provider.set(stringList.get(i), dataList.get(i));

        String[] keysToDel = new String[SMALL_CNT];
        for(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);

        Future<Long> delCnt1 = provider.del(keysToDel);
        for(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)).get(), "key should have been deleted");
        assertEquals(delCnt1.get().longValue(), SMALL_CNT, "SMALL_CNT keys were deleted");
       
        // delete many keys but also spec one non existent keys - delete result should be less than key cnt
        provider.flushdb();
        for(int i=0; i<SMALL_CNT-1; i++) provider.set(stringList.get(i), dataList.get(i));

        keysToDel = new String[SMALL_CNT];
        for(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);

        Future<Long> delCnt2 = provider.del(keysToDel);
        for(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)).get(), "key should have been deleted");
        assertEquals(delCnt2.get().longValue(), SMALL_CNT-1, "SMALL_CNT-1 keys were actually deleted");

        // edge cases
        // all should through exceptions
        boolean didRaiseEx;
        didRaiseEx = false;
        try {
          String[] keys = null;
          provider.del(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }

        didRaiseEx = false;
        try {
          String[] keys = new String[0];
          provider.del(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }

        didRaiseEx = false;
        try {
          String[] keys = new String[3];
          keys[0] = stringList.get(0);
          keys[1] = null;
          keys[2] = stringList.get(2);
          provider.del(keys).get();
        }
        catch (IllegalArgumentException e) {didRaiseEx = true;}
        catch (Throwable whatsthis) { fail ("unexpected exception raised", whatsthis);}
        if(!didRaiseEx){ fail ("Expected exception not raised."); }

      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testIncrAndDecr() throws InterruptedException {
    cmd = Command.INCR.code + " | " + Command.DECR.code;
    Log.log("TEST: %s command", cmd);
    try {
      String cntr_key = keys.get(0);

      provider.flushdb();

      Future<Long> incrResp = null;
      for(int i = 0; i<MEDIUM_CNT; i++){
        incrResp = provider.incr(cntr_key);
      }
      Future<Long> decrResp = null;
      for(int i = 0; i<MEDIUM_CNT; i++){
        decrResp = provider.decr(cntr_key);
      }
     
      try {
        assertEquals(incrResp.get().longValue(), MEDIUM_CNT, "INCR should have counted counter to MEDIUM_CNT");
        assertEquals(decrResp.get().longValue(), 0, "DECR should have counted counter to zero");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testIncrbyAndDecrby() throws InterruptedException {
    cmd = Command.INCRBY.code + " |" + Command.DECRBY.code;
    Log.log("TEST: %s command", cmd);
    try {
      String cntr_key = keys.get(0);

      provider.flushdb();

      Future<Long> incrbyResp = null;
      for(int i = 0; i<MEDIUM_CNT; i++){
        incrbyResp = provider.incrby(cntr_key, 10);
      }
      Future<Long> decrbyResp = null;
      for(int i = 0; i<MEDIUM_CNT; i++){
        decrbyResp = provider.decrby(cntr_key, 10);
      }
     
      try {
        assertEquals(incrbyResp.get().longValue(), MEDIUM_CNT*10, "INCRBY should have counted counter to MEDIUM_CNT*10");
        assertEquals(decrbyResp.get().longValue(), 0, "DECRBY should have counted counter to zero");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testGetSetStringByteArray() throws InterruptedException {
    cmd = Command.SET.code + " | " + Command.GETSET.code + " byte[] ";
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      provider.set(keys.get(0), dataList.get(0));
      Future<byte[]> getResp = provider.get(keys.get(0));
      Future<byte[]> getsetResp1 = provider.getset(keys.get(0), dataList.get(1));
      Future<byte[]> getsetResp2 = provider.getset(keys.get(1), dataList.get(2));
     
      try {
        assertEquals(getResp.get(), dataList.get(0), "get results doesn't match the expected data");
        assertEquals(getsetResp1.get(), dataList.get(0), "getset results doesn't match the expected data");
        assertEquals(getsetResp2.get(), null, "getset result for new key should have been null");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  @Test
  public void testHsetHget() throws InterruptedException {
    cmd = Command.HSET.code + " | " + Command.HGET + " | " + Command.HEXISTS;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));
      Future<Boolean> hexistsResp1 = provider.hexists(keys.get(0), keys.get(1));
      Future<Boolean> hexistsResp2 = provider.hexists(keys.get(0), keys.get(2));
      Future<Boolean> hsetResp1_1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));
      Future<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));
      Future<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);
      objectList.get(0).setName("Hash Stash");
      Future<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));
     
      Future<byte[]> hgetResp1 = provider.hget(keys.get(0), keys.get(1));
      Future<byte[]> hgetResp2 = provider.hget(keys.get(0), keys.get(2));
      Future<byte[]> hgetResp3 = provider.hget(keys.get(0), keys.get(3));
      Future<byte[]> hgetResp4 = provider.hget(keys.get(0), keys.get(4));
     
      Future<Long> hlenResp1 = provider.hlen(keys.get(0));

      Future<Boolean> hdelResp1 = provider.hdel(keys.get(0), keys.get(1));
      Future<Boolean> hdelResp2 = provider.hdel(keys.get(0), keys.get(1));
     
      Future<Long> hlenResp2 = provider.hlen(keys.get(0));
      Future<Long> hlenResp3 = provider.hlen("some-random-key");
     
     
      try {
        assertTrue (hsetResp1.get(), "hset using byte[] value");
        assertTrue (hexistsResp1.get(), "hexists of field should be true");
        assertTrue (!hexistsResp2.get(), "hexists of non existent field should be false");
        assertTrue (!hsetResp1_1.get(), "second hset using byte[] value should return false");
        assertTrue (hsetResp2.get(), "hset using String value");
        assertTrue (hsetResp3.get(), "hset using Number value");
        assertTrue (hsetResp4.get(), "hset using Object value");
       
        assertEquals (hgetResp1.get(), dataList.get(0), "hget of field with byte[] value");
        assertEquals (DefaultCodec.toStr(hgetResp2.get()), stringList.get(0), "hget of field with String value");
        assertEquals (DefaultCodec.toLong(hgetResp3.get()).longValue(), 222, "hget of field with Number value");
        TestBean objval = DefaultCodec.decode(hgetResp4.get());
        assertEquals (objval.getName(), objectList.get(0).getName(), "hget of field with Object value");
       
        assertTrue (hdelResp1.get(), "hdel of field should be true");
        assertTrue (!hdelResp2.get(), "hdel of non-existent field should be false");
       
        assertEquals (hlenResp1.get().longValue(), 4, "hlen of hash should be 4");
        assertEquals (hlenResp2.get().longValue(), 3, "hlen of hash should be 3");
        assertEquals (hlenResp3.get().longValue(), 0, "hlen of non-existant hash should be 0");

      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }


  @Test
  public void testHIncrBy() throws InterruptedException {
    cmd = Command.HSET.code + " | " + Command.HGET + " | " + Command.HINCRBY;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), 41);
      Future<Long> hincrBy1 = provider.hincrby(keys.get(0), keys.get(1), 1);
      Future<byte[]> hget = provider.hget(keys.get(0), keys.get(1));
           
      Future<Long> hincrBy2 = provider.hincrby(keys.get(0), keys.get(2), 4);
     
      try {
        assertTrue (hsetResp1.get(), "hset using byte[] value");
        assertEquals (hincrBy1.get(), (Long)42l, "hexists of field should be true");
        assertEquals(hget.get(), Convert.toBytes(42l));
        assertEquals(hincrBy2.get(), (Long)4l);

      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testHkeys() throws InterruptedException {
    cmd = Command.HSET.code + " | " + Command.HKEYS;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));
      Future<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));
      Future<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);
      objectList.get(0).setName("Hash Stash");
      Future<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));
     
      // get keys
      Future<List<byte[]>> hkeysResp1 = provider.hkeys(keys.get(0));
      // alright - empty the hash
      for(int i=1; i<5; i++)
              try {
                  assertTrue(provider.hdel(keys.get(0), keys.get(i).getBytes()).get());
                }
                catch (ExecutionException e) {
            Throwable cause = e.getCause();
            fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
                }
      // get keys again
      Future<List<byte[]>> hkeysResp2 = provider.hkeys(keys.get(0));
      // nil case
      Future<List<byte[]>> hkeysResp3 = provider.hkeys("no-such-hash");
     
     
      try {
        assertTrue (hsetResp1.get(), "hset using byte[] value");
        assertTrue (hsetResp2.get(), "hset using String value");
        assertTrue (hsetResp3.get(), "hset using Number value");
        assertTrue (hsetResp4.get(), "hset using Object value");
       
        List<byte[]> hkeys = hkeysResp1.get();
        assertEquals (hkeys.size(), 4, "keys list size should be 4");
        assertEquals(hkeysResp2.get(), Collections.EMPTY_LIST, "result should be empty");
        assertEquals(hkeysResp3.get(), Collections.EMPTY_LIST, "list of keys of non-existent hash should be empty");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  @Test
  public void testSetBitGetBit() throws InterruptedException {
    cmd = Command.SETBIT.code + " | " + Command.GETBIT;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> setbit1 = provider.setbit(keys.get(0), 1, true);
      Future<Boolean> setbit32 = provider.setbit(keys.get(0), 32, true);

      Future<Boolean> getbit1 = provider.getbit(keys.get(0), 1);
      Future<Boolean> getbit2 = provider.getbit(keys.get(0), 2);
      Future<Boolean> getbit32 = provider.getbit(keys.get(0), 32);
     
      try {
        assertFalse (setbit1.get(), "original bit at 1");
        assertFalse (setbit32.get(), "original bit at 32");
        assertTrue (getbit1.get(), "getbit at 1");
        assertFalse (getbit2.get(), "getbit at 2");
        assertTrue (getbit32.get(), "getbit at 32");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }


  @Test
  public void testHvals() throws InterruptedException {
    cmd = Command.HSET.code + " | " + Command.HVALS;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));
      Future<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));
      Future<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);
      objectList.get(0).setName("Hash Stash");
      Future<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));
     
      // get values
      Future<List<byte[]>> hvalsResp1 = provider.hvals(keys.get(0));
      // alright - empty the hash
      for(int i=1; i<5; i++)
              try {
                  assertTrue(provider.hdel(keys.get(0), keys.get(i)).get());
                }
                catch (ExecutionException e) {
            Throwable cause = e.getCause();
            fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
                }
      // get values again
          // get values
      Future<List<byte[]>> hvalsResp2 = provider.hvals(keys.get(0));
      // nil case
      Future<List<byte[]>> hvalsResp3 = provider.hvals("no-such-hash");
     
     
      try {
        assertTrue (hsetResp1.get(), "hset using byte[] value");
        assertTrue (hsetResp2.get(), "hset using String value");
        assertTrue (hsetResp3.get(), "hset using Number value");
        assertTrue (hsetResp4.get(), "hset using Object value");
       
        List<byte[]> hvals = hvalsResp1.get();
        assertEquals(hvals.size(), 4, "values list size should be 4");
        assertEquals(hvalsResp2.get(), Collections.EMPTY_LIST, "values list size should be empty");
        assertEquals(hvalsResp3.get(), Collections.EMPTY_LIST, "list of values of non-existent hash should be empty");

      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }


  @Test
  public void testHgetall() throws InterruptedException {
    cmd = Command.HSET.code + " | " + Command.HGETALL;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));
      Future<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));
      Future<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);
      objectList.get(0).setName("Hash Stash");
      Future<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));
     
      // get keys
      Future<List<byte[]>> frHkeys = provider.hkeys(keys.get(0));
     
      // get all
      Future<Map<byte[], byte[]>> frHmap1 = provider.hgetall(keys.get(0));
     
      // delete all keys
      for(int i =1; i<5; i++) {
              try {
                  provider.hdel(keys.get(0), keys.get(i)).get();
                }
                catch (ExecutionException e) {
            Throwable cause = e.getCause();
            fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
                }
      }
      // get all again
      Future<Map<byte[], byte[]>> frHmap2 = provider.hgetall(keys.get(0));
         
      // get all for non-existent hash
      Future<Map<byte[], byte[]>> frHmap3 = provider.hgetall("no-such-hash");
             
      try {
        assertTrue (hsetResp1.get(), "hset using byte[] value");
        assertTrue (hsetResp2.get(), "hset using String value");
        assertTrue (hsetResp3.get(), "hset using Number value");
        assertTrue (hsetResp4.get(), "hset using Object value");
       
        assertEquals( frHmap1.get().size(), 4, "hash map length");
        assertEquals( frHkeys.get().size(), 4, "keys list length");

        Map<String, byte[]> hmap = DefaultCodec.toDataDictionary(frHmap1.get());
        assertEquals(hmap.get(keys.get(1)), dataList.get(0), "byte[] value mapping should correspond to prior HSET");
        assertEquals(DefaultCodec.toStr(hmap.get(keys.get(2))), stringList.get(0), "String value mapping should correspond to prior HSET");
        assertEquals(DefaultCodec.toLong(hmap.get(keys.get(3))).longValue(), 222, "Number value mapping should correspond to prior HSET");
        assertEquals(DefaultCodec.decode(hmap.get(keys.get(4))), objectList.get(0), "Object value mapping should correspond to prior HSET");
       
        Map<String, byte[]> hmap2 = DefaultCodec.toDataDictionary(frHmap2.get());
        assertEquals(hmap2, Collections.EMPTY_MAP, "result should be empty");
       
        Map<String, byte[]> hmap3 = DefaultCodec.toDataDictionary(frHmap3.get());
        assertEquals(hmap3, Collections.EMPTY_MAP, "hgetall for non existent hash should be empty");
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

 
  /**
   * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, byte[])}.
   * @throws InterruptedException
   */
  @Test
  public void testSetStringByteArray() throws InterruptedException {
    cmd = Command.SET.code + " | " + Command.SETNX.code + " byte[] | " + Command.GET;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      provider.set(keys.get(keys.size()-1), emptyBytes);
      Future<byte[]> getResp = provider.get(keys.get(keys.size()-1));
      Future<Boolean> setnxResp1 = provider.setnx(keys.get(1), dataList.get(1));
      Future<Boolean> setnxResp2 = provider.setnx(keys.get(1), dataList.get(2));
     
      try {
        assertEquals(getResp.get(), emptyBytes, "set and get results for empty byte[]");
        assertTrue(setnxResp1.get());
        assertFalse(setnxResp2.get());
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
 
  /**
   * Test method for {@link JRedisFuture#append(String, String)}
   * @throws InterruptedException
   */
  @Test
  public void testAppendStringString() throws InterruptedException {
    cmd = Command.APPEND.code + " | " + Command.GET.code + " String";
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
     
      // append to a non-existent key
      // as of Redis 1.3.7 it behaves just like set but returns value len instead of status
      String key1 = keys.get(0);
     
      Future<Long> frLen0 = provider.append(key1, emptyString);
      Future<byte[]> frGet0 = provider.get(key1);
     
      Future<Long> frLen1 = provider.append(key1, stringList.get(0));
      Future<byte[]> frGet1 = provider.get(key1);
     
      Future<Long> frLen2 = provider.append(key1, stringList.get(1));
      Future<byte[]> frGet2 = provider.get(key1);
     
      provider.sadd(keys.get(1), stringList.get(0));
      Future<Long>   frExpectedError = provider.append(keys.get(1), stringList.get(0));
     
      try {
        assertEquals(frLen0.get().longValue(), 0, "append of emtpy string to new key should be zero");
        assertEquals(DefaultCodec.toStr(frGet0.get()), emptyString, "get results after append to new key for empty string");
       
        assertEquals(frLen1.get().longValue(), stringList.get(0).length(), "append of emtpy string to new key should be zero");
        assertEquals(DefaultCodec.toStr(frGet1.get()), stringList.get(0), "get results after append to new key for empty string");
       
        assertEquals(frLen2.get().longValue(), stringList.get(0).length() + stringList.get(1).length(), "append of emtpy string to new key should be zero");
        StringBuffer appendedString = new StringBuffer();
        appendedString.append(stringList.get(0));
        appendedString.append(stringList.get(1));
        assertEquals(DefaultCodec.toStr(frGet2.get()), appendedString.toString(), "get results after append to new key for empty string");
       
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }

     
      // check see if we got the expected RedisException
      boolean expected = false;
      try {
        frExpectedError.get();
      }
      catch(ExecutionException e){
        Throwable cause = e.getCause();
        if(cause instanceof RedisException)
          expected = true;
        else
          fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
      assertTrue(expected, "expecting RedisException for append to a non-string key");
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }
  /**
   * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rename(java.lang.String, java.lang.String)}.
   * @throws InterruptedException
   */
  @Test
  public void testRename() throws InterruptedException {
    cmd = Command.RENAME.code;
    Log.log("TEST: %s command", cmd);
    try {
     
      String newkey = null;
      byte[] value = dataList.get(0);
      key = getRandomAsciiString (random.nextInt(24)+2);
      newkey = getRandomAsciiString (random.nextInt(24)+2);
     
      Future<ResponseStatus>   flushResp = provider.flushdb();
      Future<ResponseStatus>   setResp = provider.set (key, value);
      Future<byte[]>       getOldResp = provider.get(key);
      Future<ResponseStatus>   reanmeResp = provider.rename (key, newkey);
      Future<byte[]>       getNewResp = provider.get(newkey);
     
      try {
        flushResp.get();
        setResp.get();
        assertEquals(value, getOldResp.get());
        reanmeResp.get();
        assertEquals(value, getNewResp.get());
      }
      catch(ExecutionException e){
        // errors in response
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  /**
   * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rename(java.lang.String, java.lang.String)}.
   * @throws InterruptedException
   */
  @Test
  public void testRenamenx() throws InterruptedException {
    cmd = Command.RENAMENX.code;
    Log.log("TEST: %s command", cmd);
    try {
      // flush db and set a key
      provider.flushdb();
      provider.set (keys.get(0), dataList.get(0));
     
      // this should return true in future
      Future<Boolean>   reanmenxResp1 = provider.renamenx (keys.get(0), keys.get(2));

      // flush db again and set 2 keys
      provider.flushdb();
      provider.set (keys.get(1), dataList.get(1));
      provider.set (keys.get(2), dataList.get(2));
     
      // this should return false in future
      Future<Boolean>   reanmenxResp2 = provider.renamenx (keys.get(1), keys.get(2));
     
      try {
        // note that we don't have to 'get' the future results for
        // commands we are not interested in.
        assertTrue (reanmenxResp1.get(), "1st renamenx should have been true");
        assertFalse (reanmenxResp2.get(), "2nd renamenx should have been false");
      }
      catch(ExecutionException e){
        // errors in response
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {  fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e)}
  }

  /**
   * Test settting a key in a flushed db, and then checking
   * exists, flushing again, and finally keys(). 
   * Will invoke commands asynchronously, and after
   * @throws InterruptedException
   */
  @Test
  public void testSetAndFlushdbAndExistsAndKeys() throws InterruptedException {
    cmd =
      Command.FLUSHDB.code + " | " +
      Command.SET.code + " | " +
      Command.EXISTS.code + " | " +
      Command.FLUSHDB.code + " | " +
      Command.KEYS.code;
     
    Log.log("TEST: %s commands", cmd);
    try {
      key = "woof";
      Future<ResponseStatus> flushResp = provider.flushdb();
      Future<ResponseStatus> setResp = provider.set(key, "meow");
      Future<Boolean> existsResp = provider.exists(key);
      Future<ResponseStatus> flush2Resp = provider.flushdb();
      Future<List<byte[]>>  keysResp = provider.keys();
     
      try {
        flushResp.get(); // no need to check status; if error exception is raised
        setResp.get();
        assertTrue(existsResp.get(), "key should exists at this point");
        flush2Resp.get();
        assertTrue(keysResp.get().size() == 0, "keys should have returned list of 0 items");
      }
      catch(ExecutionException e){
        // errors in response
        Throwable cause = e.getCause();
        fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
      }
    }
    catch (ClientRuntimeException e) {
      // errors in request time
      fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e);
    }
  }
 
  /**
   * Tests to force RedisExceptions against various response types.
   * First we queue the requests and then we get the responses for all.
   * This tests both the primary goal and the correct behaviour of asynch
   * provider to queue the responses.
   * @throws InterruptedException
   */
  @Test
  public void testElicitErrors() throws InterruptedException {
    Log.log("TEST: Elicit errors");
    try {
      provider.flushdb();
     
      String key = keys.get(0);
      try {
              provider.set(key, smallData).get();
            }
            catch (ExecutionException e) {
              fail(cmd + " ERROR => " + e.getLocalizedMessage(), e);
            }
     
            // queue a few commands -- all are expected to result in ExecutionExcetion on Future.get()
            //
      Future<Boolean>  fSaddResp = provider.sadd(key, dataList.get(0));
      Future<Long>  fScardResp = provider.scard(key);
      Future<byte[]>  fLpopResp = provider.lpop(key);
      Future<List<byte[]>> fSmembersResp = provider.smembers(key);
     
      boolean expectedError;
     
      expectedError = false;
      try {
        Log.log("1 - Expecting an operation against key holding the wrong kind of value ERROR for SADD..");
        fSaddResp.get();
      }
      catch (ExecutionException e) { expectedError = true; }
      assertTrue(expectedError, "should have raised an exception but did not");
     
      expectedError = false;
      try {
        Log.log("2 - Expecting an operation against key holding the wrong kind of value ERROR for SCARD..");
        fScardResp.get();
      }
      catch (ExecutionException e) { expectedError = true; }
      assertTrue(expectedError, "should have raised an exception but did not");
     
      expectedError = false;
      try {
        Log.log("3 - Expecting an operation against key holding the wrong kind of value ERROR for LPOP ..");
        fLpopResp.get();
      }
      catch (ExecutionException e) { expectedError = true; }
      assertTrue(expectedError, "should have raised an exception but did not");
     
      expectedError = false;
      try {
        Log.log("4 - Expecting an operation against key holding the wrong kind of value ERROR for SMEMBERS ..");
        fSmembersResp.get();
      }
      catch (ExecutionException e) { expectedError = true; }
      assertTrue(expectedError, "should have raised an exception but did not");
     
     
    }
    catch (ClientRuntimeException e) { fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e); }
  }
 
  /**
   * Asynchronous responses must provide reference to {@link RedisException}
   * through the {@link ExecutionException#getCause()} per {@link Future} semantics.
   * @throws InterruptedException
   */
  @Test
  public void testExecutionExceptionCauseType() throws InterruptedException {
    boolean expectedError;
    String key = keys.get(0);
    try {
      expectedError = false;
      try {
        Log.log("Expecting an operation against key holding the wrong kind of value ERROR..");
       
        provider.set(key, smallData)// don't wait for response ..
        Future<Boolean> fBool = provider.sadd(key, dataList.get(0));
        @SuppressWarnings("unused")
                boolean response = fBool.get(); // wait for response
      }
            catch (ExecutionException e) {
              expectedError = true;
              Throwable cause = e.getCause();
              if(cause instanceof RedisException)
                Log.log("%s (as excepted)", cause);
              else
                fail("FAULT: the cause of ExecutionException was expected to be a RedisException");
            }
      assertTrue(expectedError, "should have raised an exception but did not");
    }
    finally {
     
    }
  }
 
  /**
   * Test {@link JRedisFuture#ping()}
   * @throws InterruptedException
   */
  @Test
  public void testPing () throws InterruptedException {
    Future<ResponseStatus> frStatus = null;
    cmd = Command.PING.code;
    Log.log("TEST: %s command", cmd);
    try {
      frStatus = provider.ping();
      ResponseStatus status = frStatus.get();
      assertTrue(!status.isError(), "ping return status");
    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }
  /**
   * Test {@link JRedisFuture#flushdb()}
   * @throws InterruptedException
   */
  @Test
  public void testFlushDb () throws InterruptedException {
    Future<ResponseStatus> frStatus = null;
    cmd = Command.FLUSHDB.code;
    Log.log("TEST: %s command", cmd);
    try {
      frStatus = provider.flushdb();
      ResponseStatus status = frStatus.get();
      assertTrue(!status.isError(), "flushdb return status");
    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }
  @Test
  public void testEcho() throws InterruptedException {
    Future<byte[]> echoResp = null;
    cmd = Command.ECHO.code;
    Log.log("TEST: %s command", cmd);
    try {
      echoResp = provider.echo(dataList.get(0));
      assertEquals(dataList.get(0), echoResp.get(), "data and echo results");

      byte[] zerolenData = new byte[0];
      assertEquals(zerolenData, provider.echo(zerolenData).get(), "zero len byte[] and echo results");
      boolean expected = false;
      try {
        provider.echo((byte[])null);
      }
      catch(IllegalArgumentException e) { expected = true; }
      assertTrue(expected, "expecting exception for null value to ECHO");

    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }
 
  @Test
  public void testBgrewriteaof() throws InterruptedException {
    Future<String> cmdRespMsg = null;
    cmd = Command.BGREWRITEAOF.code;
    Log.log("TEST: %s command", cmd);
    try {
      cmdRespMsg = provider.bgrewriteaof();
      assertTrue(cmdRespMsg.get() != null, "cmd response message should not be null");
    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }
 
  /**
   * Test {@link JRedisFuture#debug()}
   * @throws InterruptedException
   */
  @Test
  public void testDebug () throws InterruptedException {
    Future<ObjectInfo> frInfo = null;
    cmd = Command.DEBUG.code;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb();
      provider.set("foo", "bar");
      frInfo = provider.debug("foo");
      ObjectInfo info = frInfo.get();
      assertNotNull(info);
      Log.log("DEBUG of key => %s", info);
    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }
 
  @Test
  public void testExpireat() throws InterruptedException {
    cmd = Command.EXPIREAT.code;
    Log.log("TEST: %s command", cmd);
    try {
      provider.flushdb().get();
      String keyToExpire = "expire-me";
      provider.set(keyToExpire, dataList.get(0)).get();

      Log.log("TEST: %s with expire time 1000 msecs in future", Command.EXPIREAT);
      assertTrue(provider.expireat(keyToExpire, System.currentTimeMillis() + 2000).get(), "expireat for existing key should be true");
      assertTrue (provider.exists(keyToExpire).get());
      assertTrue(!provider.expireat("no-such-key", System.currentTimeMillis() + 500).get(), "expireat for non-existant key should be false");
     
     
      // NOTE: IT SIMPLY WON'T WORK WITHOUT GIVING REDIS A CHANCE
      // could be network latency, or whatever, but the expire command is NOT
      // that precise, so we need to wait a bit longer
     
      Thread.sleep(5000);
      assertTrue (!provider.exists(keyToExpire).get(), "key should have expired by now");
    }
        catch (ExecutionException e) {
          e.printStackTrace();
          fail(cmd + " FAULT: " + e.getCause().getLocalizedMessage(), e);
        }
  }

}
TOP

Related Classes of org.jredis.ri.alphazero.JRedisFutureProviderTestsBase

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.