Package org.springmodules.cache.provider.jcs

Source Code of org.springmodules.cache.provider.jcs.JcsFacadeTests

/*
* Created on May 3, 2005
*
* 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.
*
* Copyright @2005 the original author or authors.
*/
package org.springmodules.cache.provider.jcs;

import java.beans.PropertyEditor;
import java.io.Serializable;
import java.lang.reflect.Method;

import junit.framework.TestCase;

import org.apache.jcs.engine.CacheElement;
import org.apache.jcs.engine.CompositeCacheAttributes;
import org.apache.jcs.engine.ElementAttributes;
import org.apache.jcs.engine.behavior.ICacheElement;
import org.apache.jcs.engine.behavior.ICompositeCacheAttributes;
import org.apache.jcs.engine.behavior.IElementAttributes;
import org.apache.jcs.engine.control.CompositeCache;
import org.apache.jcs.engine.control.CompositeCacheManager;
import org.apache.jcs.engine.control.group.GroupAttrName;
import org.apache.jcs.engine.control.group.GroupId;
import org.easymock.AbstractMatcher;
import org.easymock.MockControl;
import org.easymock.classextension.MockClassControl;

import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import org.springmodules.cache.FatalCacheException;
import org.springmodules.cache.provider.CacheAccessException;
import org.springmodules.cache.provider.CacheModelValidator;
import org.springmodules.cache.provider.CacheNotFoundException;
import org.springmodules.cache.provider.ReflectionCacheModelEditor;
import org.springmodules.cache.provider.jcs.JcsFlushingModel.CacheStruct;

/**
* <p>
* Unit Tests for <code>{@link JcsFacade}</code>.
* </p>
*
* @author Alex Ruiz
*/
public final class JcsFacadeTests extends TestCase {

  protected class CacheElementMatcher extends AbstractMatcher {
    /**
     * @see AbstractMatcher#argumentMatches(Object, Object)
     */
    protected boolean argumentMatches(Object expected, Object actual) {
      if (!(expected instanceof CacheElement)) {
        throw new IllegalArgumentException(
            "Element matcher only evaluates instances of <"
                + CacheElement.class.getName() + ">");
      }
      if (!(actual instanceof CacheElement)) {
        return false;
      }

      CacheElement expectedElement = (CacheElement) expected;
      CacheElement actualElement = (CacheElement) actual;

      return equals(expectedElement, actualElement);
    }

    private boolean equals(CacheElement expected, CacheElement actual) {
      if (expected == actual) {
        return true;
      }
      if (!ObjectUtils.nullSafeEquals(expected.getKey(), actual.getKey())) {
        return false;
      }
      if (!ObjectUtils.nullSafeEquals(expected.getVal(), actual.getVal())) {
        return false;
      }
      return true;
    }
  }

  private class CacheEntry {
    String group;

    Serializable key;

    Object value;

    public CacheEntry(Serializable newKey, String newGroup, Object newValue) {
      super();
      key = newKey;
      group = newGroup;
      value = newValue;
    }
  }

  private static final String CACHE_NAME = "testCache";

  private CompositeCache cache;

  private MockClassControl cacheControl;

  private CacheEntry[] cacheEntries;

  private CompositeCacheManager cacheManager;

  private MockClassControl cacheManagerControl;

  private JcsCachingModel cachingModel;

  private JcsFlushingModel flushingModel;

  private JcsFacade jcsFacade;

  public JcsFacadeTests(String name) {
    super(name);
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#modelValidator()}</code> returns an an
   * instance of <code>{@link JcsModelValidator}</code> not equal to
   * <code>null</code>.
   */
  public void testGetCacheModelValidator() {
    CacheModelValidator validator = jcsFacade.modelValidator();
    assertNotNull(validator);
    assertEquals(JcsModelValidator.class, validator.getClass());
  }

  public void testGetCacheWithExistingCache() {
    setUpCacheAdministratorAndCache();
    assertSame(cacheManager.getCache(CACHE_NAME), jcsFacade
        .getCache(CACHE_NAME));
  }

  public void testGetCacheWithNotExistingCache() throws Exception {
    Method getCacheMethod = this
        .getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCacheMethod);

    expectCacheIsNotFound();
    replay();

    try {
      jcsFacade.getCache(CACHE_NAME);
      fail();
    } catch (CacheNotFoundException exception) {
      // expecting this exception
    }
    verify();
  }

  public void testGetCachingModelEditor() {
    PropertyEditor editor = jcsFacade.getCachingModelEditor();

    assertNotNull(editor);
    assertEquals(ReflectionCacheModelEditor.class, editor.getClass());

    ReflectionCacheModelEditor modelEditor = (ReflectionCacheModelEditor) editor;
    assertEquals(JcsCachingModel.class, modelEditor.getCacheModelClass());
    assertNull(modelEditor.getCacheModelPropertyEditors());
  }

  public void testGetFlushingModelEditor() {
    PropertyEditor editor = jcsFacade.getFlushingModelEditor();
    assertNotNull(editor);
    assertEquals(JcsFlushingModelEditor.class, editor.getClass());
  }

  public void testGetKeyWithGroupName() {
    cachingModel.setGroup("empire");
    Serializable key = "Vader";
    GroupId groupId = new GroupId(CACHE_NAME, cachingModel.getGroup());
    GroupAttrName expected = new GroupAttrName(groupId, key);
    Serializable actual = jcsFacade.getKey(key, cachingModel);
    assertEquals(expected, actual);
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#getKey(Serializable, JcsCachingModel)}</code>
   * creates a key that does not contain the group if the given cache model does
   * not specify any group.
   */
  public void testGetKeyWithoutGroupName() {
    Serializable key = "FalconMillenium";
    assertEquals(key, jcsFacade.getKey(key, cachingModel));
  }

  public void testIsSerializableCacheElementRequired() {
    assertTrue(jcsFacade.isSerializableCacheElementRequired());
  }

  public void testOnFlushCacheCacheStructArrayEqualToNull() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();
    updateCache();

    int expected = cache.getSize();

    flushingModel.setCacheStructs(null);
    jcsFacade.onFlushCache(flushingModel);

    // the cache should not be flushed.
    assertEquals(expected, cache.getSize());
  }

  public void testOnFlushCacheWhenCacheAccessThrowsException() throws Exception {
    Method getCache = getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCache);

    Method removeAll = CompositeCache.class
        .getMethod("removeAll", new Class[0]);
    setUpCacheAsMockObject(removeAll);

    expectCacheIsFound();

    // cache manager throws exception when flushing the cache.
    RuntimeException expected = new RuntimeException();
    cache.removeAll();
    cacheControl.setThrowable(expected);

    replay();

    try {
      jcsFacade.onFlushCache(flushingModel);
      fail();

    } catch (CacheAccessException exception) {
      assertSame(expected, exception.getCause());
    }
    verify();
  }

  public void testOnFlushCacheWhenCacheIsNotFound() throws Exception {
    Method getCacheMethod = this
        .getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCacheMethod);

    expectCacheIsNotFound();
    replay();

    try {
      jcsFacade.onFlushCache(flushingModel);
      fail();
    } catch (CacheAccessException exception) {
      // expecting this exception
    }
    verify();
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#onFlushCache(org.springmodules.cache.FlushingModel)}</code>
   * flushes only the specified groups of the specified cache.
   */
  public void testOnFlushCacheWithGroups() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();

    Serializable[] keys = updateCache();

    int entryToRemoveIndex = 0;
    CacheEntry entryToRemove = cacheEntries[entryToRemoveIndex];

    flushingModel.setCacheStruct(new CacheStruct(CACHE_NAME,
        entryToRemove.group));
    jcsFacade.onFlushCache(flushingModel);

    int cacheElementCount = keys.length;
    for (int i = 0; i < cacheElementCount; i++) {
      if (i == entryToRemoveIndex) {
        // the group of this element should have been removed.
        assertNull(cache.get(keys[i]));

      } else {
        // the group of this element should exist.
        assertNotNull(cache.get(keys[i]));
      }
    }
  }

  public void testOnFlushCacheWithoutCacheStructs() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();
    updateCache();

    int expected = cache.getSize();

    flushingModel.setCacheStruct(null);
    jcsFacade.onFlushCache(flushingModel);

    // the cache should not be flushed.
    assertEquals(expected, cache.getSize());
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#onFlushCache(org.springmodules.cache.FlushingModel)}</code>
   * flushes the whole cache if there are not any specified groups.
   */
  public void testOnFlushCacheWithoutGroups() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();
    updateCache();

    jcsFacade.onFlushCache(flushingModel);

    // the whole cache should be flushed.
    assertEquals(0, cache.getSize());
  }

  public void testOnGetFromCache() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();
    CacheEntry entryToAdd = cacheEntries[0];
    updateCache(entryToAdd);

    cachingModel.setGroup(entryToAdd.group);
    Object actual = jcsFacade.onGetFromCache(entryToAdd.key, cachingModel);
    assertSame(entryToAdd.value, actual);
  }

  public void testOnGetFromCacheWhenCacheAccessThrowsException()
      throws Exception {
    Method getCache = getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCache);

    Method get = CompositeCache.class.getMethod("get",
        new Class[] { Serializable.class });
    setUpCacheAsMockObject(get);

    expectCacheIsFound();

    // cache manager throws exception.
    Serializable key = "R2-D2";
    RuntimeException expected = new RuntimeException();
    cacheControl.expectAndThrow(cache.get(key), expected);
    replay();

    try {
      jcsFacade.onGetFromCache(key, cachingModel);
      fail();
    } catch (CacheAccessException exception) {
      assertSame(expected, exception.getCause());
    }
    verify();
  }

  public void testOnGetFromCacheWhenCacheIsNotFound() throws Exception {
    Method getCacheMethod = this
        .getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCacheMethod);

    expectCacheIsNotFound();
    replay();

    try {
      jcsFacade.onGetFromCache("C-3PO", cachingModel);
      fail();
    } catch (CacheNotFoundException exception) {
      // expecting this exception
    }
    verify();
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#onGetFromCache(Serializable, org.springmodules.cache.CachingModel)}</code>
   * returns <code>null</code> if the specified key does not exist in the
   * cache.
   */
  public void testOnGetFromCacheWhenKeyIsNotFound() throws Exception {
    setUpCacheAdministratorAndCache();
    assertNull(jcsFacade.onGetFromCache("SomeNotExistingKey", cachingModel));
  }

  public void testOnPutInCache() throws Exception {
    setUpCacheAdministratorAndCache();

    Serializable key = "Obi-Wan";
    Object expected = "Jedi Master";

    jcsFacade.onPutInCache(key, cachingModel, expected);
    assertSame(expected, cache.get(key).getVal());
  }

  public void testOnPutInCacheWhenCacheAccessThrowsException() throws Exception {
    Method getCache = getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCache);

    Method update = CompositeCache.class.getMethod("update",
        new Class[] { ICacheElement.class });
    setUpCacheAsMockObject(update);

    // cache manager finds the cache we are looking for.
    expectCacheIsFound();

    // cache manager throws exception.
    Serializable key = "Jabba";
    Object objToStore = "Bobba Fett";

    CacheElement cacheElement = new CacheElement(cachingModel.getCacheName(),
        key, objToStore);
    cache.update(cacheElement);
    cacheControl.setMatcher(new CacheElementMatcher());

    RuntimeException expected = new RuntimeException();
    cacheControl.setThrowable(expected);

    replay();

    try {
      jcsFacade.onPutInCache(key, cachingModel, objToStore);
      fail();
    } catch (CacheAccessException exception) {
      assertSame(expected, exception.getCause());
    }
    verify();
  }

  public void testOnPutInCacheWhenCacheIsNotFound() throws Exception {
    Method getCache = getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCache);

    expectCacheIsNotFound();
    replay();

    try {
      jcsFacade.onPutInCache("Skywalker", cachingModel, "Luke");
      fail();
    } catch (CacheNotFoundException exception) {
      // expecting this exception
    }
    verify();
  }

  public void testOnRemoveFromCache() throws Exception {
    setUpCacheAdministratorAndCache();
    setUpCacheEntries();

    CacheEntry entry = cacheEntries[0];
    Serializable key = updateCache(entry);

    cachingModel.setGroup(entry.group);
    jcsFacade.onRemoveFromCache(entry.key, cachingModel);

    ICacheElement cacheElement = cache.get(key);
    assertNull(cacheElement);
  }

  public void testOnRemoveFromCacheWhenCacheAccessThrowsException()
      throws Exception {
    Method getCacheMethod = this
        .getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCacheMethod);

    Method removeMethod = CompositeCache.class.getMethod("remove",
        new Class[] { Serializable.class });
    setUpCacheAsMockObject(removeMethod);

    expectCacheIsFound();

    // cache manager throws exception.
    Serializable key = "FalconMillenium";
    RuntimeException expected = new RuntimeException();
    cache.remove(key);
    cacheControl.setThrowable(expected);

    replay();

    try {
      jcsFacade.onRemoveFromCache(key, cachingModel);
      fail();

    } catch (CacheAccessException exception) {
      assertSame(expected, exception.getCause());
    }
    verify();

  }

  public void testOnRemoveFromCacheWhenCacheIsNotFound() throws Exception {
    Method getCache = getGetCacheMethodFromCompositeCacheManagerClass();
    setUpCacheAdministratorAsMockObject(getCache);

    expectCacheIsNotFound();
    replay();

    try {
      jcsFacade.onRemoveFromCache("Chewbacca", cachingModel);
      fail();
    } catch (CacheNotFoundException exception) {
      // expecting this exception
    }
    verify();
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#validateCacheManager()}</code> throws an
   * <code>{@link FatalCacheException}</code> the cache manager is
   * <code>null</code>.
   */
  public void testValidateCacheManagerWithCacheManagerEqualToNull() {
    jcsFacade.setCacheManager(null);
    try {
      jcsFacade.validateCacheManager();
      fail();
    } catch (FatalCacheException exception) {
      // we are expecting this exception.
    }
  }

  /**
   * Verifies that the method
   * <code>{@link JcsFacade#validateCacheManager()}</code> does not throw any
   * exception if the cache manager is not <code>null</code>.
   */
  public void testValidateCacheManagerWithCacheManagerNotEqualToNull()
      throws Exception {
    setUpCacheAdministratorAndCache();
    jcsFacade.validateCacheManager();
  }

  protected void setUp() {
    cachingModel = new JcsCachingModel(CACHE_NAME);
    flushingModel = new JcsFlushingModel(CACHE_NAME);
    jcsFacade = new JcsFacade();
  }

  protected void tearDown() {
    if (cacheManager != null) {
      cacheManager.shutDown();
    }
  }

  private void expectCacheIsFound() {
    cacheManager.getCache(CACHE_NAME);
    cacheManagerControl.setReturnValue(cache);
  }

  private void expectCacheIsNotFound() {
    cacheManager.getCache(CACHE_NAME);
    cacheManagerControl.setReturnValue(null);
  }

  private Method getGetCacheMethodFromCompositeCacheManagerClass()
      throws Exception {
    return CompositeCacheManager.class.getDeclaredMethod("getCache",
        new Class[] { String.class });
  }

  private void replay() {
    replay(cacheControl);
    cacheManagerControl.replay();
  }

  private void replay(MockControl mockControl) {
    if (mockControl == null) {
      return;
    }
    mockControl.replay();
   }

  private void setUpCacheAdministratorAndCache() {
    cacheManager = CompositeCacheManager.getInstance();
    cache = cacheManager.getCache(CACHE_NAME);

    jcsFacade.setCacheManager(cacheManager);
  }

  private void setUpCacheAdministratorAsMockObject(Method methodToMock) {
    setUpCacheAdministratorAsMockObject(new Method[] { methodToMock });
  }

  private void setUpCacheAdministratorAsMockObject(Method[] methodsToMock) {
    Class targetClass = CompositeCacheManager.class;

    cacheManagerControl = MockClassControl.createControl(targetClass, null,
        null, methodsToMock);
    cacheManager = (CompositeCacheManager) cacheManagerControl.getMock();

    jcsFacade.setCacheManager(cacheManager);
  }

  private void setUpCacheAsMockObject(Method methodToMock) throws Exception {
    setUpCacheAsMockObject(new Method[] { methodToMock });
  }

  private void setUpCacheAsMockObject(Method[] methodsToMock) throws Exception {
    Class[] constructorTypes = new Class[] { String.class,
        ICompositeCacheAttributes.class, IElementAttributes.class };

    ICompositeCacheAttributes cacheAttributes = new CompositeCacheAttributes();
    cacheAttributes.setCacheName(CACHE_NAME);
    cacheAttributes.setMaxObjects(10);
    cacheAttributes
        .setMemoryCacheName("org.apache.jcs.engine.memory.lru.LRUMemoryCache");
    ElementAttributes elementAttributes = new ElementAttributes();
    Object[] constructorArgs = new Object[] { CACHE_NAME, cacheAttributes,
        elementAttributes };

    // set up the methods to mock.
    Class targetClass = CompositeCache.class;

    cacheControl = MockClassControl.createControl(targetClass,
        constructorTypes, constructorArgs, methodsToMock);
    cache = (CompositeCache) cacheControl.getMock();
  }

  private void setUpCacheEntries() {
    cacheEntries = new CacheEntry[] {
        new CacheEntry("sith", "empire", "Darth Vader"),
        new CacheEntry("jedi", "rebellion", "Luke Skywalker") };
  }

  private Serializable[] updateCache() throws Exception {
    int elementCount = cacheEntries.length;
    Serializable[] keys = new Serializable[elementCount];
    for (int i = 0; i < elementCount; i++) {
      keys[i] = updateCache(cacheEntries[i]);
    }
    assertTrue("The size of the cache should be greater than zero", cache
        .getSize() > 0);
    return keys;
  }

  private Serializable updateCache(CacheEntry cacheEntry) throws Exception {
    Serializable key = cacheEntry.key;
    String group = cacheEntry.group;

    if (StringUtils.hasText(group)) {
      GroupId groupId = new GroupId(CACHE_NAME, group);
      GroupAttrName groupAttrName = new GroupAttrName(groupId, key);
      key = groupAttrName;
    }

    ICacheElement cacheElement = new CacheElement(CACHE_NAME, key,
        cacheEntry.value);
    IElementAttributes attributes = cache.getElementAttributes().copy();
    cacheElement.setElementAttributes(attributes);

    cache.update(cacheElement);
    return key;
  }

  private void verify() {
    verify(cacheControl);
    cacheManagerControl.verify();
  }

  private void verify(MockControl mockControl) {
    if (mockControl == null) {
      return;
    }
    mockControl.verify();
   }
}
TOP

Related Classes of org.springmodules.cache.provider.jcs.JcsFacadeTests

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.