Package org.springframework.data.redis.cache

Source Code of org.springframework.data.redis.cache.RedisCacheTest

/*
* Copyright 2011-2014 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.redis.cache;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeThat;
import static org.springframework.data.redis.matcher.RedisTestMatchers.isEqual;

import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.ConnectionFactoryTracker;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.core.AbstractOperationsTestParams;
import org.springframework.data.redis.core.RedisTemplate;

/**
* @author Costin Leau
* @author Jennifer Hickey
* @author Christoph Strobl
*/
@SuppressWarnings("rawtypes")
@RunWith(Parameterized.class)
public class RedisCacheTest extends AbstractNativeCacheTest<RedisTemplate> {

  private ObjectFactory<Object> keyFactory;
  private ObjectFactory<Object> valueFactory;
  private RedisTemplate template;

  public RedisCacheTest(RedisTemplate template, ObjectFactory<Object> keyFactory, ObjectFactory<Object> valueFactory) {
    this.keyFactory = keyFactory;
    this.valueFactory = valueFactory;
    this.template = template;
    ConnectionFactoryTracker.add(template.getConnectionFactory());
  }

  @Parameters
  public static Collection<Object[]> testParams() {
    return AbstractOperationsTestParams.testParams();
  }

  @SuppressWarnings("unchecked")
  protected RedisCache createCache(RedisTemplate nativeCache) {
    return new RedisCache(CACHE_NAME, CACHE_NAME.concat(":").getBytes(), nativeCache, TimeUnit.MINUTES.toSeconds(10));
  }

  protected RedisTemplate createNativeCache() throws Exception {
    return template;
  }

  @Before
  public void setUp() throws Exception {
    ConnectionFactoryTracker.add(template.getConnectionFactory());
    super.setUp();
  }

  @AfterClass
  public static void cleanUp() {
    ConnectionFactoryTracker.cleanUp();
  }

  protected Object getValue() {
    return valueFactory.instance();
  }

  protected Object getKey() {
    return keyFactory.instance();
  }

  @Test
  public void testConcurrentRead() throws Exception {
    final Object key1 = getKey();
    final Object value1 = getValue();

    final Object k1 = getKey();
    final Object v1 = getValue();

    final Object key2 = getKey();
    final Object value2 = getValue();

    final Object k2 = getKey();
    final Object v2 = getValue();

    final AtomicBoolean failed = new AtomicBoolean(true);
    cache.put(key1, value1);
    cache.put(key2, value2);

    Thread th = new Thread(new Runnable() {
      public void run() {
        cache.clear();
        cache.put(k1, v1);
        cache.put(k2, v2);
        failed.set(v1.equals(cache.get(k1)));

      }
    }, "concurrent-cache-access");
    th.start();
    th.join();

    assertFalse(failed.get());

    final Object key3 = getKey();
    final Object key4 = getKey();
    final Object value3 = getValue();
    final Object value4 = getValue();

    cache.put(key3, value3);
    cache.put(key4, value4);

    assertNull(cache.get(key1));
    assertNull(cache.get(key2));
    ValueWrapper valueWrapper = cache.get(k1);
    assertNotNull(valueWrapper);
    assertThat(valueWrapper.get(), isEqual(v1));
  }

  @Test
  public void testCacheName() throws Exception {
    CacheManager redisCM = new RedisCacheManager(template);
    String cacheName = "s2gx11";
    Cache cache = redisCM.getCache(cacheName);
    assertNotNull(cache);
    assertTrue(redisCM.getCacheNames().contains(cacheName));
  }

  @Test
  public void testGetWhileClear() throws InterruptedException {
    final Object key1 = getKey();
    final Object value1 = getValue();
    int numTries = 10;
    final AtomicBoolean monitorStateException = new AtomicBoolean(false);
    final CountDownLatch latch = new CountDownLatch(numTries);
    Runnable clearCache = new Runnable() {
      public void run() {
        cache.clear();
      }
    };
    Runnable putCache = new Runnable() {
      public void run() {
        try {
          cache.put(key1, value1);
        } catch (IllegalMonitorStateException e) {
          monitorStateException.set(true);
        } finally {
          latch.countDown();
        }
      }
    };
    for (int i = 0; i < numTries; i++) {
      new Thread(clearCache).start();
      new Thread(putCache).start();
    }
    latch.await();
    assertFalse(monitorStateException.get());
  }

  /**
   * @see DATAREDIS-243
   */
  @Test
  public void testCacheGetShouldReturnCachedInstance() {
    assumeThat(cache, instanceOf(RedisCache.class));

    Object key = getKey();
    Object value = getValue();
    cache.put(key, value);

    assertThat(value, isEqual(((RedisCache) cache).get(key, Object.class)));
  }

  /**
   * @see DATAREDIS-243
   */
  @Test
  public void testCacheGetShouldRetunInstanceOfCorrectType() {
    assumeThat(cache, instanceOf(RedisCache.class));

    Object key = getKey();
    Object value = getValue();
    cache.put(key, value);

    RedisCache redisCache = (RedisCache) cache;
    assertThat(redisCache.get(key, value.getClass()), instanceOf(value.getClass()));
  }

  /**
   * @see DATAREDIS-243
   */
  @Test(expected = ClassCastException.class)
  public void testCacheGetShouldThrowExceptionOnInvalidType() {
    assumeThat(cache, instanceOf(RedisCache.class));

    Object key = getKey();
    Object value = getValue();
    cache.put(key, value);

    RedisCache redisCache = (RedisCache) cache;
    @SuppressWarnings("unused")
    Cache retrievedObject = redisCache.get(key, Cache.class);
  }

  /**
   * @see DATAREDIS-243
   */
  @Test
  public void testCacheGetShouldReturnNullIfNoCachedValueFound() {
    assumeThat(cache, instanceOf(RedisCache.class));

    Object key = getKey();
    Object value = getValue();
    cache.put(key, value);

    RedisCache redisCache = (RedisCache) cache;

    Object invalidKey = template.getKeySerializer() == null ? "spring-data-redis".getBytes() : "spring-data-redis";
    assertThat(redisCache.get(invalidKey, value.getClass()), nullValue());
  }

  /**
   * @see DATAREDIS-344
   */
  @Test
  public void putIfAbsentShouldSetValueOnlyIfNotPresent() {

    assumeThat(cache, instanceOf(RedisCache.class));

    RedisCache redisCache = (RedisCache)cache;
   
    Object key = getKey();
    template.delete(key);

    Object value = getValue();
    ValueWrapper wrapper = redisCache.putIfAbsent(key, value);

    assertThat(wrapper.get(), sameInstance(value));

    ValueWrapper wrapper2 = redisCache.putIfAbsent(key, value);

    if (!(value instanceof Number)) {
      assertThat(wrapper2.get(), not(sameInstance(value)));
    }

    assertThat(wrapper2.get(), equalTo(value));
  }
}
TOP

Related Classes of org.springframework.data.redis.cache.RedisCacheTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.