diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java new file mode 100644 index 0000000000..36313c24ca --- /dev/null +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/ListPipelineCommandsTest.java @@ -0,0 +1,1033 @@ +package redis.clients.jedis.commands.unified.pipeline; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.RedisProtocol; +import redis.clients.jedis.Response; +import redis.clients.jedis.args.ListDirection; +import redis.clients.jedis.args.ListPosition; +import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.params.LPosParams; +import redis.clients.jedis.util.KeyValue; + +@RunWith(Parameterized.class) +public class ListPipelineCommandsTest extends PipelineCommandsTestBase { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + protected final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; + protected final byte[] bfoo1 = { 0x01, 0x02, 0x03, 0x04, 0x05 }; + protected final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; + protected final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C }; + protected final byte[] bA = { 0x0A }; + protected final byte[] bB = { 0x0B }; + protected final byte[] bC = { 0x0C }; + protected final byte[] b1 = { 0x01 }; + protected final byte[] b2 = { 0x02 }; + protected final byte[] b3 = { 0x03 }; + protected final byte[] bhello = { 0x04, 0x02 }; + protected final byte[] bx = { 0x02, 0x04 }; + protected final byte[] bdst = { 0x11, 0x12, 0x13, 0x14 }; + + public ListPipelineCommandsTest(RedisProtocol protocol) { + super(protocol); + } + + @Test + public void rpush() { + pipe.rpush("foo", "bar"); + pipe.rpush("foo", "foo"); + pipe.rpush("foo", "bar", "foo"); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 2L, + 4L + )); + + // Binary + pipe.rpush(bfoo, bbar); + pipe.rpush(bfoo, bfoo); + pipe.rpush(bfoo, bbar, bfoo); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 2L, + 4L + )); + } + + @Test + public void lpush() { + pipe.lpush("foo", "bar"); + pipe.lpush("foo", "foo"); + pipe.lpush("foo", "bar", "foo"); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 2L, + 4L + )); + + // Binary + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo, bfoo); + pipe.lpush(bfoo, bbar, bfoo); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 2L, + 4L + )); + } + + @Test + public void llen() { + pipe.llen("foo"); + pipe.lpush("foo", "bar"); + pipe.lpush("foo", "car"); + pipe.llen("foo"); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L, + 2L + )); + + // Binary + pipe.llen(bfoo); + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo, bcar); + pipe.llen(bfoo); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L, + 2L + )); + } + + @Test + public void llenNotOnList() { + pipe.set("foo", "bar"); + pipe.llen("foo"); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo("OK"), + instanceOf(JedisDataException.class) + )); + + // Binary + pipe.set(bfoo, bbar); + pipe.llen(bfoo); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo("OK"), + instanceOf(JedisDataException.class) + )); + } + + @Test + public void lrange() { + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "c"); + + Response> range1 = pipe.lrange("foo", 0, 2); + Response> range2 = pipe.lrange("foo", 0, 20); + Response> range3 = pipe.lrange("foo", 1, 2); + Response> range4 = pipe.lrange("foo", 2, 1); + + pipe.sync(); + + assertThat(range1.get(), contains("a", "b", "c")); + assertThat(range2.get(), contains("a", "b", "c")); + assertThat(range3.get(), contains("b", "c")); + assertThat(range4.get(), empty()); + + // Binary + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bC); + + Response> brange1 = pipe.lrange(bfoo, 0, 2); + Response> brange2 = pipe.lrange(bfoo, 0, 20); + Response> brange3 = pipe.lrange(bfoo, 1, 2); + Response> brange4 = pipe.lrange(bfoo, 2, 1); + + pipe.sync(); + + assertThat(brange1.get(), contains(bA, bB, bC)); + assertThat(brange2.get(), contains(bA, bB, bC)); + assertThat(brange3.get(), contains(bB, bC)); + assertThat(brange4.get(), empty()); + } + + @Test + public void ltrim() { + pipe.lpush("foo", "1"); + pipe.lpush("foo", "2"); + pipe.lpush("foo", "3"); + + Response status = pipe.ltrim("foo", 0, 1); + Response len = pipe.llen("foo"); + Response> range = pipe.lrange("foo", 0, 100); + + pipe.sync(); + + assertThat(status.get(), equalTo("OK")); + assertThat(len.get(), equalTo(2L)); + assertThat(range.get(), contains("3", "2")); + + // Binary + pipe.lpush(bfoo, b1); + pipe.lpush(bfoo, b2); + pipe.lpush(bfoo, b3); + + Response bstatus = pipe.ltrim(bfoo, 0, 1); + Response blen = pipe.llen(bfoo); + Response> brange = pipe.lrange(bfoo, 0, 100); + + pipe.sync(); + + assertThat(bstatus.get(), equalTo("OK")); + assertThat(blen.get(), equalTo(2L)); + assertThat(brange.get(), contains(b3, b2)); + } + + @Test + public void lset() { + pipe.lpush("foo", "1"); + pipe.lpush("foo", "2"); + pipe.lpush("foo", "3"); + + Response status = pipe.lset("foo", 1, "bar"); + Response> range = pipe.lrange("foo", 0, 100); + + pipe.sync(); + + assertThat(status.get(), equalTo("OK")); + assertThat(range.get(), contains("3", "bar", "1")); + + // Binary + pipe.lpush(bfoo, b1); + pipe.lpush(bfoo, b2); + pipe.lpush(bfoo, b3); + + Response bstatus = pipe.lset(bfoo, 1, bbar); + Response> brange = pipe.lrange(bfoo, 0, 100); + + pipe.sync(); + + assertThat(bstatus.get(), equalTo("OK")); + assertThat(brange.get(), contains(b3, bbar, b1)); + } + + @Test + public void lindex() { + pipe.lpush("foo", "1"); + pipe.lpush("foo", "2"); + pipe.lpush("foo", "3"); + + Response index1 = pipe.lindex("foo", 0); + Response index2 = pipe.lindex("foo", 100); + + pipe.sync(); + + assertThat(index1.get(), equalTo("3")); + assertThat(index2.get(), nullValue()); + + // Binary + pipe.lpush(bfoo, b1); + pipe.lpush(bfoo, b2); + pipe.lpush(bfoo, b3); + + Response bindex1 = pipe.lindex(bfoo, 0); + Response bindex2 = pipe.lindex(bfoo, 100); + + pipe.sync(); + + assertThat(bindex1.get(), equalTo(b3)); + assertThat(bindex2.get(), nullValue()); + } + + @Test + public void lrem() { + pipe.lpush("foo", "hello"); + pipe.lpush("foo", "hello"); + pipe.lpush("foo", "x"); + pipe.lpush("foo", "hello"); + pipe.lpush("foo", "c"); + pipe.lpush("foo", "b"); + pipe.lpush("foo", "a"); + + Response result1 = pipe.lrem("foo", -2, "hello"); + Response> range = pipe.lrange("foo", 0, 1000); + Response result2 = pipe.lrem("bar", 100, "foo"); + + pipe.sync(); + + assertThat(result1.get(), equalTo(2L)); + assertThat(range.get(), contains("a", "b", "c", "hello", "x")); + assertThat(result2.get(), equalTo(0L)); + + // Binary + pipe.lpush(bfoo, bhello); + pipe.lpush(bfoo, bhello); + pipe.lpush(bfoo, bx); + pipe.lpush(bfoo, bhello); + pipe.lpush(bfoo, bC); + pipe.lpush(bfoo, bB); + pipe.lpush(bfoo, bA); + + Response bresult1 = pipe.lrem(bfoo, -2, bhello); + Response> brange = pipe.lrange(bfoo, 0, 1000); + Response bresult2 = pipe.lrem(bbar, 100, bfoo); + + pipe.sync(); + + assertThat(bresult1.get(), equalTo(2L)); + assertThat(brange.get(), contains(bA, bB, bC, bhello, bx)); + assertThat(bresult2.get(), equalTo(0L)); + } + + @Test + public void lpop() { + Response response1 = pipe.lpop("foo"); + Response> response2 = pipe.lpop("foo", 0); + + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "c"); + + Response response3 = pipe.lpop("foo"); + Response> response4 = pipe.lpop("foo", 10); + Response response5 = pipe.lpop("foo"); + Response> response6 = pipe.lpop("foo", 1); + + pipe.sync(); + + assertThat(response1.get(), nullValue()); + assertThat(response2.get(), nullValue()); + assertThat(response3.get(), equalTo("a")); + assertThat(response4.get(), contains("b", "c")); + assertThat(response5.get(), nullValue()); + assertThat(response6.get(), nullValue()); + + // Binary + Response bresponse1 = pipe.lpop(bfoo); + Response> bresponse2 = pipe.lpop(bfoo, 0); + + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bC); + + Response bresponse3 = pipe.lpop(bfoo); + Response> bresponse4 = pipe.lpop(bfoo, 10); + Response bresponse5 = pipe.lpop(bfoo); + Response> bresponse6 = pipe.lpop(bfoo, 1); + + pipe.sync(); + + assertThat(bresponse1.get(), nullValue()); + assertThat(bresponse2.get(), nullValue()); + assertThat(bresponse3.get(), equalTo(bA)); + assertThat(bresponse4.get(), contains(bB, bC)); + assertThat(bresponse5.get(), nullValue()); + assertThat(bresponse6.get(), nullValue()); + } + + @Test + public void rpop() { + Response response1 = pipe.rpop("foo"); + Response> response2 = pipe.rpop("foo", 0); + + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "c"); + + Response response3 = pipe.rpop("foo"); + Response> response4 = pipe.rpop("foo", 10); + Response response5 = pipe.rpop("foo"); + Response> response6 = pipe.rpop("foo", 1); + + pipe.sync(); + + assertThat(response1.get(), nullValue()); + assertThat(response2.get(), nullValue()); + assertThat(response3.get(), equalTo("c")); + assertThat(response4.get(), contains("b", "a")); + assertThat(response5.get(), nullValue()); + assertThat(response6.get(), nullValue()); + + // Binary + Response bresponse1 = pipe.rpop(bfoo); + Response> bresponse2 = pipe.rpop(bfoo, 0); + + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bC); + + Response bresponse3 = pipe.rpop(bfoo); + Response> bresponse4 = pipe.rpop(bfoo, 10); + Response bresponse5 = pipe.rpop(bfoo); + Response> bresponse6 = pipe.rpop(bfoo, 1); + + pipe.sync(); + + assertThat(bresponse1.get(), nullValue()); + assertThat(bresponse2.get(), nullValue()); + assertThat(bresponse3.get(), equalTo(bC)); + assertThat(bresponse4.get(), contains(bB, bA)); + assertThat(bresponse5.get(), nullValue()); + assertThat(bresponse6.get(), nullValue()); + } + + @Test + public void rpoplpush() { + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "c"); + + pipe.rpush("dst", "foo"); + pipe.rpush("dst", "bar"); + + Response element = pipe.rpoplpush("foo", "dst"); + Response> srcRange = pipe.lrange("foo", 0, 1000); + Response> dstRange = pipe.lrange("dst", 0, 1000); + + pipe.sync(); + + assertThat(element.get(), equalTo("c")); + assertThat(srcRange.get(), contains("a", "b")); + assertThat(dstRange.get(), contains("c", "foo", "bar")); + + // Binary + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bC); + + pipe.rpush(bdst, bfoo); + pipe.rpush(bdst, bbar); + + Response belement = pipe.rpoplpush(bfoo, bdst); + Response> bsrcRange = pipe.lrange(bfoo, 0, 1000); + Response> bdstRange = pipe.lrange(bdst, 0, 1000); + + pipe.sync(); + + assertThat(belement.get(), equalTo(bC)); + assertThat(bsrcRange.get(), contains(bA, bB)); + assertThat(bdstRange.get(), contains(bC, bfoo, bbar)); + } + + @Test + public void blpop() throws InterruptedException { + Response> result1 = pipe.blpop(1, "foo"); + + pipe.lpush("foo", "bar"); + + Response> result2 = pipe.blpop(1, "foo"); + + // Multi keys + Response> result3 = pipe.blpop(1, "foo", "foo1"); + + pipe.lpush("foo", "bar"); + pipe.lpush("foo1", "bar1"); + + Response> result4 = pipe.blpop(1, "foo1", "foo"); + + pipe.sync(); + + assertThat(result1.get(), nullValue()); + assertThat(result2.get(), contains("foo", "bar")); + assertThat(result3.get(), nullValue()); + assertThat(result4.get(), contains("foo1", "bar1")); + + // Binary + pipe.lpush(bfoo, bbar); + + Response> bresult1 = pipe.blpop(1, bfoo); + + // Binary Multi keys + Response> bresult2 = pipe.blpop(1, bfoo, bfoo1); + + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo1, bcar); + + Response> bresult3 = pipe.blpop(1, bfoo1, bfoo); + + pipe.sync(); + + assertThat(bresult1.get(), contains(bfoo, bbar)); + assertThat(bresult2.get(), nullValue()); + assertThat(bresult3.get(), contains(bfoo1, bcar)); + } + + @Test + public void blpopDouble() { + Response> result1 = pipe.blpop(0.1, "foo"); + + pipe.lpush("foo", "bar"); + + Response> result2 = pipe.blpop(3.2, "foo"); + + // Multi keys + Response> result3 = pipe.blpop(0.18, "foo", "foo1"); + + pipe.lpush("foo", "bar"); + pipe.lpush("foo1", "bar1"); + + Response> result4 = pipe.blpop(1d, "foo1", "foo"); + + pipe.sync(); + + assertThat(result1.get(), nullValue()); + assertThat(result2.get(), equalTo(new KeyValue<>("foo", "bar"))); + assertThat(result3.get(), nullValue()); + assertThat(result4.get(), equalTo(new KeyValue<>("foo1", "bar1"))); + + // Binary + pipe.lpush(bfoo, bbar); + + Response> bresult1 = pipe.blpop(3.12, bfoo); + + // Binary Multi keys + Response> bresult2 = pipe.blpop(0.11, bfoo, bfoo1); + + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo1, bcar); + + Response> bresult3 = pipe.blpop(1d, bfoo1, bfoo); + + pipe.sync(); + + assertThat(bresult1.get().getKey(), equalTo(bfoo)); + assertThat(bresult1.get().getValue(), equalTo(bbar)); + assertThat(bresult2.get(), nullValue()); + assertThat(bresult3.get().getKey(), equalTo(bfoo1)); + assertThat(bresult3.get().getValue(), equalTo(bcar)); + } + + @Test + public void blpopDoubleWithSleep() { + long startMillis, totalMillis; + + startMillis = System.currentTimeMillis(); + + Response> result = pipe.blpop(0.04, "foo"); + pipe.sync(); + + totalMillis = System.currentTimeMillis() - startMillis; + assertTrue("TotalMillis=" + totalMillis, totalMillis < 200); + + assertThat(result.get(), nullValue()); + + startMillis = System.currentTimeMillis(); + new Thread(() -> { + try { + Thread.sleep(30); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.lpush("foo", "bar"); + }).start(); + + result = pipe.blpop(1.2, "foo"); + pipe.sync(); + + totalMillis = System.currentTimeMillis() - startMillis; + assertTrue("TotalMillis=" + totalMillis, totalMillis < 200); + + assertThat(result.get().getKey(), equalTo("foo")); + assertThat(result.get().getValue(), equalTo("bar")); + } + + @Test + public void brpop() { + Response> result1 = pipe.brpop(1, "foo"); + + pipe.lpush("foo", "bar"); + + Response> result2 = pipe.brpop(1, "foo"); + + // Multi keys + Response> result3 = pipe.brpop(1, "foo", "foo1"); + + pipe.lpush("foo", "bar"); + pipe.lpush("foo1", "bar1"); + + Response> result4 = pipe.brpop(1, "foo1", "foo"); + + pipe.sync(); + + assertThat(result1.get(), nullValue()); + assertThat(result2.get(), contains("foo", "bar")); + assertThat(result3.get(), nullValue()); + assertThat(result4.get(), contains("foo1", "bar1")); + + // Binary + pipe.lpush(bfoo, bbar); + + Response> bresult1 = pipe.brpop(1, bfoo); + + // Binary Multi keys + Response> bresult2 = pipe.brpop(1, bfoo, bfoo1); + + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo1, bcar); + + Response> bresult3 = pipe.brpop(1, bfoo1, bfoo); + + pipe.sync(); + + assertThat(bresult1.get(), contains(bfoo, bbar)); + assertThat(bresult2.get(), nullValue()); + assertThat(bresult3.get(), contains(bfoo1, bcar)); + } + + @Test + public void brpopDouble() { + Response> result1 = pipe.brpop(0.1, "foo"); + + pipe.lpush("foo", "bar"); + + Response> result2 = pipe.brpop(3.2, "foo"); + + // Multi keys + Response> result3 = pipe.brpop(0.18, "foo", "foo1"); + + pipe.lpush("foo", "bar"); + pipe.lpush("foo1", "bar1"); + + Response> result4 = pipe.brpop(1d, "foo1", "foo"); + + pipe.sync(); + + assertThat(result1.get(), nullValue()); + assertThat(result2.get(), equalTo(new KeyValue<>("foo", "bar"))); + assertThat(result3.get(), nullValue()); + assertThat(result4.get(), equalTo(new KeyValue<>("foo1", "bar1"))); + + // Binary + pipe.lpush(bfoo, bbar); + + Response> bresult1 = pipe.brpop(3.12, bfoo); + + // Binary Multi keys + Response> bresult2 = pipe.brpop(0.11, bfoo, bfoo1); + + pipe.lpush(bfoo, bbar); + pipe.lpush(bfoo1, bcar); + + Response> bresult3 = pipe.brpop(1d, bfoo1, bfoo); + + pipe.sync(); + + assertThat(bresult1.get().getKey(), equalTo(bfoo)); + assertThat(bresult1.get().getValue(), equalTo(bbar)); + assertThat(bresult2.get(), nullValue()); + assertThat(bresult3.get().getKey(), equalTo(bfoo1)); + assertThat(bresult3.get().getValue(), equalTo(bcar)); + } + + @Test + public void brpopDoubleWithSleep() { + long startMillis, totalMillis; + + startMillis = System.currentTimeMillis(); + + Response> result = pipe.brpop(0.04, "foo"); + pipe.sync(); + + totalMillis = System.currentTimeMillis() - startMillis; + assertTrue("TotalMillis=" + totalMillis, totalMillis < 200); + + assertThat(result.get(), nullValue()); + + startMillis = System.currentTimeMillis(); + new Thread(() -> { + try { + Thread.sleep(30); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.lpush("foo", "bar"); + }).start(); + + result = pipe.brpop(1.2, "foo"); + pipe.sync(); + + totalMillis = System.currentTimeMillis() - startMillis; + assertTrue("TotalMillis=" + totalMillis, totalMillis < 200); + + assertThat(result.get().getKey(), equalTo("foo")); + assertThat(result.get().getValue(), equalTo("bar")); + } + + @Test + public void lpushx() { + pipe.lpushx("foo", "bar"); + pipe.lpush("foo", "a"); + pipe.lpushx("foo", "b"); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L + )); + + // Binary + pipe.lpushx(bfoo, bbar); + pipe.lpush(bfoo, bA); + pipe.lpushx(bfoo, bB); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L + )); + } + + @Test + public void rpushx() { + pipe.rpushx("foo", "bar"); + pipe.lpush("foo", "a"); + pipe.rpushx("foo", "b"); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L + )); + + // Binary + pipe.rpushx(bfoo, bbar); + pipe.lpush(bfoo, bA); + pipe.rpushx(bfoo, bB); + + assertThat(pipe.syncAndReturnAll(), contains( + 0L, + 1L, + 2L + )); + } + + @Test + public void linsert() { + Response result1 = pipe.linsert("foo", ListPosition.BEFORE, "bar", "car"); + + pipe.lpush("foo", "a"); + + Response result2 = pipe.linsert("foo", ListPosition.AFTER, "a", "b"); + + Response> range = pipe.lrange("foo", 0, 100); + + Response result3 = pipe.linsert("foo", ListPosition.BEFORE, "bar", "car"); + + pipe.sync(); + + assertThat(result1.get(), equalTo(0L)); + assertThat(result2.get(), equalTo(2L)); + assertThat(range.get(), contains("a", "b")); + assertThat(result3.get(), equalTo(-1L)); + + // Binary + Response bresult1 = pipe.linsert(bfoo, ListPosition.BEFORE, bbar, bcar); + + pipe.lpush(bfoo, bA); + + Response bresult2 = pipe.linsert(bfoo, ListPosition.AFTER, bA, bB); + + Response> brange = pipe.lrange(bfoo, 0, 100); + + Response bresult3 = pipe.linsert(bfoo, ListPosition.BEFORE, bbar, bcar); + + pipe.sync(); + + assertThat(bresult1.get(), equalTo(0L)); + assertThat(bresult2.get(), equalTo(2L)); + assertThat(brange.get(), contains(bA, bB)); + assertThat(bresult3.get(), equalTo(-1L)); + } + + @Test + public void brpoplpush() { + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.lpush("foo", "a"); + } + }).start(); + + Response element = pipe.brpoplpush("foo", "bar", 0); + Response len = pipe.llen("bar"); + Response> range = pipe.lrange("bar", 0, -1); + + pipe.sync(); + + assertThat(element.get(), equalTo("a")); + assertThat(len.get(), equalTo(1L)); + assertThat(range.get(), contains("a")); + + // Binary + + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.lpush(bfoo, bA); + } + }).start(); + + Response belement = pipe.brpoplpush(bfoo, bbar, 0); + Response blen = pipe.llen(bbar); + Response> brange = pipe.lrange(bbar, 0, -1); + + pipe.sync(); + + assertThat(belement.get(), equalTo(bA)); + assertThat(blen.get(), equalTo(1L)); + assertThat(brange.get(), contains(bA)); + } + + @Test + public void lpos() { + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "c"); + pipe.sync(); + + pipe.lpos("foo", "b"); + pipe.lpos("foo", "d"); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo(1L), + nullValue() + )); + + pipe.rpush("foo", "a"); + pipe.rpush("foo", "b"); + pipe.rpush("foo", "b"); + pipe.sync(); + + pipe.lpos("foo", "b", LPosParams.lPosParams()); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(3)); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(-2)); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(-5)); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(1).maxlen(2)); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(2).maxlen(2)); + pipe.lpos("foo", "b", LPosParams.lPosParams().rank(-2).maxlen(2)); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo(1L), + equalTo(5L), + equalTo(4L), + nullValue(), + equalTo(1L), + nullValue(), + equalTo(4L) + )); + + Response> posList1 = pipe.lpos("foo", "b", LPosParams.lPosParams(), 2); + Response> posList2 = pipe.lpos("foo", "b", LPosParams.lPosParams(), 0); + Response> posList3 = pipe.lpos("foo", "b", LPosParams.lPosParams().rank(2), 0); + Response> posList4 = pipe.lpos("foo", "b", LPosParams.lPosParams().rank(2).maxlen(5), 0); + Response> posList5 = pipe.lpos("foo", "b", LPosParams.lPosParams().rank(-2), 0); + Response> posList6 = pipe.lpos("foo", "b", LPosParams.lPosParams().rank(-1).maxlen(5), 2); + + pipe.sync(); + + assertThat(posList1.get(), contains(1L, 4L)); + assertThat(posList2.get(), contains(1L, 4L, 5L)); + assertThat(posList3.get(), contains(4L, 5L)); + assertThat(posList4.get(), contains(4L)); + assertThat(posList5.get(), contains(4L, 1L)); + assertThat(posList6.get(), contains(5L, 4L)); + + // Binary + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bC); + pipe.sync(); + + pipe.lpos(bfoo, bB); + pipe.lpos(bfoo, b3); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo(1L), + nullValue() + )); + + pipe.rpush(bfoo, bA); + pipe.rpush(bfoo, bB); + pipe.rpush(bfoo, bA); + pipe.sync(); + + pipe.lpos(bfoo, bB, LPosParams.lPosParams().rank(2)); + pipe.lpos(bfoo, bB, LPosParams.lPosParams().rank(-2).maxlen(5)); + + assertThat(pipe.syncAndReturnAll(), contains( + equalTo(4L), + equalTo(1L) + )); + + Response> bposList1 = pipe.lpos(bfoo, bA, LPosParams.lPosParams().maxlen(6), 0); + Response> bposList2 = pipe.lpos(bfoo, bA, LPosParams.lPosParams().maxlen(6).rank(2), 1); + + pipe.sync(); + + assertThat(bposList1.get(), contains(0L, 3L, 5L)); + assertThat(bposList2.get(), contains(3L)); + } + + @Test + public void lmove() { + pipe.rpush("foo", "bar1", "bar2", "bar3"); + + Response item1 = pipe.lmove("foo", "bar", ListDirection.RIGHT, ListDirection.LEFT); + Response> range1 = pipe.lrange("bar", 0, -1); + Response> range2 = pipe.lrange("foo", 0, -1); + + pipe.sync(); + + assertThat(item1.get(), equalTo("bar3")); + assertThat(range1.get(), contains("bar3")); + assertThat(range2.get(), contains("bar1", "bar2")); + + // Binary + pipe.rpush(bfoo, b1, b2, b3); + + Response bitem1 = pipe.lmove(bfoo, bbar, ListDirection.RIGHT, ListDirection.LEFT); + Response> brange1 = pipe.lrange(bbar, 0, -1); + Response> brange2 = pipe.lrange(bfoo, 0, -1); + + pipe.sync(); + + assertThat(bitem1.get(), equalTo(b3)); + assertThat(brange1.get(), contains(b3)); + assertThat(brange2.get(), contains(b1, b2)); + } + + @Test + public void blmove() { + new Thread(() -> { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.rpush("foo", "bar1", "bar2", "bar3"); + }).start(); + + Response response = pipe.blmove("foo", "bar", ListDirection.RIGHT, ListDirection.LEFT, 0); + Response> range1 = pipe.lrange("bar", 0, -1); + Response> range2 = pipe.lrange("foo", 0, -1); + + pipe.sync(); + + assertThat(response.get(), equalTo("bar3")); + assertThat(range1.get(), contains("bar3")); + assertThat(range2.get(), contains("bar1", "bar2")); + + // Binary + new Thread(() -> { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error("", e); + } + jedis.rpush(bfoo, b1, b2, b3); + }).start(); + + Response bresponse = pipe.blmove(bfoo, bbar, ListDirection.RIGHT, ListDirection.LEFT, 0); + Response> brange1 = pipe.lrange(bbar, 0, -1); + Response> brange2 = pipe.lrange(bfoo, 0, -1); + + pipe.sync(); + + assertThat(bresponse.get(), equalTo(b3)); + assertThat(brange1.get(), contains(b3)); + assertThat(brange2.get(), contains(b1, b2)); + } + + @Test + public void lmpop() { + String mylist1 = "mylist1"; + String mylist2 = "mylist2"; + + // add elements to list + pipe.lpush(mylist1, "one1", "two1", "three1", "four1", "five1"); + pipe.lpush(mylist2, "one2", "two2", "three2", "four2", "five2"); + + Response>> elements1 = pipe.lmpop(ListDirection.LEFT, mylist1, mylist2); + Response>> elements2 = pipe.lmpop(ListDirection.LEFT, 5, mylist1, mylist2); + Response>> elements3 = pipe.lmpop(ListDirection.RIGHT, 100, mylist1, mylist2); + Response>> elements4 = pipe.lmpop(ListDirection.RIGHT, mylist1, mylist2); + + pipe.sync(); + + assertThat(elements1.get().getKey(), equalTo(mylist1)); + assertThat(elements1.get().getValue(), contains("five1")); + + assertThat(elements2.get().getKey(), equalTo(mylist1)); + assertThat(elements2.get().getValue(), contains("four1", "three1", "two1", "one1")); + + assertThat(elements3.get().getKey(), equalTo(mylist2)); + assertThat(elements3.get().getValue(), contains("one2", "two2", "three2", "four2", "five2")); + + assertThat(elements4.get(), nullValue()); + } + + @Test + public void blmpopSimple() { + String mylist1 = "mylist1"; + String mylist2 = "mylist2"; + + // add elements to list + pipe.lpush(mylist1, "one1", "two1", "three1", "four1", "five1"); + pipe.lpush(mylist2, "one2", "two2", "three2", "four2", "five2"); + + Response>> elements1 = pipe.blmpop(1L, ListDirection.LEFT, mylist1, mylist2); + Response>> elements2 = pipe.blmpop(1L, ListDirection.LEFT, 5, mylist1, mylist2); + Response>> elements3 = pipe.blmpop(1L, ListDirection.RIGHT, 100, mylist1, mylist2); + Response>> elements4 = pipe.blmpop(1L, ListDirection.RIGHT, mylist1, mylist2); + + pipe.sync(); + + assertThat(elements1.get().getKey(), equalTo(mylist1)); + assertThat(elements1.get().getValue(), contains("five1")); + + assertThat(elements2.get().getKey(), equalTo(mylist1)); + assertThat(elements2.get().getValue(), contains("four1", "three1", "two1", "one1")); + + assertThat(elements3.get().getKey(), equalTo(mylist2)); + assertThat(elements3.get().getValue(), contains("one2", "two2", "three2", "four2", "five2")); + + assertThat(elements4.get(), nullValue()); + } +} diff --git a/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java new file mode 100644 index 0000000000..0dd0a18559 --- /dev/null +++ b/src/test/java/redis/clients/jedis/commands/unified/pipeline/SetPipelineCommandsTest.java @@ -0,0 +1,659 @@ +package redis.clients.jedis.commands.unified.pipeline; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START; +import static redis.clients.jedis.params.ScanParams.SCAN_POINTER_START_BINARY; +import static redis.clients.jedis.util.AssertUtil.assertByteArrayCollectionContainsAll; +import static redis.clients.jedis.util.AssertUtil.assertByteArraySetEquals; +import static redis.clients.jedis.util.AssertUtil.assertCollectionContainsAll; +import static redis.clients.jedis.util.ByteArrayUtil.byteArrayCollectionRemoveAll; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import redis.clients.jedis.RedisProtocol; +import redis.clients.jedis.Response; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; + +@RunWith(Parameterized.class) +public class SetPipelineCommandsTest extends PipelineCommandsTestBase { + + final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; + final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; + final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C }; + final byte[] ba = { 0x0A }; + final byte[] bb = { 0x0B }; + final byte[] bc = { 0x0C }; + final byte[] bd = { 0x0D }; + final byte[] bx = { 0x42 }; + + final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A }; + final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B }; + final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C }; + final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' }; + + public SetPipelineCommandsTest(RedisProtocol protocol) { + super(protocol); + } + + @Test + public void sadd() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "a"); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 0L + )); + + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, ba); + + assertThat(pipe.syncAndReturnAll(), contains( + 1L, + 0L + )); + } + + @Test + public void smembers() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + Response> members = pipe.smembers("foo"); + + pipe.sync(); + + assertThat(members.get(), containsInAnyOrder("a", "b")); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + Response> bmembers = pipe.smembers(bfoo); + + pipe.sync(); + + assertThat(bmembers.get(), containsInAnyOrder(ba, bb)); + } + + @Test + public void srem() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + Response status1 = pipe.srem("foo", "a"); + Response> members = pipe.smembers("foo"); + Response status2 = pipe.srem("foo", "bar"); + + pipe.sync(); + + assertThat(status1.get(), equalTo(1L)); + assertThat(members.get(), containsInAnyOrder("b")); + assertThat(status2.get(), equalTo(0L)); + + // Binary + + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + Response bstatus1 = pipe.srem(bfoo, ba); + Response> bmembers = pipe.smembers(bfoo); + Response bstatus2 = pipe.srem(bfoo, bbar); + + pipe.sync(); + + assertThat(bstatus1.get(), equalTo(1L)); + assertThat(bmembers.get(), containsInAnyOrder(bb)); + assertThat(bstatus2.get(), equalTo(0L)); + } + + @Test + public void spop() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + Response member1 = pipe.spop("foo"); + Response> members = pipe.smembers("foo"); + Response member2 = pipe.spop("bar"); + + pipe.sync(); + + assertThat(member1.get(), anyOf(equalTo("a"), equalTo("b"))); + assertThat(members.get(), hasSize(1)); + assertThat(member2.get(), nullValue()); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + Response bmember1 = pipe.spop(bfoo); + Response> bmembers = pipe.smembers(bfoo); + Response bmember2 = pipe.spop(bbar); + + pipe.sync(); + + assertThat(bmember1.get(), anyOf(equalTo(ba), equalTo(bb))); + assertThat(bmembers.get(), hasSize(1)); + assertThat(bmember2.get(), nullValue()); + } + + @Test + public void spopWithCount() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + pipe.sadd("foo", "c"); + + Response> members1 = pipe.spop("foo", 2); + Response> members2 = pipe.spop("foo", 2); + Response> members3 = pipe.spop("foo", 2); + + pipe.sync(); + + assertThat(members1.get(), hasSize(2)); + assertThat(members2.get(), hasSize(1)); + assertThat(members3.get(), empty()); + + Set superSet = new HashSet<>(); + superSet.add("c"); + superSet.add("b"); + superSet.add("a"); + + assertCollectionContainsAll(superSet, members1.get()); + superSet.removeAll(members1.get()); + + assertThat(members2.get(), equalTo(superSet)); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + pipe.sadd(bfoo, bc); + + Response> bmembers1 = pipe.spop(bfoo, 2); + Response> bmembers2 = pipe.spop(bfoo, 2); + Response> bmembers3 = pipe.spop(bfoo, 2); + + pipe.sync(); + + assertThat(bmembers1.get(), hasSize(2)); + assertThat(bmembers2.get(), hasSize(1)); + assertThat(bmembers3.get(), empty()); + + Set bsuperSet = new HashSet<>(); + bsuperSet.add(bc); + bsuperSet.add(bb); + bsuperSet.add(ba); + + assertByteArrayCollectionContainsAll(bsuperSet, bmembers1.get()); + byteArrayCollectionRemoveAll(bsuperSet, bmembers1.get()); + + assertByteArraySetEquals(bsuperSet, bmembers2.get()); + } + + @Test + public void smove() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "c"); + + Response status1 = pipe.smove("foo", "bar", "a"); + Response> srcMembers = pipe.smembers("foo"); + Response> dstMembers = pipe.smembers("bar"); + Response status2 = pipe.smove("foo", "bar", "a"); + + pipe.sync(); + + assertThat(status1.get(), equalTo(1L)); + assertThat(srcMembers.get(), containsInAnyOrder("b")); + assertThat(dstMembers.get(), containsInAnyOrder("a", "c")); + assertThat(status2.get(), equalTo(0L)); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, bc); + + Response bstatus1 = pipe.smove(bfoo, bbar, ba); + Response> bsrcMembers = pipe.smembers(bfoo); + Response> bdstMembers = pipe.smembers(bbar); + Response bstatus2 = pipe.smove(bfoo, bbar, ba); + + pipe.sync(); + + assertThat(bstatus1.get(), equalTo(1L)); + assertThat(bsrcMembers.get(), containsInAnyOrder(bb)); + assertThat(bdstMembers.get(), containsInAnyOrder(ba, bc)); + assertThat(bstatus2.get(), equalTo(0L)); + } + + @Test + public void scard() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + pipe.sync(); + + pipe.scard("foo"); + pipe.scard("bar"); + + assertThat(pipe.syncAndReturnAll(), contains( + 2L, + 0L + )); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + pipe.sync(); + + pipe.scard(bfoo); + pipe.scard(bbar); + + assertThat(pipe.syncAndReturnAll(), contains( + 2L, + 0L + )); + } + + @Test + public void sismember() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + pipe.sync(); + + pipe.sismember("foo", "a"); + pipe.sismember("foo", "c"); + + assertThat(pipe.syncAndReturnAll(), contains( + true, + false + )); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + pipe.sync(); + + pipe.sismember(bfoo, ba); + pipe.sismember(bfoo, bc); + + assertThat(pipe.syncAndReturnAll(), contains( + true, + false + )); + } + + @Test + public void smismember() { + pipe.sadd("foo", "a", "b"); + + Response> response = pipe.smismember("foo", "a", "c"); + + pipe.sync(); + + assertThat(response.get(), contains(true, false)); + + // Binary + pipe.sadd(bfoo, ba, bb); + + Response> bresponse = pipe.smismember(bfoo, ba, bc); + + pipe.sync(); + + assertThat(bresponse.get(), contains(true, false)); + } + + @Test + public void sinter() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "b"); + pipe.sadd("bar", "c"); + + Response> intersection = pipe.sinter("foo", "bar"); + + pipe.sync(); + + assertThat(intersection.get(), containsInAnyOrder("b")); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, bb); + pipe.sadd(bbar, bc); + + Response> bintersection = pipe.sinter(bfoo, bbar); + + pipe.sync(); + + assertThat(bintersection.get(), containsInAnyOrder(bb)); + } + + @Test + public void sinterstore() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "b"); + pipe.sadd("bar", "c"); + + Response status = pipe.sinterstore("car", "foo", "bar"); + Response> members = pipe.smembers("car"); + + pipe.sync(); + + assertThat(status.get(), equalTo(1L)); + assertThat(members.get(), containsInAnyOrder("b")); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, bb); + pipe.sadd(bbar, bc); + + Response bstatus = pipe.sinterstore(bcar, bfoo, bbar); + Response> bmembers = pipe.smembers(bcar); + + pipe.sync(); + + assertThat(bstatus.get(), equalTo(1L)); + assertThat(bmembers.get(), containsInAnyOrder(bb)); + } + + @Test + public void sintercard() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "a"); + pipe.sadd("bar", "b"); + pipe.sadd("bar", "c"); + + Response card = pipe.sintercard("foo", "bar"); + Response limitedCard = pipe.sintercard(1, "foo", "bar"); + + pipe.sync(); + + assertThat(card.get(), equalTo(2L)); + assertThat(limitedCard.get(), equalTo(1L)); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, ba); + pipe.sadd(bbar, bb); + pipe.sadd(bbar, bc); + + Response bcard = pipe.sintercard(bfoo, bbar); + Response blimitedCard = pipe.sintercard(1, bfoo, bbar); + + pipe.sync(); + + assertThat(bcard.get(), equalTo(2L)); + assertThat(blimitedCard.get(), equalTo(1L)); + } + + @Test + public void sunion() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "b"); + pipe.sadd("bar", "c"); + + Response> union = pipe.sunion("foo", "bar"); + + pipe.sync(); + + assertThat(union.get(), containsInAnyOrder("a", "b", "c")); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, bb); + pipe.sadd(bbar, bc); + + Response> bunion = pipe.sunion(bfoo, bbar); + + pipe.sync(); + + assertThat(bunion.get(), containsInAnyOrder(ba, bb, bc)); + } + + @Test + public void sunionstore() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + pipe.sadd("bar", "b"); + pipe.sadd("bar", "c"); + + Response status = pipe.sunionstore("car", "foo", "bar"); + Response> members = pipe.smembers("car"); + + pipe.sync(); + + assertThat(status.get(), equalTo(3L)); + assertThat(members.get(), containsInAnyOrder("a", "b", "c")); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + pipe.sadd(bbar, bb); + pipe.sadd(bbar, bc); + + Response bstatus = pipe.sunionstore(bcar, bfoo, bbar); + Response> bmembers = pipe.smembers(bcar); + + pipe.sync(); + + assertThat(bstatus.get(), equalTo(3L)); + assertThat(bmembers.get(), containsInAnyOrder(ba, bb, bc)); + } + + @Test + public void sdiff() { + pipe.sadd("foo", "x"); + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + pipe.sadd("foo", "c"); + + pipe.sadd("bar", "c"); + + pipe.sadd("car", "a"); + pipe.sadd("car", "d"); + + Response> diff = pipe.sdiff("foo", "bar", "car"); + + pipe.sync(); + + assertThat(diff.get(), containsInAnyOrder("b", "x")); + + // Binary + pipe.sadd(bfoo, bx); + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + pipe.sadd(bfoo, bc); + + pipe.sadd(bbar, bc); + + pipe.sadd(bcar, ba); + pipe.sadd(bcar, bd); + + Response> bdiff = pipe.sdiff(bfoo, bbar, bcar); + + pipe.sync(); + + assertThat(bdiff.get(), containsInAnyOrder(bb, bx)); + } + + @Test + public void sdiffstore() { + pipe.sadd("foo", "x"); + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + pipe.sadd("foo", "c"); + + pipe.sadd("bar", "c"); + + pipe.sadd("car", "a"); + pipe.sadd("car", "d"); + + Response status = pipe.sdiffstore("tar", "foo", "bar", "car"); + Response> members = pipe.smembers("tar"); + + pipe.sync(); + + assertThat(status.get(), equalTo(2L)); + assertThat(members.get(), containsInAnyOrder("b", "x")); + + // Binary + pipe.sadd(bfoo, bx); + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + pipe.sadd(bfoo, bc); + + pipe.sadd(bbar, bc); + + pipe.sadd(bcar, ba); + pipe.sadd(bcar, bd); + + Response bstatus = pipe.sdiffstore("tar".getBytes(), bfoo, bbar, bcar); + Response> bmembers = pipe.smembers("tar".getBytes()); + + pipe.sync(); + + assertThat(bstatus.get(), equalTo(2L)); + assertThat(bmembers.get(), containsInAnyOrder(bb, bx)); + } + + @Test + public void srandmember() { + pipe.sadd("foo", "a"); + pipe.sadd("foo", "b"); + + Response member1 = pipe.srandmember("foo"); + Response> allMembers = pipe.smembers("foo"); + Response> members1 = pipe.srandmember("foo", 2); + Response member2 = pipe.srandmember("bar"); + Response> members2 = pipe.srandmember("bar", 2); + + pipe.sync(); + + assertThat(member1.get(), anyOf(equalTo("a"), equalTo("b"))); + assertThat(allMembers.get(), containsInAnyOrder("a", "b")); + assertThat(members1.get(), containsInAnyOrder("a", "b")); + assertThat(member2.get(), nullValue()); + assertThat(members2.get(), empty()); + + // Binary + pipe.sadd(bfoo, ba); + pipe.sadd(bfoo, bb); + + Response bmember1 = pipe.srandmember(bfoo); + Response> bmembers1 = pipe.srandmember(bfoo, 2); + Response bmember2 = pipe.srandmember(bbar); + Response> bmembers2 = pipe.srandmember("bbar", 2); + + pipe.sync(); + + assertThat(bmember1.get(), anyOf(equalTo(ba), equalTo(bb))); + assertThat(bmembers1.get(), containsInAnyOrder(ba, bb)); + assertThat(bmember2.get(), nullValue()); + assertThat(bmembers2.get(), empty()); + } + + @Test + public void sscan() { + pipe.sadd("foo", "a", "b"); + + Response> result = pipe.sscan("foo", SCAN_POINTER_START); + + pipe.sync(); + + assertThat(result.get().getCursor(), equalTo(SCAN_POINTER_START)); + assertThat(result.get().getResult(), not(empty())); + + // binary + pipe.sadd(bfoo, ba, bb); + + Response> bResult = pipe.sscan(bfoo, SCAN_POINTER_START_BINARY); + + pipe.sync(); + + assertThat(bResult.get().getCursor(), equalTo(SCAN_POINTER_START)); + assertThat(bResult.get().getResult(), not(empty())); + } + + @Test + public void sscanMatch() { + ScanParams params = new ScanParams(); + params.match("a*"); + + pipe.sadd("foo", "b", "a", "aa"); + Response> result = pipe.sscan("foo", SCAN_POINTER_START, params); + + pipe.sync(); + + assertThat(result.get().getCursor(), equalTo(SCAN_POINTER_START)); + assertThat(result.get().getResult(), not(empty())); + + // binary + pipe.sadd(bfoo, bbar1, bbar2, bbar3); + + params = new ScanParams(); + params.match(bbarstar); + + Response> bResult = pipe.sscan(bfoo, SCAN_POINTER_START_BINARY, params); + + pipe.sync(); + + assertThat(bResult.get().getCursor(), equalTo(SCAN_POINTER_START)); + assertThat(bResult.get().getResult(), not(empty())); + } + + @Test + public void sscanCount() { + ScanParams params = new ScanParams(); + params.count(2); + + pipe.sadd("foo", "a1", "a2", "a3", "a4", "a5"); + + Response> result = pipe.sscan("foo", SCAN_POINTER_START, params); + + pipe.sync(); + + assertThat(result.get().getResult(), not(empty())); + + // binary + pipe.sadd(bfoo, bbar1, bbar2, bbar3); + + params = new ScanParams(); + params.count(2); + + Response> bResult = pipe.sscan(bfoo, SCAN_POINTER_START_BINARY, params); + + pipe.sync(); + assertThat(bResult.get().getResult(), not(empty())); + } +}