/*
* Created on May 28, 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 @2007 the original author or authors.
*/
package org.springmodules.cache.provider.oscache;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.EntryRefreshPolicy;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.base.events.CacheEntryEventListener;
import com.opensymphony.oscache.extra.CacheEntryEventListenerImpl;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.TestCase;
import org.easymock.classextension.MockClassControl;
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
import org.springmodules.cache.FatalCacheException;
import org.springmodules.cache.provider.CacheModelValidator;
import org.springmodules.cache.provider.ReflectionCacheModelEditor;
import java.beans.PropertyEditor;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Unit Tests for <code>{@link OsCacheFacade}</code>.
*
* @author Omar Irbouh
* @author Alex Ruiz
*/
public class OsCacheFacadeTests extends TestCase {
private static final String CACHE_KEY = "key";
private GeneralCacheAdministrator cacheAdministrator;
private MockClassControl cacheAdministratorControl;
private CacheEntryEventListenerImpl cacheEntryEventListener;
private OsCacheCachingModel cachingModel;
private OsCacheFlushingModel flushingModel;
/**
* Name of the groups in <code>{@link #cacheAdministrator}</code> to use.
*/
private String[] groups;
private OsCacheFacade osCacheFacade;
public OsCacheFacadeTests(String name) {
super(name);
}
public void testGetCacheModelEditor() {
PropertyEditor editor = osCacheFacade.getCachingModelEditor();
assertNotNull(editor);
assertEquals(ReflectionCacheModelEditor.class, editor.getClass());
ReflectionCacheModelEditor modelEditor = (ReflectionCacheModelEditor) editor;
assertEquals(OsCacheCachingModel.class, modelEditor.getCacheModelClass());
Map cacheModelPropertyEditors = modelEditor.getCacheModelPropertyEditors();
assertNotNull(cacheModelPropertyEditors);
assertEquals(1, cacheModelPropertyEditors.size());
PropertyEditor refreshPeriodEditor = (PropertyEditor) cacheModelPropertyEditors
.get("refreshPeriod");
assertNotNull(refreshPeriodEditor);
assertEquals(RefreshPeriodEditor.class, refreshPeriodEditor.getClass());
}
/**
* Verifies that the method
* <code>{@link OsCacheFacade#modelValidator()}</code> returns an an
* instance of <code>{@link OsCacheModelValidator}</code> not equal to
* <code>null</code>.
*/
public void testGetCacheModelValidator() {
CacheModelValidator validator = osCacheFacade.modelValidator();
assertNotNull(validator);
assertEquals(OsCacheModelValidator.class, validator.getClass());
}
public void testGetFlushingModelEditor() {
PropertyEditor editor = osCacheFacade.getFlushingModelEditor();
assertNotNull(editor);
assertEquals(ReflectionCacheModelEditor.class, editor.getClass());
ReflectionCacheModelEditor modelEditor = (ReflectionCacheModelEditor) editor;
assertEquals(OsCacheFlushingModel.class, modelEditor.getCacheModelClass());
Map propertyEditors = modelEditor.getCacheModelPropertyEditors();
assertEquals(1, propertyEditors.size());
assertSame(StringArrayPropertyEditor.class, propertyEditors.get("cacheNames").getClass());
}
public void testIsSerializableCacheElementRequired() {
assertFalse(osCacheFacade.isSerializableCacheElementRequired());
}
/**
* Verifies that the method
* <code>{@link OsCacheFacade#onCancelCacheUpdate(java.io.Serializable)}</code>
* cancels the update of the entry under the given key.
*/
public void testOnCancelCacheUpdate() throws Exception {
Method cancelUpdateMethod = GeneralCacheAdministrator.class.getMethod(
"cancelUpdate", new Class[]{String.class});
setUpCacheAdministratorAsMockObject(cancelUpdateMethod);
String key = "Jedi";
cacheAdministrator.cancelUpdate(key);
cacheAdministratorControl.replay();
// execute the method to test.
osCacheFacade.cancelCacheUpdate(key);
cacheAdministratorControl.verify();
}
public void testOnFlushCache() {
setUpCacheAdministrator();
Object objectToStore = "An Object";
cacheAdministrator.putInCache(CACHE_KEY, objectToStore, groups);
String groupToFlush = groups[0];
flushingModel.setGroups(new String[]{groupToFlush});
// execute the method to test.
osCacheFacade.onFlushCache(flushingModel);
assertEquals("<Number of groups flushed>", 1, cacheEntryEventListener
.getGroupFlushedCount());
}
public void testOnFlushCacheWithoutGroups() {
setUpCacheAdministrator();
Object objectToStore = "An Object";
cacheAdministrator.putInCache(CACHE_KEY, objectToStore, groups);
flushingModel.setGroups((String[]) null);
// execute the method to test.
osCacheFacade.onFlushCache(flushingModel);
String cachedObject = cacheAdministrator.getProperty(CACHE_KEY);
assertNull(cachedObject);
}
public void testOnGetFromCache() {
setUpCacheAdministrator();
Object expected = "An Object";
cacheAdministrator.putInCache(CACHE_KEY, expected);
// execute the method to test.
Object actual = osCacheFacade.onGetFromCache(CACHE_KEY, cachingModel);
assertSame(expected, actual);
}
public void testOnGetFromCacheWhenKeyIsNotFound() {
setUpCacheAdministrator();
Object cachedObject = osCacheFacade.onGetFromCache("NonExistingKey",
cachingModel);
assertNull(cachedObject);
}
public void testOnGetFromCacheWhenEntryIsStale() {
setUpCacheAdministrator();
Cache cache = cacheAdministrator.getCache();
cache.putInCache(CACHE_KEY, "An Object",
new EntryRefreshPolicy() {
/** force refresh */
public boolean needsRefresh(CacheEntry cacheEntry) {
return true;
}
});
Object cachedObject = osCacheFacade.onGetFromCache(CACHE_KEY, cachingModel);
assertNull(cachedObject);
// Recent releases of OsCache allow for cancelling an update on a key
// that either does not exist or is not currently being updated.
// try {
// cacheAdministrator.cancelUpdate(CACHE_KEY);
// fail("osCacheFacade.onGetFromCache should have call cacheManager.cancelUpdate(newKey)");
// } catch (IllegalStateException e) {
// // expected
// }
}
public void testOnGetFromCacheWhenRefreshPeriodIsNotNullAndCronExpressionIsNotNull()
throws Exception {
Method getFromCacheMethod = GeneralCacheAdministrator.class
.getDeclaredMethod("getFromCache", new Class[]{String.class,
int.class, String.class});
setUpCacheAdministratorAsMockObject(getFromCacheMethod);
String cronExpression = "* * * 0 0";
int refreshPeriod = 45;
cachingModel.setCronExpression(cronExpression);
cachingModel.setRefreshPeriod(refreshPeriod);
Object expected = "Anakin";
cacheAdministratorControl.expectAndReturn(cacheAdministrator.getFromCache(
CACHE_KEY, refreshPeriod, cronExpression), expected);
cacheAdministratorControl.replay();
// execute the method to test.
Object actual = osCacheFacade.onGetFromCache(CACHE_KEY, cachingModel);
assertSame(expected, actual);
cacheAdministratorControl.verify();
}
public void testOnGetFromCacheWhenRefreshPeriodIsNotNullAndCronExpressionIsNull()
throws Exception {
Method getFromCacheMethod = GeneralCacheAdministrator.class
.getDeclaredMethod("getFromCache", new Class[]{String.class,
int.class});
setUpCacheAdministratorAsMockObject(getFromCacheMethod);
int refreshPeriod = 556;
cachingModel.setRefreshPeriod(refreshPeriod);
Object expected = "Anakin";
cacheAdministratorControl.expectAndReturn(cacheAdministrator.getFromCache(
CACHE_KEY, refreshPeriod), expected);
cacheAdministratorControl.replay();
// execute the method to test.
Object actual = osCacheFacade.onGetFromCache(CACHE_KEY, cachingModel);
assertSame(expected, actual);
cacheAdministratorControl.verify();
}
public void testOnGetFromCacheWhenRefreshPeriodIsNull() throws Exception {
Method getFromCacheMethod = GeneralCacheAdministrator.class
.getDeclaredMethod("getFromCache", new Class[]{String.class});
setUpCacheAdministratorAsMockObject(getFromCacheMethod);
cachingModel.setRefreshPeriod(null);
Object expected = "Anakin";
// retrieve an entry using only the provided key.
cacheAdministratorControl.expectAndReturn(cacheAdministrator
.getFromCache(CACHE_KEY), expected);
cacheAdministratorControl.replay();
// execute the method to test.
Object actual = osCacheFacade.onGetFromCache(CACHE_KEY, cachingModel);
assertSame(expected, actual);
cacheAdministratorControl.verify();
}
public void testOnPutInCacheWithGroups() throws Exception {
setUpCacheAdministrator();
Object objectToStore = "An Object";
String group = groups[0];
cachingModel.setGroups(new String[]{group});
// execute the method to test.
osCacheFacade.onPutInCache(CACHE_KEY, cachingModel, objectToStore);
Object cachedObject = cacheAdministrator.getFromCache(CACHE_KEY);
assertSame(objectToStore, cachedObject);
// if we flush the group used, we should not be able to get the cached
// object.
cacheAdministrator.flushGroup(group);
try {
cacheAdministrator.getFromCache(CACHE_KEY);
fail();
} catch (NeedsRefreshException exception) {
// we are expecting this exception
}
}
/**
* Verifies that the method
* <code>{@link OsCacheFacade#onPutInCache(java.io.Serializable,org.springmodules.cache.CachingModel,Object)}</code>
* stores an entry using the given key. The entry should not be associated
* with any group.
*/
public void testOnPutInCacheWithoutGroups() throws Exception {
setUpCacheAdministrator();
Object objectToStore = "An Object";
cachingModel.setGroups((String[]) null);
// execute the method to test.
osCacheFacade.onPutInCache(CACHE_KEY, cachingModel, objectToStore);
Object cachedObject = cacheAdministrator.getFromCache(CACHE_KEY);
assertSame(objectToStore, cachedObject);
// if we flush all the groups, we should be able to get the cached object.
int groupCount = groups.length;
for (int i = 0; i < groupCount; i++) {
String group = groups[i];
cacheAdministrator.flushGroup(group);
}
cachedObject = cacheAdministrator.getFromCache(CACHE_KEY);
assertSame(objectToStore, cachedObject);
}
/**
* Verifies that the method
* <code>{@link OsCacheFacade#onRemoveFromCache(java.io.Serializable,org.springmodules.cache.CachingModel)}</code>
* removes from the cache the entry stored under the given key.
*/
public void testOnRemoveFromCache() throws Exception {
Method flushEntryMethod = GeneralCacheAdministrator.class
.getDeclaredMethod("flushEntry", new Class[]{String.class});
setUpCacheAdministratorAsMockObject(flushEntryMethod);
String key = "Luke";
cacheAdministrator.flushEntry(key);
cacheAdministratorControl.replay();
// execute the method to test.
osCacheFacade.onRemoveFromCache(key, null);
cacheAdministratorControl.verify();
}
public void testValidateCacheManagerWithCacheManagerEqualToNull() {
osCacheFacade.setCacheManager(null);
try {
osCacheFacade.validateCacheManager();
fail();
} catch (FatalCacheException exception) {
// we are expecting this exception.
}
}
/**
* Verifies that the method
* <code>{@link OsCacheFacade#validateCacheManager()}</code> does not throw
* any exception if the cache manager is not <code>null</code>.
*/
public void testValidateCacheManagerWithCacheManagerNotEqualToNull()
throws Exception {
setUpCacheAdministrator();
osCacheFacade.validateCacheManager();
}
protected void setUp() {
cachingModel = new OsCacheCachingModel();
groups = new String[]{"Empire", "Rebels"};
flushingModel = new OsCacheFlushingModel();
osCacheFacade = new OsCacheFacade();
}
protected void tearDown() {
if (cacheAdministrator != null) {
cacheAdministrator.destroy();
}
}
private void setUpCacheAdministrator() {
cacheAdministrator = new GeneralCacheAdministrator();
Cache cache = cacheAdministrator.getCache();
cacheEntryEventListener = new CacheEntryEventListenerImpl();
cache.addCacheEventListener(cacheEntryEventListener,
CacheEntryEventListener.class);
osCacheFacade.setCacheManager(cacheAdministrator);
}
private void setUpCacheAdministratorAsMockObject(Method methodToMock) {
setUpCacheAdministratorAsMockObject(new Method[]{methodToMock});
}
private void setUpCacheAdministratorAsMockObject(Method[] methodsToMock) {
Class targetClass = GeneralCacheAdministrator.class;
cacheAdministratorControl = MockClassControl.createControl(targetClass,
null, null, methodsToMock);
cacheAdministrator = (GeneralCacheAdministrator) cacheAdministratorControl
.getMock();
osCacheFacade.setCacheManager(cacheAdministrator);
}
}