diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java index 79ef537ba..a42d5dabf 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java @@ -17,7 +17,6 @@ package org.springframework.data.redis.connection; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -47,8 +46,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; -import org.springframework.data.redis.Address; -import org.springframework.data.redis.Person; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.RedisTestProfileValueSource; import org.springframework.data.redis.RedisVersionUtils; @@ -94,7 +91,7 @@ public abstract class AbstractConnectionIntegrationTests { public void setUp() { byteConnection = connectionFactory.getConnection(); connection = new DefaultStringRedisConnection(byteConnection); - ((DefaultStringRedisConnection)connection).setDeserializePipelineResults(false); + initConnection(); } @After @@ -118,7 +115,8 @@ public abstract class AbstractConnectionIntegrationTests { @IfProfileValue(name = "runLongTests", value = "true") public void testExpire() throws Exception { connection.set("exp", "true"); - assertTrue(connection.expire("exp", 1)); + actual.add(connection.expire("exp", 1)); + verifyResults(Arrays.asList(new Object[] { true })); assertTrue(waitFor(new KeyExpired("exp"), 3000l)); } @@ -126,7 +124,8 @@ public abstract class AbstractConnectionIntegrationTests { @IfProfileValue(name = "runLongTests", value = "true") public void testExpireAt() throws Exception { connection.set("exp2", "true"); - assertTrue(connection.expireAt("exp2", System.currentTimeMillis() / 1000 + 1)); + actual.add(connection.expireAt("exp2", System.currentTimeMillis() / 1000 + 1)); + verifyResults(Arrays.asList(new Object[] { true })); assertTrue(waitFor(new KeyExpired("exp2"), 3000l)); } @@ -134,140 +133,166 @@ public abstract class AbstractConnectionIntegrationTests { @IfProfileValue(name = "redisVersion", value = "2.6") public void testPExpire() { connection.set("exp", "true"); - assertTrue(connection.pExpire("exp", 100)); - assertTrue(waitFor(new KeyExpired("exp"), 300l)); + actual.add(connection.pExpire("exp", 100)); + verifyResults(Arrays.asList(new Object[] { true })); + assertTrue(waitFor(new KeyExpired("exp"), 1000l)); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testPExpireKeyNotExists() { - assertFalse(connection.pExpire("nonexistent", 100)); + actual.add(connection.pExpire("nonexistent", 100)); + verifyResults(Arrays.asList(new Object[] { false })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testPExpireAt() { - connection.set("exp", "true"); - assertTrue(connection.pExpireAt("exp", System.currentTimeMillis() + 200)); - assertTrue(waitFor(new KeyExpired("exp"), 600l)); + connection.set("exp2", "true"); + actual.add(connection.pExpireAt("exp2", System.currentTimeMillis() + 200)); + verifyResults(Arrays.asList(new Object[] { true })); + assertTrue(waitFor(new KeyExpired("exp2"), 1000l)); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testPExpireAtKeyNotExists() { - assertFalse(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200)); + actual.add(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200)); + verifyResults(Arrays.asList(new Object[] { false })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testScriptLoadEvalSha() { + getResults(); String sha1 = connection.scriptLoad("return KEYS[1]"); + initConnection(); actual.add(connection.evalSha(sha1, ReturnType.VALUE, 2, "key1", "key2")); - verifyResults(Arrays.asList(new Object[] {"key1"}), actual); + assertEquals("key1", new String((byte[]) getResults().get(0))); } + @SuppressWarnings("unchecked") @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalShaArrayStrings() { + getResults(); String sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}"); + initConnection(); actual.add(connection.evalSha(sha1, ReturnType.MULTI, 1, "key1", "arg1")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"key1", "arg1"} )}), actual); + List results = getResults(); + List scriptResults = (List) results.get(0); + assertEquals( + Arrays.asList(new Object[] { "key1", "arg1" }), + Arrays.asList(new Object[] { new String(scriptResults.get(0)), + new String(scriptResults.get(1)) })); } - @Test(expected=RedisSystemException.class) + @Test(expected = RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalShaNotFound() { connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); + getResults(); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnString() { actual.add(connection.eval("return KEYS[1]", ReturnType.VALUE, 1, "foo")); - verifyResults(Arrays.asList(new Object[] {"foo"}), actual); + byte[] result = (byte[]) getResults().get(0); + assertEquals("foo", new String(result)); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnNumber() { actual.add(connection.eval("return 10", ReturnType.INTEGER, 0)); - verifyResults(Arrays.asList(new Object[] {10l}), actual); + verifyResults(Arrays.asList(new Object[] { 10l })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnSingleOK() { actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0)); - assertEquals(Arrays.asList(new Object[] { "OK" }), convertResults(false)); + assertEquals(Arrays.asList(new Object[] { "OK" }), getResults()); } - @Test(expected=RedisSystemException.class) + @Test(expected = RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnSingleError() { connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); + getResults(); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnFalse() { actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { false }), actual); + verifyResults(Arrays.asList(new Object[] { false })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnTrue() { actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { true }), actual); + verifyResults(Arrays.asList(new Object[] { true })); } + @SuppressWarnings("unchecked") @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayStrings() { actual.add(connection.eval("return {KEYS[1],ARGV[1]}", ReturnType.MULTI, 1, "foo", "bar")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"foo", "bar"} )}), actual); + List result = (List) getResults().get(0); + assertEquals(Arrays.asList(new Object[] { "foo", "bar" }), Arrays.asList(new Object[] { + new String(result.get(0)), new String(result.get(1)) })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayNumbers() { actual.add(connection.eval("return {1,2}", ReturnType.MULTI, 1, "foo", "bar")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {1l, 2l} )}), actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l, 2l }) })); } + @SuppressWarnings("unchecked") @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayOKs() { - actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", + actual.add(connection.eval( + "return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", ReturnType.MULTI, 0)); - assertEquals(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"OK", "OK"} )}), convertResults(false)); + List result = (List) getResults().get(0); + assertEquals(Arrays.asList(new Object[] { "OK", "OK" }), Arrays.asList(new Object[] { + new String(result.get(0)), new String(result.get(1)) })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayFalses() { actual.add(connection.eval("return { false, false}", ReturnType.MULTI, 0)); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {null, null} )}), actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { null, null }) })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayTrues() { - actual.add(connection.eval("return { true, true}", ReturnType.MULTI,0)); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {1l, 1l} )}), actual); + actual.add(connection.eval("return { true, true}", ReturnType.MULTI, 0)); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { 1l, 1l }) })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testScriptExists() { + getResults(); String sha1 = connection.scriptLoad("return 'foo'"); + initConnection(); actual.add(connection.scriptExists(sha1, "98777234")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {true, false})}), actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { true, false }) })); } @Test @IfProfileValue(name = "runLongTests", value = "true") - public void testScriptKill() throws Exception{ + public void testScriptKill() throws Exception { getResults(); assumeTrue(RedisVersionUtils.atLeast("2.6", byteConnection)); initConnection(); @@ -277,8 +302,9 @@ public abstract class AbstractConnectionIntegrationTests { DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( connectionFactory.getConnection()); try { - conn2.eval("local time=1 while time < 10000000000 do time=time+1 end", ReturnType.BOOLEAN, 0); - }catch(DataAccessException e) { + conn2.eval("local time=1 while time < 10000000000 do time=time+1 end", + ReturnType.BOOLEAN, 0); + } catch (DataAccessException e) { scriptDead.set(true); } conn2.close(); @@ -298,10 +324,12 @@ public abstract class AbstractConnectionIntegrationTests { @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testScriptFlush() { + getResults(); String sha1 = connection.scriptLoad("return KEYS[1]"); connection.scriptFlush(); + initConnection(); actual.add(connection.scriptExists(sha1)); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { false })}), actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { false }) })); } @Test @@ -312,15 +340,16 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.persist("exp3")); Thread.sleep(1500); actual.add(connection.exists("exp3")); - verifyResults(Arrays.asList(new Object[] { true, true, true }), actual); + verifyResults(Arrays.asList(new Object[] { true, true, true })); } @Test @IfProfileValue(name = "runLongTests", value = "true") public void testSetEx() throws Exception { connection.setEx("expy", 1l, "yep"); - assertEquals("yep", connection.get("expy")); - assertTrue(waitFor(new KeyExpired("expy"), 3000l)); + actual.add(connection.get("expy")); + verifyResults(Arrays.asList(new Object[] { "yep" })); + assertTrue(waitFor(new KeyExpired("expy"), 2500l)); } @Test @@ -328,7 +357,7 @@ public abstract class AbstractConnectionIntegrationTests { public void testBRPopTimeout() throws Exception { actual.add(connection.bRPop(1, "alist")); Thread.sleep(1500l); - verifyResults(Arrays.asList(new Object[] { null }), actual); + verifyResults(Arrays.asList(new Object[] { null })); } @Test @@ -336,7 +365,7 @@ public abstract class AbstractConnectionIntegrationTests { public void testBLPopTimeout() throws Exception { actual.add(connection.bLPop(1, "alist")); Thread.sleep(1500l); - verifyResults(Arrays.asList(new Object[] { null }), actual); + verifyResults(Arrays.asList(new Object[] { null })); } @Test @@ -344,7 +373,7 @@ public abstract class AbstractConnectionIntegrationTests { public void testBRPopLPushTimeout() throws Exception { actual.add(connection.bRPopLPush(1, "alist", "foo")); Thread.sleep(1500l); - verifyResults(Arrays.asList(new Object[] { null }), actual); + verifyResults(Arrays.asList(new Object[] { null })); } @Test @@ -353,26 +382,13 @@ public abstract class AbstractConnectionIntegrationTests { String value = "blabla"; connection.set(key.getBytes(), value.getBytes()); actual.add(connection.get(key)); - verifyResults(new ArrayList(Collections.singletonList(value)), actual); - } - - @Test - public void testByteValue() { - String value = UUID.randomUUID().toString(); - Person person = new Person(value, value, 1, new Address(value, 2)); - String key = getClass() + ":byteValue"; - byte[] rawKey = stringSerializer.serialize(key); - - connection.set(rawKey, serializer.serialize(person)); - byte[] rawValue = connection.get(rawKey); - assertNotNull(rawValue); - assertEquals(person, serializer.deserialize(rawValue)); + verifyResults(new ArrayList(Collections.singletonList(value))); } @Test public void testPingPong() throws Exception { actual.add(connection.ping()); - verifyResults(new ArrayList(Collections.singletonList("PONG")), actual); + verifyResults(new ArrayList(Collections.singletonList("PONG"))); } @Test @@ -382,7 +398,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.setBit(key, 1, true); actual.add(connection.getBit(key, 0)); actual.add(connection.getBit(key, 1)); - verifyResults(Arrays.asList(new Object[] { false, true }), actual); + verifyResults(Arrays.asList(new Object[] { false, true })); } @Test @@ -393,7 +409,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.setBit(key, 1, true); connection.setBit(key, 2, true); actual.add(connection.bitCount(key)); - verifyResults(new ArrayList(Collections.singletonList(2l)), actual); + verifyResults(new ArrayList(Collections.singletonList(2l))); } @Test @@ -401,14 +417,14 @@ public abstract class AbstractConnectionIntegrationTests { public void testBitCountInterval() { connection.set("mykey", "foobar"); actual.add(connection.bitCount("mykey", 1, 1)); - verifyResults(new ArrayList(Collections.singletonList(6l)), actual); + verifyResults(new ArrayList(Collections.singletonList(6l))); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testBitCountNonExistentKey() { actual.add(connection.bitCount("mykey")); - verifyResults(new ArrayList(Collections.singletonList(0l)), actual); + verifyResults(new ArrayList(Collections.singletonList(0l))); } @Test @@ -418,7 +434,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("key2", "bar"); actual.add(connection.bitOp(BitOperation.AND, "key3", "key1", "key2")); actual.add(connection.get("key3")); - verifyResults(Arrays.asList(new Object[] { 3l, "bab" }), actual); + verifyResults(Arrays.asList(new Object[] { 3l, "bab" })); } @Test @@ -428,7 +444,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("key2", "ugh"); actual.add(connection.bitOp(BitOperation.OR, "key3", "key1", "key2")); actual.add(connection.get("key3")); - verifyResults(Arrays.asList(new Object[] { 3l, "woo" }), actual); + verifyResults(Arrays.asList(new Object[] { 3l, "woo" })); } @Test @@ -437,7 +453,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("key1", "abcd"); connection.set("key2", "efgh"); actual.add(connection.bitOp(BitOperation.XOR, "key3", "key1", "key2")); - verifyResults(Arrays.asList(new Object[] { 4l }), actual); + verifyResults(Arrays.asList(new Object[] { 4l })); } @Test @@ -445,21 +461,23 @@ public abstract class AbstractConnectionIntegrationTests { public void testBitOpNot() { connection.set("key1", "abcd"); actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1")); - verifyResults(Arrays.asList(new Object[] { 4l }), actual); + verifyResults(Arrays.asList(new Object[] { 4l })); } - @Test(expected=RedisSystemException.class) + @Test(expected = RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testBitOpNotMultipleSources() { connection.set("key1", "abcd"); connection.set("key2", "efgh"); actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); + getResults(); } @Test public void testInfo() throws Exception { - Properties info = connection.info(); - assertNotNull(info); + actual.add(connection.info()); + List results = getResults(); + Properties info = (Properties) results.get(0); assertTrue("at least 5 settings should be present", info.size() >= 5); String version = info.getProperty("redis_version"); assertNotNull(version); @@ -468,8 +486,9 @@ public abstract class AbstractConnectionIntegrationTests { @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testInfoBySection() throws Exception { - Properties info = connection.info("server"); - assertNotNull(info); + actual.add(connection.info("server")); + List results = getResults(); + Properties info = (Properties) results.get(0); assertTrue("at least 5 settings should be present", info.size() >= 5); String version = info.getProperty("redis_version"); assertNotNull(version); @@ -526,14 +545,20 @@ public abstract class AbstractConnectionIntegrationTests { public void testNullSerialization() throws Exception { String[] keys = new String[] { "~", "[" }; actual.add(connection.mGet(keys)); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { null, null }) }), - actual); - + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { null, null }) })); StringRedisTemplate stringTemplate = new StringRedisTemplate(connectionFactory); List multiGet = stringTemplate.opsForValue().multiGet(Arrays.asList(keys)); assertEquals(Arrays.asList(new String[] { null, null }), multiGet); } + @Test + public void testAppend() { + connection.set("a", "b"); + actual.add(connection.append("a", "c")); + actual.add(connection.get("a")); + verifyResults(Arrays.asList(new Object[] { 2l, "bc" })); + } + @Test public void testPubSubWithNamedChannels() throws Exception { final String expectedChannel = "channel1"; @@ -634,28 +659,37 @@ public abstract class AbstractConnectionIntegrationTests { @Test(expected = DataAccessException.class) public void exceptionExecuteNative() throws Exception { + connection.execute("set", "foo"); connection.execute("ZadD", getClass() + "#foo\t0.90\titem"); + getResults(); } @Test public void testExecute() { connection.set("foo", "bar"); - assertEquals("bar", stringSerializer.deserialize((byte[])connection.execute("GET", "foo"))); + actual.add(connection.execute("GET", "foo")); + assertEquals("bar", stringSerializer.deserialize((byte[]) getResults().get(0))); } @Test public void testExecuteNoArgs() { - assertEquals("PONG", stringSerializer.deserialize((byte[])connection.execute("PING"))); + actual.add(connection.execute("PING")); + List results = getResults(); + assertEquals("PONG", stringSerializer.deserialize((byte[])results.get(0))); } + @SuppressWarnings("unchecked") @Test public void testMultiExec() throws Exception { connection.multi(); connection.set("key", "value"); - assertNull(connection.get("key")); - List results = connection.exec(); - assertEquals(2, results.size()); - assertEquals("value", new String((byte[]) results.get(1))); + actual.add(connection.get("key")); + actual.add(connection.exec()); + List results = getResults(); + assertNull(results.get(0)); + List execResults = (List) results.get(1); + assertEquals(2, execResults.size()); + assertEquals("value", new String((byte[]) execResults.get(1))); assertEquals("value", connection.get("key")); } @@ -668,11 +702,16 @@ public abstract class AbstractConnectionIntegrationTests { @Test public void testMultiDiscard() throws Exception { - connection.set("testitnow", "willdo"); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.set("testitnow", "willdo"); connection.multi(); - connection.set("testitnow", "notok"); + connection.set("testitnow2", "notok"); connection.discard(); - assertEquals("willdo", connection.get("testitnow")); + actual.add(connection.get("testitnow")); + List results = getResults(); + assertEquals(Arrays.asList(new String[] { "willdo" }), results); + initConnection(); // Ensure we can run a new tx after discarding previous one testMultiExec(); } @@ -689,9 +728,10 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("testitnow", "somethingelse"); actual.add(connection.exec()); actual.add(connection.get("testitnow")); - verifyResults(Arrays.asList(new Object[] { null, "something" }), actual); + verifyResults(Arrays.asList(new Object[] { null, "something" })); } + @SuppressWarnings("unchecked") @Test public void testUnwatch() throws Exception { connection.set("testitnow", "willdo"); @@ -702,8 +742,12 @@ public abstract class AbstractConnectionIntegrationTests { connectionFactory.getConnection()); conn2.set("testitnow", "something"); connection.set("testitnow", "somethingelse"); - assertNotNull(connection.exec()); - assertEquals("somethingelse", connection.get("testitnow")); + actual.add(connection.get("testitnow")); + actual.add(connection.exec()); + List results = getResults(); + assertNull(results.get(0)); + List execResults = (List) results.get(1); + assertEquals("somethingelse", new String((byte[]) execResults.get(1))); } @Test @@ -714,7 +758,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sort("sortlist", new DefaultSortParameters(null, Order.ASC, true))); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, - Arrays.asList(new String[] { "bar", "baz", "foo" }) }), actual); + Arrays.asList(new String[] { "bar", "baz", "foo" }) })); } @Test @@ -727,7 +771,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lRange("newlist", 0, 9)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, 3l, - Arrays.asList(new String[] { "bar", "baz", "foo" }) }), actual); + Arrays.asList(new String[] { "bar", "baz", "foo" }) })); } @Test @@ -738,7 +782,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sort("sortlist", null)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, - Arrays.asList(new String[] { "2", "3", "5" }) }), actual); + Arrays.asList(new String[] { "2", "3", "5" }) })); } @Test @@ -750,59 +794,35 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lRange("newlist", 0, 9)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, 3l, - Arrays.asList(new String[] { "3", "5", "9" }) }), actual); + Arrays.asList(new String[] { "3", "5", "9" }) })); } @Test public void testDbSize() { connection.set("dbparam", "foo"); - assertTrue(connection.dbSize() > 0); - } - - @Test - public void testLLen() { - actual.add(connection.rPush("PopList", "hello")); - actual.add(connection.rPush("PopList", "big")); - actual.add(connection.rPush("PopList", "world")); - actual.add(connection.rPush("PopList", "hello")); - actual.add(connection.lLen("PopList")); - verifyResults( - Arrays.asList(new Object[] { 1l, 2l, 3l, 4l, 4l }), actual); - } - - @Test - public void testDel() { - connection.set("testing","123"); - actual.add(connection.del("testing")); - actual.add(connection.exists("testing")); - verifyResults(Arrays.asList(new Object[] { 1l, false }), actual); - } - - @Test - public void testAppend() { - connection.set("a", "b"); - actual.add(connection.append("a", "c")); - actual.add(connection.get("a")); - verifyResults(Arrays.asList(new Object[] { 2l, "bc" }), actual); + actual.add(connection.dbSize()); + assertTrue((Long) getResults().get(0) > 0); } @Test public void testFlushDb() { connection.flushDb(); actual.add(connection.dbSize()); - verifyResults(Arrays.asList(new Object[] { 0l }), actual); + verifyResults(Arrays.asList(new Object[] { 0l })); } + @SuppressWarnings("unchecked") @Test public void testGetConfig() { - List config = connection.getConfig("*"); + actual.add(connection.getConfig("*")); + List config = (List) getResults().get(0); assertTrue(!config.isEmpty()); } @Test public void testEcho() { actual.add(connection.echo("Hello World")); - verifyResults(Arrays.asList(new Object[] { "Hello World" }), actual); + verifyResults(Arrays.asList(new Object[] { "Hello World" })); } @Test @@ -810,19 +830,23 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("existent", "true"); actual.add(connection.exists("existent")); actual.add(connection.exists("nonexistent")); - verifyResults(Arrays.asList(new Object[] { true, false }), actual); + verifyResults(Arrays.asList(new Object[] { true, false })); } + @SuppressWarnings("unchecked") @Test public void testKeys() throws Exception { connection.set("keytest", "true"); - assertTrue(connection.keys("key*").contains("keytest")); + actual.add(connection.keys("key*")); + assertTrue(((Collection) getResults().get(0)).contains("keytest")); } @Test public void testRandomKey() { connection.set("some", "thing"); - assertNotNull(connection.randomKey()); + actual.add(connection.randomKey()); + List results = getResults(); + assertNotNull(results.get(0)); } @Test @@ -831,7 +855,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.rename("renametest", "newrenametest"); actual.add(connection.get("newrenametest")); actual.add(connection.exists("renametest")); - verifyResults(Arrays.asList(new Object[] { "testit", false }), actual); + verifyResults(Arrays.asList(new Object[] { "testit", false })); } @Test @@ -840,14 +864,14 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.renameNX("nxtest", "newnxtest")); actual.add(connection.get("newnxtest")); actual.add(connection.exists("nxtest")); - verifyResults(Arrays.asList(new Object[] { true, "testit", false }), actual); + verifyResults(Arrays.asList(new Object[] { true, "testit", false })); } @Test public void testTtl() { connection.set("whatup", "yo"); actual.add(connection.ttl("whatup")); - verifyResults(Arrays.asList(new Object[] { -1L }), actual); + verifyResults(Arrays.asList(new Object[] { -1L })); } @Test @@ -855,68 +879,86 @@ public abstract class AbstractConnectionIntegrationTests { public void testPTtlNoExpire() { connection.set("whatup", "yo"); actual.add(connection.pTtl("whatup")); - verifyResults(Arrays.asList(new Object[] { -1L }), actual); + verifyResults(Arrays.asList(new Object[] { -1L })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testPTtl() { connection.set("whatup", "yo"); - connection.pExpire("whatup", 9000l); - assertTrue(connection.pTtl("whatup") > -1); + actual.add(connection.pExpire("whatup", 9000l)); + actual.add(connection.pTtl("whatup")); + List results = getResults(); + assertTrue((Long) results.get(1) > -1); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testDumpAndRestore() { connection.set("testing", "12"); - byte[] serializedResults = connection.dump("testing".getBytes()); - assertNotNull(serializedResults); - connection.del("testing"); - assertNull(connection.get("testing")); - connection.restore("testing".getBytes(), 0, serializedResults); - assertEquals("12",connection.get("testing")); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); + actual.add((connection.get("testing"))); + connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); + actual.add(connection.get("testing")); + verifyResults(Arrays.asList(new Object[] { 1l, null, "12" })); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testDumpNonExistentKey() { actual.add(connection.dump("fakey".getBytes())); - verifyResults(Arrays.asList(new Object[] { null }), actual); + verifyResults(Arrays.asList(new Object[] { null })); } - @Test(expected=RedisSystemException.class) + @Test(expected = RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreBadData() { // Use something other than dump-specific serialization connection.restore("testing".getBytes(), 0, "foo".getBytes()); + getResults(); } - @Test(expected=RedisSystemException.class) + @Test(expected = RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreExistingKey() { connection.set("testing", "12"); - byte[] serializedResults = connection.dump("testing".getBytes()); - assertNotNull(serializedResults); - connection.restore("testing".getBytes(), 0, serializedResults); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + connection.restore("testing".getBytes(), 0, (byte[]) results.get(0)); + getResults(); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreTtl() { connection.set("testing", "12"); - byte[] serializedResults = connection.dump("testing".getBytes()); - assertNotNull(serializedResults); - connection.del("testing"); - assertNull(connection.get("testing")); - connection.restore("testing".getBytes(), 100l, serializedResults); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); + actual.add(connection.get("testing")); + connection.restore("testing".getBytes(), 100l, (byte[]) results.get(0)); + verifyResults(Arrays.asList(new Object[] { 1l, null })); assertTrue(waitFor(new KeyExpired("testing"), 300l)); } + @Test + public void testDel() { + connection.set("testing","123"); + actual.add(connection.del("testing")); + actual.add(connection.exists("testing")); + verifyResults(Arrays.asList(new Object[] { 1l, false })); + } + @Test public void testType() { connection.set("something", "yo"); - assertEquals(DataType.STRING, connection.type("something")); + actual.add(connection.type("something")); + verifyResults(Arrays.asList(new Object[] { DataType.STRING })); } @Test @@ -924,7 +966,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("testGS", "1"); actual.add(connection.getSet("testGS", "2")); actual.add(connection.get("testGS")); - verifyResults(Arrays.asList(new Object[] { "1", "2" }), actual); + verifyResults(Arrays.asList(new Object[] { "1", "2" })); } @Test @@ -934,9 +976,7 @@ public abstract class AbstractConnectionIntegrationTests { vals.put("size", "1"); connection.mSetString(vals); actual.add(connection.mGet("color", "size")); - verifyResults( - Arrays.asList(new Object[] { Arrays.asList(new String[] { "orange", "1" }) }), - actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { "orange", "1" }) })); } @Test @@ -946,8 +986,7 @@ public abstract class AbstractConnectionIntegrationTests { vals.put("width", "1"); actual.add(connection.mSetNXString(vals)); actual.add(connection.mGet("height", "width")); - verifyResults(Arrays.asList(new Object[] { true, Arrays.asList(new String[] { "5", "1" }) }), - actual); + verifyResults(Arrays.asList(new Object[] { true, Arrays.asList(new String[] { "5", "1" }) })); } @Test @@ -958,8 +997,7 @@ public abstract class AbstractConnectionIntegrationTests { vals.put("width", "1"); actual.add(connection.mSetNXString(vals)); actual.add(connection.mGet("height", "width")); - verifyResults(Arrays.asList(new Object[] { false, Arrays.asList(new String[] { "2", null }) }), - actual); + verifyResults(Arrays.asList(new Object[] { false, Arrays.asList(new String[] { "2", null }) })); } @Test @@ -968,7 +1006,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.get("notaround")); actual.add(connection.setNX("notaround", "55")); actual.add(connection.get("notaround")); - verifyResults(Arrays.asList(new Object[] { true, "54", false, "54" }), actual); + verifyResults(Arrays.asList(new Object[] { true, "54", false, "54" })); } @Test @@ -977,7 +1015,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.getRange("rangekey", 0l, 2l)); connection.setRange("rangekey", "ck", 2); actual.add(connection.get("rangekey")); - verifyResults(Arrays.asList(new Object[] { "sup", "suckrcalifrag" }), actual); + verifyResults(Arrays.asList(new Object[] { "sup", "suckrcalifrag" })); } @Test @@ -985,7 +1023,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("tdb", "4"); actual.add(connection.decrBy("tdb", 3l)); actual.add(connection.incrBy("tdb", 7l)); - verifyResults(Arrays.asList(new Object[] { 1l, 8l }), actual); + verifyResults(Arrays.asList(new Object[] { 1l, 8l })); } @Test @@ -994,7 +1032,32 @@ public abstract class AbstractConnectionIntegrationTests { connection.set("tdb", "4.5"); actual.add(connection.incrBy("tdb", 7.2)); actual.add(connection.get("tdb")); - verifyResults(Arrays.asList(new Object[] { 11.7d, "11.7" }), actual); + verifyResults(Arrays.asList(new Object[] { 11.7d, "11.7" })); + } + + @Test + public void testIncrDecrByLong() { + String key = "test.count"; + long largeNumber = 0x123456789L; // > 32bits + connection.set(key, "0"); + actual.add(connection.incrBy(key, largeNumber)); + actual.add(connection.decrBy(key, largeNumber)); + actual.add(connection.decrBy(key, 2 * largeNumber)); + verifyResults(Arrays.asList(new Object[] {largeNumber, 0l, -2 * largeNumber})); + } + + @Test + public void testHashIncrDecrByLong() { + String key = "test.hcount"; + String hkey = "hashkey"; + + long largeNumber = 0x123456789L; // > 32bits + actual.add(connection.hSet(key, hkey, "0")); + actual.add(connection.hIncrBy(key, hkey, largeNumber)); + //assertEquals(largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); + actual.add(connection.hIncrBy(key, hkey, -2 * largeNumber)); + //assertEquals(-largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); + verifyResults(Arrays.asList(new Object[] {true, largeNumber, -largeNumber})); } @Test @@ -1004,36 +1067,40 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.get("incrtest")); actual.add(connection.decr("incrtest")); actual.add(connection.get("incrtest")); - verifyResults(Arrays.asList(new Object[] { 1l, "1", 0l, "0" }), actual); + verifyResults(Arrays.asList(new Object[] { 1l, "1", 0l, "0" })); } @Test public void testStrLen() { connection.set("strlentest", "cat"); actual.add(connection.strLen("strlentest")); - verifyResults(Arrays.asList(new Object[] { 3l }), actual); + verifyResults(Arrays.asList(new Object[] { 3l })); } // List operations @Test public void testBLPop() { - actual.add(connection.lPush("poplist", "foo")); - actual.add(connection.lPush("poplist", "bar")); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.lPush("poplist", "foo"); + conn2.lPush("poplist", "bar"); actual.add(connection.bLPop(100, "poplist", "otherlist")); verifyResults( - Arrays.asList(new Object[] { 1l, 2l, - Arrays.asList(new String[] { "poplist", "bar" }) }), actual); + Arrays.asList(new Object[] { + Arrays.asList(new String[] { "poplist", "bar" }) })); } @Test public void testBRPop() { - actual.add(connection.rPush("rpoplist", "bar")); - actual.add(connection.rPush("rpoplist", "foo")); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.rPush("rpoplist", "bar"); + conn2.rPush("rpoplist", "foo"); actual.add(connection.bRPop(1, "rpoplist")); verifyResults( - Arrays.asList(new Object[] { 1l, 2l, - Arrays.asList(new String[] { "rpoplist", "foo" }) }), actual); + Arrays.asList(new Object[] { + Arrays.asList(new String[] { "rpoplist", "foo" }) })); } @Test @@ -1047,7 +1114,7 @@ public abstract class AbstractConnectionIntegrationTests { verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, Arrays.asList(new String[] { "hello", "big", "world" }), 4l, - Arrays.asList(new String[] { "hello", "very", "big", "world" }) }), actual); + Arrays.asList(new String[] { "hello", "very", "big", "world" }) })); } @Test @@ -1055,7 +1122,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.lPop("PopList")); - verifyResults(Arrays.asList(new Object[] { 1l, 2l, "hello" }), actual); + verifyResults(Arrays.asList(new Object[] { 1l, 2l, "hello" })); } @Test @@ -1068,7 +1135,18 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lRange("PopList", 0, -1)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, 4l, 2l, - Arrays.asList(new String[] { "big", "world" }) }), actual); + Arrays.asList(new String[] { "big", "world" }) })); + } + + @Test + public void testLLen() { + actual.add(connection.rPush("PopList", "hello")); + actual.add(connection.rPush("PopList", "big")); + actual.add(connection.rPush("PopList", "world")); + actual.add(connection.rPush("PopList", "hello")); + actual.add(connection.lLen("PopList")); + verifyResults( + Arrays.asList(new Object[] { 1l, 2l, 3l, 4l, 4l })); } @Test @@ -1080,7 +1158,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lRange("PopList", 0, -1)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, - Arrays.asList(new String[] { "hello", "cruel", "world" }) }), actual); + Arrays.asList(new String[] { "hello", "cruel", "world" }) })); } @Test @@ -1092,7 +1170,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lRange("PopList", 0, -1)); verifyResults( Arrays.asList(new Object[] { 1l, 2l, 3l, - Arrays.asList(new String[] { "big", "world" }) }), actual); + Arrays.asList(new String[] { "big", "world" }) })); } @Test @@ -1100,7 +1178,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.rPush("PopList", "hello")); actual.add(connection.rPush("PopList", "world")); actual.add(connection.rPop("PopList")); - verifyResults(Arrays.asList(new Object[] { 1l, 2l, "world" }), actual); + verifyResults(Arrays.asList(new Object[] { 1l, 2l, "world" })); } @Test @@ -1114,22 +1192,23 @@ public abstract class AbstractConnectionIntegrationTests { verifyResults( Arrays.asList(new Object[] { 1l, 2l, 1l, "world", Arrays.asList(new String[] { "hello" }), - Arrays.asList(new String[] { "world", "hey" }) }), actual); + Arrays.asList(new String[] { "world", "hey" }) })); } @Test public void testBRPopLPush() { - actual.add(connection.rPush("PopList", "hello")); - actual.add(connection.rPush("PopList", "world")); - actual.add(connection.rPush("pop2", "hey")); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.rPush("PopList", "hello"); + conn2.rPush("PopList", "world"); + conn2.rPush("pop2", "hey"); actual.add(connection.bRPopLPush(1, "PopList", "pop2")); - actual.add(connection.lRange("PopList", 0, -1)); - actual.add(connection.lRange("pop2", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 2l, 1l, "world", - Arrays.asList(new String[] { "hello" }), - Arrays.asList(new String[] { "world", "hey" }) }), actual); + List results = getResults(); + assertEquals(Arrays.asList(new String[] { "world" }), results); + assertEquals(Arrays.asList(new String[] { "hello" }), connection.lRange("PopList", 0, -1)); + assertEquals(Arrays.asList(new String[] { "world", "hey" }), + connection.lRange("pop2", 0, -1)); } @Test @@ -1137,9 +1216,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.rPush("mylist", "hi")); actual.add(connection.lPushX("mylist", "foo")); actual.add(connection.lRange("mylist", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 2l, Arrays.asList(new String[] { "foo", "hi" }) }), - actual); + verifyResults(Arrays.asList(new Object[] { 1l, 2l, Arrays.asList(new String[] { "foo", "hi" }) })); } @Test @@ -1147,16 +1224,14 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.rPush("mylist", "hi")); actual.add(connection.rPushX("mylist", "foo")); actual.add(connection.lRange("mylist", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 2l, Arrays.asList(new String[] { "hi", "foo" }) }), - actual); + verifyResults(Arrays.asList(new Object[] { 1l, 2l, Arrays.asList(new String[] { "hi", "foo" }) })); } @Test public void testLIndex() { actual.add(connection.lPush("testylist", "foo")); actual.add(connection.lIndex("testylist", 0)); - verifyResults(Arrays.asList(new Object[] { 1l, "foo" }), actual); + verifyResults(Arrays.asList(new Object[] { 1l, "foo" })); } @Test @@ -1165,102 +1240,113 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.lPush("testlist", "baz")); actual.add(connection.lRange("testlist", 0, -1)); verifyResults(Arrays.asList(new Object[] { 1l, 2l, - Arrays.asList(new String[] { "baz", "bar" }) }), actual); + Arrays.asList(new String[] { "baz", "bar" }) })); } // Set operations @Test public void testSAdd() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertEquals(new HashSet(Arrays.asList(new String[] { "foo", "bar" })), - connection.sMembers("myset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sMembers("myset")); + verifyResults(Arrays.asList(new Object[] { true, true, new HashSet(Arrays.asList(new String[] { "foo", "bar" })) })); } @Test public void testSCard() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertEquals(Long.valueOf(2), connection.sCard("myset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sCard("myset")); + verifyResults(Arrays.asList(new Object[] { true, true, 2l })); } @Test public void testSDiff() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - assertEquals(new HashSet(Collections.singletonList("foo")), - connection.sDiff("myset", "otherset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sDiff("myset", "otherset")); + verifyResults( + Arrays.asList(new Object[] { true, true, true, + new HashSet(Collections.singletonList("foo")) })); } @Test public void testSDiffStore() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - connection.sDiffStore("thirdset", "myset", "otherset"); - assertEquals(new HashSet(Collections.singletonList("foo")), - connection.sMembers("thirdset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sDiffStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + verifyResults( + Arrays.asList(new Object[] { true, true, true, 1l, + new HashSet(Collections.singletonList("foo")) })); } @Test public void testSInter() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - assertEquals(new HashSet(Collections.singletonList("bar")), - connection.sInter("myset", "otherset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sInter("myset", "otherset")); + verifyResults( + Arrays.asList(new Object[] { true, true, true, + new HashSet(Collections.singletonList("bar")) })); } @Test public void testSInterStore() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - connection.sInterStore("thirdset", "myset", "otherset"); - assertEquals(new HashSet(Collections.singletonList("bar")), - connection.sMembers("thirdset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sInterStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + verifyResults( + Arrays.asList(new Object[] { true, true, true, 1l, + new HashSet(Collections.singletonList("bar")) })); } @Test public void testSIsMember() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertTrue(connection.sIsMember("myset", "foo")); - assertFalse(connection.sIsMember("myset", "baz")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sIsMember("myset", "foo")); + actual.add(connection.sIsMember("myset", "baz")); + verifyResults(Arrays.asList(new Object[] { true, true, true, false })); } @Test public void testSMove() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - assertTrue(connection.sMove("myset", "otherset", "foo")); - assertEquals(new HashSet(Arrays.asList(new String[] { "foo", "bar" })), - connection.sMembers("otherset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sMove("myset", "otherset", "foo")); + verifyResults(Arrays.asList(new Object[] { true, true, true, true })); } @Test public void testSPop() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sPop("myset")); assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })) - .contains(connection.sPop("myset"))); + .contains((String) getResults().get(2))); } @Test public void testSRandMember() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sRandMember("myset")); assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })) - .contains(connection.sRandMember("myset"))); + .contains((String) getResults().get(2))); } @Test public void testSRandMemberKeyNotExists() { actual.add(connection.sRandMember("notexist")); - assertNull(convertResults().get(0)); + assertNull(getResults().get(0)); } @SuppressWarnings("rawtypes") @@ -1271,7 +1357,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.sAdd("myset", "bar")); actual.add(connection.sAdd("myset", "baz")); actual.add(connection.sRandMember("myset", 2)); - assertTrue(((Collection)convertResults().get(3)).size() == 2); + assertTrue(((Collection) getResults().get(3)).size() == 2); } @SuppressWarnings("rawtypes") @@ -1280,7 +1366,7 @@ public abstract class AbstractConnectionIntegrationTests { public void testSRandMemberCountNegative() { actual.add(connection.sAdd("myset", "foo")); actual.add(connection.sRandMember("myset", -2)); - assertEquals(Arrays.asList(new String[] {"foo", "foo"}), (List)convertResults().get(1)); + assertEquals(Arrays.asList(new String[] { "foo", "foo" }), (List) getResults().get(1)); } @SuppressWarnings("rawtypes") @@ -1288,295 +1374,345 @@ public abstract class AbstractConnectionIntegrationTests { @IfProfileValue(name = "redisVersion", value = "2.6") public void testSRandMemberCountKeyNotExists() { actual.add(connection.sRandMember("notexist", 2)); - assertTrue(((Collection)convertResults().get(0)).isEmpty()); + assertTrue(((Collection) getResults().get(0)).isEmpty()); } @Test public void testSRem() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertTrue(connection.sRem("myset", "foo")); - assertFalse(connection.sRem("myset", "baz")); - assertEquals(new HashSet(Collections.singletonList("bar")), - connection.sMembers("myset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sRem("myset", "foo")); + actual.add(connection.sRem("myset", "baz")); + actual.add(connection.sMembers("myset")); + verifyResults( + Arrays.asList(new Object[] { true, true, true, false, + new HashSet(Collections.singletonList("bar")) })); } @Test public void testSUnion() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - connection.sAdd("otherset", "baz"); - assertEquals(new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })), - connection.sUnion("myset", "otherset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sAdd("otherset", "baz")); + actual.add(connection.sUnion("myset", "otherset")); + verifyResults(Arrays.asList(new Object[] { true, true, true, true, + new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); } @Test public void testSUnionStore() { - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - connection.sAdd("otherset", "bar"); - connection.sAdd("otherset", "baz"); - connection.sUnionStore("thirdset", "myset", "otherset"); - assertEquals(new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })), - connection.sMembers("thirdset")); + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sAdd("otherset", "baz")); + actual.add(connection.sUnionStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + verifyResults(Arrays.asList(new Object[] { true, true, true, true, 3l, + new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); } // ZSet @Test public void testZAddAndZRange() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob" })), - connection.zRange("myset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRange("myset", 0, -1)); + verifyResults(Arrays.asList(new Object[] { true, true, new LinkedHashSet(Arrays.asList(new String[] { "James", "Bob" })) })); } @Test public void testZCard() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(Long.valueOf(2), connection.zCard("myset")); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zCard("myset")); + verifyResults(Arrays.asList(new Object[] { true, true, 2l })); } @Test public void testZCount() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 4, "Joe"); - assertEquals(Long.valueOf(2), connection.zCount("myset", 1, 2)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 4, "Joe")); + actual.add(connection.zCount("myset", 1, 2)); + verifyResults(Arrays.asList(new Object[] { true, true, true, 2l })); } @Test public void testZIncrBy() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 4, "Joe"); - connection.zIncrBy("myset", 2, "Joe"); - assertEquals(new LinkedHashSet(Collections.singletonList("Joe")), - connection.zRangeByScore("myset", 6, 6)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 4, "Joe")); + actual.add(connection.zIncrBy("myset", 2, "Joe")); + actual.add(connection.zRangeByScore("myset", 6, 6)); + verifyResults( + Arrays.asList(new Object[] { true, true, true, 6d, + new LinkedHashSet(Collections.singletonList("Joe")) })); } @Test public void testZInterStore() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 4, "Joe"); - connection.zAdd("otherset", 1, "Bob"); - connection.zAdd("otherset", 4, "James"); - assertEquals(Long.valueOf(2), connection.zInterStore("thirdset", "myset", "otherset")); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })), - connection.zRange("thirdset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 4, "Joe")); + actual.add(connection.zAdd("otherset", 1, "Bob")); + actual.add(connection.zAdd("otherset", 4, "James")); + actual.add(connection.zInterStore("thirdset", "myset", "otherset")); + actual.add(connection.zRange("thirdset", 0, -1)); + verifyResults(Arrays.asList(new Object[] { true, true, true, true, true, 2l, + new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); } @Test public void testZInterStoreAggWeights() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 4, "Joe"); - connection.zAdd("otherset", 1, "Bob"); - connection.zAdd("otherset", 4, "James"); - assertEquals(Long.valueOf(2), connection.zInterStore("thirdset", Aggregate.MAX, new int[] { - 2, 3 }, "myset", "otherset")); - assertEquals( - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("James".getBytes(), "James", 12d) })), - connection.zRangeWithScores("thirdset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 4, "Joe")); + actual.add(connection.zAdd("otherset", 1, "Bob")); + actual.add(connection.zAdd("otherset", 4, "James")); + actual.add(connection.zInterStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", + "otherset")); + + actual.add(connection.zRangeWithScores("thirdset", 0, -1)); + verifyResults( + Arrays.asList(new Object[] { + true, + true, + true, + true, + true, + 2l, + new LinkedHashSet(Arrays.asList(new StringTuple[] { + new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), + new DefaultStringTuple("James".getBytes(), "James", 12d) })) })); } @Test public void testZRangeWithScores() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals( - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("James".getBytes(), "James", 1d), - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })), - connection.zRangeWithScores("myset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRangeWithScores("myset", 0, -1)); + verifyResults( + Arrays.asList(new Object[] { + true, + true, + new LinkedHashSet(Arrays.asList(new StringTuple[] { + new DefaultStringTuple("James".getBytes(), "James", 1d), + new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) })) })); } @Test public void testZRangeByScore() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "James" })), - connection.zRangeByScore("myset", 1, 1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRangeByScore("myset", 1, 1)); + verifyResults(Arrays.asList(new Object[] { true, true, + new LinkedHashSet(Arrays.asList(new String[] { "James" })) })); } @Test public void testZRangeByScoreOffsetCount() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob" })), - connection.zRangeByScore("myset", 1d, 3d, 1, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRangeByScore("myset", 1d, 3d, 1, -1)); + verifyResults( + Arrays.asList(new Object[] { true, true, + new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test public void testZRangeByScoreWithScores() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals( - new LinkedHashSet( - Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), - "Bob", 2d) })), connection.zRangeByScoreWithScores("myset", 2d, 5d)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRangeByScoreWithScores("myset", 2d, 5d)); + verifyResults(Arrays.asList(new Object[] { + true, + true, + new LinkedHashSet(Arrays + .asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), "Bob", + 2d) })) })); } @Test public void testZRangeByScoreWithScoresOffsetCount() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals( - new LinkedHashSet( - Arrays.asList(new StringTuple[] { new DefaultStringTuple( - "James".getBytes(), "James", 1d) })), - connection.zRangeByScoreWithScores("myset", 1d, 5d, 0, 1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRangeByScoreWithScores("myset", 1d, 5d, 0, 1)); + verifyResults(Arrays.asList(new Object[] { + true, + true, + new LinkedHashSet(Arrays + .asList(new StringTuple[] { new DefaultStringTuple("James".getBytes(), + "James", 1d) })) })); } @Test public void testZRevRange() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })), - connection.zRevRange("myset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRevRange("myset", 0, -1)); + verifyResults(Arrays.asList(new Object[] { true, true, + new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })) })); } @Test public void testZRevRangeWithScores() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals( - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d) })), - connection.zRevRangeWithScores("myset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRevRangeWithScores("myset", 0, -1)); + verifyResults( + Arrays.asList(new Object[] { + true, + true, + new LinkedHashSet(Arrays.asList(new StringTuple[] { + new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), + new DefaultStringTuple("James".getBytes(), "James", 1d) })) })); } + @SuppressWarnings("unchecked") @Test public void testZRevRangeByScoreOffsetCount() { - byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes()); - byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes()); - assertEquals( - new LinkedHashSet(Arrays.asList(new String[] { "Bob", - "James" })), SerializationUtils.deserialize( - byteConnection.zRevRangeByScore("myset".getBytes(), 0d, - 3d, 0, 5), stringSerializer)); + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d, 0, 5)); + assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })), + SerializationUtils.deserialize((Set) getResults().get(2), stringSerializer)); } + @SuppressWarnings("unchecked") @Test public void testZRevRangeByScore() { - byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes()); - byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes()); - assertEquals( - new LinkedHashSet(Arrays.asList(new String[] { "Bob", - "James" })), SerializationUtils.deserialize( - byteConnection.zRevRangeByScore("myset".getBytes(), 0d, - 3d), stringSerializer)); + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d)); + assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })), + SerializationUtils.deserialize((Set) getResults().get(2), stringSerializer)); } @Test public void testZRevRangeByScoreWithScoresOffsetCount() { - byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes()); - byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes()); + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScoreWithScores("myset".getBytes(), 0d, 3d, 0, 1)); assertEquals( - new LinkedHashSet( - Arrays.asList(new Tuple[] { new DefaultTuple("Bob" - .getBytes(), 2d) })), - byteConnection.zRevRangeByScoreWithScores("myset".getBytes(), - 0d, 3d, 0, 1)); + new LinkedHashSet(Arrays.asList(new Tuple[] { new DefaultTuple("Bob" + .getBytes(), 2d) })), getResults().get(2)); } @Test public void testZRevRangeByScoreWithScores() { - byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes()); - byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes()); - byteConnection.zAdd("myset".getBytes(), 3, "Joe".getBytes()); + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 3, "Joe".getBytes())); + actual.add(byteConnection.zRevRangeByScoreWithScores("myset".getBytes(), 0d, 2d)); assertEquals( new LinkedHashSet(Arrays.asList(new Tuple[] { new DefaultTuple("Bob".getBytes(), 2d), - new DefaultTuple("James".getBytes(), 1d) })), - byteConnection.zRevRangeByScoreWithScores("myset".getBytes(), - 0d, 2d)); + new DefaultTuple("James".getBytes(), 1d) })), getResults().get(3)); } @Test public void testZRank() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(Long.valueOf(0), connection.zRank("myset", "James")); - assertEquals(Long.valueOf(1), connection.zRank("myset", "Bob")); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRank("myset", "James")); + actual.add(connection.zRank("myset", "Bob")); + verifyResults(Arrays.asList(new Object[] { true, true, 0l, 1l })); } @Test public void testZRem() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertTrue(connection.zRem("myset", "James")); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob" })), - connection.zRange("myset", 0l, -1l)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRem("myset", "James")); + actual.add(connection.zRange("myset", 0l, -1l)); + verifyResults( + Arrays.asList(new Object[] { true, true, true, + new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test public void testZRemRangeByRank() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(Long.valueOf(2), connection.zRemRange("myset", 0l, 3l)); - assertTrue(connection.zRange("myset", 0l, -1l).isEmpty()); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRemRange("myset", 0l, 3l)); + actual.add(connection.zRange("myset", 0l, -1l)); + verifyResults(Arrays.asList(new Object[] { true, true, 2l, new LinkedHashSet(0) })); } @Test public void testZRemRangeByScore() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - assertEquals(Long.valueOf(1), connection.zRemRangeByScore("myset", 0d, 1d)); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob" })), - connection.zRange("myset", 0l, -1l)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRemRangeByScore("myset", 0d, 1d)); + actual.add(connection.zRange("myset", 0l, -1l)); + verifyResults( + Arrays.asList(new Object[] { true, true, 1l, + new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); } @Test public void testZRevRank() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 3, "Joe"); - assertEquals(Long.valueOf(0), connection.zRevRank("myset", "Joe")); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 3, "Joe")); + actual.add(connection.zRevRank("myset", "Joe")); + verifyResults(Arrays.asList(new Object[] { true, true, true, 0l })); } @Test public void testZScore() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 3, "Joe"); - assertEquals(Double.valueOf(3d), connection.zScore("myset", "Joe")); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 3, "Joe")); + actual.add(connection.zScore("myset", "Joe")); + verifyResults(Arrays.asList(new Object[] { true, true, true, 3d })); } @Test public void testZUnionStore() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 5, "Joe"); - connection.zAdd("otherset", 1, "Bob"); - connection.zAdd("otherset", 4, "James"); - assertEquals(Long.valueOf(3), connection.zUnionStore("thirdset", "myset", "otherset")); - assertEquals( - new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James", "Joe" })), - connection.zRange("thirdset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 5, "Joe")); + actual.add(connection.zAdd("otherset", 1, "Bob")); + actual.add(connection.zAdd("otherset", 4, "James")); + actual.add(connection.zUnionStore("thirdset", "myset", "otherset")); + actual.add(connection.zRange("thirdset", 0, -1)); + verifyResults( + Arrays.asList(new Object[] { + true, + true, + true, + true, + true, + 3l, + new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James", + "Joe" })) })); } @Test public void testZUnionStoreAggWeights() { - connection.zAdd("myset", 2, "Bob"); - connection.zAdd("myset", 1, "James"); - connection.zAdd("myset", 4, "Joe"); - connection.zAdd("otherset", 1, "Bob"); - connection.zAdd("otherset", 4, "James"); - assertEquals(Long.valueOf(3), connection.zUnionStore("thirdset", Aggregate.MAX, new int[] { - 2, 3 }, "myset", "otherset")); - assertEquals( - new LinkedHashSet(Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("Joe".getBytes(), "Joe", 8d), - new DefaultStringTuple("James".getBytes(), "James", 12d) })), - connection.zRangeWithScores("thirdset", 0, -1)); + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 4, "Joe")); + actual.add(connection.zAdd("otherset", 1, "Bob")); + actual.add(connection.zAdd("otherset", 4, "James")); + actual.add(connection.zUnionStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", + "otherset")); + actual.add(connection.zRangeWithScores("thirdset", 0, -1)); + verifyResults( + Arrays.asList(new Object[] { + true, + true, + true, + true, + true, + 3l, + new LinkedHashSet(Arrays.asList(new StringTuple[] { + new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), + new DefaultStringTuple("Joe".getBytes(), "Joe", 8d), + new DefaultStringTuple("James".getBytes(), "James", 12d) })) })); } // Hash Ops @@ -1595,7 +1731,7 @@ public abstract class AbstractConnectionIntegrationTests { Map expected = new HashMap(); expected.put(key1, value1); expected.put(key2, value2); - verifyResults(Arrays.asList(new Object[] { true, true, value1, expected }), actual); + verifyResults(Arrays.asList(new Object[] { true, true, value1, expected })); } @Test @@ -1603,15 +1739,16 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hSetNX("myhash", "key1", "foo")); actual.add(connection.hSetNX("myhash", "key1", "bar")); actual.add(connection.hGet("myhash", "key1")); - verifyResults(Arrays.asList(new Object[] { true, false, "foo" }), actual); + verifyResults(Arrays.asList(new Object[] { true, false, "foo" })); } @Test public void testHDel() throws Exception { - connection.hSet("test", "key", "val"); - assertTrue(connection.hDel("test", "key")); - assertFalse(connection.hDel("test", "foo")); - assertFalse(connection.hExists("test", "key")); + actual.add(connection.hSet("test", "key", "val")); + actual.add(connection.hDel("test", "key")); + actual.add(connection.hDel("test", "foo")); + actual.add(connection.hExists("test", "key")); + verifyResults(Arrays.asList(new Object[] { true, true, false, false })); } @Test @@ -1619,7 +1756,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hIncrBy("test", "key", 3l)); actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 5l, "5" }), actual); + verifyResults(Arrays.asList(new Object[] { true, 5l, "5" })); } @Test @@ -1628,15 +1765,16 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hSet("test", "key", "2.9")); actual.add(connection.hIncrBy("test", "key", 3.5)); actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 6.4d, "6.4" }), actual); + verifyResults(Arrays.asList(new Object[] { true, 6.4d, "6.4" })); } @Test public void testHKeys() { - connection.hSet("test", "key", "2"); - connection.hSet("test", "key2", "2"); - assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "key", "key2" })), - connection.hKeys("test")); + actual.add(connection.hSet("test", "key", "2")); + actual.add(connection.hSet("test", "key2", "2")); + actual.add(connection.hKeys("test")); + verifyResults(Arrays.asList(new Object[] { true, true, + new LinkedHashSet(Arrays.asList(new String[] { "key", "key2" })) })); } @Test @@ -1644,7 +1782,7 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hSet("test", "key", "2")); actual.add(connection.hSet("test", "key2", "2")); actual.add(connection.hLen("test")); - verifyResults(Arrays.asList(new Object[] { true, true, 2l }), actual); + verifyResults(Arrays.asList(new Object[] { true, true, 2l })); } @Test @@ -1654,8 +1792,7 @@ public abstract class AbstractConnectionIntegrationTests { tuples.put("key2", "bar"); connection.hMSet("test", tuples); actual.add(connection.hMGet("test", "key", "key2")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { "foo", "bar" }) }), - actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { "foo", "bar" }) })); } @Test @@ -1665,14 +1802,14 @@ public abstract class AbstractConnectionIntegrationTests { actual.add(connection.hVals("test")); verifyResults( Arrays.asList(new Object[] { true, true, - Arrays.asList(new String[] { "foo", "bar" }) }), actual); + Arrays.asList(new String[] { "foo", "bar" }) })); } @Test public void testMove() { connection.set("foo", "bar"); actual.add(connection.move("foo", 1)); - verifyResults(Arrays.asList(new Object[] { true}), actual); + verifyResults(Arrays.asList(new Object[] { true})); connection.select(1); try { assertEquals("bar",connection.get("foo")); @@ -1683,52 +1820,16 @@ public abstract class AbstractConnectionIntegrationTests { } } - protected void verifyResults(List expected, List actual) { - assertEquals(expected, convertResults(true)); - } - - protected List convertResults() { - return convertResults(true); - } - - protected List convertResults(boolean filterStatus) { - List actual = getResults(); - List serializedResults = new ArrayList(); - for (Object result : actual) { - Object convertedResult = convertResult(result); - if (filterStatus) { - if(!"OK".equals(convertedResult) && !"QUEUED".equals(convertedResult)) { - serializedResults.add(convertedResult); - } - }else { - serializedResults.add(convertedResult); - } - } - return serializedResults; + protected void verifyResults(List expected) { + assertEquals(expected, getResults()); } protected List getResults() { return actual; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected Object convertResult(Object result) { - if (result instanceof List && !(((List) result).isEmpty()) - && ((List) result).get(0) instanceof byte[]) { - return (SerializationUtils.deserialize((List) result, stringSerializer)); - } else if (result instanceof byte[]) { - return (stringSerializer.deserialize((byte[]) result)); - } else if (result instanceof Map - && ((Map) result).keySet().iterator().next() instanceof byte[]) { - return (SerializationUtils.deserialize((Map) result, stringSerializer)); - } else if (result instanceof Set && !(((Set) result).isEmpty()) - && ((Set) result).iterator().next() instanceof byte[]) { - return (SerializationUtils.deserialize((Set) result, stringSerializer)); - } - return result; - } - protected void initConnection() { + actual = new ArrayList(); } protected class KeyExpired implements TestCondition { diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionPipelineIntegrationTests.java index 125e39313..ef6726f1c 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionPipelineIntegrationTests.java @@ -17,30 +17,14 @@ package org.springframework.data.redis.connection; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.springframework.data.redis.SpinBarrier.waitFor; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.springframework.data.redis.TestCondition; -import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; -import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate; -import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; -import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; import org.springframework.test.annotation.IfProfileValue; /** @@ -58,28 +42,6 @@ import org.springframework.test.annotation.IfProfileValue; abstract public class AbstractConnectionPipelineIntegrationTests extends AbstractConnectionIntegrationTests { - /** - * Individual results from closePipeline should be converted from List to - * LinkedHashSet - **/ - protected boolean convertResultToSet = false; - - /** - * Individual results from closePipeline should be converted to - * {@link Tuple}s - **/ - protected boolean convertResultToTuples = false; - - @Before - public void setUp() { - super.setUp(); - initConnection(); - } - - @Ignore - public void testByteValue() { - } - @Ignore public void testNullKey() throws Exception { } @@ -106,9 +68,37 @@ abstract public class AbstractConnectionPipelineIntegrationTests extends @Test(expected = RedisPipelineException.class) public void exceptionExecuteNative() throws Exception { - connection.execute("set", "foo"); - connection.execute("ZadD", getClass() + "#foo\t0.90\titem"); - getResults(); + super.exceptionExecuteNative(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaNotFound() { + super.testEvalShaNotFound(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnSingleError() { + super.testEvalReturnSingleError(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testBitOpNotMultipleSources() { + super.testBitOpNotMultipleSources(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreBadData() { + super.testRestoreBadData(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreExistingKey() { + super.testRestoreExistingKey(); } @Test @@ -125,304 +115,16 @@ abstract public class AbstractConnectionPipelineIntegrationTests extends assertTrue(results.isEmpty()); } - @Test - public void testExecute() { - connection.set("foo", "bar"); - actual.add(connection.execute("GET", "foo")); - verifyResults(Arrays.asList(new Object[] { "bar" }), actual); - } - - @IfProfileValue(name = "redisVersion", value = "2.6") - @Test - public void testPExpire() { - connection.set("exp", "true"); - actual.add(connection.pExpire("exp", 100)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - assertTrue(waitFor(new KeyExpired("exp"), 1000l)); - } - - @IfProfileValue(name = "redisVersion", value = "2.6") - @Test - public void testPExpireKeyNotExists() { - actual.add(connection.pExpire("nonexistent", 100)); - verifyResults(Arrays.asList(new Object[] { 0l }), actual); - } - - @IfProfileValue(name = "redisVersion", value = "2.6") - @Test - public void testPExpireAt() { - connection.set("exp2", "true"); - actual.add(connection.pExpireAt("exp2", System.currentTimeMillis() + 200)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - assertTrue(waitFor(new KeyExpired("exp2"), 1000l)); - } - - @IfProfileValue(name = "redisVersion", value = "2.6") - @Test - public void testPExpireAtKeyNotExists() { - actual.add(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200)); - verifyResults(Arrays.asList(new Object[] { 0l }), actual); - } - - @IfProfileValue(name = "redisVersion", value = "2.6") - @Test - public void testPTtl() { - connection.set("whatup", "yo"); - actual.add(connection.pExpire("whatup", 9000l)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - assertTrue(waitFor(new TestCondition() { - public boolean passes() { - return (connection.pTtl("whatup") > -1); - } - }, 1000l)); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreBadData() { - // Use something other than dump-specific serialization - connection.restore("testing".getBytes(), 0, "foo".getBytes()); - getResults(); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreExistingKey() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(1)); - try { - getResults(); - fail("Expected pipeline exception restoring an existing key"); - }catch(RedisPipelineException e) { - } - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreTtl() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - actual.add(connection.del("testing")); - actual.add(connection.get("testing")); - connection.restore("testing".getBytes(), 100l, (byte[]) results.get(results.size() - 1)); - verifyResults(Arrays.asList(new Object[] { 1l, null }), actual); - assertTrue(waitFor(new KeyExpired("testing"), 300l)); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testDumpAndRestore() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - actual.add(connection.del("testing")); - actual.add((connection.get("testing"))); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); - actual.add(connection.get("testing")); - verifyResults(Arrays.asList(new Object[] { 1l, null, "12" }), actual); - } - - @Test - public void testExecuteNoArgs() { - actual.add(connection.execute("PING")); - verifyResults(Arrays.asList(new Object[] { "PONG" }), actual); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testExpire() throws Exception { - connection.set("exp", "true"); - actual.add(connection.expire("exp", 1)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - assertTrue(waitFor(new KeyExpired("exp"), 2500l)); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testExpireAt() throws Exception { - connection.set("exp2", "true"); - actual.add(connection.expireAt("exp2", System.currentTimeMillis() / 1000 + 1)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - assertTrue(waitFor(new KeyExpired("exp2"), 2500l)); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testPersist() throws Exception { - connection.set("exp3", "true"); - actual.add(connection.expire("exp3", 1)); - actual.add(connection.persist("exp3")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l }), actual); - Thread.sleep(1500); - assertTrue(connection.exists("exp3")); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testSetEx() throws Exception { - connection.setEx("expy", 1l, "yep"); - actual.add(connection.get("expy")); - verifyResults(Arrays.asList(new Object[] { "yep" }), actual); - assertTrue(waitFor(new KeyExpired("expy"), 2500l)); - } - - @Test - public void testBitSet() throws Exception { - String key = "bitset-test"; - connection.setBit(key, 0, false); - connection.setBit(key, 1, true); - actual.add(connection.getBit(key, 0)); - actual.add(connection.getBit(key, 1)); - verifyResults(Arrays.asList(new Object[] { 0l, 0l, 0l, 1l }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testBitCount() { - String key = "bitset-test"; - connection.setBit(key, 0, false); - connection.setBit(key, 1, true); - connection.setBit(key, 2, true); - actual.add(connection.bitCount(key)); - verifyResults(Arrays.asList(new Object[] { 0l, 0l, 0l, 2l }), actual); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testBitOpNotMultipleSources() { - connection.set("key1", "abcd"); - connection.set("key2", "efgh"); - actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); - getResults(); - } - - @Test - public void testDbSize() { - connection.set("dbparam", "foo"); - assertNull(connection.dbSize()); - List results = getResults(); - assertEquals(2, results.size()); - assertTrue((Long) results.get(1) > 0); - } - - @SuppressWarnings("rawtypes") - @Test - public void testGetConfig() { - assertNull(connection.getConfig("*")); - List results = convertResults(); - assertEquals(1, results.size()); - assertTrue(!((List) results.get(0)).isEmpty()); - } - - @SuppressWarnings("rawtypes") - @Test - public void testKeys() throws Exception { - connection.set("keytest", "true"); - connection.set("keytest2", "true"); - connection.keys("key*"); - List results = convertResults(); - assertEquals(1, results.size()); - assertTrue(((List) results.get(0)).contains("keytest")); - } - - @Test - public void testRandomKey() { - connection.set("some", "thing"); - assertNull(connection.randomKey()); - List results = convertResults(); - assertEquals(1, results.size()); - assertNotNull(results.get(0)); - } - - @Test - public void testType() { - connection.set("something", "yo"); - assertNull(connection.type("something")); - List results = convertResults(); - assertEquals(1, results.size()); - assertEquals("string", results.get(0)); - } - - @Test - public void testMSetNx() { - Map vals = new HashMap(); - vals.put("height", "5"); - vals.put("width", "1"); - connection.mSetNXString(vals); - assertNull(connection.mGet("height", "width")); - verifyResults(Arrays.asList(new Object[] { 1l, Arrays.asList(new String[] { "5", "1" }) }), - actual); - } - - @Test - public void testMSetNxFailure() { - connection.set("height", "2"); - Map vals = new HashMap(); - vals.put("height", "5"); - vals.put("width", "1"); - actual.add(connection.mSetNXString(vals)); - actual.add(connection.mGet("height", "width")); - verifyResults(Arrays.asList(new Object[] { 0l, Arrays.asList(new String[] { "2", null }) }), - actual); - } - - @Test - public void testSetNx() { - actual.add(connection.setNX("notaround", "54")); - actual.add(connection.get("notaround")); - actual.add(connection.setNX("notaround", "55")); - actual.add(connection.get("notaround")); - verifyResults(Arrays.asList(new Object[] { 1l, "54", 0l, "54" }), actual); - } - - @Test - public void testRenameNx() { - connection.set("nxtest", "testit"); - actual.add(connection.renameNX("nxtest", "newnxtest")); - actual.add(connection.get("newnxtest")); - actual.add(connection.exists("nxtest")); - verifyResults(Arrays.asList(new Object[] { 1l, "testit", 0l }), actual); - } - - @Test - public void testGetRangeSetRange() { - connection.set("rangekey", "supercalifrag"); - actual.add(connection.getRange("rangekey", 0l, 2l)); - connection.setRange("rangekey", "ck", 2); - actual.add(connection.get("rangekey")); - verifyResults(Arrays.asList(new Object[] { "sup", 13l, "suckrcalifrag" }), actual); - } - - @Test - public void testMultiDiscard() throws Exception { - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.set("testitnow", "willdo"); - connection.multi(); - connection.set("testitnow2", "notok"); - connection.discard(); - connection.get("testitnow"); - List convertedResults = convertResults(); - assertEquals(Arrays.asList(new String[] { "willdo" }), convertedResults); - connection.openPipeline(); - // Ensure we can run a new tx after discarding previous one - testMultiExec(); - } - @Test public void testMultiExec() throws Exception { connection.multi(); connection.set("key", "value"); assertNull(connection.get("key")); assertNull(connection.exec()); - List convertedResults = convertResults(); - assertEquals(Arrays.asList(new Object[] { "value" }), convertedResults); + // We expect pipelined exec results to be flattened into results of closePipeline + List results = getResults(); + assertEquals(1,results.size()); + assertEquals("value",new String((byte[])results.get(0))); } @Test @@ -437,659 +139,24 @@ abstract public class AbstractConnectionPipelineIntegrationTests extends connection.set("testitnow", "somethingelse"); connection.get("testitnow"); connection.exec(); - List convertedResults = convertResults(); - assertEquals(Arrays.asList(new Object[] {"somethingelse"}), convertedResults); - } - - @Test - public void testSAdd() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sMembers("myset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, - new HashSet(Arrays.asList(new String[] { "foo", "bar" })) }), - actual); - } - - @Test - public void testSCard() { - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sCard("myset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 2l }), actual); - } - - @Test - public void testSDiff() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sDiff("myset", "otherset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, - new HashSet(Collections.singletonList("foo")) }), actual); - } - - @Test - public void testSDiffStore() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - connection.sDiffStore("thirdset", "myset", "otherset"); - actual.add(connection.sMembers("thirdset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, - new HashSet(Collections.singletonList("foo")) }), actual); - } - - @Test - public void testSInter() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sInter("myset", "otherset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, - new HashSet(Collections.singletonList("bar")) }), actual); - } - - @Test - public void testSInterStore() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - connection.sInterStore("thirdset", "myset", "otherset"); - actual.add(connection.sMembers("thirdset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, - new HashSet(Collections.singletonList("bar")) }), actual); - } - - @Test - public void testSIsMember() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sIsMember("myset", "foo")); - actual.add(connection.sIsMember("myset", "baz")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, true, false }), actual); - } - - @Test - public void testSMove() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sMove("myset", "otherset", "foo")); - actual.add(connection.sMembers("otherset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, - new HashSet(Arrays.asList(new String[] { "foo", "bar" })) }), - actual); - } - - @Test - public void testSPop() { - convertResultToSet = true; - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertNull(connection.sPop("myset")); - List results = convertResults(); - assertEquals(3, results.size()); - assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })) - .contains(results.get(2))); - } - - @Test - public void testSRandMember() { - convertResultToSet = true; - connection.sAdd("myset", "foo"); - connection.sAdd("myset", "bar"); - assertNull(connection.sRandMember("myset")); - List results = convertResults(); - assertEquals(3, results.size()); - assertTrue(new HashSet(Arrays.asList(new String[] { "foo", "bar" })) - .contains(results.get(2))); - } - - @Test - public void testSRem() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sRem("myset", "foo")); - actual.add(connection.sRem("myset", "baz")); - actual.add(connection.sMembers("myset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 0l, - new HashSet(Arrays.asList(new String[] { "bar" })) }), actual); - } - - @Test - public void testSUnion() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sAdd("otherset", "baz")); - actual.add(connection.sUnion("myset", "otherset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, - new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) }), - actual); - } - - @Test - public void testSUnionStore() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sAdd("otherset", "baz")); - connection.sUnionStore("thirdset", "myset", "otherset"); - actual.add(connection.sMembers("thirdset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, 3l, - new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) }), - actual); - } - - @Test - public void testZAddAndZRange() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, - Arrays.asList(new String[] { "James", "Bob" }) }), actual); - } - - @Test - public void testZCard() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zCard("myset")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 2l }), actual); - } - - @Test - public void testZCount() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zCount("myset", 1, 2)); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 2l }), actual); - } - - @Test - public void testZIncrBy() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zIncrBy("myset", 2, "Joe")); - actual.add(connection.zRangeByScore("myset", 6, 6)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 6d, Collections.singletonList("Joe") }), - actual); - } - - @Test - public void testZInterStore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zAdd("otherset", 1, "Bob")); - actual.add(connection.zAdd("otherset", 4, "James")); - actual.add(connection.zInterStore("thirdset", "myset", "otherset")); - actual.add(connection.zRange("thirdset", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, 1l, 2l, - Arrays.asList(new String[] { "Bob", "James" }) }), actual); - } - - @Test - public void testZInterStoreAggWeights() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zAdd("otherset", 1, "Bob")); - actual.add(connection.zAdd("otherset", 4, "James")); - actual.add(connection.zInterStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", - "otherset")); - actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - 1l, - 1l, - 1l, - 2l, - Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("James".getBytes(), "James", 12d) }) }), - actual); - } - - @Test - public void testZRangeWithScores() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRangeWithScores("myset", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - Arrays.asList(new StringTuple[] { - new DefaultStringTuple("James".getBytes(), "James", 1d), - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d) }) }), actual); - } - - @Test - public void testZRangeByScore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRangeByScore("myset", 1, 1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, Arrays.asList(new String[] { "James" }) }), - actual); - } - - @Test - public void testZRangeByScoreOffsetCount() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRangeByScore("myset", 1d, 3d, 1, -1)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, Arrays.asList(new String[] { "Bob" }) }), - actual); - } - - @Test - public void testZRangeByScoreWithScores() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRangeByScoreWithScores("myset", 2d, 5d)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob".getBytes(), - "Bob", 2d) }) }), actual); - } - - @Test - public void testZRangeByScoreWithScoresOffsetCount() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRangeByScoreWithScores("myset", 1d, 5d, 0, 1)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - Arrays.asList(new StringTuple[] { new DefaultStringTuple( - "James".getBytes(), "James", 1d) }) }), actual); - } - - @Test - public void testZRevRange() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRevRange("myset", 0, -1)); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, - Arrays.asList(new String[] { "Bob", "James" }) }), actual); - } - - @Test - public void testZRevRangeWithScores() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRevRangeWithScores("myset", 0, -1)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 2d), - new DefaultStringTuple("James".getBytes(), "James", 1d) }) }), - actual); - } - - @Test - public void testZRevRangeByScoreOffsetCount() { - actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); - actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); - actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d, - 0, 5)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, - Arrays.asList(new String[] { "Bob", "James" }) }), - actual); - } - - @Test - public void testZRevRangeByScore() { - actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); - actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); - actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, - Arrays.asList(new String[] { "Bob", "James" }) }), - actual); - } - - @Test - public void testZRevRangeByScoreWithScoresOffsetCount() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); - actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); - actual.add(byteConnection.zRevRangeByScoreWithScores( - "myset".getBytes(), 0d, 3d, 0, 1)); - verifyResults(Arrays.asList(new Object[] { - 1l, - 1l, - Arrays.asList(new StringTuple[] { new DefaultStringTuple("Bob" - .getBytes(), "Bob", 2d) }) }), actual); - } - - @Test - public void testZRevRangeByScoreWithScores() { - convertResultToTuples = true; - actual.add(connection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); - actual.add(connection.zAdd("myset".getBytes(), 1, "James".getBytes())); - actual.add(connection.zAdd("myset".getBytes(), 3, "Joe".getBytes())); - actual.add(byteConnection.zRevRangeByScoreWithScores( - "myset".getBytes(), 0d, 2d)); - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - 1l, - Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", - 2d), - new DefaultStringTuple("James".getBytes(), - "James", 1d) }) }), actual); - } - - @Test - public void testZRank() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRank("myset", "James")); - actual.add(connection.zRank("myset", "Bob")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 0l, 1l }), actual); - } - - @Test - public void testZRem() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRem("myset", "James")); - actual.add(connection.zRange("myset", 0l, -1l)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, Arrays.asList(new String[] { "Bob" }) }), - actual); - } - - @Test - public void testZRemRangeByRank() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRemRange("myset", 0l, 3l)); - actual.add(connection.zRange("myset", 0l, -1l)); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 2l, new ArrayList() }), actual); - } - - @Test - public void testZRemRangeByScore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zRemRangeByScore("myset", 0d, 1d)); - actual.add(connection.zRange("myset", 0l, -1l)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, Arrays.asList(new String[] { "Bob" }) }), - actual); - } - - @Test - public void testZRevRank() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 3, "Joe")); - actual.add(connection.zRevRank("myset", "Joe")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 0l }), actual); - } - - @Test - public void testZScore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 3, "Joe")); - actual.add(connection.zScore("myset", "Joe")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 3d }), actual); - } - - @Test - public void testZUnionStore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 6, "Joe")); - actual.add(connection.zAdd("otherset", 1, "Bob")); - actual.add(connection.zAdd("otherset", 4, "James")); - actual.add(connection.zUnionStore("thirdset", "myset", "otherset")); - actual.add(connection.zRange("thirdset", 0, -1)); - - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, 1l, 3l, - Arrays.asList(new String[] { "Bob", "James", "Joe" }) }), actual); - } - - @Test - public void testZUnionStoreAggWeights() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zAdd("otherset", 1, "Bob")); - actual.add(connection.zAdd("otherset", 4, "James")); - actual.add(connection.zUnionStore("thirdset", Aggregate.MAX, new int[] { 2, 3 }, "myset", - "otherset")); - actual.add(connection.zRangeWithScores("thirdset", 0, -1)); - - verifyResults( - Arrays.asList(new Object[] { - 1l, - 1l, - 1l, - 1l, - 1l, - 3l, - Arrays.asList(new StringTuple[] { - new DefaultStringTuple("Bob".getBytes(), "Bob", 4d), - new DefaultStringTuple("Joe".getBytes(), "Joe", 8d), - new DefaultStringTuple("James".getBytes(), "James", 12d) }) }), - actual); - } - - @Test - public void testHDel() throws Exception { - actual.add(connection.hSet("test", "key", "val")); - actual.add(connection.hDel("test", "key")); - actual.add(connection.hDel("test", "foo")); - actual.add(connection.hExists("test", "key")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 0l, 0l }), actual); - } - - @Test - public void testHKeys() { - convertResultToSet = true; - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hSet("test", "key2", "2")); - actual.add(connection.hKeys("test")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, - new LinkedHashSet(Arrays.asList(new String[] { "key", "key2" })) }), - actual); - } - - @Test - public void testHSetGet() throws Exception { - String hash = getClass() + ":hashtest"; - String key1 = UUID.randomUUID().toString(); - String key2 = UUID.randomUUID().toString(); - String value1 = "foo"; - String value2 = "bar"; - actual.add(connection.hSet(hash, key1, value1)); - actual.add(connection.hSet(hash, key2, value2)); - actual.add(connection.hGet(hash, key1)); - actual.add(connection.hGetAll(hash)); - List expected = Arrays.asList(new String[] { key1, value1, key2, value2 }); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, value1, expected }), actual); - } - - @Test - public void testHSetNX() throws Exception { - actual.add(connection.hSetNX("myhash", "key1", "foo")); - actual.add(connection.hSetNX("myhash", "key1", "bar")); - actual.add(connection.hGet("myhash", "key1")); - verifyResults(Arrays.asList(new Object[] { 1l, 0l, "foo" }), actual); - } - - @Test - public void testHIncrBy() { - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hIncrBy("test", "key", 3l)); - actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { 1l, 5l, "5" }), actual); - } - - @Test - public void testHLen() { - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hSet("test", "key2", "2")); - actual.add(connection.hLen("test")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 2l }), actual); - } - - @Test - public void testHVals() { - actual.add(connection.hSet("test", "key", "foo")); - actual.add(connection.hSet("test", "key2", "bar")); - actual.add(connection.hVals("test")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, - Arrays.asList(new String[] { "foo", "bar" }) }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptLoadEvalSha() { - connection.scriptLoad("return KEYS[1]"); - List results = convertResults(); - String sha1 = (String)results.get(0); - initConnection(); - actual.add(connection.evalSha(sha1, ReturnType.VALUE, 2, "key1", "key2")); - verifyResults(Arrays.asList(new Object[] {"key1"}), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalShaArrayStrings() { - // close the pipeline to get the return value of script load - getResults(); - String sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}"); - initConnection(); - actual.add(connection.evalSha(sha1, ReturnType.MULTI, 1, "key1", "arg1")); - verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] {"key1", "arg1"})}), actual); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalShaNotFound() { - connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); - getResults(); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnSingleError() { - connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); - getResults(); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnFalse() { - // pipelined results don't get converted to Booleans - actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { null }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnTrue() { - // pipelined results don't get converted to Booleans - actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptExists() { - getResults(); - String sha1 = connection.scriptLoad("return 'foo'"); - initConnection(); - actual.add(connection.scriptExists(sha1, "98777234")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {true, false})}), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptFlush() { - getResults(); - String sha1 = connection.scriptLoad("return KEYS[1]"); - initConnection(); - connection.scriptFlush(); - actual.add(connection.scriptExists(sha1)); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { 0l })}), actual); - } - - @Test - public void testMove() { - connection.set("foo", "bar"); - actual.add(connection.move("foo", 1)); - verifyResults(Arrays.asList(new Object[] { 1l }), actual); - connection.select(1); - try { - assertEquals("bar",connection.get("foo")); - } finally { - if(connection.exists("foo")) { - connection.del("foo"); - } - } + // We expect pipelined exec results to be flattened into results of closePipeline + List results = getResults(); + assertEquals(1,results.size()); + assertEquals("somethingelse",new String((byte[])results.get(0))); } protected void initConnection() { connection.openPipeline(); } - protected void verifyResults(List expected, List actual) { + protected void verifyResults(List expected) { List expectedPipeline = new ArrayList(); for (int i = 0; i < actual.size(); i++) { expectedPipeline.add(null); } assertEquals(expectedPipeline, actual); - assertEquals(expected, convertResults()); + List results = getResults(); + assertEquals(expected, results); } protected List getResults() { diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java new file mode 100644 index 000000000..2af559853 --- /dev/null +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java @@ -0,0 +1,456 @@ +package org.springframework.data.redis.connection; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.RedisSystemException; +import org.springframework.data.redis.connection.convert.Converters; +import org.springframework.data.redis.serializer.SerializationUtils; +import org.springframework.test.annotation.IfProfileValue; + +abstract public class AbstractConnectionTransactionIntegrationTests extends + AbstractConnectionIntegrationTests { + + protected boolean convert = true; + + protected boolean convertLongToBoolean = true; + + protected boolean convertStringToProps = false; + + @Ignore + public void testMultiDiscard() { + } + + @Ignore + public void testMultiExec() { + } + + @Ignore + public void testUnwatch() { + } + + @Ignore + public void testWatch() { + } + + /* + * Using blocking ops inside a tx does not make a lot of sense as it would require blocking the + * entire server in order to execute the block atomically, which in turn does not allow other + * clients to perform a push operation. * + */ + + @Ignore + public void testBLPop() { + } + + @Ignore + public void testBRPop() { + } + + @Ignore + public void testBRPopLPush() { + } + + @Ignore + public void testBLPopTimeout() { + } + + @Ignore + public void testBRPopTimeout() { + } + + @Ignore + public void testBRPopLPushTimeout() { + } + + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithNamedChannels() throws Exception { + } + + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithPatterns() throws Exception { + } + + @Ignore + public void testNullKey() throws Exception { + } + + @Ignore + public void testNullValue() throws Exception { + } + + @Ignore + public void testHashNullKey() throws Exception { + } + + @Ignore + public void testHashNullValue() throws Exception { + } + + // Type conversion overrides + + @Test + public void testExecute() { + connection.set("foo", "bar"); + actual.add(connection.execute("GET", "foo")); + assertEquals("bar", getResults().get(0)); + } + + @Test + public void testExecuteNoArgs() { + actual.add(connection.execute("PING")); + assertEquals("PONG", getResults().get(0)); + } + + @Test + public void testSort() { + convertLongToBoolean = false; + super.testSort(); + } + + @Test + public void testSortStore() { + convertLongToBoolean = false; + super.testSortStore(); + } + + @Test + public void testSortNullParams() { + convertLongToBoolean = false; + super.testSortNullParams(); + } + + @Test + public void testDbSize() { + convertLongToBoolean = false; + super.testDbSize(); + } + + @Test + public void testFlushDb() { + convertLongToBoolean = false; + super.testFlushDb(); + } + + @Test + public void testDel() { + convertLongToBoolean = false; + super.testDel(); + } + + @Test + public void testIncDecrByLong() { + convertLongToBoolean = false; + super.testIncrDecrByLong(); + } + + @Test + public void testDecrByIncrBy() { + convertLongToBoolean = false; + super.testDecrByIncrBy(); + } + + @Test + public void testIncrDecr() { + convertLongToBoolean = false; + super.testIncDecr(); + } + + @Test + public void testLInsert() { + convertLongToBoolean = false; + super.testLInsert(); + } + + @Test + public void testLRem() { + convertLongToBoolean = false; + super.testLRem(); + } + + @Test + public void testLPop() { + convertLongToBoolean = false; + super.testLPop(); + } + + @Test + public void testLLen() { + convertLongToBoolean = false; + super.testLLen(); + } + + @Test + public void testLSet() { + convertLongToBoolean = false; + super.testLSet(); + } + + @Test + public void testLTrim() { + convertLongToBoolean = false; + super.testLTrim(); + } + + @Test + public void testRPop() { + convertLongToBoolean = false; + super.testRPop(); + } + + @Test + public void testRPopLPush() { + convertLongToBoolean = false; + super.testRPopLPush(); + } + + @Test + public void testLPushX() { + convertLongToBoolean = false; + super.testLPushX(); + } + + @Test + public void testRPushX() { + convertLongToBoolean = false; + super.testRPushX(); + } + + @Test + public void testLIndex() { + convertLongToBoolean = false; + super.testLIndex(); + } + + @Test + public void testLPush() throws Exception { + convertLongToBoolean = false; + super.testLPush(); + } + + @Test + public void testSDiffStore() { + convertLongToBoolean = false; + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sDiffStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, + new HashSet(Collections.singletonList("foo")) })); + } + + @Test + public void testSInterStore() { + convertLongToBoolean = false; + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sInterStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 1l, + new HashSet(Collections.singletonList("bar")) })); + } + + @Test + public void testZRank() { + convertLongToBoolean = false; + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRank("myset", "James")); + actual.add(connection.zRank("myset", "Bob")); + verifyResults(Arrays.asList(new Object[] { 1l, 1l, 0l, 1l })); + } + + @Test + public void testZRemRangeByScore() { + convertLongToBoolean = false; + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zRemRangeByScore("myset", 0d, 1d)); + actual.add(connection.zRange("myset", 0l, -1l)); + verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, + new LinkedHashSet(Arrays.asList(new String[] { "Bob" })) })); + } + + @Test + public void testZRevRank() { + convertLongToBoolean = false; + actual.add(connection.zAdd("myset", 2, "Bob")); + actual.add(connection.zAdd("myset", 1, "James")); + actual.add(connection.zAdd("myset", 3, "Joe")); + actual.add(connection.zRevRank("myset", "Joe")); + verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 0l })); + } + + @Test + public void testIncrDecrByLong() { + convertLongToBoolean = false; + super.testIncrDecrByLong(); + } + + @Test + public void testIncDecr() { + convertLongToBoolean = false; + super.testIncDecr(); + } + + @Test + public void testType() { + connection.set("something", "yo"); + actual.add(connection.type("something")); + verifyResults(Arrays.asList(new Object[] { "string" })); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testBitCountNonExistentKey() { + convertLongToBoolean = false; + super.testBitCountNonExistentKey(); + } + + @Test + public void testInfo() throws Exception { + convertStringToProps = true; + super.testInfo(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testInfoBySection() throws Exception { + convertStringToProps = true; + super.testInfoBySection(); + } + + @Test + public void testDumpAndRestore() { + convert = false; + super.testDumpAndRestore(); + } + + @Test + public void testScriptLoadEvalSha() { + convert = false; + super.testScriptLoadEvalSha(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaArrayStrings() { + convert = false; + super.testEvalShaArrayStrings(); + } + + @Test(expected = RedisSystemException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreExistingKey() { + convert = false; + super.testRestoreExistingKey(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnString() { + convert = false; + super.testEvalReturnString(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayStrings() { + convert = false; + super.testEvalReturnArrayStrings(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreTtl() { + convert = false; + super.testRestoreTtl(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testScriptKill() { + // Impossible to call script kill in a tx because you can't issue the + // exec command while Redis is running a script + connection.scriptKill(); + } + + protected void initConnection() { + connection.multi(); + } + + protected abstract DataAccessException convertException(Exception ex); + + protected List getResults() { + List actual = connection.exec(); + if (actual == null) { + return null; + } + List serializedResults = new ArrayList(); + for (Object result : actual) { + Object convertedResult = convertResult(result); + if (convertedResult instanceof Exception) { + throw convertException((Exception) convertedResult); + } + if (!"OK".equals(convertedResult) && !"QUEUED".equals(convertedResult)) { + serializedResults.add(convertedResult); + } + } + return serializedResults; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object convertResult(Object result) { + if (!convert) { + return result; + } + if (result instanceof List && !(((List) result).isEmpty()) + && ((List) result).get(0) instanceof byte[]) { + return (SerializationUtils.deserialize((List) result, stringSerializer)); + } else if (result instanceof byte[]) { + return (stringSerializer.deserialize((byte[]) result)); + } else if (result instanceof Map + && ((Map) result).keySet().iterator().next() instanceof byte[]) { + return (SerializationUtils.deserialize((Map) result, stringSerializer)); + } else if (result instanceof Set && !(((Set) result).isEmpty())) { + Object firstResult = ((Set) result).iterator().next(); + if (firstResult instanceof byte[]) { + return (SerializationUtils.deserialize((Set) result, stringSerializer)); + } + } else if (convertLongToBoolean && result instanceof Long) { + if ((Long) result == 1l) { + return true; + } else if ((Long) result == 0l) { + return false; + } else { + return result; + } + } else if (convertStringToProps && result instanceof String) { + return Converters.toProperties((String) result); + } + return result; + } + + protected void verifyResults(List expected) { + List expectedTx = new ArrayList(); + for (int i = 0; i < actual.size(); i++) { + expectedTx.add(null); + } + assertEquals(expectedTx, actual); + List results = getResults(); + assertEquals(expected, results); + } +} diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests.java index 934eee398..87b5df4e2 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests.java @@ -16,8 +16,6 @@ package org.springframework.data.redis.connection.jedis; -import static org.junit.Assert.assertEquals; - import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -182,32 +180,6 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati super.testInfoBySection(); } - @Test - public void testIncrDecrByLong() { - String key = "test.count"; - long largeNumber = 0x123456789L; // > 32bits - connection.set(key, "0"); - connection.incrBy(key, largeNumber); - assertEquals(largeNumber, Long.valueOf(connection.get(key)).longValue()); - connection.decrBy(key, largeNumber); - assertEquals(0, Long.valueOf(connection.get(key)).longValue()); - connection.decrBy(key, 2 * largeNumber); - assertEquals(-2 * largeNumber, Long.valueOf(connection.get(key)).longValue()); - } - - @Test - public void testHashIncrDecrByLong() { - String key = "test.hcount"; - String hkey = "hashkey"; - - long largeNumber = 0x123456789L; // > 32bits - connection.hSet(key, hkey, "0"); - connection.hIncrBy(key, hkey, largeNumber); - assertEquals(largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); - connection.hIncrBy(key, hkey, -2 * largeNumber); - assertEquals(-largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue()); - } - @Test public void testCreateConnectionWithDb() { JedisConnectionFactory factory2 = new JedisConnectionFactory(); diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java index 10deb213f..73a78ca5b 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java @@ -15,27 +15,15 @@ */ package org.springframework.data.redis.connection.jedis; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - import org.junit.After; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; -import org.springframework.data.redis.connection.DefaultStringTuple; -import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import redis.clients.jedis.Tuple; - /** * Integration test of {@link JedisConnection} pipeline functionality * @@ -47,12 +35,6 @@ import redis.clients.jedis.Tuple; public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionPipelineIntegrationTests { - /** - * Individual results from closePipeline should be converted from - * LinkedHashSet to List - **/ - private boolean convertResultToList; - @After public void tearDown() { try { @@ -67,19 +49,19 @@ public class JedisConnectionPipelineIntegrationTests extends connection = null; } - @Ignore("DATAREDIS-143 Jedis ClassCastExceptions closing pipeline on certain ops") + @Ignore("DATAREDIS-143 Pipeline tries to return String instead of List") public void testGetConfig() { } - @Ignore("DATAREDIS-143 Jedis ClassCastExceptions closing pipeline on certain ops") + @Ignore("DATAREDIS-143 MultiResponseBuilder trying to cast QUEUED to a List") public void testWatch() { } - @Ignore("DATAREDIS-143 Jedis ClassCastExceptions closing pipeline on certain ops") + @Ignore("DATAREDIS-143 MultiResponseBuilder trying to cast QUEUED to a List") public void testUnwatch() { } - @Ignore("DATAREDIS-143 Jedis ClassCastExceptions closing pipeline on certain ops") + @Ignore("DATAREDIS-143 Pipeline tries to return List instead of Long on sort") public void testSortStore() { } @@ -162,7 +144,7 @@ public class JedisConnectionPipelineIntegrationTests extends @Test(expected = UnsupportedOperationException.class) public void testBitGet() { - connection.getBit("foo", 1l); + connection.getBit("bitly", 1l); } @Test(expected=UnsupportedOperationException.class) @@ -359,7 +341,7 @@ public class JedisConnectionPipelineIntegrationTests extends @Test(expected=UnsupportedOperationException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testScriptFlush() { - super.testScriptFlush(); + connection.scriptFlush(); } @Test(expected=UnsupportedOperationException.class) @@ -385,129 +367,4 @@ public class JedisConnectionPipelineIntegrationTests extends public void testInfoBySection() throws Exception { super.testInfoBySection(); } - - // Overrides, usually due to return values being Long vs Boolean or Set vs - // List - - @Test - public void testRenameNx() { - connection.set("nxtest", "testit"); - actual.add(connection.renameNX("nxtest", "newnxtest")); - actual.add(connection.get("newnxtest")); - actual.add(connection.exists("nxtest")); - verifyResults(Arrays.asList(new Object[] { 1l, "testit", false }), actual); - } - - @Test - public void testKeys() throws Exception { - convertResultToList = true; - super.testKeys(); - } - - @Test - public void testZAddAndZRange() { - convertResultToList = true; - super.testZAddAndZRange(); - } - - @Test - public void testZIncrBy() { - convertResultToList = true; - super.testZIncrBy(); - } - - @Test - public void testZInterStore() { - convertResultToList = true; - super.testZInterStore(); - } - - @Test - public void testZRangeByScore() { - convertResultToList = true; - super.testZRangeByScore(); - } - - @Test - public void testZRangeByScoreOffsetCount() { - convertResultToList = true; - super.testZRangeByScoreOffsetCount(); - } - - @Test - public void testZRevRange() { - convertResultToList = true; - super.testZRevRange(); - } - - @Test - public void testZRem() { - convertResultToList = true; - super.testZRem(); - } - - @Test - public void testZRemRangeByScore() { - convertResultToList = true; - super.testZRemRangeByScore(); - } - - @Test - public void testZUnionStore() { - convertResultToList = true; - super.testZUnionStore(); - } - - @Test - public void testZRemRangeByRank() { - convertResultToList = true; - super.testZRemRangeByRank(); - } - - @Test - public void testHDel() throws Exception { - actual.add(connection.hSet("test", "key", "val")); - actual.add(connection.hDel("test", "key")); - actual.add(connection.hDel("test", "foo")); - actual.add(connection.hExists("test", "key")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 0l, false }), actual); - } - - @Test - public void testHSetGet() throws Exception { - String hash = getClass() + ":hashtest"; - String key1 = UUID.randomUUID().toString(); - String key2 = UUID.randomUUID().toString(); - String value1 = "foo"; - String value2 = "bar"; - actual.add(connection.hSet(hash, key1, value1)); - actual.add(connection.hSet(hash, key2, value2)); - actual.add(connection.hGet(hash, key1)); - actual.add(connection.hGetAll(hash)); - Map expected = new HashMap(); - expected.put(key1, value1); - expected.put(key2, value2); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, value1, expected }), actual); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected Object convertResult(Object result) { - Object convertedResult = super.convertResult(result); - if (convertedResult instanceof Set) { - if (convertResultToList) { - // Other providers represent zSets as Lists, so transform here - return new ArrayList((Set) convertedResult); - } else if (!(((Set) convertedResult).isEmpty()) - && ((Set) convertedResult).iterator().next() instanceof Tuple) { - List tuples = new ArrayList(); - for (Tuple value : ((Set) convertedResult)) { - DefaultStringTuple tuple = new DefaultStringTuple( - (byte[]) value.getBinaryElement(), value.getElement(), value.getScore()); - tuples.add(tuple); - } - return tuples; - } - } - return convertedResult; - } } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java index 4a7d4aedb..ebdd8f260 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java @@ -18,12 +18,24 @@ package org.springframework.data.redis.connection.jedis; import static org.junit.Assert.fail; import java.util.Arrays; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; +import org.junit.After; import org.junit.Ignore; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.RedisVersionUtils; +import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests; +import org.springframework.data.redis.connection.DefaultStringTuple; +import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; +import org.springframework.test.annotation.IfProfileValue; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import redis.clients.jedis.Tuple; /** * Integration test of {@link JedisConnection} transaction functionality. @@ -35,61 +47,309 @@ import org.springframework.data.redis.RedisVersionUtils; * @author Jennifer Hickey * */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("JedisConnectionIntegrationTests-context.xml") public class JedisConnectionTransactionIntegrationTests extends - JedisConnectionPipelineIntegrationTests { + AbstractConnectionTransactionIntegrationTests { - @Ignore - public void testMultiDiscard() { + @After + public void tearDown() { + try { + connection.flushDb(); + connection.close(); + } catch (Exception e) { + // Jedis leaves some incomplete data in OutputStream on NPE caused + // by null key/value tests + // Attempting to close the connection will result in error on + // sending QUIT to Redis + } + connection = null; } - @Ignore - public void testMultiExec() { + @Ignore("DATAREDIS-143 transaction tries to return List instead of Long on sort") + public void testSortStore() { } - @Ignore - public void testUnwatch() { - } - - @Ignore - public void testWatch() { - } - - /* - * Using blocking ops inside a tx does not make a lot of sense as it would - * require blocking the entire server in order to execute the block - * atomically, which in turn does not allow other clients to perform a push - * operation. * - */ - - @Ignore - public void testBLPop() { - } - - @Ignore - public void testBRPop() { - } - - @Ignore - public void testBRPopLPush() { - } - - @Ignore - public void testBLPopTimeout() { - } - - @Ignore - public void testBRPopTimeout() { - } - - @Ignore - public void testBRPopLPushTimeout() { - } - - @Ignore - public void testOpenPipelineTwice() { + @Ignore("DATAREDIS-143 transaction tries to return Long instead of List on sort with no params") + public void testSortStoreNullParams() { } // Unsupported Ops + @Test(expected = UnsupportedOperationException.class) + public void testPExpire() { + super.testPExpire(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPExpireKeyNotExists() { + super.testPExpireKeyNotExists(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPExpireAt() { + super.testPExpireAt(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPExpireAtKeyNotExists() { + super.testPExpireAtKeyNotExists(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPTtl() { + super.testPTtl(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPTtlNoExpire() { + super.testPTtlNoExpire(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDumpAndRestore() { + super.testDumpAndRestore(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDumpNonExistentKey() { + super.testDumpNonExistentKey(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testRestoreBadData() { + super.testRestoreBadData(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testRestoreExistingKey() { + super.testRestoreExistingKey(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testRestoreTtl() { + super.testRestoreTtl(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitSet() throws Exception { + super.testBitSet(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitCount() { + connection.bitCount("foo"); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitCountInterval() { + super.testBitCountInterval(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitCountNonExistentKey() { + super.testBitCountNonExistentKey(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpAnd() { + super.testBitOpAnd(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpOr() { + super.testBitOpOr(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpXOr() { + super.testBitOpXOr(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpNot() { + super.testBitOpNot(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpNotMultipleSources() { + super.testBitOpNotMultipleSources(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testRandomKey() { + super.testRandomKey(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testGetRangeSetRange() { + super.testGetRangeSetRange(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testPingPong() throws Exception { + super.testPingPong(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testInfo() throws Exception { + super.testInfo(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testZRevRangeByScore() { + super.testZRevRangeByScore(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testZRevRangeByScoreOffsetCount() { + super.testZRevRangeByScoreOffsetCount(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testZRevRangeByScoreWithScores() { + super.testZRevRangeByScoreWithScores(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testZRevRangeByScoreWithScoresOffsetCount() { + super.testZRevRangeByScoreWithScoresOffsetCount(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testHIncrByDouble() { + super.testHIncrByDouble(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testIncrByDouble() { + super.testIncrByDouble(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testScriptLoadEvalSha() { + super.testScriptLoadEvalSha(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaArrayStrings() { + super.testEvalShaArrayStrings(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaNotFound() { + super.testEvalShaNotFound(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnString() { + super.testEvalReturnString(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnNumber() { + super.testEvalReturnNumber(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnSingleOK() { + super.testEvalReturnSingleOK(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnSingleError() { + super.testEvalReturnSingleError(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnFalse() { + super.testEvalReturnFalse(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnTrue() { + super.testEvalReturnTrue(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayStrings() { + super.testEvalReturnArrayStrings(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayNumbers() { + super.testEvalReturnArrayNumbers(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayOKs() { + super.testEvalReturnArrayOKs(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayFalses() { + super.testEvalReturnArrayFalses(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayTrues() { + super.testEvalReturnArrayTrues(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testScriptExists() { + super.testScriptExists(); + } + + @IfProfileValue(name = "redisVersion", value = "2.6") + @Test(expected = UnsupportedOperationException.class) + public void testScriptKill() { + connection.scriptKill(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testScriptFlush() { + connection.scriptFlush(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testSRandMemberCount() { + super.testSRandMemberCount(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testSRandMemberCountKeyNotExists() { + super.testSRandMemberCountKeyNotExists(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testSRandMemberCountNegative() { + super.testSRandMemberCountNegative(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testInfoBySection() throws Exception { + super.testInfoBySection(); + } @Test(expected = UnsupportedOperationException.class) public void testGetConfig() { @@ -107,19 +367,34 @@ public class JedisConnectionTransactionIntegrationTests extends try { // Syntax error on queued commands are swallowed and no results are // returned - verifyResults(Arrays.asList(new Object[] {}), actual); - if(RedisVersionUtils.atLeast("2.6.5", connection)) { + verifyResults(Arrays.asList(new Object[] {})); + if (RedisVersionUtils.atLeast("2.6.5", connection)) { fail("Redis 2.6 should throw an Exception on exec if commands are invalid"); } - }catch(InvalidDataAccessApiUsageException e) { + } catch (InvalidDataAccessApiUsageException e) { } } - protected void initConnection() { - connection.multi(); + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object convertResult(Object result) { + Object convertedResult = super.convertResult(result); + if (convertedResult instanceof Set) { + if (!(((Set) convertedResult).isEmpty()) + && ((Set) convertedResult).iterator().next() instanceof Tuple) { + Set tuples = new LinkedHashSet(); + for (Tuple value : ((Set) convertedResult)) { + DefaultStringTuple tuple = new DefaultStringTuple( + (byte[]) value.getBinaryElement(), value.getElement(), value.getScore()); + tuples.add(tuple); + } + return tuples; + } + } + return convertedResult; } - protected List getResults() { - return connection.exec(); + @Override + protected DataAccessException convertException(Exception ex) { + return JedisConverters.toDataAccessException(ex); } } diff --git a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java index ff0a96247..6f372b443 100644 --- a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.jredis.JRedis; @@ -86,6 +88,10 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat public void testMSetNxFailure() { } + @Ignore("JRedis casts to int") + public void testIncrDecrByLong() { + } + @Ignore("Ping returns status response instead of value response") public void testExecuteNoArgs() { } @@ -409,6 +415,11 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat super.testHIncrByDouble(); } + @Test(expected=UnsupportedOperationException.class) + public void testHashIncrDecrByLong() { + super.testHashIncrDecrByLong(); + } + @Test(expected=UnsupportedOperationException.class) public void testIncrByDouble() { super.testIncrByDouble(); @@ -539,7 +550,17 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat super.testInfoBySection(); } - // Jredis returns null for rPush + // Jredis returns null for rPush and lPush + @Test + public void testLLen() { + connection.rPush("PopList", "hello"); + connection.rPush("PopList", "big"); + connection.rPush("PopList", "world"); + connection.rPush("PopList", "hello"); + actual.add(connection.lLen("PopList")); + verifyResults(Arrays.asList(new Object[] { 4l })); + } + @Test public void testSort() { connection.rPush("sortlist", "foo"); @@ -565,8 +586,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat connection.rPush("sortlist", "2"); connection.rPush("sortlist", "3"); actual.add(connection.sort("sortlist", null)); - verifyResults( - Arrays.asList(new Object[] { Arrays.asList(new String[] { "2", "3", "5" }) }), actual); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new String[] { "2", "3", "5" }) })); } @Test @@ -576,8 +596,7 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat connection.rPush("sortlist", "5"); actual.add(connection.sort("sortlist", null, "newlist")); actual.add(connection.lRange("newlist", 0, 9)); - verifyResults(Arrays.asList(new Object[] { 3l, - Arrays.asList(new String[] { "3", "5", "9" }) }), actual); + verifyResults(Arrays.asList(new Object[] { 3l, Arrays.asList(new String[] { "3", "5", "9" }) })); } @Test @@ -646,16 +665,6 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat assertEquals(Arrays.asList(new String[] { "baz", "bar" }), connection.lRange("testlist", 0, -1)); } - @Test - public void testLLen() { - connection.rPush("PopList", "hello"); - connection.rPush("PopList", "big"); - connection.rPush("PopList", "world"); - connection.rPush("PopList", "hello"); - actual.add(connection.lLen("PopList")); - verifyResults(Arrays.asList(new Object[] { 4l }), actual); - } - @Test public void testExecute() { connection.set("foo", "bar"); @@ -663,11 +672,48 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat assertEquals("bar", stringSerializer.deserialize(response.getBulkData())); } + @Test + public void testSDiffStore() { + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sDiffStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + // JRedis returns void for sDiffStore, so we always return -1 + verifyResults(Arrays.asList(new Object[] { true, true, true, -1l, + new HashSet(Collections.singletonList("foo")) })); + } + + @Test + public void testSInterStore() { + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sInterStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + // JRedis returns void for sInterStore, so we always return -1 + verifyResults(Arrays.asList(new Object[] { true, true, true, -1l, + new HashSet(Collections.singletonList("bar")) })); + } + + @Test + public void testSUnionStore() { + actual.add(connection.sAdd("myset", "foo")); + actual.add(connection.sAdd("myset", "bar")); + actual.add(connection.sAdd("otherset", "bar")); + actual.add(connection.sAdd("otherset", "baz")); + actual.add(connection.sUnionStore("thirdset", "myset", "otherset")); + actual.add(connection.sMembers("thirdset")); + // JRedis returns void for sUnionStore, so we always return -1 + verifyResults(Arrays.asList(new Object[] { true, true, true, true, -1l, + new HashSet(Arrays.asList(new String[] { "foo", "bar", "baz" })) })); + } + @Test public void testMove() { connection.set("foo", "bar"); actual.add(connection.move("foo", 1)); - verifyResults(Arrays.asList(new Object[] { true}), actual); + verifyResults(Arrays.asList(new Object[] { true})); // JRedis does not support select() on existing conn, create new one JredisConnectionFactory factory2 = new JredisConnectionFactory(); factory2.setDatabase(1); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/AuthenticatingRedisClientTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/AuthenticatingRedisClientTests.java index 08a204716..3c3d46cc6 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/AuthenticatingRedisClientTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/AuthenticatingRedisClientTests.java @@ -56,7 +56,7 @@ public class AuthenticatingRedisClientTests { @Test public void codecConnect() { - RedisConnection conn = client.connect(LettuceUtils.CODEC); + RedisConnection conn = client.connect(LettuceConnection.CODEC); conn.ping(); } @@ -68,7 +68,7 @@ public class AuthenticatingRedisClientTests { @Test public void codecConnectAsync() { - RedisAsyncConnection conn = client.connectAsync(LettuceUtils.CODEC); + RedisAsyncConnection conn = client.connectAsync(LettuceConnection.CODEC); conn.ping(); } @@ -80,7 +80,7 @@ public class AuthenticatingRedisClientTests { @Test public void codecConnectPubSub() { - RedisPubSubConnection conn = client.connectPubSub(LettuceUtils.CODEC); + RedisPubSubConnection conn = client.connectPubSub(LettuceConnection.CODEC); conn.ping(); } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java index 4edb7bb8a..fe019ee78 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java @@ -201,11 +201,6 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra factory2.destroy(); } - @Test(expected = UnsupportedOperationException.class) - public void testSelect() { - super.testSelect(); - } - @Test public void testSelectNotShared() { DefaultLettucePool pool = new DefaultLettucePool(SettingsUtils.getHost(), @@ -219,6 +214,11 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra factory2.destroy(); } + @Test(expected = UnsupportedOperationException.class) + public void testSelect() { + super.testSelect(); + } + @Test(expected=UnsupportedOperationException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testBitOpNotMultipleSources() { @@ -241,6 +241,7 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra final AtomicBoolean scriptDead = new AtomicBoolean(false); Thread th = new Thread(new Runnable() { public void run() { + // Use a different factory to get a non-shared native conn for blocking script final LettuceConnectionFactory factory2 = new LettuceConnectionFactory(SettingsUtils.getHost(), SettingsUtils.getPort()); factory2.afterPropertiesSet(); @@ -268,7 +269,7 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra public void testMove() { connection.set("foo", "bar"); actual.add(connection.move("foo", 1)); - verifyResults(Arrays.asList(new Object[] { true}), actual); + verifyResults(Arrays.asList(new Object[] { true})); // Lettuce does not support select when using shared conn, use a new conn factory LettuceConnectionFactory factory2 = new LettuceConnectionFactory(); factory2.setDatabase(1); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java index b31c19083..d4dbb3cc7 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java @@ -16,20 +16,12 @@ package org.springframework.data.redis.connection.lettuce; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import static org.springframework.data.redis.SpinBarrier.waitFor; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Ignore; @@ -41,18 +33,13 @@ import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.TestCondition; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; -import org.springframework.data.redis.connection.DefaultStringTuple; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.data.redis.connection.ReturnType; import org.springframework.data.redis.connection.StringRedisConnection; -import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.lambdaworks.redis.KeyValue; -import com.lambdaworks.redis.ScoredValue; - /** * Integration test of {@link LettuceConnection} pipeline functionality * @@ -73,308 +60,6 @@ public class LettuceConnectionPipelineIntegrationTests extends super.testSelect(); } - // Overrides, usually due to return values being Long vs Boolean or Set vs - // List - - @Test - public void testWatch() throws Exception { - connection.set("testitnow", "willdo"); - connection.watch("testitnow".getBytes()); - //Give some time for watch to be asynch executed - Thread.sleep(500); - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.set("testitnow", "something"); - conn2.close(); - connection.multi(); - connection.set("testitnow", "somethingelse"); - actual.add(connection.exec()); - actual.add(connection.get("testitnow")); - verifyResults(Arrays.asList(new Object[] { null, "something" }), actual); - } - - @Test - public void testUnwatch() throws Exception { - connection.set("testitnow", "willdo"); - connection.watch("testitnow".getBytes()); - connection.unwatch(); - connection.multi(); - //Give some time for unwatch to be asynch executed - Thread.sleep(500); - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.set("testitnow", "something"); - connection.set("testitnow", "somethingelse"); - connection.get("testitnow"); - connection.exec(); - List convertedResults = convertResults(); - assertEquals(Arrays.asList(new Object[] {"somethingelse"}), convertedResults); - } - - @Test - public void testBLPop() { - // Use a different synchronous connection to add items to the list, else blpop may - // execute before items in the list (LettuceConnection uses different underlying conns for blocking ops) - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.lPush("poplist", "foo"); - conn2.lPush("poplist", "bar"); - actual.add(connection.bLPop(1, "poplist", "otherlist")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new String[] {"poplist", "bar"})}), actual); - } - - @Test - public void testBRPop() { - // Use a different synchronous connection to add items to the list, else blpop may - // execute before items in the list (LettuceConnection uses different underlying conns for blocking ops) - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.rPush("rpoplist", "bar"); - conn2.rPush("rpoplist", "foo"); - actual.add(connection.bRPop(1, "rpoplist")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new String[] {"rpoplist", "foo"})}), actual); - } - - @Test - public void testBRPopLPush() { - // Use a different synchronous connection to add items to the list, else blpop may - // execute before items in the list (LettuceConnection uses different underlying conns for blocking ops) - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.rPush("PopList", "hello"); - conn2.rPush("PopList", "world"); - conn2.rPush("pop2", "hey"); - assertNull(connection.bRPopLPush(1, "PopList", "pop2")); - List results = convertResults(); - assertEquals(Arrays.asList(new String[] { "world" }), results); - assertEquals(Arrays.asList(new String[] { "hello" }), connection.lRange("PopList", 0, -1)); - assertEquals(Arrays.asList(new String[] { "world", "hey" }), - connection.lRange("pop2", 0, -1)); - } - - @Test - public void testHSetGet() throws Exception { - String hash = getClass() + ":hashtest"; - String key1 = UUID.randomUUID().toString(); - String key2 = UUID.randomUUID().toString(); - String value1 = "foo"; - String value2 = "bar"; - actual.add(connection.hSet(hash, key1, value1)); - actual.add(connection.hSet(hash, key2, value2)); - actual.add(connection.hGet(hash, key1)); - actual.add(connection.hGetAll(hash)); - Map expected = new HashMap(); - expected.put(key1, value1); - expected.put(key2, value2); - verifyResults(Arrays.asList(new Object[] { true, true, value1, expected }), actual); - } - - @Test - public void testInfo() throws Exception { - assertNull(connection.info()); - List results = getResults(); - assertEquals(1, results.size()); - Properties info = LettuceUtils.info((String) results.get(0)); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testInfoBySection() throws Exception { - assertNull(connection.info("server")); - List results = getResults(); - assertEquals(1, results.size()); - Properties info = LettuceUtils.info((String) results.get(0)); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test - public void testMSetNx() { - Map vals = new HashMap(); - vals.put("height", "5"); - vals.put("width", "1"); - connection.mSetNXString(vals); - assertNull(connection.mGet("height", "width")); - verifyResults( - Arrays.asList(new Object[] { true, Arrays.asList(new String[] { "5", "1" }) }), - actual); - } - - @Test - public void testMSetNxFailure() { - connection.set("height", "2"); - Map vals = new HashMap(); - vals.put("height", "5"); - vals.put("width", "1"); - actual.add(connection.mSetNXString(vals)); - actual.add(connection.mGet("height", "width")); - verifyResults(Arrays.asList(new Object[] { false, Arrays.asList(new String[] { "2", null }) }), - actual); - } - - @Test - public void testSetNx() { - actual.add(connection.setNX("notaround", "54")); - actual.add(connection.get("notaround")); - actual.add(connection.setNX("notaround", "55")); - actual.add(connection.get("notaround")); - verifyResults(Arrays.asList(new Object[] { true, "54", false, "54" }), actual); - } - - @Test - public void testRenameNx() { - connection.set("nxtest", "testit"); - actual.add(connection.renameNX("nxtest", "newnxtest")); - actual.add(connection.get("newnxtest")); - actual.add(connection.exists("nxtest")); - verifyResults(Arrays.asList(new Object[] { true, "testit", false }), actual); - } - - @Test - public void testSMove() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sAdd("otherset", "bar")); - actual.add(connection.sMove("myset", "otherset", "foo")); - actual.add(connection.sMembers("otherset")); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, true, - new HashSet(Arrays.asList(new String[] { "foo", "bar" })) }), - actual); - } - - @Test - public void testHKeys() { - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hSet("test", "key2", "2")); - actual.add(connection.hKeys("test")); - verifyResults( - Arrays.asList(new Object[] { true, true, - Arrays.asList(new String[] { "key", "key2" }) }), actual); - } - - @Test - public void testHSetNX() throws Exception { - actual.add(connection.hSetNX("myhash", "key1", "foo")); - actual.add(connection.hSetNX("myhash", "key1", "bar")); - actual.add(connection.hGet("myhash", "key1")); - verifyResults(Arrays.asList(new Object[] { true, false, "foo" }), actual); - } - - @Test - public void testHIncrBy() { - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hIncrBy("test", "key", 3l)); - actual.add(connection.hGet("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 5l, "5" }), actual); - } - - @Test - public void testHLen() { - actual.add(connection.hSet("test", "key", "2")); - actual.add(connection.hSet("test", "key2", "2")); - actual.add(connection.hLen("test")); - verifyResults(Arrays.asList(new Object[] { true, true, 2l }), actual); - } - - @Test - public void testHVals() { - actual.add(connection.hSet("test", "key", "foo")); - actual.add(connection.hSet("test", "key2", "bar")); - actual.add(connection.hVals("test")); - verifyResults( - Arrays.asList(new Object[] { true, true, - Arrays.asList(new String[] { "foo", "bar" }) }), actual); - } - - @Test - public void testHDel() throws Exception { - actual.add(connection.hSet("test", "key", "val")); - actual.add(connection.hDel("test", "key")); - actual.add(connection.hDel("test", "foo")); - actual.add(connection.hExists("test", "key")); - verifyResults(Arrays.asList(new Object[] { true, 1l, 0l, false }), actual); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testPersist() throws Exception { - connection.set("exp3", "true"); - actual.add(connection.expire("exp3", 1)); - actual.add(connection.persist("exp3")); - verifyResults(Arrays.asList(new Object[] { true, true }), actual); - Thread.sleep(1500); - assertTrue(connection.exists("exp3")); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testExpireAt() throws Exception { - connection.set("exp2", "true"); - actual.add(connection.expireAt("exp2", System.currentTimeMillis() / 1000 + 1)); - verifyResults(Arrays.asList(new Object[] { true}), actual); - assertTrue(waitFor(new KeyExpired("exp2"), 2500l)); - } - - @Test - @IfProfileValue(name = "runLongTests", value = "true") - public void testExpire() throws Exception { - connection.set("exp", "true"); - actual.add(connection.expire("exp", 1)); - verifyResults(Arrays.asList(new Object[] { true }), actual); - assertTrue(waitFor(new KeyExpired("exp"), 2500)); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testPExpire() { - connection.set("exp", "true"); - actual.add(connection.pExpire("exp", 100)); - verifyResults(Arrays.asList(new Object[] { true }), actual); - assertTrue(waitFor(new KeyExpired("exp"), 1000l)); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testPExpireKeyNotExists() { - actual.add(connection.pExpire("nonexistent", 100)); - verifyResults(Arrays.asList(new Object[] { false }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testPExpireAt() { - connection.set("exp2", "true"); - actual.add(connection.pExpireAt("exp2", System.currentTimeMillis() + 200)); - verifyResults(Arrays.asList(new Object[] { true }), actual); - assertTrue(waitFor(new KeyExpired("exp2"), 1000l)); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testPExpireAtKeyNotExists() { - actual.add(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200)); - verifyResults(Arrays.asList(new Object[] { false }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testPTtl() { - connection.set("whatup", "yo"); - actual.add(connection.pExpire("whatup", 9000l)); - verifyResults(Arrays.asList(new Object[] { true }), actual); - assertTrue(waitFor(new TestCondition() { - public boolean passes() { - return (connection.pTtl("whatup") > -1); - } - }, 1000l)); - } - // LettuceConnection throws an UnsupportedOpException before we close the pipeline @Test(expected=UnsupportedOperationException.class) @IfProfileValue(name = "redisVersion", value = "2.6") @@ -395,31 +80,44 @@ public class LettuceConnectionPipelineIntegrationTests extends } @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnFalse() { - // Lettuce actually returns booleans, it's not an SDR conversion - actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { false }), actual); + public void testWatch() throws Exception { + connection.set("testitnow", "willdo"); + connection.watch("testitnow".getBytes()); + //Give some time for watch to be asynch executed + Thread.sleep(500); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.set("testitnow", "something"); + conn2.close(); + connection.multi(); + connection.set("testitnow", "somethingelse"); + actual.add(connection.exec()); + actual.add(connection.get("testitnow")); + // Exec results lost on flatten in closePipeline and also won't get converted + // by DefaultStringRedisConnection yet + List results = getResults(); + assertEquals("something", new String((byte[])results.get(0))); } @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnTrue() { - // Lettuce actually returns booleans, it's not an SDR conversion - actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0)); - verifyResults(Arrays.asList(new Object[] { true }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptFlush() { - getResults(); - String sha1 = connection.scriptLoad("return KEYS[1]"); - initConnection(); - connection.scriptFlush(); - actual.add(connection.scriptExists(sha1)); - // Lettuce actually returns booleans, it's not an SDR conversion - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { false })}), actual); + public void testUnwatch() throws Exception { + connection.set("testitnow", "willdo"); + connection.watch("testitnow".getBytes()); + connection.unwatch(); + connection.multi(); + //Give some time for unwatch to be asynch executed + Thread.sleep(500); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.set("testitnow", "something"); + connection.set("testitnow", "somethingelse"); + connection.get("testitnow"); + connection.exec(); + // Exec results lost on flatten in closePipeline and also won't get converted + // by DefaultStringRedisConnection yet + List results = getResults(); + assertEquals(1,results.size()); + assertEquals("somethingelse",new String((byte[])results.get(0)));; } @Test @@ -431,6 +129,7 @@ public class LettuceConnectionPipelineIntegrationTests extends final AtomicBoolean scriptDead = new AtomicBoolean(false); Thread th = new Thread(new Runnable() { public void run() { + // Use separate conn factory to avoid using the underlying shared native conn on blocking script final LettuceConnectionFactory factory2 = new LettuceConnectionFactory(SettingsUtils.getHost(), SettingsUtils.getPort()); factory2.afterPropertiesSet(); @@ -459,7 +158,7 @@ public class LettuceConnectionPipelineIntegrationTests extends public void testMove() { connection.set("foo", "bar"); actual.add(connection.move("foo", 1)); - verifyResults(Arrays.asList(new Object[] { true}), actual); + verifyResults(Arrays.asList(new Object[] { true})); // Lettuce does not support select when using shared conn, use a new conn factory LettuceConnectionFactory factory2 = new LettuceConnectionFactory(); factory2.setDatabase(1); @@ -474,25 +173,4 @@ public class LettuceConnectionPipelineIntegrationTests extends conn2.close(); } } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected Object convertResult(Object result) { - Object convertedResult = super.convertResult(result); - if (convertedResult instanceof KeyValue) { - List keyValue = new ArrayList(); - keyValue.add((String) super.convertResult(((KeyValue) convertedResult).key)); - keyValue.add((String) super.convertResult(((KeyValue) convertedResult).value)); - return keyValue; - } else if (convertedResult instanceof List && !(((List) result).isEmpty()) - && ((List) convertedResult).get(0) instanceof ScoredValue) { - List tuples = new ArrayList(); - for (ScoredValue value : ((List) convertedResult)) { - DefaultStringTuple tuple = new DefaultStringTuple((byte[]) value.value, new String( - (byte[]) value.value), value.score); - tuples.add(tuple); - } - return tuples; - } - return convertedResult; - } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java index 2784009a7..519748a75 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java @@ -1,18 +1,25 @@ package org.springframework.data.redis.connection.lettuce; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; -import java.util.Properties; +import java.util.Map; +import java.util.Set; +import org.junit.Ignore; import org.junit.Test; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.redis.connection.DefaultStringTuple; import org.springframework.data.redis.connection.RedisPipelineException; +import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; +import org.springframework.data.redis.connection.convert.SetConverter; +import org.springframework.data.redis.serializer.SerializationUtils; import org.springframework.test.annotation.IfProfileValue; /** @@ -22,98 +29,207 @@ import org.springframework.test.annotation.IfProfileValue; * */ public class LettuceConnectionPipelineTxIntegrationTests extends - LettuceConnectionTransactionIntegrationTests { + LettuceConnectionPipelineIntegrationTests { + + private boolean convert=true; + + private boolean convertToStringTuple=true; + + @Ignore + public void testMultiDiscard() { + } + + @Ignore + public void testMultiExec() { + } + + @Ignore + public void testUnwatch() { + } + + @Ignore + public void testWatch() { + } + + /* + * Using blocking ops inside a tx does not make a lot of sense as it would + * require blocking the entire server in order to execute the block + * atomically, which in turn does not allow other clients to perform a push + * operation. * + */ + + @Ignore + public void testBLPop() { + } + + @Ignore + public void testBRPop() { + } + + @Ignore + public void testBRPopLPush() { + } + + @Ignore + public void testBLPopTimeout() { + } + + @Ignore + public void testBRPopTimeout() { + } + + @Ignore + public void testBRPopLPushTimeout() { + } + + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithNamedChannels() throws Exception { + } + + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithPatterns() throws Exception { + } + + @Ignore + public void testNullKey() throws Exception { + } + + @Ignore + public void testNullValue() throws Exception { + } + + @Ignore + public void testHashNullKey() throws Exception { + } + + @Ignore + public void testHashNullValue() throws Exception { + } + + // Lettuce closePipeline() is now returning converted data types for executed txs, but + // DefaultStringRedisConnection isn't converting byte[]s from exec() yet. + // We implement the conversion in convertResult(), but convertResult's a bit over-eager in certain scenarios, hence these overrides @Test(expected = RedisPipelineException.class) - public void exceptionExecuteNative() throws Exception { - connection.execute("ZadD", getClass() + "#foo\t0.90\titem"); - getResults(); - } - - @Test - public void testDbSize() { - connection.set("dbparam", "foo"); - assertNull(connection.dbSize()); - List results = getResults(); - assertEquals(3, results.size()); - assertTrue((Long) results.get(2) > 0); - } - - @Test - public void testInfo() throws Exception { - assertNull(connection.info()); - List results = getResults(); - assertEquals(2, results.size()); - Properties info = LettuceUtils.info((String) results.get(1)); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testInfoBySection() throws Exception { - assertNull(connection.info("server")); - List results = getResults(); - assertEquals(2, results.size()); - Properties info = LettuceUtils.info((String) results.get(1)); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreBadData() { - // Use something other than dump-specific serialization - connection.restore("testing".getBytes(), 0, "foo".getBytes()); - getResults(); - } - - @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreExistingKey() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(2)); - try { - getResults(); - fail("Expected RedisPipelineException restoring existing key"); - }catch(RedisPipelineException e) { - } - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalShaNotFound() { - connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); - getResults(); - } - - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnSingleError() { - connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); - getResults(); + convert = false; + super.testRestoreExistingKey(); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnSingleOK() { - actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0)); - // We pipeline the result of multi, so add an extra OK here - assertEquals(Arrays.asList(new Object[] { "OK", "OK" }), convertResults(false)); + public void testScriptLoadEvalSha() { + convert = false; + super.testScriptLoadEvalSha(); } + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaArrayStrings() { + convert = false; + super.testEvalShaArrayStrings(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnString() { + convert = false; + super.testEvalReturnString(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayStrings() { + convert = false; + super.testEvalReturnArrayStrings(); + } + + @SuppressWarnings("unchecked") @Test @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnArrayOKs() { - actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", + actual.add(connection.eval( + "return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", ReturnType.MULTI, 0)); - // We pipeline the result of multi, so add an extra OK here - assertEquals(Arrays.asList(new Object[] {"OK", Arrays.asList(new Object[] {"OK", "OK"} )}), convertResults(false)); + List result = (List) getResults().get(0); + assertEquals(Arrays.asList(new Object[] { "OK", "OK" }), result); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testDumpAndRestore() { + convert = false; + connection.set("testing", "12"); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); + actual.add((connection.get("testing"))); + connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); + actual.add(connection.get("testing")); + results = getResults(); + assertEquals(3,results.size()); + assertEquals(1l, results.get(0)); + assertNull(results.get(1)); + assertEquals("12", new String((byte[])results.get(2))); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreTtl() { + convert = false; + super.testRestoreTtl(); + } + + @Test + public void testExecute() { + convert = false; + super.testExecute(); + } + + @Test + public void testExecuteNoArgs() { + convert = false; + super.testExecuteNoArgs(); + } + + @SuppressWarnings("unchecked") + @Test + public void testZRevRangeByScoreOffsetCount() { + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d, 0, 5)); + assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })),(Set) getResults().get(2)); + } + + @SuppressWarnings("unchecked") + @Test + public void testZRevRangeByScore() { + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d)); + assertEquals(new LinkedHashSet(Arrays.asList(new String[] { "Bob", "James" })), (Set) getResults().get(2)); + } + + @Test + public void testZRevRangeByScoreWithScoresOffsetCount() { + convertToStringTuple = false; + super.testZRevRangeByScoreWithScoresOffsetCount(); + } + + @Test + public void testZRevRangeByScoreWithScores() { + convertToStringTuple = false; + super.testZRevRangeByScoreWithScores(); + } + + @Test(expected = UnsupportedOperationException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testScriptKill() { + // Impossible to call script kill in a tx because you can't issue the + // exec command while Redis is running a script + connection.scriptKill(); } protected void initConnection() { @@ -123,7 +239,47 @@ public class LettuceConnectionPipelineTxIntegrationTests extends protected List getResults() { assertNull(connection.exec()); - return connection.closePipeline(); + List pipelined = connection.closePipeline(); + List convertedResults = new ArrayList(); + for(Object result: pipelined) { + convertedResults.add(convertResult(result)); + } + return convertedResults; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object convertResult(Object result) { + if(!convert) { + return result; + } + if (result instanceof List && !(((List) result).isEmpty()) + && ((List) result).get(0) instanceof byte[]) { + return (SerializationUtils.deserialize((List) result, stringSerializer)); + } else if (result instanceof byte[]) { + return (stringSerializer.deserialize((byte[]) result)); + } else if (result instanceof Map + && ((Map) result).keySet().iterator().next() instanceof byte[]) { + return (SerializationUtils.deserialize((Map) result, stringSerializer)); + } else if (result instanceof Set && !(((Set) result).isEmpty())) { + Object firstResult = ((Set) result).iterator().next(); + if(firstResult instanceof byte[]) { + return (SerializationUtils.deserialize((Set) result, stringSerializer)); + } + } + if (result instanceof Set && !(((Set) result).isEmpty()) + && ((Set) result).iterator().next() instanceof Tuple) { + if(convertToStringTuple) { + return new SetConverter(new TupleConverter()) + .convert((Set)result); + } + } + return result; + } + + private class TupleConverter implements Converter { + public StringTuple convert(Tuple source) { + return new DefaultStringTuple(source, stringSerializer.deserialize(source.getValue())); + } } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java index fffe4ea96..d12b2fdb7 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java @@ -15,20 +15,34 @@ */ package org.springframework.data.redis.connection.lettuce; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.core.convert.converter.Converter; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests; +import org.springframework.data.redis.connection.DefaultStringRedisConnection; +import org.springframework.data.redis.connection.DefaultStringTuple; +import org.springframework.data.redis.connection.StringRedisConnection; +import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; +import org.springframework.data.redis.connection.convert.SetConverter; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.lambdaworks.redis.RedisException; +import com.lambdaworks.redis.KeyValue; +import com.lambdaworks.redis.ScoredValue; /** * Integration test of {@link LettuceConnection} functionality within a @@ -40,118 +54,313 @@ import com.lambdaworks.redis.RedisException; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("LettuceConnectionIntegrationTests-context.xml") public class LettuceConnectionTransactionIntegrationTests extends - LettuceConnectionPipelineIntegrationTests { + AbstractConnectionTransactionIntegrationTests { + + private boolean convertListToSet; + + private boolean convertToStringTuple=true; @Ignore - public void testMultiDiscard() { + public void testMultiConnectionsOneInTx() { } @Ignore - public void testMultiExec() { + public void testCloseBlockingOps() { } - @Ignore - public void testUnwatch() { + // Native Lettuce returns ZSets as Lists + @Test + public void testZAddAndZRange() { + convertListToSet = true; + super.testZAddAndZRange(); } - @Ignore - public void testWatch() { + @Test + public void testZIncrBy() { + convertListToSet = true; + super.testZIncrBy(); } - /* - * Using blocking ops inside a tx does not make a lot of sense as it would - * require blocking the entire server in order to execute the block - * atomically, which in turn does not allow other clients to perform a push - * operation. Also, Lettuce always times out in these scenarios b/c it waits - * for an actual response instead of accepting the null returned by op in tx - * * - */ - - @Ignore - public void testBLPop() { + @Test + public void testZInterStore() { + convertListToSet = true; + super.testZInterStore(); } - @Ignore - public void testBRPop() { + @Test + public void testZInterStoreAggWeights() { + convertListToSet = true; + super.testZInterStoreAggWeights(); } - @Ignore - public void testBRPopLPush() { + @Test + public void testZRangeWithScores() { + convertListToSet = true; + super.testZRangeWithScores(); } - @Ignore - public void testBLPopTimeout() { + @Test + public void testZRangeByScore() { + convertListToSet = true; + super.testZRangeByScore(); } - @Ignore - public void testBRPopTimeout() { + @Test + public void testZRangeByScoreOffsetCount() { + convertListToSet = true; + super.testZRangeByScoreOffsetCount(); } - @Ignore - public void testBRPopLPushTimeout() { + @Test + public void testZRangeByScoreWithScores() { + convertListToSet = true; + super.testZRangeByScoreWithScores(); } - @Ignore - public void testOpenPipelineTwice() { + @Test + public void testZRangeByScoreWithScoresOffsetCount() { + convertListToSet = true; + super.testZRangeByScoreWithScoresOffsetCount(); + } + + @Test + public void testZRevRange() { + convertListToSet = true; + super.testZRevRange(); + } + + @Test + public void testZRevRangeWithScores() { + convertListToSet = true; + super.testZRevRangeWithScores(); + } + + @Test + public void testZRem() { + convertListToSet = true; + super.testZRem(); + } + + @Test + public void testZRemRangeByRank() { + convertListToSet = true; + super.testZRemRangeByRank(); + } + + @Test + public void testZRemRangeByScore() { + convertListToSet = true; + super.testZRemRangeByScore(); + } + + @Test + public void testZUnionStore() { + convertListToSet = true; + super.testZUnionStore(); + } + + @Test + public void testZUnionStoreAggWeights() { + convertListToSet = true; + super.testZUnionStoreAggWeights(); + } + + @Test + public void testBitSet() throws Exception { + convertLongToBoolean = false; + String key = "bitset-test"; + connection.setBit(key, 0, false); + connection.setBit(key, 1, true); + actual.add(connection.getBit(key, 0)); + actual.add(connection.getBit(key, 1)); + // Lettuce setBit returns Long instead of void + verifyResults(Arrays.asList(new Object[] { 0l, 0l, 0l, 1l })); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testBitCount() { + convertLongToBoolean = false; + String key = "bitset-test"; + connection.setBit(key, 0, false); + connection.setBit(key, 1, true); + connection.setBit(key, 2, true); + actual.add(connection.bitCount(key)); + // Lettuce setBit returns Long instead of void + verifyResults(new ArrayList(Arrays.asList(0l, 0l, 0l, 2l))); + } + + @Test + public void testHKeys() { + convertListToSet = true; + super.testHKeys(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testBitOpNotMultipleSources() { + super.testBitOpNotMultipleSources(); } @Test public void exceptionExecuteNative() throws Exception { connection.execute("ZadD", getClass() + "#foo\t0.90\titem"); - // Syntax error on queued commands are swallowed and no results are returned + // Syntax error on queued commands are swallowed and no results are + // returned assertNull(getResults()); } @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreBadData() { - // Use something other than dump-specific serialization - connection.restore("testing".getBytes(), 0, "foo".getBytes()); - List results = getResults(); - assertTrue(results.get(0) instanceof RedisException); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreExistingKey() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(1)); - List restoreResults = getResults(); - assertTrue(restoreResults.get(0) instanceof RedisException); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalShaNotFound() { - connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); - List results = getResults(); - assertTrue(results.get(0) instanceof RedisException); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnSingleError() { - connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); - List results = getResults(); - assertTrue(results.get(0) instanceof RedisException); + public void testGetRangeSetRange() { + connection.set("rangekey", "supercalifrag"); + actual.add(connection.getRange("rangekey", 0l, 2l)); + connection.setRange("rangekey", "ck", 2); + actual.add(connection.get("rangekey")); + // Lettuce returns a value for setRange + verifyResults(Arrays.asList(new Object[] { "sup", 13l, "suckrcalifrag" })); } @Test(expected = UnsupportedOperationException.class) @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptKill() { - // Impossible to call script kill in a tx because you can't issue the - // exec command while Redis is running a script - connection.scriptKill(); + public void testSRandMemberCountNegative() { + super.testSRandMemberCountNegative(); } - protected void initConnection() { - connection.multi(); + @Test + public void testSortStoreNullParams() { + convertLongToBoolean = false; + super.testSortStoreNullParams(); } - protected List getResults() { - return connection.exec(); + @SuppressWarnings("unchecked") + @Test + public void testZRevRangeByScoreOffsetCount() { + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d, 0, 5)); + assertEquals(Arrays.asList(new String[] { "Bob", "James" }),(List) getResults().get(2)); + } + + @SuppressWarnings("unchecked") + @Test + public void testZRevRangeByScore() { + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d)); + assertEquals(Arrays.asList(new String[] { "Bob", "James" }), (List) getResults().get(2)); + } + + @SuppressWarnings("unchecked") + @Test + public void testZRevRangeByScoreWithScoresOffsetCount() { + actual.add(byteConnection.zAdd("myset".getBytes(), 2, "Bob".getBytes())); + actual.add(byteConnection.zAdd("myset".getBytes(), 1, "James".getBytes())); + actual.add(byteConnection.zRevRangeByScore("myset".getBytes(), 0d, 3d, 0, 5)); + assertEquals(Arrays.asList(new String[] { "Bob", "James" }), + (List) getResults().get(2)); + } + + @Test + public void testZRevRangeByScoreWithScores() { + convertToStringTuple = false; + super.testZRevRangeByScoreWithScores(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnSingleOK() { + actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0)); + assertEquals(Arrays.asList(new Object[] { "OK" }), connection.exec()); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testDumpAndRestore() { + convert = false; + connection.set("testing", "12"); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); + actual.add((connection.get("testing"))); + connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); + actual.add(connection.get("testing")); + results = getResults(); + assertEquals(3,results.size()); + assertEquals(1l, results.get(0)); + assertNull(results.get(1)); + assertEquals("12", new String((byte[])results.get(2))); + } + + @SuppressWarnings("unchecked") + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayOKs() { + actual.add(connection.eval( + "return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", + ReturnType.MULTI, 0)); + List result = (List) getResults().get(0); + assertEquals(Arrays.asList(new Object[] { "OK", "OK" }), result); + } + + @Test + public void testMove() { + connection.set("foo", "bar"); + actual.add(connection.move("foo", 1)); + verifyResults(Arrays.asList(new Object[] { true})); + // Lettuce does not support select when using shared conn, use a new conn factory + LettuceConnectionFactory factory2 = new LettuceConnectionFactory(); + factory2.setDatabase(1); + factory2.afterPropertiesSet(); + StringRedisConnection conn2 = new DefaultStringRedisConnection(factory2.getConnection()); + try { + assertEquals("bar",conn2.get("foo")); + } finally { + if(conn2.exists("foo")) { + conn2.del("foo"); + } + conn2.close(); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + protected Object convertResult(Object result) { + if (!convert) { + return result; + } + Object convertedResult = super.convertResult(result); + if (convertedResult instanceof KeyValue) { + List keyValue = new ArrayList(); + keyValue.add((String) super.convertResult(((KeyValue) convertedResult).key)); + keyValue.add((String) super.convertResult(((KeyValue) convertedResult).value)); + return keyValue; + } + if (convertedResult instanceof List && !(((List) result).isEmpty()) + && ((List) convertedResult).get(0) instanceof ScoredValue) { + Set tuples = LettuceConverters.toTupleSet((List) convertedResult); + if(convertToStringTuple) { + return new SetConverter(new TupleConverter()) + .convert(tuples); + } + return tuples; + } + if (convertListToSet && convertedResult instanceof List) { + return new LinkedHashSet((List) convertedResult); + } + if (convertStringToProps && convertedResult instanceof String) { + return LettuceConverters.toProperties((String) convertedResult); + } + return convertedResult; + } + + private class TupleConverter implements Converter { + public StringTuple convert(Tuple source) { + return new DefaultStringTuple(source, stringSerializer.deserialize(source.getValue())); + } + } + + @Override + protected DataAccessException convertException(Exception ex) { + return LettuceConverters.toDataAccessException(ex); } } diff --git a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests.java index aa760d23c..fa7f4e419 100644 --- a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests.java @@ -17,13 +17,16 @@ package org.springframework.data.redis.connection.srp; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import java.util.Arrays; +import java.util.List; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests; +import org.springframework.data.redis.connection.DefaultStringRedisConnection; import org.springframework.data.redis.connection.ReturnType; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.context.ContextConfiguration; @@ -66,18 +69,15 @@ public class SrpConnectionIntegrationTests extends AbstractConnectionIntegration @Test @IfProfileValue(name = "redisVersion", values = {"2.4", "2.6"}) public void testGetRangeSetRange() { + // SRP throws an Exception if you try to execute on version lower than 2.4 super.testGetRangeSetRange(); } - @Test - public void testExecute() { - connection.set("foo", "bar"); - assertEquals("bar", stringSerializer.deserialize((byte[])connection.execute("GET", "foo"))); - } - @Test public void testExecuteNoArgs() { - assertEquals("PONG", connection.execute("PING")); + // SRP returns this as String while other drivers return as byte[] + actual.add(connection.execute("PING")); + verifyResults(Arrays.asList(new Object[] { "PONG" })); } @Test @@ -86,6 +86,43 @@ public class SrpConnectionIntegrationTests extends AbstractConnectionIntegration // SRP returns the Strings from individual StatusReplys in a MultiBulkReply, while other clients return as byte[] actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", ReturnType.MULTI, 0)); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"OK", "OK"} )}), actual); + verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"OK", "OK"} )})); + } + + @SuppressWarnings("unchecked") + @Test + public void testMultiExec() throws Exception { + connection.multi(); + connection.set("key", "value"); + actual.add(connection.get("key")); + actual.add(connection.exec()); + List results = getResults(); + assertNull(results.get(0)); + List execResults = (List) results.get(1); + // SRP is already filtering out the void types since tx uses pipeline, so result size here is only 1 + assertEquals(1, execResults.size()); + // However, since DefaultStringRedisConnection doesn't yet convert tx results, the data is still in raw bytes + assertEquals("value", new String((byte[]) execResults.get(0))); + assertEquals("value", connection.get("key")); + } + + @SuppressWarnings("unchecked") + @Test + public void testUnwatch() throws Exception { + connection.set("testitnow", "willdo"); + connection.watch("testitnow".getBytes()); + connection.unwatch(); + connection.multi(); + DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( + connectionFactory.getConnection()); + conn2.set("testitnow", "something"); + connection.set("testitnow", "somethingelse"); + actual.add(connection.get("testitnow")); + actual.add(connection.exec()); + List results = getResults(); + assertNull(results.get(0)); + List execResults = (List) results.get(1); + // SRP is already filtering out the void types since tx uses pipeline, so result size here is only 1 + assertEquals("somethingelse", new String((byte[]) execResults.get(0))); } } diff --git a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineIntegrationTests.java index 60c20f258..4fdc230a5 100644 --- a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineIntegrationTests.java @@ -16,36 +16,20 @@ package org.springframework.data.redis.connection.srp; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.Set; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; -import org.springframework.data.redis.connection.DefaultStringTuple; import org.springframework.data.redis.connection.RedisPipelineException; -import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; -import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; -import org.springframework.data.redis.serializer.SerializationUtils; +import org.springframework.data.redis.connection.ReturnType; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import redis.reply.BulkReply; -import redis.reply.IntegerReply; -import redis.reply.Reply; -import redis.reply.StatusReply; - /** * Integration test of {@link SrpConnection} pipeline functionality * @@ -65,11 +49,12 @@ public class SrpConnectionPipelineIntegrationTests extends connection.multi(); connection.set("testitnow2", "notok"); connection.discard(); - // SRP throws Exception on transaction discard, so we expect pipeline exception here + // SRP throws Exception on transaction discard, so we expect pipeline + // exception here try { getResults(); fail("Closing the pipeline on a discarded tx should throw a RedisPipelineException"); - }catch(RedisPipelineException e) { + } catch (RedisPipelineException e) { } assertEquals("willdo", connection.get("testitnow")); connection.openPipeline(); @@ -77,23 +62,30 @@ public class SrpConnectionPipelineIntegrationTests extends testMultiExec(); } - // SRP sets results of all commands in the pipeline to RedisException if exec returns a + // SRP sets results of all commands in the pipeline to RedisException if + // exec returns a // null multi-bulk reply - @Test(expected=RedisPipelineException.class) + @Test(expected = RedisPipelineException.class) public void testWatch() throws Exception { - connection.set("testitnow", "willdo"); - connection.watch("testitnow".getBytes()); - //Give some time for watch to be asynch executed - Thread.sleep(500); - DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection( - connectionFactory.getConnection()); - conn2.set("testitnow", "something"); - conn2.close(); - connection.multi(); - connection.set("testitnow", "somethingelse"); - actual.add(connection.exec()); - actual.add(connection.get("testitnow")); - verifyResults(Arrays.asList(new Object[] { null, "something" }), actual); + super.testWatch(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayOKs() { + // SRP returns the Strings from individual StatusReplys in a + // MultiBulkReply, while other clients return as byte[] + actual.add(connection.eval( + "return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}", + ReturnType.MULTI, 0)); + verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] { "OK", "OK" }) })); + } + + @Test + public void testExecuteNoArgs() { + // SRP returns this as String while other drivers return as byte[] + actual.add(connection.execute("PING")); + verifyResults(Arrays.asList(new Object[] { "PONG" })); } @Test(expected = UnsupportedOperationException.class) @@ -105,147 +97,4 @@ public class SrpConnectionPipelineIntegrationTests extends public void testZUnionStoreAggWeights() { super.testZUnionStoreAggWeights(); } - - // Overrides, usually due to return values being Long vs Boolean or Set vs - // List - - @Test - public void testInfo() throws Exception { - assertNull(connection.info()); - List results = getResults(); - assertEquals(1, results.size()); - Properties info = SrpUtils.info(new BulkReply((byte[]) results.get(0))); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testInfoBySection() throws Exception { - assertNull(connection.info("server")); - List results = getResults(); - assertEquals(1, results.size()); - Properties info = SrpUtils.info(new BulkReply((byte[]) results.get(0))); - assertTrue("at least 5 settings should be present", info.size() >= 5); - String version = info.getProperty("redis_version"); - assertNotNull(version); - } - - @Test - public void testExists() { - connection.set("existent", "true"); - actual.add(connection.exists("existent")); - actual.add(connection.exists("nonexistent")); - verifyResults(Arrays.asList(new Object[] { 1l, 0l }), actual); - } - - @Test - public void testRename() { - connection.set("renametest", "testit"); - connection.rename("renametest", "newrenametest"); - actual.add(connection.get("newrenametest")); - actual.add(connection.exists("renametest")); - verifyResults(Arrays.asList(new Object[] { "testit", 0l }), actual); - } - - @Test - public void testSIsMember() { - convertResultToSet = true; - actual.add(connection.sAdd("myset", "foo")); - actual.add(connection.sAdd("myset", "bar")); - actual.add(connection.sIsMember("myset", "foo")); - actual.add(connection.sIsMember("myset", "baz")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, 0l }), actual); - } - - @Test - public void testZIncrBy() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 4, "Joe")); - actual.add(connection.zIncrBy("myset", 2, "Joe")); - actual.add(connection.zRangeByScore("myset", 6, 6)); - verifyResults( - Arrays.asList(new Object[] { 1l, 1l, 1l, "6", Collections.singletonList("Joe") }), - actual); - } - - @Test - public void testZScore() { - actual.add(connection.zAdd("myset", 2, "Bob")); - actual.add(connection.zAdd("myset", 1, "James")); - actual.add(connection.zAdd("myset", 3, "Joe")); - actual.add(connection.zScore("myset", "Joe")); - verifyResults(Arrays.asList(new Object[] { 1l, 1l, 1l, "3" }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", values = {"2.4", "2.6"}) - public void testGetRangeSetRange() { - super.testGetRangeSetRange(); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testIncrByDouble() { - connection.set("tdb", "4.5"); - actual.add(connection.incrBy("tdb", 7.2)); - actual.add(connection.get("tdb")); - // pipelined incrBy returns value as a byte[] instead of Double - verifyResults(Arrays.asList(new Object[] { "11.7" , "11.7" }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testHIncrByDouble() { - actual.add(connection.hSet("test", "key", "2.9")); - actual.add(connection.hIncrBy("test", "key", 3.5)); - actual.add(connection.hGet("test", "key")); - // pipelined hIncrBy returns value as a byte[] instead of Double - verifyResults(Arrays.asList(new Object[] { 1l, "6.4", "6.4" }), actual); - } - - @Test - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testScriptExists() { - getResults(); - String sha1 = connection.scriptLoad("return 'foo'"); - initConnection(); - actual.add(connection.scriptExists(sha1, "98777234")); - verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {1l, 0l})}), actual); - } - - @Test - public void testDel() { - connection.set("testing","123"); - actual.add(connection.del("testing")); - actual.add(connection.exists("testing")); - verifyResults(Arrays.asList(new Object[] { 1l, 0l }), actual); - } - - protected Object convertResult(Object result) { - Object convertedResult = super.convertResult(result); - if (convertedResult instanceof Reply[]) { - if (convertResultToSet) { - return SerializationUtils.deserialize(SrpUtils.toSet((Reply[]) convertedResult), - stringSerializer); - } else if (convertResultToTuples) { - Set tuples = SrpUtils.convertTuple((Reply[]) convertedResult); - List stringTuples = new ArrayList(); - for (Tuple tuple : tuples) { - stringTuples.add(new DefaultStringTuple(tuple, new String(tuple.getValue()))); - } - return stringTuples; - } else if(((Reply[]) convertedResult).length > 0 && ((Reply[])convertedResult)[0] instanceof IntegerReply) { - return SrpUtils.asIntegerList((Reply[])convertedResult); - } else if(((Reply[]) convertedResult).length > 0 && ((Reply[])convertedResult)[0] instanceof StatusReply) { - return SrpUtils.asStatusList((Reply[])convertedResult); - } else { - return SerializationUtils.deserialize( - SrpUtils.toBytesList((Reply[]) convertedResult), stringSerializer); - } - } - return convertedResult; - } } diff --git a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineTxIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineTxIntegrationTests.java index 822f8bfb5..8f78c0dbf 100644 --- a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineTxIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionPipelineTxIntegrationTests.java @@ -19,15 +19,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.RedisVersionUtils; import org.springframework.data.redis.connection.RedisPipelineException; -import org.springframework.data.redis.connection.ReturnType; -import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.test.annotation.IfProfileValue; /** @@ -69,9 +67,8 @@ public class SrpConnectionPipelineTxIntegrationTests extends SrpConnectionTransa assertNull(connection.exec()); assertNull(connection.get("foo")); List results = connection.closePipeline(); - assertEquals(2, results.size()); - assertEquals("OK", results.get(0)); - assertEquals("bar", new String((byte[]) results.get(1))); + assertEquals(1, results.size()); + assertEquals("bar", new String((byte[]) results.get(0))); assertEquals("bar", connection.get("foo")); } @@ -85,67 +82,39 @@ public class SrpConnectionPipelineTxIntegrationTests extends SrpConnectionTransa assertNull(connection.get("foo")); assertNull(connection.exec()); List results = connection.closePipeline(); - assertEquals(4, results.size()); - assertEquals("OK", results.get(0)); - assertEquals("bar", new String((byte[]) results.get(1))); - assertEquals("OK", results.get(2)); - assertEquals("baz", new String((byte[]) results.get(3))); - } - - @Test - @IfProfileValue(name = "redisVersion", values = {"2.4", "2.6"}) - public void testGetRangeSetRange() { - connection.set("rangekey", "supercalifrag"); - actual.add(connection.getRange("rangekey", 0l, 2l)); - connection.setRange("rangekey", "ck", 2); - actual.add(connection.get("rangekey")); - verifyResults(Arrays.asList(new Object[] { "sup", 13l, "suckrcalifrag" }), actual); + assertEquals(2, results.size()); + assertEquals("bar", new String((byte[]) results.get(0))); + assertEquals("baz", new String((byte[]) results.get(1))); } @Test(expected=RedisPipelineException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalShaNotFound() { - connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); - getResults(); + super.testEvalShaNotFound(); } @Test(expected=RedisPipelineException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testEvalReturnSingleError() { - connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); - getResults(); + super.testEvalReturnSingleError(); } - @Test(expected=RedisPipelineException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreBadData() { - // Use something other than dump-specific serialization - connection.restore("testing".getBytes(), 0, "foo".getBytes()); - getResults(); - } - - @Test + @Test(expected = RedisPipelineException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreExistingKey() { - connection.set("testing", "12"); - connection.dump("testing".getBytes()); - List results = getResults(); - initConnection(); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(1)); - try { - getResults(); - fail("Expected pipeline exception restoring an existing key"); - }catch(RedisPipelineException e) { - } + super.testRestoreExistingKey(); } - @Test(expected=RedisPipelineException.class) + @Test(expected = RedisPipelineException.class) @IfProfileValue(name = "redisVersion", value = "2.6") public void testBitOpNotMultipleSources() { - connection.set("key1", "abcd"); - connection.set("key2", "efgh"); - actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); - getResults(); + super.testBitOpNotMultipleSources(); + } + + @Test(expected = RedisPipelineException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testRestoreBadData() { + super.testRestoreBadData(); } protected void initConnection() { @@ -155,6 +124,12 @@ public class SrpConnectionPipelineTxIntegrationTests extends SrpConnectionTransa protected List getResults() { assertNull(connection.exec()); - return connection.closePipeline(); + List actual = connection.closePipeline(); + List serializedResults = new ArrayList(); + for (Object result : actual) { + Object convertedResult = convertResult(result); + serializedResults.add(convertedResult); + } + return serializedResults; } } diff --git a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionTransactionIntegrationTests.java index dfb1268bd..73a8d85ed 100644 --- a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionTransactionIntegrationTests.java @@ -15,25 +15,35 @@ */ package org.springframework.data.redis.connection.srp; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import org.junit.Ignore; import org.junit.Test; import org.springframework.data.redis.RedisSystemException; -import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; -import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.connection.DefaultStringTuple; +import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; +import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; +import org.springframework.data.redis.serializer.SerializationUtils; import org.springframework.test.annotation.IfProfileValue; + + /** * Integration test of {@link SrpConnection} functionality within a transaction * * @author Jennifer Hickey * */ -public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipelineIntegrationTests { +public class SrpConnectionTransactionIntegrationTests extends SrpConnectionIntegrationTests { + + private boolean convert = true; @Ignore public void testMultiDiscard() { @@ -48,7 +58,6 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel } @Ignore - @Test public void testWatch() { } @@ -56,7 +65,7 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel * Using blocking ops inside a tx does not make a lot of sense as it would * require blocking the entire server in order to execute the block * atomically, which in turn does not allow other clients to perform a push - * operation. + * operation. * */ @Ignore @@ -83,70 +92,132 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel public void testBRPopLPushTimeout() { } + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithNamedChannels() throws Exception { + } + + @Ignore("Pub/Sub not supported with transactions") + public void testPubSubWithPatterns() throws Exception { + } + @Ignore - public void testOpenPipelineTwice() { + public void testNullKey() throws Exception { + } + + @Ignore + public void testNullValue() throws Exception { + } + + @Ignore + public void testHashNullKey() throws Exception { + } + + @Ignore + public void testHashNullValue() throws Exception { } @Test(expected = RedisSystemException.class) public void exceptionExecuteNative() throws Exception { - connection.execute("ZadD", getClass() + "#foo\t0.90\titem"); - getResults(); + super.exceptionExecuteNative(); + } + + // SRP tx.exec() is now returning converted data types b/c it uses pipeline, but + // DefaultStringRedisConnection isn't converting byte[]s from exec() yet. + // We implement the conversion in convertResult(), but convertResult's a bit over-eager in certain scenarios, hence these overrides + + @Test + public void testExecute() { + convert = false; + super.testExecute(); } @Test - @IfProfileValue(name = "redisVersion", values = { "2.4", "2.6" }) - public void testGetRangeSetRange() { - connection.set("rangekey", "supercalifrag"); - actual.add(connection.getRange("rangekey", 0l, 2l)); - connection.setRange("rangekey", "ck", 2); - actual.add(connection.get("rangekey")); - verifyResults(Arrays.asList(new Object[] { "sup", 13l, "suckrcalifrag" }), actual); - } - - @Test(expected=RedisSystemException.class) @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalReturnSingleError() { - connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0); - getResults(); - } - - @Test(expected=RedisSystemException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testEvalShaNotFound() { - connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2"); - getResults(); - } - - @Test(expected=RedisSystemException.class) - @IfProfileValue(name = "redisVersion", value = "2.6") - public void testRestoreBadData() { - // Use something other than dump-specific serialization - connection.restore("testing".getBytes(), 0, "foo".getBytes()); - getResults(); + public void testScriptLoadEvalSha() { + convert = false; + super.testScriptLoadEvalSha(); } @Test @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalShaArrayStrings() { + convert = false; + super.testEvalShaArrayStrings(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnString() { + convert = false; + super.testEvalReturnString(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testEvalReturnArrayStrings() { + convert = false; + super.testEvalReturnArrayStrings(); + } + + @Test + @IfProfileValue(name = "redisVersion", value = "2.6") + public void testDumpAndRestore() { + convert = false; + connection.set("testing", "12"); + actual.add(connection.dump("testing".getBytes())); + List results = getResults(); + initConnection(); + actual.add(connection.del("testing")); + actual.add((connection.get("testing"))); + connection.restore("testing".getBytes(), 0, (byte[]) results.get(results.size() - 1)); + actual.add(connection.get("testing")); + results = getResults(); + assertEquals(3,results.size()); + assertEquals(1l, results.get(0)); + assertNull(results.get(1)); + assertEquals("12", new String((byte[])results.get(2))); + } + + @Test(expected = RedisSystemException.class) + @IfProfileValue(name = "redisVersion", value = "2.6") public void testRestoreExistingKey() { connection.set("testing", "12"); - connection.dump("testing".getBytes()); + actual.add(connection.dump("testing".getBytes())); List results = getResults(); initConnection(); - connection.restore("testing".getBytes(), 0, (byte[]) results.get(1)); - try { - getResults(); - fail("Expected pipeline exception restoring an existing key"); - }catch(RedisSystemException e) { - } + connection.restore("testing".getBytes(), 0, ((String)results.get(0)).getBytes()); + getResults(); } - @Test(expected=RedisSystemException.class) + @Test @IfProfileValue(name = "redisVersion", value = "2.6") - public void testBitOpNotMultipleSources() { - connection.set("key1", "abcd"); - connection.set("key2", "efgh"); - actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); - getResults(); + public void testRestoreTtl() { + convert = false; + super.testRestoreTtl(); + } + + @Test + public void testZRevRangeByScoreOffsetCount() { + convert = false; + super.testZRevRangeByScoreOffsetCount(); + } + + @Test + public void testZRevRangeByScore() { + convert = false; + super.testZRevRangeByScore(); + } + + @Test + public void testZRevRangeByScoreWithScoresOffsetCount() { + convert = false; + super.testZRevRangeByScoreWithScoresOffsetCount(); + } + + @Test + public void testZRevRangeByScoreWithScores() { + convert = false; + super.testZRevRangeByScoreWithScores(); } @Test(expected = UnsupportedOperationException.class) @@ -162,6 +233,52 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel } protected List getResults() { - return connection.exec(); + List actual = connection.exec(); + List serializedResults = new ArrayList(); + for (Object result : actual) { + Object convertedResult = convertResult(result); + serializedResults.add(convertedResult); + } + return serializedResults; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object convertResult(Object result) { + if(! convert) { + return result; + } + if (result instanceof List && !(((List) result).isEmpty()) + && ((List) result).get(0) instanceof byte[]) { + return (SerializationUtils.deserialize((List) result, stringSerializer)); + } else if (result instanceof byte[]) { + return (stringSerializer.deserialize((byte[]) result)); + } else if (result instanceof Map + && ((Map) result).keySet().iterator().next() instanceof byte[]) { + return (SerializationUtils.deserialize((Map) result, stringSerializer)); + } else if (result instanceof Set && !(((Set) result).isEmpty())) { + Object firstResult = ((Set) result).iterator().next(); + if(firstResult instanceof byte[]) { + return (SerializationUtils.deserialize((Set) result, stringSerializer)); + } + if(firstResult instanceof Tuple) { + Set tuples = new LinkedHashSet(); + for (Tuple value : ((Set) result)) { + DefaultStringTuple tuple = new DefaultStringTuple(value,stringSerializer.deserialize(value.getValue())); + tuples.add(tuple); + } + return tuples; + } + } + return result; + } + + protected void verifyResults(List expected) { + List expectedTx = new ArrayList(); + for (int i = 0; i < actual.size(); i++) { + expectedTx.add(null); + } + assertEquals(expectedTx, actual); + List results = getResults(); + assertEquals(expected, results); } } diff --git a/src/test/resources/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests-context.xml index 876c19840..e5a93aef9 100644 --- a/src/test/resources/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests-context.xml +++ b/src/test/resources/org/springframework/data/redis/connection/jedis/JedisConnectionIntegrationTests-context.xml @@ -10,7 +10,7 @@ reconnect them on next attempted use --> + p:usePool="false" p:timeout="60000"> diff --git a/src/test/resources/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests-context.xml index dcbe15f1d..75da6c57d 100644 --- a/src/test/resources/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests-context.xml +++ b/src/test/resources/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests-context.xml @@ -11,7 +11,6 @@ - \ No newline at end of file diff --git a/src/test/resources/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests-context.xml index 1739fe362..89a45052b 100644 --- a/src/test/resources/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests-context.xml +++ b/src/test/resources/org/springframework/data/redis/connection/srp/SrpConnectionIntegrationTests-context.xml @@ -13,7 +13,6 @@ - \ No newline at end of file