diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java index 5e84e389f..ff580c50b 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java @@ -137,4 +137,31 @@ public class DefaultRedisMap implements RedisMap { public Collection values() { return hashOps.values(); } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + + if (o instanceof RedisMap) { + return o.hashCode() == hashCode(); + } + return false; + } + + @Override + public int hashCode() { + int result = 17 + getClass().hashCode(); + result = result * 31 + getKey().hashCode(); + return result; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("RedisStore for key:"); + sb.append(getKey()); + return sb.toString(); + } } \ No newline at end of file diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/AbstractRedisMapTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/AbstractRedisMapTests.java new file mode 100644 index 000000000..4d0ce897d --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/AbstractRedisMapTests.java @@ -0,0 +1,219 @@ +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.keyvalue.redis.util; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory; +import org.springframework.data.keyvalue.redis.core.RedisCallback; +import org.springframework.data.keyvalue.redis.core.RedisOperations; +import org.springframework.data.keyvalue.redis.core.RedisTemplate; + +/** + * Integration test for Redis Map. + * + * @author Costin Leau + */ +@RunWith(Parameterized.class) +public abstract class AbstractRedisMapTests { + + protected RedisMap map; + protected ObjectFactory keyFactory; + protected ObjectFactory valueFactory; + protected RedisTemplate template; + + private static Set connFactories = new LinkedHashSet(); + + abstract RedisMap createMap(); + + @Before + public void setUp() throws Exception { + map = createMap(); + } + + public AbstractRedisMapTests(ObjectFactory keyFactory, ObjectFactory valueFactory, RedisTemplate template) { + this.keyFactory = keyFactory; + this.valueFactory = valueFactory; + this.template = template; + connFactories.add(template.getConnectionFactory()); + } + + @AfterClass + public static void cleanUp() { + if (connFactories != null) { + for (RedisConnectionFactory connectionFactory : connFactories) { + try { + ((DisposableBean) connectionFactory).destroy(); + System.out.println("Succesfully cleaned up factory " + connectionFactory); + } catch (Exception ex) { + System.err.println("Cannot clean factory " + connectionFactory + ex); + } + } + } + } + + protected K getKey() { + return keyFactory.instance(); + } + + protected V getValue() { + return valueFactory.instance(); + } + + protected RedisStore copyStore(RedisStore store) { + return new DefaultRedisMap(store.getKey(), store.getOperations()); + } + + @After + public void tearDown() throws Exception { + // remove the collection entirely since clear() doesn't always work + map.getOperations().delete(map.getKey()); + template.execute(new RedisCallback() { + + @Override + public Object doInRedis(RedisConnection connection) { + connection.flushDb(); + return null; + } + }); + } + + @Test + public void testClear() { + map.clear(); + assertEquals(0, map.size()); + map.put(getKey(), getValue()); + assertEquals(1, map.size()); + map.clear(); + assertEquals(0, map.size()); + } + + @Test + public void testContainsKey() { + K k1 = getKey(); + K k2 = getKey(); + + assertFalse(map.containsKey(k1)); + assertFalse(map.containsKey(k2)); + map.put(k1, getValue()); + assertTrue(map.containsKey(k1)); + map.put(k2, getValue()); + assertTrue(map.containsKey(k2)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testContainsValue() { + V v1 = getValue(); + V v2 = getValue(); + + assertFalse(map.containsValue(v1)); + assertFalse(map.containsValue(v2)); + map.put(getKey(), v1); + assertTrue(map.containsValue(v1)); + map.put(getKey(), v2); + assertTrue(map.containsValue(v2)); + } + + public Set> entrySet() { + return map.entrySet(); + } + + @Test + public void testEquals() { + RedisStore clone = copyStore(map); + assertEquals(clone, map); + assertEquals(clone, clone); + assertEquals(map, map); + } + + @Test + public void testNotEquals() { + RedisOperations ops = map.getOperations(); + RedisStore newInstance = new DefaultRedisMap(ops. forHash(map.getKey() + ":new")); + assertFalse(map.equals(newInstance)); + assertFalse(newInstance.equals(map)); + } + + public V get(Object key) { + return map.get(key); + } + + @Test + public void testGetKey() { + assertNotNull(map.getKey()); + } + + public RedisOperations getOperations() { + return map.getOperations(); + } + + @Test + public void testHashCode() { + assertThat(map.hashCode(), not(equalTo(map.getKey().hashCode()))); + assertEquals(map.hashCode(), copyStore(map).hashCode()); + } + + public Integer increment(K key, int delta) { + return map.increment(key, delta); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public Set keySet() { + return map.keySet(); + } + + public V put(K key, V value) { + return map.put(key, value); + } + + public void putAll(Map m) { + map.putAll(m); + } + + public boolean putIfAbsent(K key, V value) { + return map.putIfAbsent(key, value); + } + + public V remove(Object key) { + return map.remove(key); + } + + public int size() { + return map.size(); + } + + public Collection values() { + return map.values(); + } +} \ No newline at end of file diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/RedisMapTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/RedisMapTests.java new file mode 100644 index 000000000..ea74a089d --- /dev/null +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/util/RedisMapTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.keyvalue.redis.util; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.runners.Parameterized.Parameters; +import org.springframework.data.keyvalue.redis.Person; +import org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.keyvalue.redis.core.RedisTemplate; + +/** + * Integration test for RedisMap. + * + * @author Costin Leau + */ +public class RedisMapTests extends AbstractRedisMapTests { + + public RedisMapTests(ObjectFactory keyFactory, ObjectFactory valueFactory, RedisTemplate template) { + super(keyFactory, valueFactory, template); + } + + @Override + RedisMap createMap() { + String redisName = getClass().getName(); + return new DefaultRedisMap(redisName, template); + } + + @Parameters + public static Collection testParams() { + // create Jedis Factory + ObjectFactory stringFactory = new StringObjectFactory(); + ObjectFactory personFactory = new PersonObjectFactory(); + + JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory(); + jedisConnFactory.setPooling(false); + jedisConnFactory.afterPropertiesSet(); + + RedisTemplate stringTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate personTemplate = new RedisTemplate(jedisConnFactory); + + // JredisConnectionFactory jredisConnFactory = new JredisConnectionFactory(); + // jredisConnFactory.setPooling(false); + // jredisConnFactory.afterPropertiesSet(); + // + // RedisTemplate stringTemplateJR = new RedisTemplate(jredisConnFactory); + // RedisTemplate personTemplateJR = new RedisTemplate(jredisConnFactory); + + return Arrays.asList(new Object[][] { { stringFactory, stringFactory, stringTemplate }, + { personFactory, personFactory, personTemplate } }); + } +} \ No newline at end of file