diff --git a/src/test/java/org/springframework/data/redis/DoubleObjectFactory.java b/src/test/java/org/springframework/data/redis/DoubleObjectFactory.java index a5e9622ad..fbc06485b 100644 --- a/src/test/java/org/springframework/data/redis/DoubleObjectFactory.java +++ b/src/test/java/org/springframework/data/redis/DoubleObjectFactory.java @@ -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 { 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())); } } diff --git a/src/test/java/org/springframework/data/redis/core/AbstractOperationsTestParams.java b/src/test/java/org/springframework/data/redis/core/AbstractOperationsTestParams.java index f41eb8fbf..7fc92f3e7 100644 --- a/src/test/java/org/springframework/data/redis/core/AbstractOperationsTestParams.java +++ b/src/test/java/org/springframework/data/redis/core/AbstractOperationsTestParams.java @@ -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 testParams() { ObjectFactory stringFactory = new StringObjectFactory(); + ObjectFactory longFactory = new LongObjectFactory(); + ObjectFactory doubleFactory = new DoubleObjectFactory(); SrpConnectionFactory srConnFactory = new SrpConnectionFactory(); srConnFactory.setPort(SettingsUtils.getPort()); srConnFactory.setHostName(SettingsUtils.getHost()); srConnFactory.afterPropertiesSet(); - RedisTemplate stringTemplate = new StringRedisTemplate(); + RedisTemplate stringTemplate = new StringRedisTemplate(); stringTemplate.setConnectionFactory(srConnFactory); stringTemplate.afterPropertiesSet(); - return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory } }); + RedisTemplate longTemplate = new RedisTemplate(); + longTemplate.setKeySerializer(new StringRedisSerializer()); + longTemplate.setValueSerializer(new GenericToStringSerializer(Long.class)); + longTemplate.setConnectionFactory(srConnFactory); + longTemplate.afterPropertiesSet(); + RedisTemplate doubleTemplate = new RedisTemplate(); + doubleTemplate.setKeySerializer(new StringRedisSerializer()); + doubleTemplate.setValueSerializer(new GenericToStringSerializer(Double.class)); + doubleTemplate.setConnectionFactory(srConnFactory); + doubleTemplate.afterPropertiesSet(); + return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory }, + { longTemplate, stringFactory, longFactory }, { doubleTemplate, stringFactory, doubleFactory } + }); } } diff --git a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java index cb7d66ad4..4f4f65820 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultValueOperationsTests.java @@ -74,29 +74,7 @@ public class DefaultValueOperationsTests { @Parameters public static Collection testParams() { - ObjectFactory stringFactory = new StringObjectFactory(); - ObjectFactory longFactory = new LongObjectFactory(); - ObjectFactory doubleFactory = new DoubleObjectFactory(); - SrpConnectionFactory srConnFactory = new SrpConnectionFactory(); - srConnFactory.setPort(SettingsUtils.getPort()); - srConnFactory.setHostName(SettingsUtils.getHost()); - srConnFactory.afterPropertiesSet(); - RedisTemplate stringTemplate = new StringRedisTemplate(); - stringTemplate.setConnectionFactory(srConnFactory); - stringTemplate.afterPropertiesSet(); - RedisTemplate longTemplate = new RedisTemplate(); - longTemplate.setKeySerializer(new StringRedisSerializer()); - longTemplate.setValueSerializer(new GenericToStringSerializer(Long.class)); - longTemplate.setConnectionFactory(srConnFactory); - longTemplate.afterPropertiesSet(); - RedisTemplate doubleTemplate = new RedisTemplate(); - doubleTemplate.setKeySerializer(new StringRedisSerializer()); - doubleTemplate.setValueSerializer(new GenericToStringSerializer(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 { 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 diff --git a/src/test/java/org/springframework/data/redis/core/RedisTemplateTests.java b/src/test/java/org/springframework/data/redis/core/RedisTemplateTests.java index 374d2b611..8bea1bca9 100644 --- a/src/test/java/org/springframework/data/redis/core/RedisTemplateTests.java +++ b/src/test/java/org/springframework/data/redis/core/RedisTemplateTests.java @@ -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 { } @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 { 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 results = redisTemplate.execute(new SessionCallback>() { @SuppressWarnings({ "rawtypes", "unchecked" }) public List execute(RedisOperations operations) throws DataAccessException { operations.multi(); operations.opsForValue().set(key1, value1); - // byte[] operations.opsForValue().get(key1); operations.opsForList().leftPush(listKey, listValue); - // List operations.opsForList().range(listKey, 0l, 1l); operations.opsForSet().add(setKey, setValue); - // Set operations.opsForSet().members(setKey); operations.opsForZSet().add(zsetKey, zsetValue, 1d); - // Set operations.opsForZSet().rangeWithScores(zsetKey, 0l, -1l); operations.opsForHash().put(mapKey, hashKey, hashValue); - // Map operations.opsForHash().entries(mapKey); return operations.exec(); } @@ -197,6 +201,24 @@ public class RedisTemplateTests { 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>() { + @SuppressWarnings({ "rawtypes", "unchecked" }) + public List 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 { public List execute(RedisOperations operations) throws DataAccessException { operations.multi(); operations.opsForValue().set("foo", "5"); - // byte[] operations.opsForValue().get("foo"); operations.opsForList().leftPush("foolist", "6"); - // List operations.opsForList().range("foolist", 0l, 1l); operations.opsForSet().add("fooset", "7"); - // Set operations.opsForSet().members("fooset"); operations.opsForZSet().add("foozset", "9", 1d); - // Set operations.opsForZSet().rangeWithScores("foozset", 0l, -1l); operations.opsForZSet().range("foozset", 0, -1); operations.opsForHash().put("foomap", "10", "11"); - // Map operations.opsForHash().entries("foomap"); return operations.exec(new GenericToStringSerializer(Long.class)); } @@ -356,8 +373,256 @@ public class RedisTemplateTests { }); } + @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 keys = new ArrayList(); + 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 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 results = redisTemplate.sort(SortQueryBuilder.sort(key1).get("#").build(), new BulkMapper() { + public String mapBulk(List 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 results = redisTemplate.execute(new SessionCallback>() { + @SuppressWarnings({ "unchecked", "rawtypes" }) + public List 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 results = redisTemplate.execute(new SessionCallback>() { + @SuppressWarnings({ "unchecked", "rawtypes" }) + public List 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 results = redisTemplate.execute(new SessionCallback>() { + @SuppressWarnings({ "unchecked", "rawtypes" }) + public List execute(RedisOperations operations) throws DataAccessException { + List keys = new ArrayList(); + 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); + } }