Improve RedisTemplate test coverage

This commit is contained in:
Jennifer Hickey
2013-07-29 17:42:40 -07:00
parent 4505629ad8
commit b190103056
4 changed files with 306 additions and 45 deletions

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis;
import java.text.DecimalFormat;
import java.util.Random;
/**
@@ -27,8 +28,10 @@ public class DoubleObjectFactory implements ObjectFactory<Double> {
private Random random = new Random(System.currentTimeMillis());
private static final DecimalFormat TWO_D_FORM = new DecimalFormat("#.##");
public Double instance() {
return random.nextDouble();
return Double.valueOf(TWO_D_FORM.format(random.nextDouble()));
}
}

View File

@@ -18,10 +18,14 @@ package org.springframework.data.redis.core;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.data.redis.DoubleObjectFactory;
import org.springframework.data.redis.LongObjectFactory;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.SettingsUtils;
import org.springframework.data.redis.StringObjectFactory;
import org.springframework.data.redis.connection.srp.SrpConnectionFactory;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Parameters for testing implementations of {@link AbstractOperations}
@@ -33,13 +37,27 @@ abstract public class AbstractOperationsTestParams {
public static Collection<Object[]> testParams() {
ObjectFactory<String> stringFactory = new StringObjectFactory();
ObjectFactory<Long> longFactory = new LongObjectFactory();
ObjectFactory<Double> doubleFactory = new DoubleObjectFactory();
SrpConnectionFactory srConnFactory = new SrpConnectionFactory();
srConnFactory.setPort(SettingsUtils.getPort());
srConnFactory.setHostName(SettingsUtils.getHost());
srConnFactory.afterPropertiesSet();
RedisTemplate<String, String> stringTemplate = new StringRedisTemplate();
RedisTemplate<String,String> stringTemplate = new StringRedisTemplate();
stringTemplate.setConnectionFactory(srConnFactory);
stringTemplate.afterPropertiesSet();
return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory } });
RedisTemplate<String,Long> longTemplate = new RedisTemplate<String,Long>();
longTemplate.setKeySerializer(new StringRedisSerializer());
longTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
longTemplate.setConnectionFactory(srConnFactory);
longTemplate.afterPropertiesSet();
RedisTemplate<String,Double> doubleTemplate = new RedisTemplate<String,Double>();
doubleTemplate.setKeySerializer(new StringRedisSerializer());
doubleTemplate.setValueSerializer(new GenericToStringSerializer<Double>(Double.class));
doubleTemplate.setConnectionFactory(srConnFactory);
doubleTemplate.afterPropertiesSet();
return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory },
{ longTemplate, stringFactory, longFactory }, { doubleTemplate, stringFactory, doubleFactory }
});
}
}

View File

@@ -74,29 +74,7 @@ public class DefaultValueOperationsTests<K,V> {
@Parameters
public static Collection<Object[]> testParams() {
ObjectFactory<String> stringFactory = new StringObjectFactory();
ObjectFactory<Long> longFactory = new LongObjectFactory();
ObjectFactory<Double> doubleFactory = new DoubleObjectFactory();
SrpConnectionFactory srConnFactory = new SrpConnectionFactory();
srConnFactory.setPort(SettingsUtils.getPort());
srConnFactory.setHostName(SettingsUtils.getHost());
srConnFactory.afterPropertiesSet();
RedisTemplate<String,String> stringTemplate = new StringRedisTemplate();
stringTemplate.setConnectionFactory(srConnFactory);
stringTemplate.afterPropertiesSet();
RedisTemplate<String,Long> longTemplate = new RedisTemplate<String,Long>();
longTemplate.setKeySerializer(new StringRedisSerializer());
longTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
longTemplate.setConnectionFactory(srConnFactory);
longTemplate.afterPropertiesSet();
RedisTemplate<String,Double> doubleTemplate = new RedisTemplate<String,Double>();
doubleTemplate.setKeySerializer(new StringRedisSerializer());
doubleTemplate.setValueSerializer(new GenericToStringSerializer<Double>(Double.class));
doubleTemplate.setConnectionFactory(srConnFactory);
doubleTemplate.afterPropertiesSet();
return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory },
{ longTemplate, stringFactory, longFactory }, { doubleTemplate, stringFactory, doubleFactory }
});
return AbstractOperationsTestParams.testParams();
}
@Before
@@ -134,13 +112,10 @@ public class DefaultValueOperationsTests<K,V> {
assumeTrue(v1 instanceof Double);
valueOps.set(key, v1);
DecimalFormat twoDForm = new DecimalFormat("#.##");
assertEquals(twoDForm.format(Double.valueOf((Double)v1 + 1.4)),
twoDForm.format(valueOps.increment(key, 1.4)));
assertEquals(twoDForm.format(Double.valueOf((Double)v1 + 1.4)),
twoDForm.format((Double) valueOps.get(key)));
assertEquals(Double.valueOf(twoDForm.format((Double)v1 + 1.4)), valueOps.increment(key, 1.4));
assertEquals(Double.valueOf(twoDForm.format((Double)v1 + 1.4)), valueOps.get(key));
valueOps.increment(key, -10d);
assertEquals(twoDForm.format(Double.valueOf((Double)v1 + 1.4 - 10d)),
twoDForm.format((Double) valueOps.get(key)));
assertEquals(Double.valueOf(twoDForm.format((Double)v1 + 1.4 - 10d)), valueOps.get(key));
}
@Test

View File

@@ -17,12 +17,17 @@ package org.springframework.data.redis.core;
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.assertFalse;
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.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -43,10 +48,12 @@ import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.RedisTestProfileValueSource;
import org.springframework.data.redis.SettingsUtils;
import org.springframework.data.redis.TestCondition;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.connection.srp.SrpConnectionFactory;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.data.redis.core.query.SortQueryBuilder;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@@ -153,7 +160,7 @@ public class RedisTemplateTests<K,V> {
}
@Test
public void testExecDeserializes() {
public void testExec() {
final K key1 = keyFactory.instance();
final V value1 = valueFactory.instance();
final K listKey = keyFactory.instance();
@@ -163,26 +170,23 @@ public class RedisTemplateTests<K,V> {
final K zsetKey = keyFactory.instance();
final V zsetValue = valueFactory.instance();
final K mapKey = keyFactory.instance();
final Object hashKey = redisTemplate.getHashKeySerializer().deserialize("test".getBytes());
final Object hashValue = redisTemplate.getHashValueSerializer().deserialize("passed".getBytes());
final Object hashKey = deserialize(serialize("test", redisTemplate.getHashKeySerializer()),
redisTemplate.getHashKeySerializer());
final Object hashValue = deserialize(serialize("passed", redisTemplate.getHashValueSerializer()),
redisTemplate.getHashValueSerializer());
List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.opsForValue().set(key1, value1);
// byte[]
operations.opsForValue().get(key1);
operations.opsForList().leftPush(listKey, listValue);
// List<byte[]>
operations.opsForList().range(listKey, 0l, 1l);
operations.opsForSet().add(setKey, setValue);
// Set<byte[]>
operations.opsForSet().members(setKey);
operations.opsForZSet().add(zsetKey, zsetValue, 1d);
// Set<TypedTuple>
operations.opsForZSet().rangeWithScores(zsetKey, 0l, -1l);
operations.opsForHash().put(mapKey, hashKey, hashValue);
// Map<byte[],byte[]>
operations.opsForHash().entries(mapKey);
return operations.exec();
}
@@ -197,6 +201,24 @@ public class RedisTemplateTests<K,V> {
results);
}
@Test
public void testDiscard() {
final K key1 = keyFactory.instance();
final V value1 = valueFactory.instance();
final V value2 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
redisTemplate.execute(new SessionCallback<List<Object>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.opsForValue().set(key1, value2);
operations.discard();
return null;
}
});
assertEquals(value1, redisTemplate.boundValueOps(key1).get());
}
@Test
public void testExecCustomSerializer() {
assumeTrue(redisTemplate instanceof StringRedisTemplate);
@@ -205,20 +227,15 @@ public class RedisTemplateTests<K,V> {
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.opsForValue().set("foo", "5");
// byte[]
operations.opsForValue().get("foo");
operations.opsForList().leftPush("foolist", "6");
// List<byte[]>
operations.opsForList().range("foolist", 0l, 1l);
operations.opsForSet().add("fooset", "7");
// Set<byte[]>
operations.opsForSet().members("fooset");
operations.opsForZSet().add("foozset", "9", 1d);
// Set<TypedTuple>
operations.opsForZSet().rangeWithScores("foozset", 0l, -1l);
operations.opsForZSet().range("foozset", 0, -1);
operations.opsForHash().put("foomap", "10", "11");
// Map<byte[],byte[]>
operations.opsForHash().entries("foomap");
return operations.exec(new GenericToStringSerializer<Long>(Long.class));
}
@@ -356,8 +373,256 @@ public class RedisTemplateTests<K,V> {
});
}
@Test
public void testDelete() {
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
assertTrue(redisTemplate.hasKey(key1));
redisTemplate.delete(key1);
assertFalse(redisTemplate.hasKey(key1));
}
@Test
public void testDeleteMultiple() {
K key1 = keyFactory.instance();
K key2 = keyFactory.instance();
V value1 = valueFactory.instance();
V value2 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
redisTemplate.opsForValue().set(key2, value2);
List<K> keys = new ArrayList<K>();
keys.add(key1);
keys.add(key2);
redisTemplate.delete(keys);
assertFalse(redisTemplate.hasKey(key1));
assertFalse(redisTemplate.hasKey(key2));
}
@Test
public void testSort() {
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
assumeTrue(value1 instanceof Number);
redisTemplate.opsForList().rightPush(key1, value1);
List<V> results = redisTemplate.sort(SortQueryBuilder.sort(key1).build());
assertEquals(Collections.singletonList(value1), results);
}
@Test
public void testSortStore() {
K key1 = keyFactory.instance();
K key2 = keyFactory.instance();
V value1 = valueFactory.instance();
assumeTrue(value1 instanceof Number);
redisTemplate.opsForList().rightPush(key1, value1);
assertEquals(Long.valueOf(1), redisTemplate.sort(SortQueryBuilder.sort(key1).build(), key2));
assertEquals(Collections.singletonList(value1), redisTemplate.boundListOps(key2).range(0, -1));
}
@Test
public void testSortBulkMapper() {
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
assumeTrue(value1 instanceof Number);
redisTemplate.opsForList().rightPush(key1, value1);
List<String> results = redisTemplate.sort(SortQueryBuilder.sort(key1).get("#").build(), new BulkMapper<String, V>() {
public String mapBulk(List<V> tuple) {
return "FOO";
}
});
assertEquals(Collections.singletonList("FOO"),results);
}
@Test
public void testExpireAndGetExpire() {
assumeTrue(RedisTestProfileValueSource.matches("redisVersion", "2.6") &&
RedisTestProfileValueSource.matches("runLongTests", "true"));
final K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.boundValueOps(key1).set(value1);
redisTemplate.expire(key1, 1, TimeUnit.SECONDS);
assertTrue(redisTemplate.getExpire(key1) > 0l);
waitFor(new TestCondition() {
public boolean passes() {
return (!redisTemplate.hasKey(key1));
}
}, 1500l);
}
@Test
public void testExpireAt() {
assumeTrue(RedisTestProfileValueSource.matches("redisVersion", "2.6") &&
RedisTestProfileValueSource.matches("runLongTests", "true"));
final K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.boundValueOps(key1).set(value1);
redisTemplate.expireAt(key1, new Date(System.currentTimeMillis() + 1000l));
waitFor(new TestCondition() {
public boolean passes() {
return (!redisTemplate.hasKey(key1));
}
}, 1500l);
}
@Test
public void testPersist() throws Exception {
assumeTrue(RedisTestProfileValueSource.matches("redisVersion", "2.6") &&
RedisTestProfileValueSource.matches("runLongTests", "true"));
final K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
redisTemplate.expire(key1, 1, TimeUnit.SECONDS);
redisTemplate.persist(key1);
Thread.sleep(1500);
assertTrue(redisTemplate.hasKey(key1));
}
@Test
public void testRandomKey() {
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
assertEquals(key1, redisTemplate.randomKey());
}
@Test
public void testRename() {
K key1 = keyFactory.instance();
K key2 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
redisTemplate.rename(key1, key2);
assertEquals(value1, redisTemplate.opsForValue().get(key2));
}
@Test
public void testRenameIfAbsent() {
K key1 = keyFactory.instance();
K key2 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
redisTemplate.renameIfAbsent(key1, key2);
assertTrue(redisTemplate.hasKey(key2));
}
@Test
public void testType() {
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
assertEquals(DataType.STRING,redisTemplate.type(key1));
}
@Test
public void testWatch() {
final K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
final V value2 = valueFactory.instance();
final V value3 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
final Thread th = new Thread(new Runnable() {
public void run() {
redisTemplate.opsForValue().set(key1, value2);
}
});
List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.watch(key1);
th.start();
try {
th.join();
} catch (InterruptedException e) {
}
operations.multi();
operations.opsForValue().set(key1, value3);
return operations.exec();
}
});
assertNull(results);
assertEquals(value2, redisTemplate.opsForValue().get(key1));
}
@Test
public void testUnwatch() {
final K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
final V value2 = valueFactory.instance();
final V value3 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
final Thread th = new Thread(new Runnable() {
public void run() {
redisTemplate.opsForValue().set(key1, value2);
}
});
List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.watch(key1);
th.start();
try {
th.join();
} catch (InterruptedException e) {
}
operations.unwatch();
operations.multi();
operations.opsForValue().set(key1, value3);
return operations.exec();
}
});
assertTrue(results.isEmpty());
assertEquals(value3, redisTemplate.opsForValue().get(key1));
}
@Test
public void testWatchMultipleKeys() {
final K key1 = keyFactory.instance();
final K key2 = keyFactory.instance();
V value1 = valueFactory.instance();
final V value2 = valueFactory.instance();
final V value3 = valueFactory.instance();
redisTemplate.opsForValue().set(key1, value1);
final Thread th = new Thread(new Runnable() {
public void run() {
redisTemplate.opsForValue().set(key1, value2);
}
});
List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public List<Object> execute(RedisOperations operations) throws DataAccessException {
List<K> keys = new ArrayList<K>();
keys.add(key1);
keys.add(key2);
operations.watch(keys);
th.start();
try {
th.join();
} catch (InterruptedException e) {
}
operations.multi();
operations.opsForValue().set(key1, value3);
return operations.exec();
}
});
assertNull(results);
assertEquals(value2, redisTemplate.opsForValue().get(key1));
}
@Test
public void testConvertAndSend() {
V value1 = valueFactory.instance();
// Make sure basic message sent without Exception on serialization
redisTemplate.convertAndSend("Channel", value1);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private byte[] serialize(Object value, RedisSerializer serializer) {
return serializer.serialize(value);
}
@SuppressWarnings("rawtypes")
private Object deserialize(byte[] value, RedisSerializer serializer) {
return serializer.deserialize(value);
}
}