Validate converted pipeline results in conn tests
DATAREDIS-200
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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<String>(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<String>(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<String>(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<Object> getResults() {
|
||||
List<Object> actual = connection.exec();
|
||||
if (actual == null) {
|
||||
return null;
|
||||
}
|
||||
List<Object> serializedResults = new ArrayList<Object>();
|
||||
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<byte[]>) 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<Object> expected) {
|
||||
List<Object> expectedTx = new ArrayList<Object>();
|
||||
for (int i = 0; i < actual.size(); i++) {
|
||||
expectedTx.add(null);
|
||||
}
|
||||
assertEquals(expectedTx, actual);
|
||||
List<Object> results = getResults();
|
||||
assertEquals(expected, results);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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<String>")
|
||||
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<String> 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<String, String> expected = new HashMap<String, String>();
|
||||
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<StringTuple> tuples = new ArrayList<StringTuple>();
|
||||
for (Tuple value : ((Set<Tuple>) convertedResult)) {
|
||||
DefaultStringTuple tuple = new DefaultStringTuple(
|
||||
(byte[]) value.getBinaryElement(), value.getElement(), value.getScore());
|
||||
tuples.add(tuple);
|
||||
}
|
||||
return tuples;
|
||||
}
|
||||
}
|
||||
return convertedResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> 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<String> 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<StringTuple> tuples = new LinkedHashSet<StringTuple>();
|
||||
for (Tuple value : ((Set<Tuple>) convertedResult)) {
|
||||
DefaultStringTuple tuple = new DefaultStringTuple(
|
||||
(byte[]) value.getBinaryElement(), value.getElement(), value.getScore());
|
||||
tuples.add(tuple);
|
||||
}
|
||||
return tuples;
|
||||
}
|
||||
}
|
||||
return convertedResult;
|
||||
}
|
||||
|
||||
protected List<Object> getResults() {
|
||||
return connection.exec();
|
||||
@Override
|
||||
protected DataAccessException convertException(Exception ex) {
|
||||
return JedisConverters.toDataAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String>(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<String>(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<String>(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);
|
||||
|
||||
@@ -56,7 +56,7 @@ public class AuthenticatingRedisClientTests {
|
||||
|
||||
@Test
|
||||
public void codecConnect() {
|
||||
RedisConnection<byte[], byte[]> conn = client.connect(LettuceUtils.CODEC);
|
||||
RedisConnection<byte[], byte[]> conn = client.connect(LettuceConnection.CODEC);
|
||||
conn.ping();
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class AuthenticatingRedisClientTests {
|
||||
|
||||
@Test
|
||||
public void codecConnectAsync() {
|
||||
RedisAsyncConnection<byte[], byte[]> conn = client.connectAsync(LettuceUtils.CODEC);
|
||||
RedisAsyncConnection<byte[], byte[]> conn = client.connectAsync(LettuceConnection.CODEC);
|
||||
conn.ping();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AuthenticatingRedisClientTests {
|
||||
|
||||
@Test
|
||||
public void codecConnectPubSub() {
|
||||
RedisPubSubConnection<byte[], byte[]> conn = client.connectPubSub(LettuceUtils.CODEC);
|
||||
RedisPubSubConnection<byte[], byte[]> conn = client.connectPubSub(LettuceConnection.CODEC);
|
||||
conn.ping();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Object> 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<Object> 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<String, String> expected = new HashMap<String, String>();
|
||||
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<Object> 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<Object> 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<String, String> vals = new HashMap<String, String>();
|
||||
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<String, String> vals = new HashMap<String, String>();
|
||||
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<String>(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<Object> 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<Object> 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<String> keyValue = new ArrayList<String>();
|
||||
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<StringTuple> tuples = new ArrayList<StringTuple>();
|
||||
for (ScoredValue value : ((List<ScoredValue>) convertedResult)) {
|
||||
DefaultStringTuple tuple = new DefaultStringTuple((byte[]) value.value, new String(
|
||||
(byte[]) value.value), value.score);
|
||||
tuples.add(tuple);
|
||||
}
|
||||
return tuples;
|
||||
}
|
||||
return convertedResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object> results = getResults();
|
||||
assertEquals(3, results.size());
|
||||
assertTrue((Long) results.get(2) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInfo() throws Exception {
|
||||
assertNull(connection.info());
|
||||
List<Object> 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<Object> 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<Object> 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<String> result = (List<String>) 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<Object> 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<String>(Arrays.asList(new String[] { "Bob", "James" })),(Set<String>) 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<String>(Arrays.asList(new String[] { "Bob", "James" })), (Set<String>) 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<Object> getResults() {
|
||||
assertNull(connection.exec());
|
||||
return connection.closePipeline();
|
||||
List<Object> pipelined = connection.closePipeline();
|
||||
List<Object> convertedResults = new ArrayList<Object>();
|
||||
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<byte[]>) 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<Tuple, StringTuple>(new TupleConverter())
|
||||
.convert((Set)result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private class TupleConverter implements Converter<Tuple, StringTuple> {
|
||||
public StringTuple convert(Tuple source) {
|
||||
return new DefaultStringTuple(source, stringSerializer.deserialize(source.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Object>(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<Object> 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<Object> results = getResults();
|
||||
initConnection();
|
||||
connection.restore("testing".getBytes(), 0, (byte[]) results.get(1));
|
||||
List<Object> 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<Object> 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<Object> 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<Object> 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<String>) 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<String>) 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<byte[]>) 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<Object> 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<String> result = (List<String>) 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<String> keyValue = new ArrayList<String>();
|
||||
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<Tuple> tuples = LettuceConverters.toTupleSet((List) convertedResult);
|
||||
if(convertToStringTuple) {
|
||||
return new SetConverter<Tuple, StringTuple>(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<Tuple, StringTuple> {
|
||||
public StringTuple convert(Tuple source) {
|
||||
return new DefaultStringTuple(source, stringSerializer.deserialize(source.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataAccessException convertException(Exception ex) {
|
||||
return LettuceConverters.toDataAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object> results = getResults();
|
||||
assertNull(results.get(0));
|
||||
List<Object> execResults = (List<Object>) 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<Object> results = getResults();
|
||||
assertNull(results.get(0));
|
||||
List<Object> execResults = (List<Object>) 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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object> 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<Object> 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<Tuple> tuples = SrpUtils.convertTuple((Reply[]) convertedResult);
|
||||
List<StringTuple> stringTuples = new ArrayList<StringTuple>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object> 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<Object> 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<Object> 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<Object> getResults() {
|
||||
assertNull(connection.exec());
|
||||
return connection.closePipeline();
|
||||
List<Object> actual = connection.closePipeline();
|
||||
List<Object> serializedResults = new ArrayList<Object>();
|
||||
for (Object result : actual) {
|
||||
Object convertedResult = convertResult(result);
|
||||
serializedResults.add(convertedResult);
|
||||
}
|
||||
return serializedResults;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object> 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<Object> 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<Object> getResults() {
|
||||
return connection.exec();
|
||||
List<Object> actual = connection.exec();
|
||||
List<Object> serializedResults = new ArrayList<Object>();
|
||||
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<byte[]>) 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<StringTuple> tuples = new LinkedHashSet<StringTuple>();
|
||||
for (Tuple value : ((Set<Tuple>) result)) {
|
||||
DefaultStringTuple tuple = new DefaultStringTuple(value,stringSerializer.deserialize(value.getValue()));
|
||||
tuples.add(tuple);
|
||||
}
|
||||
return tuples;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void verifyResults(List<Object> expected) {
|
||||
List<Object> expectedTx = new ArrayList<Object>();
|
||||
for (int i = 0; i < actual.size(); i++) {
|
||||
expectedTx.add(null);
|
||||
}
|
||||
assertEquals(expectedTx, actual);
|
||||
List<Object> results = getResults();
|
||||
assertEquals(expected, results);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user