This commit is contained in:
Erik C. Thauvin 2017-05-21 00:05:57 -07:00
commit bd8f23d7d6
268 changed files with 34908 additions and 0 deletions

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
/**
* This is an dummy implementation of an EntryRefreshPolicy. It is just to
* illustrate how to use it.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:fbeauregard@pyxis-tech.com">Francois Beauregard</a>
*/
public final class DummyAlwayRefreshEntryPolicy implements EntryRefreshPolicy {
/**
* Dummy implementation of an entry refresh policy. A real implementation
* whould do some logic to determine if this entry needs to be refreshed.
* It can be calling a bean or checking some files, or even manually manage
* the time expiration.
*
* <p>
* @param entry The entry for wich to determine if a refresh is needed
* @return True or false
*/
public boolean needsRefresh(CacheEntry entry) {
return true;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.TestCase;
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
public class GroupConcurrencyProblemTestCase extends TestCase {
private static GeneralCacheAdministrator cache = new GeneralCacheAdministrator();
public static void main(String[] args) {
System.out.println("START");
// Create some clients and start them running.
for (int i = 0; i < 100; i++) {
System.out.println("Creating thread: " + i);
new Client(i, cache).start();
}
System.out.println("END");
}
}
/* Inner class to hammer away at the cache. */
class Client extends Thread {
private static final int MAX_ITERATIONS = 1000;
private GeneralCacheAdministrator cache;
private int id;
public Client(int newId, GeneralCacheAdministrator newCache) {
super();
id = newId;
cache = newCache;
}
public void run() {
for (int i = 0; i < MAX_ITERATIONS; i++) {
/* Put an entry from this Client into the shared group.
*/
cache.putInCache(Integer.toString(id), "Some interesting data", new String[] {
"GLOBAL_GROUP"
});
// Flush that group.
cache.flushGroup("GLOBAL_GROUP");
}
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import junit.framework.TestCase;
/**
* Test class for the AbstractCacheAdministrator class. It tests some of the
* public methods of the admin. Some others cannot be tested since they are
* linked to the property file used for the tests, and since this file
* will change, the value of some parameters cannot be asserted
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public abstract class TestAbstractCacheAdministrator extends TestCase {
// Constants used in the tests
//private final String CACHE_PATH_PROP = "cache.path";
//private final String CONTENT = "Content for the abstract cache admin test";
//private final String ENTRY_KEY = "Test Abstract Admin Key";
private final String INVALID_PROP_NAME = "INVALID_PROP_NAME";
//private final String TEST_LOG = "test log";
/**
* Constructor for the this test class.
* <p>
* @param str Test name (required by JUnit)
*/
protected TestAbstractCacheAdministrator(String str) {
super(str);
}
/**
* Cannot be tested since CacheContents is an interface
*/
public void testCacheContents() {
}
/**
* We cannot test this method because the value depends on the property
*/
public void testGetCachePath() {
}
/**
* Validate that the properties retrieved by the admin are the same as the one
* specified in the property file. Do not test cache path or memory cache
* since it changes with the tests
*/
public void testGetProperty() {
// Check if all the default properties are OK
assertNull(getAdmin().getProperty(INVALID_PROP_NAME));
assertNull(getAdmin().getProperty(""));
try {
assertNull(getAdmin().getProperty(null));
fail("NullPointerException expected (property Key null).");
} catch (Exception e) {
}
}
/**
* We cannot test this method because the value depends on the property
*/
public void testIsFileCaching() {
}
/**
* We cannot test this method because the value depends on the property
*/
public void testIsMemoryCaching() {
}
/**
* Perform a call to the log method. Unfornately, there is no way to check
* if the logging is done correctly, we only invoke it
*/
public void testLog() {
// Invoke the log
// The other log method is not tested since it calls the same as we do
//TODO
/*getAdmin().log(TEST_LOG, System.out);
getAdmin().log("", System.out);
getAdmin().log(null, System.out);
getAdmin().log(TEST_LOG, null);
*/
}
// Abstract method that returns an instance of an admin
protected abstract AbstractCacheAdministrator getAdmin();
}

View file

@ -0,0 +1,275 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import java.util.Properties;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test the public methods of the Cache class
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestCache extends TestCase {
// Static variables required thru all the tests
private static Cache map = null;
private final String CONTENT = "Content for the cache test";
// Constants needed thru all the tests
private final String ENTRY_KEY = "Test cache key";
private final int NO_REFRESH_NEEDED = CacheEntry.INDEFINITE_EXPIRY;
private final int REFRESH_NEEDED = 0;
/**
* Class constructor.
* <p>
* @param str The test name (required by JUnit)
*/
public TestCache(String str) {
super(str);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a new Cache
if (map == null) {
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
map = admin.getCache();
assertNotNull(map);
}
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestCache.class);
}
/**
* Verify that items may still be flushed by key pattern
*/
public void testFlushPattern() {
// Try to flush with a bad pattern and ensure that our data is still there
map.putInCache(ENTRY_KEY, CONTENT);
map.flushPattern(ENTRY_KEY + "do not flush");
getBackContent(map, CONTENT, NO_REFRESH_NEEDED, false);
// Flush our map for real
map.flushPattern(ENTRY_KEY.substring(1, 2));
getBackContent(map, CONTENT, NO_REFRESH_NEEDED, true);
// Check invalid values
map.flushPattern("");
map.flushPattern(null);
}
/**
* Tests that with a very large amount of keys that added and trigger cache overflows, there is no memory leak
* @throws Exception
*/
public void testBug174CacheOverflow() throws Exception {
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_ALGORITHM_KEY, "com.opensymphony.oscache.base.algorithm.LRUCache");
p.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "100");
GeneralCacheAdministrator admin = new GeneralCacheAdministrator(p);
int cacheCapacity = 100;
int maxAddedCacheEntries = cacheCapacity*10;
String baseCacheKey= "baseKey";
String cacheValue ="same_value";
admin.setCacheCapacity(cacheCapacity);
Cache cache = admin.getCache();
//Add lots of different keys to trigger cache overflow
for (int keyIndex=0; keyIndex<maxAddedCacheEntries; keyIndex++) {
String key = baseCacheKey + keyIndex;
admin.putInCache(key, cacheValue);
}
Assert.assertEquals("expected cache to be at its full capacity", cacheCapacity , cache.getSize());
Assert.assertTrue("expected cache overflows to have cleaned UpdateState instances. got [" + cache.getNbUpdateState() + "] updates while max is [" + cacheCapacity + "]", cache.getNbUpdateState() <= cacheCapacity);
}
/**
* Tests that with a very large amount of keys that added and trigger cache overflows, there is no memory leak
* @throws Exception
*/
public void testBug174CacheOverflowAndUpdate() throws Exception {
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_ALGORITHM_KEY, "com.opensymphony.oscache.base.algorithm.LRUCache");
p.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "100");
GeneralCacheAdministrator admin = new GeneralCacheAdministrator(p);
int cacheCapacity = 100;
int maxAddedCacheEntries = cacheCapacity*10;
String baseCacheKey= "baseKey";
String cacheValue ="same_value";
admin.setCacheCapacity(cacheCapacity);
Cache cache = admin.getCache();
//Add lots of different keys to trigger cache overflow, mixed with updates
//FIXME: we may need different threads to enter branches recovering from current update.
for (int keyIndex=0; keyIndex<maxAddedCacheEntries; keyIndex++) {
String key = baseCacheKey + keyIndex;
admin.putInCache(key, cacheValue);
try {
admin.getFromCache(key, 0);
fail("expected element [" + key + "] not to be present");
} catch (NeedsRefreshException e) {
admin.putInCache(key, cacheValue);
}
}
Assert.assertEquals("expected cache to be at its full capacity", cacheCapacity , cache.getSize());
Assert.assertTrue("expected cache overflows to have cleaned UpdateState instances. Nb states is:" + cache.getNbUpdateState() + " expected max="+ cacheCapacity, cache.getNbUpdateState() <= cacheCapacity);
}
/**
* Tests that with a very large amount of keys accessed and cancelled, there is no memory leak
* @throws Exception
*/
public void testBug174CacheMissesNonBlocking() throws Exception {
testBug174CacheMisses(false);
}
/**
* Tests that with a very large amount of keys accessed and cancelled, there is no memory leak
* @throws Exception
*/
public void testBug174CacheMissesBlocking() throws Exception {
testBug174CacheMisses(true);
}
/**
* Tests that with a very large amount of keys accessed and cancelled, there is no memory leak
* @throws Exception
*/
public void testBug174CacheMisses(boolean block) throws Exception {
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_ALGORITHM_KEY, "com.opensymphony.oscache.base.algorithm.LRUCache");
p.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "100");
if (block) {
p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true");
}
GeneralCacheAdministrator admin = new GeneralCacheAdministrator(p);
int cacheCapacity = 100;
int maxAddedCacheEntries = cacheCapacity*10;
String baseCacheKey= "baseKey";
//String cacheValue ="same_value";
admin.setCacheCapacity(cacheCapacity);
Cache cache = admin.getCache();
//Access lots of different keys to trigger cache overflow
for (int keyIndex=0; keyIndex<maxAddedCacheEntries; keyIndex++) {
String key = baseCacheKey + keyIndex;
try {
admin.getFromCache(key);
fail("expected element [" + key + "] not to be present");
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
}
}
Assert.assertTrue("expected cache accesses to not leak past cache capacity. Nb states is:" + cache.getNbUpdateState() + " expected max="+ cacheCapacity, cache.getNbUpdateState() < cacheCapacity);
}
/**
* Verify that we can put item in the cache and that they are correctly retrieved
*/
public void testPutGetFromCache() {
// We put content in the cache and get it back with and without refresh
map.putInCache(ENTRY_KEY, CONTENT);
getBackContent(map, CONTENT, NO_REFRESH_NEEDED, false);
getBackContent(map, CONTENT, REFRESH_NEEDED, true);
// Test with invalid values
/** TODO Verify this logic */
try {
assertNull(map.getFromCache("", NO_REFRESH_NEEDED));
} catch (NeedsRefreshException nre) {
map.cancelUpdate("");
} catch (Exception e) {
}
try {
assertNull(map.getFromCache(null, NO_REFRESH_NEEDED));
} catch (NeedsRefreshException nre) {
map.cancelUpdate(null);
} catch (Exception e) {
}
}
/**
* Verify that we can put item in the cache and that they are correctly retrieved
*/
public void testPutGetFromCacheWithPolicy() {
// We put content in the cache and get it back
map.putInCache(ENTRY_KEY + "policy", CONTENT, new DummyAlwayRefreshEntryPolicy());
// Should get a refresh
try {
map.getFromCache(ENTRY_KEY + "policy", -1);
fail("Should have got a refresh.");
} catch (NeedsRefreshException nre) {
map.cancelUpdate(ENTRY_KEY + "policy");
}
}
protected void tearDown() throws Exception {
if (map != null) {
map.clear();
}
}
/**
* Retrieve the content in the cache
* <p>
* @param map The Cache in which the data is stored
* @param content The content expected to be retrieved
* @param refresh Time interval to determine if the cache object needs refresh
* @param exceptionExpected Specify if a NeedsRefreshException is expected
*/
private void getBackContent(Cache map, Object content, int refresh, boolean exceptionExpected) {
try {
assertEquals(content, map.getFromCache(ENTRY_KEY, refresh));
if (exceptionExpected) {
fail("NeedsRefreshException should have been thrown!");
}
} catch (NeedsRefreshException nre) {
map.cancelUpdate(ENTRY_KEY);
if (!exceptionExpected) {
fail("NeedsRefreshException shouldn't have been thrown!");
}
}
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test the public methods of the CacheEntry class
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestCacheEntry extends TestCase {
// Static variables required thru the tests
static CacheEntry entry = null;
static long beforeCreation = 0;
static long afterCreation = 0;
private final String CONTENT = "Content for the cache entry test";
// Constants used thru the tests
private final String ENTRY_KEY = "Test cache entry key";
private final int NO_REFRESH_NEEDED = 1000000;
private final int REFRESH_NEEDED = 0;
/**
* Class constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheEntry(String str) {
super(str);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a cache entry object
if (entry == null) {
// Log the time before and after to verify the creation time
// in one of the tests
beforeCreation = System.currentTimeMillis();
entry = new CacheEntry(ENTRY_KEY);
afterCreation = System.currentTimeMillis();
}
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestCacheEntry.class);
}
/**
* Verify the flush
*/
public void testFlush() {
// Set the content so it shouldn't need refresh
entry.setContent(CONTENT);
assertTrue(!entry.needsRefresh(NO_REFRESH_NEEDED));
// Flush the entry. It should now needs refresh
entry.flush();
assertTrue(entry.needsRefresh(NO_REFRESH_NEEDED));
}
/**
* Verify that the creation time is correct
*/
public void testGetCreated() {
assertBetweenOrEquals(beforeCreation, entry.getCreated(), afterCreation);
}
/**
* Retrieve the item created by the setup
*/
public void testGetKey() {
assertTrue(entry.getKey().equals(ENTRY_KEY));
}
/**
* Verify that the last modification time is between the time before and
* after the alteration of the item
*/
public void testGetLastUpdate() {
// again. Then we ensure that the update time is between our timestamps
long before = System.currentTimeMillis();
entry.setContent(CONTENT);
long after = System.currentTimeMillis();
assertBetweenOrEquals(before, entry.getLastUpdate(), after);
}
/**
* Verify that the "freshness detection" function properly
*/
public void testNeedsRefresh() {
// Set the entry content so it shouldn't need refresh
// Invoke needsRefresh with no delay, so it should return true.
// Then invoke it with a big delay, so it should return false
assertTrue(entry.needsRefresh(REFRESH_NEEDED));
assertTrue(!entry.needsRefresh(NO_REFRESH_NEEDED));
}
/**
* Set the content of the item created by setup and then retrieve it and
* validate it
*/
public void testSetGetContent() {
entry.setContent(CONTENT);
assertTrue(CONTENT.equals(entry.getContent()));
// Ensure that nulls are allowed
entry.setContent(null);
assertNull(entry.getContent());
}
/**
* Ensure that a value is between two others. Since the execution may be
* very fast, equals values are also considered to be between
*/
private void assertBetweenOrEquals(long first, long between, long last) {
assertTrue(between >= first);
assertTrue(between <= last);
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import com.opensymphony.oscache.base.algorithm.TestCompleteAlgorithm;
import com.opensymphony.oscache.base.events.TestCompleteEvents;
import com.opensymphony.oscache.util.TestFastCronParser;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.base package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteBase extends TestCase {
/**
* Constructor for the osCache project main test program
*/
public TestCompleteBase(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteBase.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all base cache modules");
suite.addTest(TestFastCronParser.suite());
suite.addTest(TestCacheEntry.suite());
suite.addTest(TestCache.suite());
suite.addTest(TestConcurrency.suite());
suite.addTest(TestConcurrency2.suite());
suite.addTest(TestCompleteAlgorithm.suite());
suite.addTest(TestCompleteEvents.suite());
return suite;
}
}

View file

@ -0,0 +1,489 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.BitSet;
import java.util.Properties;
/**
* Test the Cache class for any concurrency problems
*
* $Id$
* @version $Revision$
* @author <a href="mailto:chris@chris.com">Chris Miller</a>
*/
public class TestConcurrency extends TestCase {
private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency.class
// Static variables required thru all the tests
private static GeneralCacheAdministrator admin = null;
// Constants needed in the tests
private final String KEY = "key";
private final String VALUE = "This is some content";
private final int ITERATION_COUNT = 5; //500;
private final int THREAD_COUNT = 6; //600;
private final int UNIQUE_KEYS = 1013;
/**
* Class constructor.
* <p>
* @param str The test name (required by JUnit)
*/
public TestConcurrency(String str) {
super(str);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a new Cache
if (admin == null) {
Properties config = new Properties();
config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "70");
config.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "false");
admin = new GeneralCacheAdministrator();
assertNotNull(admin);
}
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestConcurrency.class);
}
/**
* Check that the cache handles simultaneous attempts to access a
* new cache entry correctly
*/
public void testNewEntry() {
String key = "new";
try {
admin.getFromCache(key, -1);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another couple of threads to get the same cache entry
GetEntry getEntry = new GetEntry(key, VALUE, -1, false);
Thread thread = new Thread(getEntry);
thread.start();
getEntry = new GetEntry(key, VALUE, -1, false);
thread = new Thread(getEntry);
thread.start();
// OK, those threads should now be blocked waiting for the new cache
// entry to appear. Sleep for a bit to simulate the time taken to
// build the cache entry
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
// Putting the entry in the cache should unblock the previous threads
admin.putInCache(key, VALUE);
}
}
/**
* Check that the cache handles simultaneous attempts to access a
* new cache entry correctly
*/
public void testNewEntryCancel() {
String key = "newCancel";
String NEW_VALUE = VALUE + "...";
try {
admin.getFromCache(key, -1);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry
GetEntry getEntry = new GetEntry(key, NEW_VALUE, -1, true);
Thread thread = new Thread(getEntry);
thread.start();
// The above thread will be blocked waiting for the new content
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
// Now cancel the update (eg because an exception occurred while building the content).
// This will unblock the other thread and it will receive a NeedsRefreshException.
admin.cancelUpdate(key);
// Wait a bit for the other thread to update the cache
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
try {
Object newValue = admin.getFromCache(key, -1);
assertEquals(NEW_VALUE, newValue);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
fail("A NeedsRefreshException should not have been thrown");
}
}
}
/**
* Verify that we can concurrently access the cache without problems
*/
public void testPut() {
Thread[] thread = new Thread[THREAD_COUNT];
for (int idx = 0; idx < THREAD_COUNT; idx++) {
OSGeneralTest runner = new OSGeneralTest();
thread[idx] = new Thread(runner);
thread[idx].start();
}
boolean stillAlive;
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// do nothing
}
stillAlive = false;
int i = 0;
while ((i < thread.length) && !stillAlive) {
stillAlive |= thread[i++].isAlive();
}
} while (stillAlive);
}
/**
* Check that the cache handles simultaneous attempts to access a
* stale cache entry correctly
*/
public void testStaleEntry() {
String key = "stale";
assertFalse("The cache should not be in blocking mode for this test.", admin.isBlocking());
admin.putInCache(key, VALUE);
try {
// This should throw a NeedsRefreshException since the refresh
// period is 0
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry.
// Since blocking mode is currently disabled we should
// immediately get back the stale entry
GetEntry getEntry = new GetEntry(key, VALUE, 0, false);
Thread thread = new Thread(getEntry);
thread.start();
// Sleep for a bit to simulate the time taken to build the cache entry
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
}
// Putting the entry in the cache should mean that threads now retrieve
// the updated entry
String newValue = "New value";
admin.putInCache(key, newValue);
getEntry = new GetEntry(key, newValue, -1, false);
thread = new Thread(getEntry);
thread.start();
try {
Object fromCache = admin.getFromCache(key, -1);
assertEquals(newValue, fromCache);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
fail("Should not have received a NeedsRefreshException");
}
// Give the GetEntry thread a chance to finish
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
}
}
}
/**
* A test for the updating of a stale entry when CACHE.BLOCKING = TRUE
*/
public void testStaleEntryBlocking() {
// A test for the case where oscache.blocking = true
admin.destroy();
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true");
admin = new GeneralCacheAdministrator(p);
assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking());
// Use a unique key in case these test entries are being persisted
String key = "blocking";
String NEW_VALUE = VALUE + " abc";
admin.putInCache(key, VALUE);
try {
// Force a NeedsRefreshException
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry.
// Since blocking mode is enabled this thread should block
// until the entry has been updated.
GetEntry getEntry = new GetEntry(key, NEW_VALUE, 0, false);
Thread thread = new Thread(getEntry);
thread.start();
// Sleep for a bit to simulate the time taken to build the cache entry
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
}
// Putting the entry in the cache should mean that threads now retrieve
// the updated entry
admin.putInCache(key, NEW_VALUE);
getEntry = new GetEntry(key, NEW_VALUE, -1, false);
thread = new Thread(getEntry);
thread.start();
try {
Object fromCache = admin.getFromCache(key, -1);
assertEquals(NEW_VALUE, fromCache);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
fail("Should not have received a NeedsRefreshException");
}
}
}
/**
* Checks whether the cache handles simultaneous attempts to access a
* stable cache entry correctly when the blocking mode is enabled.
*
* Basically N threads are concurrently trying to access a same stale cache entry and each is cancelling its update. Each thread repeat this operation M times.
* The test is sucessfull if after some time, all threads are properly released
*/
public void testConcurrentStaleGets() {
GeneralCacheAdministrator staticAdmin = admin;
admin = new GeneralCacheAdministrator(); //avoid poluting other test cases
try {
// A test for the case where oscache.blocking = true
//admin.destroy();
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true");
admin = new GeneralCacheAdministrator(p);
assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking());
int nbThreads = 50;
int retryByThreads = 10000;
String key = "new";
//First put a value
admin.putInCache(key, VALUE);
try {
//Then test without concurrency that it is reported as stale when time-to-live is zero
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
//Ok this is was is excpected, we can release the update
admin.cancelUpdate(key);
}
//Then ask N threads to concurrently try to access this stale resource and each should receive a NeedsRefreshException, and cancel the update
Thread[] spawnedThreads = new Thread[nbThreads];
BitSet successfullThreadTerminations = new BitSet(nbThreads); //Track which thread successfully terminated
for (int threadIndex = 0; threadIndex < nbThreads; threadIndex++) {
GetStaleEntryAndCancelUpdate getEntry = new GetStaleEntryAndCancelUpdate(key, 0, retryByThreads, threadIndex, successfullThreadTerminations);
Thread thread = new Thread(getEntry);
spawnedThreads[threadIndex] = thread;
thread.start();
}
// OK, those threads should now repeatidely be blocked waiting for the new cache
// entry to appear. Wait for all of them to terminate
long maxWaitingSeconds = 100;
int maxWaitForEachThread = 5;
long waitStartTime = System.currentTimeMillis();
boolean atLeastOneThreadRunning = false;
while ((System.currentTimeMillis() - waitStartTime) < (maxWaitingSeconds * 1000)) {
atLeastOneThreadRunning = false;
//Wait a bit between each step to avoid consumming all CPU and preventing other threads from running.
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
//check whether all threads are done.
for (int threadIndex = 0; threadIndex < nbThreads;
threadIndex++) {
Thread inspectedThread = spawnedThreads[threadIndex];
try {
inspectedThread.join(maxWaitForEachThread * 1000L);
} catch (InterruptedException e) {
fail("Thread #" + threadIndex + " was interrupted");
}
if (inspectedThread.isAlive()) {
atLeastOneThreadRunning = true;
log.error("Thread #" + threadIndex + " did not complete within [" + ((System.currentTimeMillis() - waitStartTime) / 1000) + "] s ");
}
}
if (!atLeastOneThreadRunning) {
break; //while loop, test success.
}
}
assertTrue("at least one thread did not complete within [" + ((System.currentTimeMillis() - waitStartTime) / 1000) + "] s ", !atLeastOneThreadRunning);
for (int threadIndex = 0; threadIndex < nbThreads; threadIndex++) {
assertTrue("thread [" + threadIndex + "] did not successfully complete. ", successfullThreadTerminations.get(threadIndex));
}
} finally {
admin = staticAdmin;
//Avoid po
}
}
private class GetEntry implements Runnable {
String key;
String value;
boolean expectNRE;
int time;
GetEntry(String key, String value, int time, boolean expectNRE) {
this.key = key;
this.value = value;
this.time = time;
this.expectNRE = expectNRE;
}
public void run() {
try {
// Get from the cache
Object fromCache = admin.getFromCache(key, time);
assertEquals(value, fromCache);
} catch (NeedsRefreshException nre) {
if (!expectNRE) {
admin.cancelUpdate(key);
fail("Thread should have blocked until a new cache entry was ready");
} else {
// Put a new piece of content into the cache
admin.putInCache(key, value);
}
}
}
}
/**
* Basically requests a stale entry, expects to receive a NeedsRefreshException, and always cancels the update.
*/
private class GetStaleEntryAndCancelUpdate implements Runnable {
String key;
int retries;
int time;
private final BitSet successfullThreadTerminations;
private final int threadIndex;
GetStaleEntryAndCancelUpdate(String key, int time, int retries, int threadIndex, BitSet successfullThreadTerminations) {
this.key = key;
this.time = time;
this.retries = retries;
this.threadIndex = threadIndex;
this.successfullThreadTerminations = successfullThreadTerminations;
}
public void run() {
for (int retryIndex = 0; retryIndex < retries; retryIndex++) {
try {
// Get from the cache
Object fromCache = admin.getFromCache(key, time);
assertNull("Thread index [" + retryIndex + "] expected stale request [" + retryIndex + "] to be received, got [" + fromCache + "]", fromCache);
} catch (NeedsRefreshException nre) {
try {
admin.cancelUpdate(key);
} catch (Throwable t) {
log.error("Thread index [" + retryIndex + "]: Unexpectedly caught exception [" + t + "]", t);
fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]");
}
} catch (Throwable t) {
log.error("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]", t);
fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]");
}
}
//Once we successfully terminate, we update the corresponding bit to let the Junit know we succeeded.
synchronized (successfullThreadTerminations) {
successfullThreadTerminations.set(threadIndex);
}
}
}
private class OSGeneralTest implements Runnable {
public void doit(int i) {
int refreshPeriod = 500 /*millis*/;
String key = KEY + (i % UNIQUE_KEYS);
admin.putInCache(key, VALUE);
try {
// Get from the cache
admin.getFromCache(KEY, refreshPeriod);
} catch (NeedsRefreshException nre) {
// Get the value
// Store in the cache
admin.putInCache(KEY, VALUE);
}
// Flush occasionally
if ((i % (UNIQUE_KEYS + 1)) == 0) {
admin.getCache().flushEntry(key);
}
}
public void run() {
int start = (int) (Math.random() * UNIQUE_KEYS);
System.out.print(start + " ");
for (int i = start; i < (start + ITERATION_COUNT); i++) {
doit(i);
}
}
}
}

View file

@ -0,0 +1,480 @@
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Properties;
/**
* Test the Cache class for any concurrency problems
*
* $Id: TestConcurrency.java 404 2007-02-24 10:21:00Z larst $
* @version $Revision: 404 $
*/
public class TestConcurrency2 extends TestCase {
private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency2.class
// Static variables required thru all the tests
private static GeneralCacheAdministrator admin = null;
// Constants needed in the tests
private final String KEY = "key";
private final String VALUE = "This is some content";
private final int ITERATION_COUNT = 1000;
private final int THREAD_COUNT = 3;
private final int UNIQUE_KEYS = 1013;
/**
* Class constructor.
* <p>
* @param str The test name (required by JUnit)
*/
public TestConcurrency2(String str) {
super(str);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a new Cache
if (admin == null) {
Properties config = new Properties();
config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "70");
config.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "false");
admin = new GeneralCacheAdministrator(config);
assertNotNull(admin);
}
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestConcurrency2.class);
}
/**
* Check that the cache handles simultaneous attempts to access a
* new cache entry correctly
*/
public void testNewEntry() {
String key = "new";
try {
admin.getFromCache(key, -1);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another couple of threads to get the same cache entry
GetEntry getEntry1 = new GetEntry(key, VALUE, -1, false);
GetEntry getEntry2 = new GetEntry(key, VALUE, -1, false);
// OK, those threads should be blocked waiting for the new cache
// entry to appear. Sleep for a bit to simulate the time taken to
// build the cache entry
PutInCache putInCache = new PutInCache(key, VALUE, 500);
// pass that instance to the MTTR
TestRunnable[] trs = {getEntry1, getEntry2, putInCache};
MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);
// kickstarts the MTTR & fires off threads
try {
mttr.runTestRunnables(5000);
} catch (Throwable e) {
fail("Thread should have blocked until a new cache entry was ready");
}
}
}
/**
* Check that the cache handles simultaneous attempts to access a
* new cache entry correctly
*/
public void testNewEntryCancel() {
final String key = "newCancel";
final String NEW_VALUE = VALUE + "...";
try {
admin.getFromCache(key, -1);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry
// We can't use GrobeUtils, because joining functionality is missing
GetEntrySimple getEntry = new GetEntrySimple(key, NEW_VALUE, CacheEntry.INDEFINITE_EXPIRY, true);
Thread thread = new Thread(getEntry);
thread.start();
// The above thread will be blocked waiting for the new content
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
// Now cancel the update (eg because an exception occurred while building the content).
// This will unblock the other thread and it will receive a NeedsRefreshException.
admin.cancelUpdate(key);
// Wait a bit for the other thread to update the cache
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
try {
Object newValue = admin.getFromCache(key, CacheEntry.INDEFINITE_EXPIRY);
assertEquals(NEW_VALUE, newValue);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
e.printStackTrace();
fail("A NeedsRefreshException should not have been thrown. content=" + e.getCacheContent() + ", "+e.getMessage());
}
}
}
/**
* Verify that we can concurrently access the cache without problems
*/
public void testPut() {
Thread[] thread = new Thread[THREAD_COUNT];
for (int idx = 0; idx < THREAD_COUNT; idx++) {
OSGeneralTest runner = new OSGeneralTest();
thread[idx] = new Thread(runner);
thread[idx].start();
}
boolean stillAlive;
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// do nothing
}
stillAlive = false;
int i = 0;
while ((i < thread.length) && !stillAlive) {
stillAlive |= thread[i++].isAlive();
}
} while (stillAlive);
}
/**
* Check that the cache handles simultaneous attempts to access a
* stale cache entry correctly
*/
public void testStaleEntry() {
String key = "stale";
assertFalse("The cache should not be in blocking mode for this test.", admin.isBlocking());
admin.putInCache(key, VALUE);
try {
// This should throw a NeedsRefreshException since the refresh
// period is 0
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry.
// Since blocking mode is currently disabled we should
// immediately get back the stale entry
GetEntry getEntry = new GetEntry(key, VALUE, 0, false);
Thread thread = new Thread(getEntry);
thread.start();
// Sleep for a bit to simulate the time taken to build the cache entry
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
}
// Putting the entry in the cache should mean that threads now retrieve
// the updated entry
String newValue = "New value";
admin.putInCache(key, newValue);
getEntry = new GetEntry(key, newValue, -1, false);
thread = new Thread(getEntry);
thread.start();
try {
Object fromCache = admin.getFromCache(key, -1);
assertEquals(newValue, fromCache);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
fail("Should not have received a NeedsRefreshException");
}
// Give the GetEntry thread a chance to finish
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
}
}
}
/**
* A test for the updating of a stale entry when CACHE.BLOCKING = TRUE
*/
public void testStaleEntryBlocking() {
// A test for the case where oscache.blocking = true
admin.destroy();
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true");
admin = new GeneralCacheAdministrator(p);
assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking());
// Use a unique key in case these test entries are being persisted
String key = "blocking";
String NEW_VALUE = VALUE + " abc";
admin.putInCache(key, VALUE);
try {
// Force a NeedsRefreshException
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
// Fire off another thread to get the same cache entry.
// Since blocking mode is enabled this thread should block
// until the entry has been updated.
GetEntry getEntry = new GetEntry(key, NEW_VALUE, 0, false);
Thread thread = new Thread(getEntry);
thread.start();
// Sleep for a bit to simulate the time taken to build the cache entry
try {
Thread.sleep(20);
} catch (InterruptedException ie) {
}
// Putting the entry in the cache should mean that threads now retrieve
// the updated entry
admin.putInCache(key, NEW_VALUE);
getEntry = new GetEntry(key, NEW_VALUE, -1, false);
thread = new Thread(getEntry);
thread.start();
try {
Object fromCache = admin.getFromCache(key, -1);
assertEquals(NEW_VALUE, fromCache);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
fail("Should not have received a NeedsRefreshException");
}
}
}
private static final int RETRY_BY_THREADS = 100000;
private static final int NB_THREADS = 4;
/**
* Checks whether the cache handles simultaneous attempts to access a
* stable cache entry correctly when the blocking mode is enabled.
*
* Basically N threads are concurrently trying to access a same stale cache entry and each is cancelling its update. Each thread repeat this operation M times.
* The test is sucessfull if after some time, all threads are properly released
*/
public void testConcurrentStaleGets() {
GeneralCacheAdministrator staticAdmin = admin;
//admin = new GeneralCacheAdministrator(); //avoid poluting other test cases
try {
// A test for the case where oscache.blocking = true
//admin.destroy();
Properties p = new Properties();
p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true");
admin = new GeneralCacheAdministrator(p);
assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking());
String key = "new";
//First put a value
admin.putInCache(key, VALUE);
try {
//Then test without concurrency that it is reported as stale when time-to-live is zero
admin.getFromCache(key, 0);
fail("NeedsRefreshException should have been thrown");
} catch (NeedsRefreshException nre) {
//Ok this is was is excpected, we can release the update
admin.cancelUpdate(key);
}
//Then ask N threads to concurrently try to access this stale resource and each should receive a NeedsRefreshException, and cancel the update
TestRunnable[] spawnedThreads = new TestRunnable[NB_THREADS];
for (int threadIndex = 0; threadIndex < NB_THREADS; threadIndex++) {
spawnedThreads[threadIndex] = new GetStaleEntryAndCancelUpdate(key, 0, RETRY_BY_THREADS);
}
MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(spawnedThreads);
//kickstarts the MTTR & fires off threads
try {
mttr.runTestRunnables(120 * 1000);
} catch (Throwable e) {
fail("at least one thread did not complete");
e.printStackTrace();
}
} finally {
// avoid poluting other test cases
admin = staticAdmin;
}
}
private class GetEntry extends TestRunnable {
String key;
String value;
boolean expectNRE;
int time;
GetEntry(String key, String value, int time, boolean expectNRE) {
this.key = key;
this.value = value;
this.time = time;
this.expectNRE = expectNRE;
}
public void runTest() {
try {
// Get from the cache
Object fromCache = admin.getFromCache(key, time);
assertEquals(value, fromCache);
} catch (NeedsRefreshException nre) {
if (!expectNRE) {
admin.cancelUpdate(key);
fail("Thread should have blocked until a new cache entry was ready");
} else {
// Put a new piece of content into the cache
admin.putInCache(key, value);
}
}
}
}
private class GetEntrySimple extends GetEntry {
GetEntrySimple(String key, String value, int time, boolean expectNRE) {
super(key, value, time, expectNRE);
}
public void run() {
runTest();
}
}
private class PutInCache extends TestRunnable {
String key;
String value;
long wait;
PutInCache(String key, String value, long wait) {
this.key = key;
this.value = value;
this.wait = wait;
}
public void runTest() {
try {
Thread.sleep(wait);
} catch (InterruptedException ie) {
fail("PutInCache thread shouldn't be interrupted.");
}
admin.putInCache(key, value);
}
}
/**
* Basically requests a stale entry, expects to receive a NeedsRefreshException, and always cancels the update.
*/
private class GetStaleEntryAndCancelUpdate extends TestRunnable {
String key;
int retries;
int time;
GetStaleEntryAndCancelUpdate(String key, int time, int retries) {
this.key = key;
this.time = time;
this.retries = retries;
}
public void runTest() {
for (int retryIndex = 0; retryIndex < retries; retryIndex++) {
try {
// Get from the cache
Object fromCache = admin.getFromCache(key, time);
assertNull("Thread index [" + retryIndex + "] expected stale request [" + retryIndex + "] to be received, got [" + fromCache + "]", fromCache);
} catch (NeedsRefreshException nre) {
try {
admin.cancelUpdate(key);
} catch (Throwable t) {
log.error("Thread index [" + retryIndex + "]: Unexpectedly caught exception [" + t + "]", t);
fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]");
}
} catch (Throwable t) {
log.error("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]", t);
fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]");
}
}
}
}
private class OSGeneralTest extends TestRunnable {
public void doit(int i) {
int refreshPeriod = 500 /*millis*/;
String key = KEY + (i % UNIQUE_KEYS);
admin.putInCache(key, VALUE);
try {
// Get from the cache
admin.getFromCache(KEY, refreshPeriod);
} catch (NeedsRefreshException nre) {
// Get the value
// Store in the cache
admin.putInCache(KEY, VALUE);
}
// Flush occasionally
if ((i % (UNIQUE_KEYS + 1)) == 0) {
admin.getCache().flushEntry(key);
}
}
public void runTest() {
int start = (int) (Math.random() * UNIQUE_KEYS);
System.out.print(start + " ");
for (int i = start; i < (start + ITERATION_COUNT); i++) {
doit(i);
}
}
}
}

View file

@ -0,0 +1,251 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.persistence.CachePersistenceException;
import com.opensymphony.oscache.base.persistence.PersistenceListener;
import junit.framework.TestCase;
/**
* Test class for the AbstractCache class. It tests all public methods of
* the AbstractCache and assert the results. It is design to run under JUnit.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public abstract class TestAbstractCache extends TestCase {
/**
* Invalid cache capacity
*/
protected final int INVALID_MAX_ENTRIES = 0;
/**
* Cache capacity
*/
protected final int MAX_ENTRIES = 3;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
protected TestAbstractCache(String str) {
super(str);
}
/**
* Test the method that verify if the cache contains a specific key
*/
public abstract void testContainsKey();
/**
* Test the get from the cache
*/
public abstract void testGet();
/**
* Test the capacity setting
*/
public void testGetSetMaxEntries() {
getCache().setMaxEntries(MAX_ENTRIES);
assertEquals(MAX_ENTRIES, getCache().getMaxEntries());
// Specify an invalid capacity
try {
getCache().setMaxEntries(INVALID_MAX_ENTRIES);
fail("Cache capacity set with an invalid argument");
} catch (Exception e) {
// This is what we expect
}
}
/**
* Test the setting of the memory cache
*/
public void testGetSetMemoryCache() {
getCache().setMemoryCaching(true);
assertTrue(getCache().isMemoryCaching());
}
/**
* Test the iterator retrieval
*/
public abstract void testIterator();
/**
* Test the put into the cache
*/
public abstract void testPut();
/**
* Test the remove from the cache
*/
public abstract void testRemove();
/**
* Test the specific details about the cache algorithm
*/
public abstract void testRemoveItem();
/**
* Test the PersistenceListener setter. Since the persistance listener is
* an interface, just call the setter with null
*/
public void testSetPersistenceListener() {
getCache().setPersistenceListener(null);
}
// Abstract method that returns an instance of an admin
protected abstract AbstractConcurrentReadCache getCache();
/**
* Test that groups are correctly updated on puts and removes
* See CACHE-188 and maybe CACHE-244
*/
public void testGroups() {
String KEY = "testkey";
String KEY2 = "testkey2";
String GROUP_NAME = "group1";
CacheEntry entry = new CacheEntry(KEY, null);
entry.setContent("testvalue");
entry.setGroups(new String[] {GROUP_NAME});
getCache().put(KEY, entry);
Map m = getCache().getGroupsForReading();
assertNotNull("group must exist", m.get(GROUP_NAME));
try {
Set group = (Set)m.get(GROUP_NAME);
assertEquals(1, group.size());
Object keyFromGroup = group.iterator().next();
assertEquals(KEY, keyFromGroup);
} catch (ClassCastException e) {
fail("group should have been a java.util.Set but is a " +
m.get(GROUP_NAME).getClass().getName());
}
assertNotNull(getCache().remove(KEY));
m = getCache().getGroupsForReading();
assertNull("group should have been deleted (see CACHE-188)", m.get(GROUP_NAME));
getCache().clear();
// Test if persistence options are correctly considered for groups
try {
PersistenceListener listener = new MockPersistenceListener();
getCache().setPersistenceListener(listener);
getCache().setOverflowPersistence(false);
getCache().put(KEY, entry);
assertTrue(listener.isStored(KEY));
Set group = listener.retrieveGroup(GROUP_NAME);
assertNotNull(group);
assertTrue(group.contains(KEY));
getCache().remove(KEY);
assertFalse(listener.isStored(KEY));
getCache().clear();
// test overflow persistence
getCache().setOverflowPersistence(true);
getCache().setMaxEntries(1);
getCache().put(KEY, entry);
assertFalse(listener.isStored(KEY));
// is it correct that the group is persisted, even when we use overflow only?
// assertFalse(listener.isGroupStored(GROUP_NAME));
CacheEntry entry2 = new CacheEntry(KEY2);
entry2.setContent("testvalue");
entry2.setGroups(new String[] {GROUP_NAME});
getCache().put(KEY2, entry2);
// oldest must have been persisted to disk:
assertTrue(listener.isStored(KEY));
assertFalse(listener.isStored(KEY2));
assertNotNull(getCache().get(KEY2));
} catch (CachePersistenceException e) {
e.printStackTrace();
fail("Excpetion was thrown");
}
}
public void testMisc() {
getCache().clear();
assertTrue(getCache().capacity() > 0);
final String KEY = "testkeymisc";
final String CONTENT = "testkeymisc";
CacheEntry entry = new CacheEntry(KEY, null);
entry.setContent(CONTENT);
if (getCache().contains(entry) == false) {
getCache().put(KEY, entry);
}
assertTrue(getCache().contains(entry));
CacheEntry entry2 = new CacheEntry(KEY+"2", null);
entry.setContent(CONTENT+"2");
getCache().put(entry2.getKey(), entry2);
Enumeration enumeration = getCache().elements();
assertTrue(enumeration.hasMoreElements());
while (enumeration.hasMoreElements()) enumeration.nextElement();
}
private static class MockPersistenceListener implements PersistenceListener {
private Map entries = new HashMap();
private Map groups = new HashMap();
public void clear() throws CachePersistenceException {
entries.clear();
groups.clear();
}
public PersistenceListener configure(Config config) {
return this;
}
public boolean isGroupStored(String groupName) throws CachePersistenceException {
return groups.containsKey(groupName);
}
public boolean isStored(String key) throws CachePersistenceException {
return entries.containsKey(key);
}
public void remove(String key) throws CachePersistenceException {
entries.remove(key);
}
public void removeGroup(String groupName) throws CachePersistenceException {
groups.remove(groupName);
}
public Object retrieve(String key) throws CachePersistenceException {
return entries.get(key);
}
public Set retrieveGroup(String groupName) throws CachePersistenceException {
return (Set)groups.get(groupName);
}
public void store(String key, Object obj) throws CachePersistenceException {
entries.put(key, obj);
}
public void storeGroup(String groupName, Set group) throws CachePersistenceException {
groups.put(groupName, group);
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.base.algorithm package.
* It invokes all the test suites of all the other classes of the package,
* except abstract ones because they are tested via final ones.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteAlgorithm extends TestCase {
/**
* Constructor for the oscache project main test program
*/
public TestCompleteAlgorithm(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteAlgorithm.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all base algorithm cache modules");
suite.addTest(TestFIFOCache.suite());
suite.addTest(TestLRUCache.suite());
suite.addTest(TestUnlimitedCache.suite());
return suite;
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test class for the FIFOCache class. It tests that the algorithm reacts as
* expected when entries are removed
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestFIFOCache extends TestQueueCache {
/**
* FIFO Cache object
*/
private static FIFOCache cache = null;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestFIFOCache(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestFIFOCache.class);
}
/**
* Abstract method used by the TestAbstractCache class
* <p>
* @return A cache instance
*/
public AbstractConcurrentReadCache getCache() {
return cache;
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// Create a cache instance on first invocation
if (cache == null) {
cache = new FIFOCache();
assertNotNull(cache);
}
}
/**
* Test the cache algorithm
*/
public void testRemoveItem() {
// Add 2 elements in the cache and ensure that the one to remove is the first
// inserted
cache.itemPut(KEY);
cache.itemPut(KEY + 1);
assertTrue(KEY.equals(cache.removeItem()));
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test class for the LRUCache class. It only tests that the algorithm reacts as
* expected when entries are removed. All the other tests related to the LRU
* algorithm are in the TestNonQueueCache class, since those tests are shared
* with the TestUnlimitedCache class.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestLRUCache extends TestQueueCache {
/**
* LRU Cache object
*/
private static LRUCache cache = null;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestLRUCache(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestLRUCache.class);
}
/**
* Abstract method used by the TestAbstractCache class
* <p>
* @return A cache instance
*/
public AbstractConcurrentReadCache getCache() {
return cache;
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// Create a cache instance on first invocation
if (cache == null) {
cache = new LRUCache();
assertNotNull(cache);
}
}
/**
* Test the cache algorithm
*/
public void testRemoveItem() {
// Add 3 elements
cache.itemPut(KEY);
cache.itemPut(KEY + 1);
cache.itemPut(KEY + 2);
// Get the last element
cache.itemRetrieved(KEY);
// The least recently used item is key + 1
assertTrue((KEY + 1).equals(cache.removeItem()));
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.persistence.PersistenceListener;
import com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener;
import com.opensymphony.oscache.plugins.diskpersistence.TestDiskPersistenceListener;
import java.util.Iterator;
import java.util.Properties;
/**
* Test class for the QueueCache class, which is the base class for FIFO
* and LIFO algorithm classes. All the public methods of QueueCache are tested
* here.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public abstract class TestQueueCache extends TestAbstractCache {
/**
* Entry content
*/
protected final String CONTENT = "Test Queue Cache content";
/**
* Entry key
*/
protected final String KEY = "Test Queue Cache key";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestQueueCache(String str) {
super(str);
}
/**
* Test the specific algorithms
*/
public abstract void testRemoveItem();
/**
* Test the clear
*/
public void testClear() {
getCache().clear();
assertEquals(0, getCache().size());
}
/**
* Test the ContainsKey method
*/
public void testContainsKey() {
getCache().put(KEY, CONTENT);
assertTrue(getCache().containsKey(KEY));
getCache().clear();
}
/**
* Test the get method
*/
public void testGet() {
// Add an entry and verify that it is there
getCache().put(KEY, CONTENT);
assertTrue(getCache().get(KEY).equals(CONTENT));
// Call with invalid parameters
try {
getCache().get(null);
fail("Get called with null parameters!");
} catch (Exception e) { /* This is what we expect */
}
getCache().clear();
}
/**
* Test the getter and setter for the max entries
*/
public void testGetSetMaxEntries() {
// Check that the cache is full, then chop it by one and assert that
// an element has been removed
for (int count = 0; count < MAX_ENTRIES; count++) {
getCache().put(KEY + count, CONTENT + count);
}
assertEquals(MAX_ENTRIES, getCache().size());
getCache().setMaxEntries(MAX_ENTRIES - 1);
assertEquals(MAX_ENTRIES - 1, getCache().getMaxEntries());
assertEquals(MAX_ENTRIES - 1, getCache().size());
// Specify an invalid capacity
try {
getCache().setMaxEntries(INVALID_MAX_ENTRIES);
fail("Cache capacity set with an invalid argument");
} catch (Exception e) {
// This is what we expect
}
getCache().clear();
}
/**
* Test the iterator
*/
public void testIterator() {
// Verify that the iterator returns MAX_ENTRIES and no more elements
int nbEntries = getCache().size();
Iterator iterator = getCache().entrySet().iterator();
assertNotNull(iterator);
for (int count = 0; count < nbEntries; count++) {
assertNotNull(iterator.next());
}
assertTrue(!iterator.hasNext());
}
/**
* Test the put method
*/
public void testPut() {
// Put elements in cache
for (int count = 0; count < MAX_ENTRIES; count++) {
getCache().put(KEY + count, CONTENT + count);
}
// Call with invalid parameters
try {
getCache().put(null, null);
fail("Put called with null parameters!");
} catch (Exception e) { /* This is what we expect */
}
getCache().clear();
}
/**
* Test the put method with overflow parameter set
*/
public void testPutOverflow() {
// Create a listener
PersistenceListener listener = new DiskPersistenceListener();
Properties p = new Properties();
p.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR);
p.setProperty("cache.memory", "true");
p.setProperty("cache.persistence.overflow.only", "true");
p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener");
listener.configure(new Config(p));
getCache().setPersistenceListener(listener);
getCache().clear();
getCache().setMaxEntries(MAX_ENTRIES);
getCache().setOverflowPersistence(true);
if (getCache() instanceof UnlimitedCache) {
return; // nothing to test since memory will never overflow.
}
// Put elements in cache
for (int count = 0; count <= MAX_ENTRIES; count++) {
getCache().put(KEY + count, CONTENT + count);
}
try {
int numPersisted = 0;
// Check that number of elements persisted == 1 if it is an overflow cache or all
// if it is not overflow and writes every time.
for (int count = 0; count <= MAX_ENTRIES; count++) {
if (getCache().getPersistenceListener().isStored(KEY + count)) {
numPersisted++;
}
}
if (getCache().isOverflowPersistence()) {
assertTrue("Only 1 element should have been persisted ", numPersisted == 1);
} else {
assertTrue("All elements should have been persisted ", numPersisted == (MAX_ENTRIES + 1));
}
} catch (Exception e) {
fail();
}
getCache().clear();
}
/**
* Test if bug CACHE-255 disappeared.
*/
public void testBugCache255() {
if (!getCache().isMemoryCaching()) {
return; // nothing to test since memory won't be used.
}
if (getCache() instanceof UnlimitedCache) {
return; // nothing to test since memory will never overflow.
}
// fill up the cache
for (int count = 0; count < MAX_ENTRIES; count++) {
getCache().put(KEY + count, CONTENT + count);
}
// get the old value
Object oldValue = getCache().put(KEY + MAX_ENTRIES, CONTENT + MAX_ENTRIES);
assertEquals("Evicted object content should be the same", CONTENT + "0", oldValue);
getCache().clear();
}
/**
* Test the remove from cache
*/
public void testRemove() {
getCache().put(KEY, CONTENT);
// Remove the object and assert the return
assertNotNull(getCache().remove(KEY));
getCache().clear();
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.algorithm;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test class for the Unlimited cache algorithm. Most of the tests are done
* in the TestNonQueueCache class, so only algorithm specific tests are done
* here. Since this is an unlimited cache, there's not much to test about
* the algorithm.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestUnlimitedCache extends TestQueueCache {
/**
* Unlimited Cache object
*/
private static UnlimitedCache cache = null;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestUnlimitedCache(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestUnlimitedCache.class);
}
/**
* Abstract method used by the TestAbstractCache class
* <p>
* @return A cache instance
*/
public AbstractConcurrentReadCache getCache() {
return cache;
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// Create a cache instance on first invocation
if (cache == null) {
cache = new UnlimitedCache();
assertNotNull(cache);
}
}
/**
* Test the getter and setter for the max entries. It overrides the TestQueueCache
* one since it shouldn't have any effect in unlimited cache
*/
public void testGetSetMaxEntries() {
// Check that the max entries cannot be changed
int entryCount = getCache().getMaxEntries();
getCache().setMaxEntries(entryCount - 1);
assertEquals(entryCount, getCache().getMaxEntries());
}
/**
* Test the cache algorithm
*/
public void testRemoveItem() {
// Add an item, and ensure that it is not removable
cache.itemPut(KEY);
assertNull(cache.removeItem());
}
/**
* Test that groups are correctly updated on puts and removes
*/
public void testGroups() {
// test not possible, because can't reduce cache max entries for this test
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* This is the test class for the CacheEntryEvent class. It checks that the
* public methods are working properly
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCacheEntryEvent extends TestCase {
/**
* Constants required for the test
*/
private final String KEY = "Test cache entry event key";
private final String KEY_2 = "Test cache entry event key 2";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheEntryEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestCacheEntryEvent.class);
}
/**
* Test the CacheEntryEvent class
*/
public void testCacheEntryEvent() {
// Create all the required objects
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence());
// test with key
CacheEntry entry = new CacheEntry(KEY);
CacheEntryEvent event = new CacheEntryEvent(map, entry, null);
// Get back the values and assert them
assertEquals(event.getEntry(), entry);
assertEquals(event.getKey(), KEY);
assertEquals(event.getMap(), map);
assertNull(event.getOrigin());
CacheEntry entry2 = new CacheEntry(KEY_2);
CacheEntryEvent event2 = new CacheEntryEvent(map, entry2);
// Get back the values and assert them
assertEquals(event2.getEntry(), entry2);
assertEquals(event2.getKey(), KEY_2);
assertEquals(event2.getMap(), map);
assertNull(event2.getOrigin());
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* This is the test class for the CacheGroupEvent class. It checks that the
* public methods are working properly
*
* $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $
* @version $Revision: 385 $
* @author Lars Torunski
*/
public final class TestCacheGroupEvent extends TestCase {
/**
* Constants required for the test
*/
private final String TEST_GROUP = "testGroup";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheGroupEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestCacheGroupEvent.class);
}
/**
* Test the CacheEntryEvent class
*/
public void testCacheEntryEvent() {
// Create all the required objects
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence());
// three parameters
CacheGroupEvent event = new CacheGroupEvent(map, TEST_GROUP, null);
// Get back the values and assert them
assertEquals(event.getMap(), map);
assertEquals(event.getGroup(), TEST_GROUP);
assertNull(event.getOrigin());
// two parameters
CachePatternEvent event2 = new CachePatternEvent(map, TEST_GROUP);
// Get back the values and assert them
assertEquals(event2.getMap(), map);
assertEquals(event.getGroup(), TEST_GROUP);
assertNull(event2.getOrigin());
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import com.opensymphony.oscache.base.CacheEntry;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* This is the test class for the CacheMapAccessEvent class. It checks that the
* public methods are working properly
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCacheMapAccessEvent extends TestCase {
private final String KEY = "Test cache map access event key";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheMapAccessEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestCacheMapAccessEvent.class);
}
/**
* Test the CacheMapAccessEvent class
*/
public void testCacheMapAccessEvent() {
// Create an object and check the parameters
CacheEntry entry = new CacheEntry(KEY);
CacheMapAccessEvent event = new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry);
assertEquals(event.getCacheEntry(), entry);
assertEquals(event.getCacheEntryKey(), KEY);
assertEquals(event.getEventType(), CacheMapAccessEventType.HIT);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* This is the test class for the CachePatternEvent class. It checks that the
* public methods are working properly
*
* $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $
* @version $Revision: 385 $
* @author Lars Torunski
*/
public final class TestCachePatternEvent extends TestCase {
/**
* Constants required for the test
*/
private final String TEST_PATTERN = "testPattern";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCachePatternEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestCachePatternEvent.class);
}
/**
* Test the CacheEntryEvent class
*/
public void testCacheEntryEvent() {
// Create all the required objects
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence());
// three parameters
CachePatternEvent event = new CachePatternEvent(map, TEST_PATTERN, null);
// Get back the values and assert them
assertEquals(event.getMap(), map);
assertEquals(event.getPattern(), TEST_PATTERN);
assertNull(event.getOrigin());
// two parameters
CachePatternEvent event2 = new CachePatternEvent(map, TEST_PATTERN);
// Get back the values and assert them
assertEquals(event2.getMap(), map);
assertEquals(event.getPattern(), TEST_PATTERN);
assertNull(event2.getOrigin());
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import java.util.Date;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* This is the test class for the CachewideEvent class. It checks that the
* public methods are working properly
*
* $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $
* @version $Revision: 385 $
* @author Lars Torunski
*/
public final class TestCachewideEvent extends TestCase {
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCachewideEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestCachewideEvent.class);
}
/**
* Test the CacheEntryEvent class
*/
public void testCacheEntryEvent() {
// Create all the required objects
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Date date = new Date();
CachewideEvent event = new CachewideEvent(admin.getCache(), date, null);
// Get back the values and assert them
assertEquals(event.getDate(), date);
assertEquals(event.getCache(), admin.getCache());
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.base.events package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteEvents extends TestCase {
/**
* Constructor for the oscache module main test program
*/
public TestCompleteEvents(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteEvents.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all base cache modules");
suite.addTest(TestCacheEntryEvent.suite());
suite.addTest(TestCacheMapAccessEvent.suite());
suite.addTest(TestScopeEvent.suite());
suite.addTest(TestCachewideEvent.suite());
suite.addTest(TestCachePatternEvent.suite());
suite.addTest(TestCacheGroupEvent.suite());
return suite;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.base.events;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.Date;
/**
* This is the test class for the ScopeEvent class. It checks that the
* public methods are working properly
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestScopeEvent extends TestCase {
private final int SCOPE = 3;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestScopeEvent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestScopeEvent.class);
}
/**
* Test the ScopeEvent class
*/
public void testScopeEvent() {
Date date = new Date();
// Create an object and check the parameters
ScopeEvent event = new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, SCOPE, date, null);
assertEquals(event.getEventType(), ScopeEventType.ALL_SCOPES_FLUSHED);
assertEquals(event.getScope(), SCOPE);
assertTrue(event.getDate().equals(date));
event = new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, SCOPE, date, null);
assertEquals(event.getEventType(), ScopeEventType.SCOPE_FLUSHED);
assertEquals(event.getScope(), SCOPE);
assertTrue(event.getDate().equals(date));
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.extra;
import java.util.Date;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.events.CacheEntryEvent;
import com.opensymphony.oscache.base.events.CacheGroupEvent;
import com.opensymphony.oscache.base.events.CachePatternEvent;
import com.opensymphony.oscache.base.events.CachewideEvent;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test the cache entry event listener implementation
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestCacheEntryEventListenerImpl extends TestCase {
/**
* Key used for this test
*/
private final String KEY = "Test Cache Entry Event Listener Impl Key";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheEntryEventListenerImpl(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestCacheEntryEventListenerImpl.class);
}
/**
* Test the basic implementation
*/
public void testCacheEntryEventListenerImpl() {
// Construct the objects required for the tests
CacheEntry entry = new CacheEntry(KEY);
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Cache cache = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence());
CacheEntryEvent event = new CacheEntryEvent(cache, entry, null);
CacheEntryEventListenerImpl listener = new CacheEntryEventListenerImpl();
// Assert the counters
assertEquals(listener.getEntryAddedCount(), 0);
assertEquals(listener.getEntryFlushedCount(), 0);
assertEquals(listener.getEntryRemovedCount(), 0);
assertEquals(listener.getEntryUpdatedCount(), 0);
assertEquals(listener.getGroupFlushedCount(), 0);
assertEquals(listener.getPatternFlushedCount(), 0);
assertEquals(listener.getCacheFlushedCount(), 0);
// Generate an event of each type
listener.cacheEntryAdded(event);
listener.cacheEntryFlushed(event);
listener.cacheEntryRemoved(event);
listener.cacheEntryUpdated(event);
listener.cacheFlushed(new CachewideEvent(cache, new Date(), null));
listener.cacheGroupFlushed(new CacheGroupEvent(cache, "testGroup", null));
listener.cachePatternFlushed(new CachePatternEvent(cache, "testPattern", null));
// Assert the counters
assertEquals(listener.getEntryAddedCount(), 1);
assertEquals(listener.getEntryFlushedCount(), 1);
assertEquals(listener.getEntryRemovedCount(), 1);
assertEquals(listener.getEntryUpdatedCount(), 1);
assertEquals(listener.getGroupFlushedCount(), 1);
assertEquals(listener.getPatternFlushedCount(), 1);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.extra;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.events.CacheMapAccessEvent;
import com.opensymphony.oscache.base.events.CacheMapAccessEventType;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test the cache map access event listener implementation
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestCacheMapAccessEventListenerImpl extends TestCase {
/**
* Key used for this test
*/
private final String KEY = "Test Cache Map Access Event Listener Impl Key";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestCacheMapAccessEventListenerImpl(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestCacheMapAccessEventListenerImpl.class);
}
/**
* Test the basic implementation of the listener
*/
public void testCacheMapAccessEventListenerImpl() {
// Build objects required for the tests
CacheEntry entry = new CacheEntry(KEY);
CacheMapAccessEventListenerImpl listener = new CacheMapAccessEventListenerImpl();
// Genereate events
listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry));
listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry));
listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.STALE_HIT, entry));
listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.MISS, entry));
// Assert the counters
assertEquals(listener.getHitCount(), 2);
assertEquals(listener.getStaleHitCount(), 1);
assertEquals(listener.getMissCount(), 1);
// Reset the counts
listener.reset();
assertEquals(listener.getHitCount(), 0);
assertEquals(listener.getStaleHitCount(), 0);
assertEquals(listener.getMissCount(), 0);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.extra;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.extra package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteExtra extends TestCase {
/**
* Constructor for the osCache Cache Extra package main test program
*/
public TestCompleteExtra(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteExtra.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the test suites of all the project classes
TestSuite suite = new TestSuite("Test all extra cache modules");
suite.addTest(TestCacheEntryEventListenerImpl.suite());
suite.addTest(TestCacheMapAccessEventListenerImpl.suite());
suite.addTest(TestScopeEventListenerImpl.suite());
suite.addTest(TestStatisticListenerImpl.suite());
return suite;
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.extra;
import com.opensymphony.oscache.base.events.ScopeEvent;
import com.opensymphony.oscache.base.events.ScopeEventType;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.Date;
/**
* Test the scope event listener implementation
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestScopeEventListenerImpl extends TestCase {
private static final int PAGE_SCOPE = 1;
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestScopeEventListenerImpl(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestScopeEventListenerImpl.class);
}
/**
* Test the basic implementation of this listener
*/
public void testScopeEventListenerImpl() {
// Construct the object we need for the test
ScopeEventListenerImpl listener = new ScopeEventListenerImpl();
// Generates events
listener.scopeFlushed(new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, PAGE_SCOPE, new Date()));
listener.scopeFlushed(new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, PAGE_SCOPE, new Date()));
// Assert the counters
assertEquals(listener.getApplicationScopeFlushCount(), 1);
assertEquals(listener.getPageScopeFlushCount(), 2);
assertEquals(listener.getRequestScopeFlushCount(), 1);
assertEquals(listener.getSessionScopeFlushCount(), 1);
assertEquals(listener.getTotalScopeFlushCount(), 5);
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.extra;
import java.util.Date;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.events.CacheEntryEvent;
import com.opensymphony.oscache.base.events.CacheGroupEvent;
import com.opensymphony.oscache.base.events.CachePatternEvent;
import com.opensymphony.oscache.base.events.CachewideEvent;
import com.opensymphony.oscache.base.events.ScopeEvent;
import com.opensymphony.oscache.base.events.ScopeEventType;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test the cache entry event listener implementation
*
* $Id: TestCacheEntryEventListenerImpl.java 254 2005-06-17 05:07:38Z dres $
* @version $Revision: 254 $
*/
public class TestStatisticListenerImpl extends TestCase {
private static final int PAGE_SCOPE = 1;
/**
* Key used for this test
*/
private final String KEY = "Test Statistikc Listener Impl Key";
/**
* Constructor
* <p>
* @param str The test name (required by JUnit)
*/
public TestStatisticListenerImpl(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestStatisticListenerImpl.class);
}
/**
* Test the basic implementation
*/
public void testCacheEntryEventListenerImpl() {
// Construct the objects required for the tests
CacheEntry entry = new CacheEntry(KEY);
GeneralCacheAdministrator admin = new GeneralCacheAdministrator();
Cache cache = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence());
CacheEntryEvent event = new CacheEntryEvent(cache, entry, null);
StatisticListenerImpl listener = new StatisticListenerImpl();
// Assert the counters
assertEquals(listener.getEntriesAdded(), 0);
assertEquals(listener.getFlushCount(), 0);
assertEquals(listener.getEntriesRemoved(), 0);
assertEquals(listener.getEntriesUpdated(), 0);
assertEquals(listener.getHitCount(), 0);
assertEquals(listener.getHitCountSum(), 0);
assertEquals(listener.getMissCount(), 0);
assertEquals(listener.getMissCountSum(), 0);
assertEquals(listener.getStaleHitCount(), 0);
assertEquals(listener.getStaleHitCountSum(), 0);
// Generate an event of each type
listener.cacheEntryAdded(event);
listener.cacheEntryFlushed(event);
listener.cacheEntryRemoved(event);
listener.cacheEntryUpdated(event);
listener.scopeFlushed(new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, PAGE_SCOPE, new Date()));
listener.scopeFlushed(new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, PAGE_SCOPE, new Date()));
listener.cacheFlushed(new CachewideEvent(cache, new Date(), null));
listener.cacheGroupFlushed(new CacheGroupEvent(cache, "testGroup"));
listener.cachePatternFlushed(new CachePatternEvent(cache, "testPattern"));
// Assert the counters
assertEquals(listener.getEntriesAdded(), 1);
assertEquals(listener.getFlushCount(), 6);
assertEquals(listener.getEntriesRemoved(), 1);
assertEquals(listener.getEntriesUpdated(), 1);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.general;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.general package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteGeneral extends TestCase {
/**
* Constructor for the osCache Cache project main test program
*/
public TestCompleteGeneral(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteGeneral.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all General cache package");
suite.addTest(TestGeneralCacheAdministrator.suite());
suite.addTest(TestConcurrent.suite());
return suite;
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.general;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.opensymphony.oscache.base.AbstractCacheAdministrator;
import com.opensymphony.oscache.base.NeedsRefreshException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Testing concurrent API accesses.
*
* @author $Author: larst $
* @version $Revision: 385 $
*/
public class TestConcurrent extends TestCase {
private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency.class
// Static instance of a cache administrator
private GeneralCacheAdministrator admin = null;
// Constants needed in the tests
private final String KEY = "ConcurrentKey";
private final String VALUE = "ConcurrentContent";
private static final int THREAD_COUNT = 5;
private static final int CACHE_SIZE_THREAD = 2000;
private static final int CACHE_SIZE = THREAD_COUNT * CACHE_SIZE_THREAD;
public TestConcurrent(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestConcurrent.class);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a new Cache
if (admin == null) {
Properties config = new Properties();
config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, Integer.toString(CACHE_SIZE));
admin = new GeneralCacheAdministrator(config);
assertNotNull(admin);
log.info("Cache Size = " + admin.getCache().getSize());
}
}
/**
* Tests concurrent accesses.
* @see http://jira.opensymphony.com/browse/CACHE-279
*/
public void testConcurrentCreation10000() {
Thread[] thread = new Thread[THREAD_COUNT];
log.info("Ramping threads...");
for (int idx = 0; idx < THREAD_COUNT; idx++) {
CreationTest runner = new CreationTest(idx);
thread[idx] = new Thread(runner);
thread[idx].start();
}
log.info("Waiting....");
boolean stillAlive;
do {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// do nothing
}
stillAlive = false;
for (int i = 0; i < thread.length; i++) {
stillAlive |= thread[i].isAlive();
}
} while (stillAlive);
log.info("All threads finished. Cache Size = " + admin.getCache().getSize());
assertTrue("Unexpected amount of objects in the cache: " + admin.getCache().getSize(), CACHE_SIZE == admin.getCache().getSize());
}
private class CreationTest implements Runnable {
private String prefixKey;
public CreationTest(int idx) {
prefixKey = KEY + "_" + Integer.toString(idx) + "_";
Thread.currentThread().setName("CreationTest-"+idx);
log.info(Thread.currentThread().getName() + " is running...");
}
public void run() {
for (int i = 0; i < CACHE_SIZE_THREAD; i++) {
String key = prefixKey + Integer.toString(i);
try {
// Get from the cache
admin.getFromCache(key);
} catch (NeedsRefreshException nre) {
// Get the value
// Store in the cache
admin.putInCache(key, VALUE);
}
}
log.info(Thread.currentThread().getName() + " finished.");
}
}
}

View file

@ -0,0 +1,400 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.general;
import java.util.Date;
import com.opensymphony.oscache.base.*;
import com.opensymphony.oscache.extra.CacheEntryEventListenerImpl;
import com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test all the public methods of the GeneralCacheAdministrator class. Since
* this class extends the TestAbstractCacheAdministrator class, the
* AbstractCacheAdministrator is tested when invoking this class.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public class TestGeneralCacheAdministrator extends TestAbstractCacheAdministrator {
// Constants used thru all the tests
private static final String KEY = "Test General Cache Admin Key";
private static final int NO_REFRESH_NEEDED = CacheEntry.INDEFINITE_EXPIRY;
private static final int REFRESH_NEEDED = 0;
private static final String CONTENT = "Content for the general cache admin test";
private static final String WILL_NOT_FLUSH_PATTERN = "This key won't flush";
private static final String GROUP1 = "group1";
private static final String GROUP2 = "group2";
private static final String GROUP3 = "group3";
// Constants for listener counters
private static final int NB_CACHE_HITS = 7;
private static final int NB_CACHE_STALE_HITS = 7;
private static final int NB_CACHE_MISSED = 1;
private static final int NB_ADD = 7;
private static final int NB_UPDATED = 2;
private static final int NB_FLUSH = 3;
private static final int NB_REMOVED = 0;
private static final int NB_GROUP_FLUSH = 2;
private static final int NB_PATTERN_FLUSH = 1;
// Static instance of a cache administrator
static GeneralCacheAdministrator admin = null;
// Declare the listeners
private CacheEntryEventListenerImpl cacheEntryEventListener = null;
private CacheMapAccessEventListenerImpl cacheMapAccessEventListener = null;
/**
* Class constructor
* <p>
* @param str Test name (required by JUnit)
*/
public TestGeneralCacheAdministrator(String str) {
super(str);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
return new TestSuite(TestGeneralCacheAdministrator.class);
}
/**
* Abstract method used by the TestAbstractCacheAdministrator class
* <p>
* @return An administrator instance
*/
public AbstractCacheAdministrator getAdmin() {
return admin;
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a administrator
admin = new GeneralCacheAdministrator();
assertNotNull(admin);
cacheEntryEventListener = new CacheEntryEventListenerImpl();
cacheMapAccessEventListener = new CacheMapAccessEventListenerImpl();
// Register the listeners on the cache map
admin.getCache().addCacheEventListener(cacheEntryEventListener);
admin.getCache().addCacheEventListener(cacheMapAccessEventListener);
}
/**
* Validate the CacheEntryEventListener's data
*/
public void testCacheEntryEventListenerCounters() {
populate();
assertEquals(NB_ADD, cacheEntryEventListener.getEntryAddedCount());
assertEquals(NB_REMOVED, cacheEntryEventListener.getEntryRemovedCount());
assertEquals(NB_UPDATED, cacheEntryEventListener.getEntryUpdatedCount());
assertEquals(NB_GROUP_FLUSH, cacheEntryEventListener.getGroupFlushedCount());
assertEquals(NB_PATTERN_FLUSH, cacheEntryEventListener.getPatternFlushedCount());
assertEquals(NB_FLUSH, cacheEntryEventListener.getEntryFlushedCount());
}
/**
* Validate the CacheEntryEventListener's data
*/
public void testCacheMapAccessEventListenerCounters() {
populate();
int missCount = cacheMapAccessEventListener.getMissCount();
if (NB_CACHE_MISSED != missCount) {
fail("We expected " + NB_CACHE_MISSED + " misses but got " + missCount + "." + " This is probably due to existing disk cache, delete it and re-run" + " the test");
}
assertEquals(NB_CACHE_HITS, cacheMapAccessEventListener.getHitCount());
assertEquals(NB_CACHE_STALE_HITS, cacheMapAccessEventListener.getStaleHitCount());
}
/**
* Ensure that item may be flushed by key pattern
*/
public void testFlushPattern() {
// Put some content in cache
admin.putInCache(KEY, CONTENT);
// Call flush pattern with parameters that must NOT flush our object
admin.flushPattern(WILL_NOT_FLUSH_PATTERN);
admin.flushPattern("");
admin.flushPattern(null);
// Ensure that our object is not gone
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false));
// This time we flush it for real
admin.flushPattern(KEY.substring(1, 2));
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true));
}
/**
* Ensure that item may be flushed by the entry itself
*/
public void testFlushEntry() {
// Put some content in cache
admin.putInCache(KEY, CONTENT);
// Call flush pattern with parameters that must NOT flush our object
admin.flushEntry(WILL_NOT_FLUSH_PATTERN);
// Ensure that our object is not gone
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false));
// This time we flush it for real
admin.flushEntry(KEY);
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true));
}
/**
* Ensure that item may be flushed by flush all
*/
public void testFlushAll() {
// Put some content in cache
admin.putInCache(KEY, CONTENT);
// Ensure that our object is not gone
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false));
// This time we flush it for real
admin.flushAll();
assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true));
}
/**
* Ensure that the cache groupings work correctly
*/
public void testGroups() {
// Flush a non-existent group - should be OK and will still fire a GROUP_FLUSHED event
admin.flushGroup(GROUP1);
// Add some items to various group combinations
admin.putInCache("1", "item 1"); // No groups
admin.putInCache("2", "item 2", new String[] {GROUP1}); // Just group 1
admin.putInCache("3", "item 3", new String[] {GROUP2}); // Just group 2
admin.putInCache("4", "item 4", new String[] {GROUP1, GROUP2}); // groups 1 & 2
admin.putInCache("5", "item 5", new String[] {GROUP1, GROUP2, GROUP3}); // groups 1,2 & 3
admin.flushGroup(GROUP3); // This should flush item 5 only
assertNotNull(checkObj("5", NO_REFRESH_NEEDED, true));
assertNotNull(checkObj("4", NO_REFRESH_NEEDED, false));
admin.flushGroup(GROUP2); // This should flush items 3 and 4
assertNotNull(checkObj("1", NO_REFRESH_NEEDED, false));
assertNotNull(checkObj("2", NO_REFRESH_NEEDED, false));
assertNotNull(checkObj("3", NO_REFRESH_NEEDED, true));
assertNotNull(checkObj("4", NO_REFRESH_NEEDED, true));
admin.flushGroup(GROUP1); // Flushes item 2
assertNotNull(checkObj("1", NO_REFRESH_NEEDED, false));
assertNotNull(checkObj("2", NO_REFRESH_NEEDED, true));
// Test if regrouping a cache entry works
admin.putInCache("A", "ABC", new String[] {"A"});
admin.putInCache("A", "ABC", new String[] {"A", "B"});
admin.putInCache("B", "DEF", new String[] {"B"});
admin.flushGroup("B");
assertNotNull(checkObj("A", NO_REFRESH_NEEDED, true));
}
/**
* Test the main cache functionalities, which are storing and retrieving objects
* from it
*/
public void testPutInCacheAndGetFromCache() {
// Put some item in cache and get it back right away. It should not need
// to be refreshed
admin.putInCache(KEY, CONTENT);
String cacheContent = (String) checkObj(KEY, NO_REFRESH_NEEDED, false);
assertTrue(CONTENT.equals(cacheContent));
// Get the item back again and expect a refresh
cacheContent = (String) checkObj(KEY, REFRESH_NEEDED, true);
assertTrue(CONTENT.equals(cacheContent));
// Call the put in cache with invalid values
invalidPutInCacheArgument(null, null);
admin.putInCache(KEY, null); // This will still update the cache - cached items can be null
// Call the getFromCache with invalid values
invalidGetFromCacheArgument(null, 0);
// Try to retrieve the values
assertNull(checkObj(KEY, NO_REFRESH_NEEDED, false));
// Try to retrieve an item that is not in the cache
Object obj = checkObj("Not in cache", NO_REFRESH_NEEDED, true);
assertNull(obj);
}
/**
* Test the main cache functionalities, which are storing and retrieving objects
* from it
*/
public void testPutInCacheAndGetFromCacheWithPolicy() {
String key = "policy";
// We put content in the cache and get it back
admin.putInCache(key, CONTENT, new DummyAlwayRefreshEntryPolicy());
// Should get a refresh
try {
admin.getFromCache(key, -1);
fail("Should have got a refresh.");
} catch (NeedsRefreshException nre) {
admin.cancelUpdate(key);
}
}
protected void tearDown() throws Exception {
if (admin != null) {
admin.getCache().removeCacheEventListener(cacheEntryEventListener);
admin.getCache().removeCacheEventListener(cacheMapAccessEventListener);
}
}
/**
* Bug CACHE-241
*/
public void testFlushDateTomorrow() {
GeneralCacheAdministrator cacheAdmin = new GeneralCacheAdministrator(null);
cacheAdmin.putInCache("key1", "key1value");
try {
assertNotNull(cacheAdmin.getFromCache("key1"));
} catch (NeedsRefreshException e1) {
fail("Previous cache key1 doesn't exsits in GCA for the test!");
}
cacheAdmin.flushAll(new Date(System.currentTimeMillis() + 5000)); // flush in 5 sec.
try {
cacheAdmin.getFromCache("key1");
} catch (NeedsRefreshException e) {
cacheAdmin.cancelUpdate("key1");
fail("NRE is thrown, but key will expire in 5s."); // it fails here
}
}
/**
* Utility method that tries to get an item from the cache and verify
* if all goes as expected
* <p>
* @param key The item key
* @param refresh The timestamp specifiying if the item needs refresh
* @param exceptionExpected Specify if we expect a NeedsRefreshException
*/
private Object checkObj(String key, int refresh, boolean exceptionExpected) {
// Cache content
Object content = null;
try {
// try to find an object
content = admin.getFromCache(key, refresh);
if (exceptionExpected) {
fail("Expected NeedsRefreshException!");
}
} catch (NeedsRefreshException nre) {
admin.cancelUpdate(key);
if (!exceptionExpected) {
fail("Did not expected NeedsRefreshException!");
}
// Return the cache content from the exception
content = nre.getCacheContent();
}
return content;
}
/**
* Method that try to retrieve data from the cache but specify wrong arguments
* <p>
* @param key The cache item key
* @param refresh The timestamp specifiying if the item needs refresh
*/
private void invalidGetFromCacheArgument(String key, int refresh) {
try {
// Try to get the data from the cache
admin.getFromCache(key, refresh);
fail("getFromCache did NOT throw an IllegalArgumentException");
} catch (IllegalArgumentException ipe) {
// This is what we expect
} catch (NeedsRefreshException nre) {
admin.cancelUpdate(key);
// Ignore this one
}
}
/**
* Method that try to insert data in the cache but specify wrong arguments
* <p>
* @param key The cache item key
* @param content The content of the cache item
*/
private void invalidPutInCacheArgument(String key, Object content) {
try {
// Try to put this data in the cache
admin.putInCache(key, content);
fail("putInCache did NOT throw an IllegalArgumentException");
} catch (IllegalArgumentException ipe) {
// This is what we expect
}
}
private void populate() {
for (int i = 0; i < 7; i++) {
String[] groups = ((i & 1) == 0) ? new String[] {GROUP1, GROUP2} : new String[] {
GROUP3
};
admin.putInCache(KEY + i, CONTENT + i, groups);
}
//register one miss.
checkObj("Not in cache", NO_REFRESH_NEEDED, true);
//register 7 hits
for (int i = 0; i < 7; i++) {
try {
admin.getFromCache(KEY + i, NO_REFRESH_NEEDED);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(KEY + i);
}
}
for (int i = 0; i < 7; i++) {
try {
admin.getFromCache(KEY + i, 0);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(KEY + i);
}
}
admin.putInCache(KEY + 1, CONTENT);
admin.putInCache(KEY + 2, CONTENT);
admin.flushPattern("blahblah");
admin.flushGroup(GROUP1);
admin.flushGroup(GROUP2);
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import com.opensymphony.oscache.base.*;
import junit.framework.TestCase;
import java.util.Date;
/**
* A base class that provides the framework for testing a cluster listener
* implementation.
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public abstract class BaseTestBroadcastingListener extends TestCase {
/**
* The persistance listener used for the tests
*/
protected static AbstractBroadcastingListener listener = null;
/**
* A cache instance to use for the tests
*/
protected static Cache cache = null;
/**
* The number of tests in this class. This is used to keep
* track of how many tests remain; once we reach zero we shut
* down the broadcasting listener.
*/
int testsRemaining = 0;
/**
* Cache group
*/
private final String GROUP = "test group";
/**
* Object key
*/
private final String KEY = "Test clustersupport persistence listener key";
public BaseTestBroadcastingListener(String str) {
super(str);
}
/**
* Tests the listener by causing the cache to fire off all its
* events
*/
public void testListener() {
CacheEntry entry = new CacheEntry(KEY, null);
cache.putInCache(KEY, entry);
cache.putInCache(KEY, entry, new String[] {GROUP});
cache.flushEntry(KEY);
cache.flushGroup(GROUP);
cache.flushAll(new Date());
// Note that the remove event is not called since it's not exposed.
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set up the broadcasting listener required for each test.
*/
public void setUp() {
// At first invocation, create a listener
if (listener == null) {
testsRemaining = countTestCases(); // This seems to always return 1 even if there are multiple tests?
listener = getListener();
assertNotNull(listener);
cache = new Cache(true, false, false);
assertNotNull(cache);
try {
listener.initialize(cache, getConfig());
} catch (InitializationException e) {
fail(e.getMessage());
}
cache.addCacheEventListener(listener);
}
}
/**
* Once all the tests are complete this will shut down the broadcasting listener.
*/
protected void tearDown() throws Exception {
if (--testsRemaining == 0) {
try {
listener.finialize();
listener = null;
} catch (FinalizationException e) {
fail(e.getMessage());
}
}
}
/**
* Child classes implement this to return the broadcasting listener instance
* that will be tested.
*/
abstract AbstractBroadcastingListener getListener();
/**
* Child classes implement this to return the configuration for their listener
* @return
*/
abstract Config getConfig();
}

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.FinalizationException;
import com.opensymphony.oscache.base.InitializationException;
import java.util.ArrayList;
import java.util.Iterator;
/**
* <p>This should be used in conjunction with the cluster test cases. Run this
* program to set up listeners for the various clustering implementations so
* you can see that the test messages are being received correctly.</p>
*
* <p>A shutdown hook is installed so the listeners can be shut down cleanly.</p>
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class ListenForClusterTests {
ArrayList listeners = new ArrayList();
Cache cache;
private void mainLoop() {
Thread shutdownHook = new ShutdownHookThread("");
Runtime.getRuntime().addShutdownHook(shutdownHook);
System.out.println();
System.out.println("------------------------------------------------");
System.out.println("Waiting for cluster messages... (CTRL-C to exit)");
System.out.println("------------------------------------------------");
while (true) {
try {
Thread.sleep(250);
} catch (InterruptedException ie) {
}
}
}
private void initListeners() {
BaseTestBroadcastingListener testcase = null;
AbstractBroadcastingListener listener;
Cache cache = new Cache(true, false, false);
// Add the JavaGroups listener
try {
testcase = new TestJavaGroupsBroadcastingListener("JavaGroups");
listener = testcase.getListener();
listener.initialize(cache, testcase.getConfig());
cache.addCacheEventListener(listener);
listeners.add(listener);
} catch (InitializationException e) {
System.out.println("The JavaGroups listener could not be initialized: " + e);
}
// Add the JMS listener
try {
testcase = new TestJMSBroadcastingListener("JMS");
listener = testcase.getListener();
Config config = testcase.getConfig();
config.set("cache.cluster.jms.node.name", "cacheNode2");
listener.initialize(cache, config);
cache.addCacheEventListener(listener);
listeners.add(listener);
} catch (InitializationException e) {
System.out.println("The JMS listener could not be initialized: " + e);
}
}
/**
* Starts up the cluster listeners.
*/
public static void main(String[] args) {
ListenForClusterTests listen = new ListenForClusterTests();
listen.initListeners();
listen.mainLoop();
}
/**
* Inner class that handles the shutdown event
*/
class ShutdownHookThread extends Thread {
protected String message;
public ShutdownHookThread(String message) {
this.message = message;
}
/**
* This is executed when the application is forcibly shutdown (via
* CTRL-C etc). Any configured listeners are shut down here.
*/
public void run() {
System.out.println("Shutting down the cluster listeners...");
for (Iterator it = listeners.iterator(); it.hasNext();) {
try {
((AbstractBroadcastingListener) it.next()).finialize();
} catch (FinalizationException e) {
System.out.println("The listener could not be shut down cleanly: " + e);
}
}
System.out.println("Shutdown complete.");
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.plugins.clustersupport package.
* It invokes all the test suites of all the other classes of the package.
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class TestCompleteClustering extends TestCase {
/**
* Constructor for the osCache project main test program
*/
public TestCompleteClustering(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteClustering.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all OSCache clustering");
suite.addTest(TestJavaGroupsBroadcastingListener.suite());
suite.addTest(TestJMSBroadcastingListener.suite());
suite.addTest(TestJMS10BroadcastingListener.suite());
return suite;
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import com.opensymphony.oscache.base.Config;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test all the public methods of the broadcasting listener and assert the
* return values
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class TestJMS10BroadcastingListener extends BaseTestBroadcastingListener {
public TestJMS10BroadcastingListener(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit.
*
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestJMS10BroadcastingListener.class);
}
/**
* Returns a configured JavaGroupsBroadcastingListener instance
* for testing.
*/
public AbstractBroadcastingListener getListener() {
return new JMS10BroadcastingListener();
}
/**
* Return the configuration for the JMS listener
*/
Config getConfig() {
Config config = new Config();
// There needs to be an application resource file present "jndi.properties" that contains the following
// parameters:
// config.set(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.ApplicationClientInitialContextFactory");
// config.set(Context.PROVIDER_URL, "ormi://localhost:23791/");
// config.set(Context.SECURITY_PRINCIPAL, "admin");
// config.set(Context.SECURITY_CREDENTIALS, "xxxxxx");
config.set("cache.cluster.jms.topic.factory", "java:comp/env/jms/TopicConnectionFactory");
config.set("cache.cluster.jms.topic.name", "java:comp/env/jms/OSCacheTopic");
config.set("cache.cluster.jms.node.name", "cacheNode1");
return config;
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import com.opensymphony.oscache.base.Config;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test all the public methods of the broadcasting listener and assert the
* return values
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class TestJMSBroadcastingListener extends BaseTestBroadcastingListener {
public TestJMSBroadcastingListener(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit.
*
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestJMSBroadcastingListener.class);
}
/**
* Returns a configured JavaGroupsBroadcastingListener instance
* for testing.
*/
public AbstractBroadcastingListener getListener() {
return new JMSBroadcastingListener();
}
/**
* Return the configuration for the JMS listener
*/
Config getConfig() {
Config config = new Config();
// There needs to be an application resource file present "jndi.properties" that contains the following
// parameters:
// config.set(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.ApplicationClientInitialContextFactory");
// config.set(Context.PROVIDER_URL, "ormi://localhost:23791/");
// config.set(Context.SECURITY_PRINCIPAL, "admin");
// config.set(Context.SECURITY_CREDENTIALS, "xxxxxx");
config.set("cache.cluster.jms.topic.factory", "java:comp/env/jms/TopicConnectionFactory");
config.set("cache.cluster.jms.topic.name", "java:comp/env/jms/OSCacheTopic");
config.set("cache.cluster.jms.node.name", "cacheNode1");
return config;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.clustersupport;
import com.opensymphony.oscache.base.Config;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test all the public methods of the broadcasting listener and assert the
* return values
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class TestJavaGroupsBroadcastingListener extends BaseTestBroadcastingListener {
public TestJavaGroupsBroadcastingListener(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit.
*
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestJavaGroupsBroadcastingListener.class);
}
/**
* Returns a configured JavaGroupsBroadcastingListener instance
* for testing.
*/
public AbstractBroadcastingListener getListener() {
return new JavaGroupsBroadcastingListener();
}
/**
* Get the configuration for this listener
*/
public Config getConfig() {
Config config = new Config();
// Just specify the IP and leave the rest of the settings at
// default values.
config.set("cache.cluster.multicast.ip", "231.12.21.132");
return config;
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.diskpersistence;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.plugins.diskpersistence package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id: TestCompleteDiskPersistence.java 254 2005-06-17 05:07:38Z dres $
* @version $Revision: 254 $
* @author Lars Torunski
*/
public final class TestCompleteDiskPersistence extends TestCase {
/**
* Constructor for the osCache Cache Extra package main test program
*/
public TestCompleteDiskPersistence(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteDiskPersistence.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the test suites of all the project classes
TestSuite suite = new TestSuite("Test all diskpersistence plugins");
suite.addTest(TestDiskPersistenceListener.suite());
suite.addTest(TestHashDiskPersistenceListener.suite());
//suite.addTest(TestUnSerializable.suite());
return suite;
}
}

View file

@ -0,0 +1,223 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.diskpersistence;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.persistence.CachePersistenceException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.File;
import java.io.FilenameFilter;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
/**
* Test all the public methods of the disk persistance listener and assert the
* return values
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestDiskPersistenceListener extends TestCase {
/**
* Cache dir to persist to
*/
public static final String CACHEDIR = "/tmp/diskcache";
/**
* The persistance listener used for the tests
*/
private DiskPersistenceListener listener = null;
/**
* Object content
*/
private final String CONTENT = "Disk persistance content";
/**
* Cache group
*/
private final String GROUP = "test group";
/**
* Object key
*/
private final String KEY = "Test disk persistance listener key";
private CacheFileFilter cacheFileFilter = new CacheFileFilter();
public TestDiskPersistenceListener(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestDiskPersistenceListener.class);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a listener
listener = new DiskPersistenceListener();
Properties p = new Properties();
p.setProperty("cache.path", CACHEDIR);
p.setProperty("cache.memory", "false");
p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener");
listener.configure(new Config(p));
}
/**
* Test the cache directory removal
*/
public void testClear() {
// Create an new element since we removed it at the last test
testStoreRetrieve();
// Remove the directory, and assert that we have no more entry
try {
listener.clear();
assertTrue(!listener.isStored(KEY));
} catch (CachePersistenceException cpe) {
cpe.printStackTrace();
fail("Exception thrown in test clear!");
}
}
/**
* Test that the previouly created file exists
*/
public void testIsStored() {
try {
listener.store(KEY, CONTENT);
// Retrieve the previously created file
assertTrue(listener.isStored(KEY));
// Check that the fake key returns false
assertTrue(!listener.isStored(KEY + "fake"));
} catch (Exception e) {
e.printStackTrace();
fail("testIsStored raised an exception");
}
}
/**
* Test the cache removal
*/
public void testRemove() {
// Create an entry if it doesn't exists
try {
if (!listener.isStored(KEY)) {
listener.store(KEY, CONTENT);
}
// Remove the previously created file
listener.remove(KEY);
} catch (CachePersistenceException cpe) {
cpe.printStackTrace();
fail("Exception thrown in test remove!");
}
}
/**
* Force CachePersistenceException to get a 100% in the unit test
*/
public void testCachePersistenceException() {
try {
for (int i = 0; i < 2; i++) {
if (i == 1) throw new CachePersistenceException("test");
}
fail("CachePersistenceException not thrown!");
} catch (CachePersistenceException cpe) {
// ignore
}
try {
for (int i = 0; i < 2; i++) {
if (i == 1) throw new CachePersistenceException();
}
fail("CachePersistenceException not thrown!");
} catch (CachePersistenceException cpe) {
// ignore
}
}
/**
* Test the disk store and retrieve
*/
public void testStoreRetrieve() {
// Create a cache entry and store it
CacheEntry entry = new CacheEntry(KEY);
entry.setContent(CONTENT);
try {
listener.store(KEY, entry);
// Retrieve our entry and validate the values
CacheEntry newEntry = (CacheEntry) listener.retrieve(KEY);
assertTrue(entry.getContent().equals(newEntry.getContent()));
assertEquals(entry.getCreated(), newEntry.getCreated());
assertTrue(entry.getKey().equals(newEntry.getKey()));
// Try to retrieve a non-existent object
assertNull(listener.retrieve("doesn't exist"));
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!");
}
}
/**
* Test the storing and retrieving of groups
*/
public void testStoreRetrieveGroups() {
// Store a group
Set groupSet = new HashSet();
groupSet.add("1");
groupSet.add("2");
try {
listener.storeGroup(GROUP, groupSet);
// Retrieve it and validate its contents
groupSet = listener.retrieveGroup(GROUP);
assertNotNull(groupSet);
assertTrue(groupSet.contains("1"));
assertTrue(groupSet.contains("2"));
assertFalse(groupSet.contains("3"));
// Try to retrieve a non-existent group
assertNull(listener.retrieveGroup("abc"));
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!");
}
}
protected void tearDown() throws Exception {
listener.clear();
assertTrue("Cache not cleared", new File(CACHEDIR).list(cacheFileFilter).length == 0);
}
private static class CacheFileFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return !"__groups__".equals(name);
}
}
}

View file

@ -0,0 +1,220 @@
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.plugins.diskpersistence;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.persistence.CachePersistenceException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.File;
import java.io.FilenameFilter;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
/**
* Test all the public methods of the disk persistance listener and assert the
* return values
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestHashDiskPersistenceListener extends TestCase {
/**
* The persistance listener used for the tests
*/
private HashDiskPersistenceListener listener = null;
/**
* Object content
*/
private final String CONTENT = "Disk persistance content";
/**
* Cache group
*/
private final String GROUP = "test group";
/**
* Object key
*/
private final String KEY = "Test disk persistance listener key";
private CacheFileFilter cacheFileFilter = new CacheFileFilter();
public TestHashDiskPersistenceListener(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestHashDiskPersistenceListener.class);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// At first invocation, create a listener
listener = new HashDiskPersistenceListener();
Properties p = new Properties();
p.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR);
p.setProperty("cache.memory", "false");
p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener");
p.setProperty("cache.persistence.disk.hash.algorithm", "MD5");
listener.configure(new Config(p));
}
/**
* Test the cache directory removal
*/
public void testClear() {
// Create an new element since we removed it at the last test
testStoreRetrieve();
// Remove the directory, and assert that we have no more entry
try {
listener.clear();
assertTrue(!listener.isStored(KEY));
} catch (CachePersistenceException cpe) {
cpe.printStackTrace();
fail("Exception thrown in test clear!");
}
}
/**
* Test that the previouly created file exists
*/
public void testIsStored() {
try {
listener.store(KEY, CONTENT);
// Retrieve the previously created file
assertTrue(listener.isStored(KEY));
// Check that the fake key returns false
assertTrue(!listener.isStored(KEY + "fake"));
} catch (Exception e) {
e.printStackTrace();
fail("testIsStored raised an exception");
}
}
/**
* Test the cache removal
*/
public void testRemove() {
// Create an entry if it doesn't exists
try {
if (!listener.isStored(KEY)) {
listener.store(KEY, CONTENT);
}
// Remove the previously created file
listener.remove(KEY);
} catch (CachePersistenceException cpe) {
cpe.printStackTrace();
fail("Exception thrown in test remove!");
}
}
/**
* Test the disk store and retrieve
*/
public void testStoreRetrieve() {
// Create a cache entry and store it
CacheEntry entry = new CacheEntry(KEY);
entry.setContent(CONTENT);
try {
listener.store(KEY, entry);
// Retrieve our entry and validate the values
CacheEntry newEntry = (CacheEntry) listener.retrieve(KEY);
assertTrue(entry.getContent().equals(newEntry.getContent()));
assertEquals(entry.getCreated(), newEntry.getCreated());
assertTrue(entry.getKey().equals(newEntry.getKey()));
// Try to retrieve a non-existent object
assertNull(listener.retrieve("doesn't exist"));
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!");
}
}
/**
* Test the storing and retrieving of groups
*/
public void testStoreRetrieveGroups() {
// Store a group
Set groupSet = new HashSet();
groupSet.add("1");
groupSet.add("2");
try {
listener.storeGroup(GROUP, groupSet);
// Retrieve it and validate its contents
groupSet = listener.retrieveGroup(GROUP);
assertNotNull(groupSet);
assertTrue(groupSet.contains("1"));
assertTrue(groupSet.contains("2"));
assertFalse(groupSet.contains("3"));
// Try to retrieve a non-existent group
assertNull(listener.retrieveGroup("abc"));
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!");
}
}
private static final byte[] BYTES_1 = {0x00};
private static final byte[] BYTES_2 = {0x00, 0x00};
private static final byte[] BYTES_3 = {0x00, 0x00, 0x00};
private static final byte[] BYTES_4 = {0x01};
/**
* Test against bug issue CACHE-288.
*/
public void testByteArrayToHexString() {
assertFalse("ByteArrayToHexStrings 1 and 2 shouldn't be equal",
HashDiskPersistenceListener.byteArrayToHexString(BYTES_1).
equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_2)));
assertFalse("ByteArrayToHexStrings 1 and 3 shouldn't be equal",
HashDiskPersistenceListener.byteArrayToHexString(BYTES_1).
equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_3)));
assertFalse("ByteArrayToHexStrings 1 and 4 shouldn't be equal",
HashDiskPersistenceListener.byteArrayToHexString(BYTES_1).
equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_4)));
assertFalse("ByteArrayToHexStrings 1 and 4 shouldn't be equal",
HashDiskPersistenceListener.byteArrayToHexString(BYTES_1).
equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_4)));
}
protected void tearDown() throws Exception {
listener.clear();
assertTrue("Cache not cleared", new File(TestDiskPersistenceListener.CACHEDIR).list(cacheFileFilter).length == 0);
}
private static class CacheFileFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return !"__groups__".equals(name);
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
/*
* Created on Mar 11, 2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package com.opensymphony.oscache.plugins.diskpersistence;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.File;
/**
* @author admin
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class TestUnSerializable extends TestCase {
final String CACHE_DIRECTORY_PATH = TestDiskPersistenceListener.CACHEDIR + "/application";
GeneralCacheAdministrator cache;
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
// TODO Auto-generated method stub
super.setUp();
java.util.Properties properties = new java.util.Properties();
properties.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR);
properties.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener");
properties.setProperty("cache.persistence.overflow.only", "true");
// properties.setProperty("cache.memory", "false");
properties.setProperty("cache.capacity", "2");
properties.setProperty("cache.unlimited.disk", "false");
cache = new GeneralCacheAdministrator(properties);
cache.getCache().getPersistenceListener().clear();
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
// TODO Auto-generated method stub
super.tearDown();
}
public void testNotSerializableObject() throws Exception {
cache.putInCache("1", new UnSerializable());
cache.putInCache("2", new UnSerializable());
assertTrue(isDirectoryEmpty(CACHE_DIRECTORY_PATH));
cache.putInCache("3", new UnSerializable());
cache.putInCache("4", new UnSerializable());
assertTrue(isDirectoryEmpty(CACHE_DIRECTORY_PATH));
cache.flushAll();
}
/**
* @param filePath
* @return
*/
private boolean isDirectoryEmpty(String filePath) {
File file = new File(filePath);
return !file.exists() || (file.list().length == 0);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The test for this class
*/
public static Test suite() {
return new TestSuite(TestUnSerializable.class);
}
public static class UnSerializable {
int asdfasdfasdf = 234;
}
}

View file

@ -0,0 +1,314 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.util;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
*
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
* @author $Author$
* @version $Revision$
*/
public class TestFastCronParser extends TestCase {
public TestFastCronParser(String str) {
super(str);
}
/**
* This methods returns the name of this test class to JUnit
* <p>
* @return The name of this class
*/
public static Test suite() {
return new TestSuite(TestFastCronParser.class);
}
/**
* Tests to see if the cron class can calculate the previous matching
* time correctly in various circumstances
*/
public void testEvaluations() {
// Minute tests
cronCall("01/01/2003 0:00", "45 * * * *", "31/12/2002 23:45", false);
cronCall("01/01/2003 0:00", "45-47,48,49 * * * *", "31/12/2002 23:49", false);
cronCall("01/01/2003 0:00", "2/5 * * * *", "31/12/2002 23:57", false);
// Hour tests
cronCall("20/12/2003 10:00", "* 3/4 * * *", "20/12/2003 07:59", false);
cronCall("20/12/2003 0:00", "* 3 * * *", "19/12/2003 03:59", false);
// Day of month tests
cronCall("07/01/2003 0:00", "30 * 1 * *", "01/01/2003 23:30", false);
cronCall("01/01/2003 0:00", "10 * 22 * *", "22/12/2002 23:10", false);
cronCall("01/01/2003 0:00", "30 23 19 * *", "19/12/2002 23:30", false);
cronCall("01/01/2003 0:00", "30 23 21 * *", "21/12/2002 23:30", false);
cronCall("01/01/2003 0:01", "* * 21 * *", "21/12/2002 23:59", false);
cronCall("10/07/2003 0:00", "* * 30,31 * *", "30/06/2003 23:59", false);
// Test month rollovers for months with 28,29,30 and 31 days
cronCall("01/03/2002 0:11", "* * * 2 *", "28/02/2002 23:59", false);
cronCall("01/03/2004 0:44", "* * * 2 *", "29/02/2004 23:59", false);
cronCall("01/04/2002 0:00", "* * * 3 *", "31/03/2002 23:59", false);
cronCall("01/05/2002 0:00", "* * * 4 *", "30/04/2002 23:59", false);
// Other month tests (including year rollover)
cronCall("01/01/2003 5:00", "10 * * 6 *", "30/06/2002 23:10", false);
cronCall("01/01/2003 5:00", "10 * * February,April-Jun *", "30/06/2002 23:10", false);
cronCall("01/01/2003 0:00", "0 12 1 6 *", "01/06/2002 12:00", false);
cronCall("11/09/1988 14:23", "* 12 1 6 *", "01/06/1988 12:59", false);
cronCall("11/03/1988 14:23", "* 12 1 6 *", "01/06/1987 12:59", false);
cronCall("11/03/1988 14:23", "* 2,4-8,15 * 6 *", "30/06/1987 15:59", false);
cronCall("11/03/1988 14:23", "20 * * january,FeB,Mar,april,May,JuNE,July,Augu,SEPT-October,Nov,DECEM *", "11/03/1988 14:20", false);
// Day of week tests
cronCall("26/06/2003 10:00", "30 6 * * 0", "22/06/2003 06:30", false);
cronCall("26/06/2003 10:00", "30 6 * * sunday", "22/06/2003 06:30", false);
cronCall("26/06/2003 10:00", "30 6 * * SUNDAY", "22/06/2003 06:30", false);
cronCall("23/06/2003 0:00", "1 12 * * 2", "17/06/2003 12:01", false);
cronCall("23/06/2003 0:00", "* * * * 3,0,4", "22/06/2003 23:59", false);
cronCall("23/06/2003 0:00", "* * * * 5", "20/06/2003 23:59", false);
cronCall("02/06/2003 18:30", "0 12 * * 2", "27/05/2003 12:00", false);
cronCall("02/06/2003 18:30", "0 12 * * Tue,Thurs-Sat,2", "31/05/2003 12:00", false);
cronCall("02/06/2003 18:30", "0 12 * * Mon-tuesday,wed,THURS-FRiday,Sat-SUNDAY", "02/06/2003 12:00", false);
// Leap year tests
cronCall("01/03/2003 12:00", "1 12 * * *", "28/02/2003 12:01", false); // non-leap year
cronCall("01/03/2004 12:00", "1 12 * * *", "29/02/2004 12:01", false); // leap year
cronCall("01/03/2003 12:00", "1 23 * * 0", "23/02/2003 23:01", false); // non-leap year
cronCall("01/03/2004 12:00", "1 23 * * 0", "29/02/2004 23:01", false); // leap year
cronCall("01/03/2003 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day
cronCall("01/02/2003 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day
cronCall("01/02/2004 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day
// Interval and range tests
cronCall("20/12/2003 10:00", "* */4 * * *", "20/12/2003 08:59", false);
cronCall("20/12/2003 10:00", "* 3/2 * * *", "20/12/2003 09:59", false);
cronCall("20/12/2003 10:00", "1-30/5 10-20/3 * jan-aug/2 *", "31/07/2003 19:26", false);
cronCall("20/12/2003 10:00", "20-25,27-30/2 10/8 * * *", "19/12/2003 18:29", false);
}
/**
* Tests a range of invalid cron expressions
*/
public void testInvalidExpressionParsing() {
FastCronParser parser = new FastCronParser();
try {
parser.setCronExpression(null);
fail("An IllegalArgumentException should have been thrown");
} catch (IllegalArgumentException e) {
// Expected
} catch (ParseException e) {
fail("Expected an IllegalArgumentException but received a ParseException instead");
}
/**
* Not enough tokens
*/
cronCall("01/01/2003 0:00", "", "", true);
cronCall("01/01/2003 0:00", "8 * 8/1 *", "", true);
/**
* Invalid syntax
*/
cronCall("01/01/2003 0:00", "* invalid * * *", "", true);
cronCall("01/01/2003 0:00", "* -1 * * *", "", true);
cronCall("01/01/2003 0:00", "* * 20 * 0", "", true);
cronCall("01/01/2003 0:00", "* * 5-6-7 * *", "", true);
cronCall("01/01/2003 0:00", "* * 5/6-7 * *", "", true);
cronCall("01/01/2003 0:00", "* * 5-* * *", "", true);
cronCall("01/01/2003 0:00", "* * 5-6* * *", "", true);
cronCall("01/01/2003 0:00", "* * * * Mo", "", true);
cronCall("01/01/2003 0:00", "* * * jxxx *", "", true);
cronCall("01/01/2003 0:00", "* * * juxx *", "", true);
cronCall("01/01/2003 0:00", "* * * fbr *", "", true);
cronCall("01/01/2003 0:00", "* * * mch *", "", true);
cronCall("01/01/2003 0:00", "* * * mAh *", "", true);
cronCall("01/01/2003 0:00", "* * * arl *", "", true);
cronCall("01/01/2003 0:00", "* * * Spteber *", "", true);
cronCall("01/01/2003 0:00", "* * * otber *", "", true);
cronCall("01/01/2003 0:00", "* * * nvemtber *", "", true);
cronCall("01/01/2003 0:00", "* * * Dcmber *", "", true);
cronCall("01/01/2003 0:00", "* * * * mnday", "", true);
cronCall("01/01/2003 0:00", "* * * * tsdeday", "", true);
cronCall("01/01/2003 0:00", "* * * * wdnesday", "", true);
cronCall("01/01/2003 0:00", "* * * * frday", "", true);
cronCall("01/01/2003 0:00", "* * * * sdhdatr", "", true);
/**
* Values out of range
*/
cronCall("01/01/2003 0:00", "* * 0 * *", "", true);
cronCall("01/01/2003 0:00", "* 50 * * *", "", true);
cronCall("01/01/2003 0:00", "* * * 1-20 *", "", true);
cronCall("01/01/2003 0:00", "* * 0-20 * *", "", true);
cronCall("01/01/2003 0:00", "* * 1-40 * *", "", true);
cronCall("01/01/2003 0:00", "* * * 1 8", "", true);
cronCall("01/01/2003 0:00", "* * 0/3 * *", "", true);
cronCall("01/01/2003 0:00", "* * 30 2 *", "", true); // 30th Feb doesn't ever exist!
cronCall("01/01/2003 0:00", "* * 31 4 *", "", true); // 31st April doesn't ever exist!
}
/**
* This tests the performance of the cron parsing engine. Note that it may take
* a couple of minutes o run - by default this test is disabled. Comment out the
* <code>return</code> statement at the start of this method to enable the
* benchmarking.
*/
public void testPerformance() {
if (true) {
// return; // Comment out this line to benchmark
}
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date = null;
try {
date = sdf.parse("21/01/2003 16:27");
} catch (ParseException e) {
fail("Failed to parse date. Please check your unit test code!");
}
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.setTime(date);
long baseTime = calendar.getTimeInMillis();
long time = 0;
try {
// Give HotSpot a chance to warm up
iterate("28 17 22 02 *", baseTime, time, 10000, true);
// Number of iterations to test
int count = 1000000;
// Test the best-case scenario
long bestCaseTime = iterate("* * * * *", baseTime, time, count, true);
System.out.println("Best case with parsing took " + bestCaseTime + "ms for " + count + " iterations. (" + (bestCaseTime / (float) count) + "ms per call)");
// Test a near worst-case scenario
long worstCaseTime = iterate("0-59,0-13,2,3,4,5 17-19 22-23,22,23 2,3 *", baseTime, time, count, true);
System.out.println("Worst case with parsing took " + worstCaseTime + "ms for " + count + " iterations. (" + (worstCaseTime / (float) count) + "ms per call)");
// Test the best-case scenario without parsing the expression on each iteration
bestCaseTime = iterate("* * * * *", baseTime, time, count, false);
System.out.println("Best case without parsing took " + bestCaseTime + "ms for " + count + " iterations. (" + (bestCaseTime / (float) count) + "ms per call)");
// Test a near worst-case scenario without parsing the expression on each iteration
worstCaseTime = iterate("0-59,0-13,2,3,4,5 17-19 22-23,22,23 2,3 *", baseTime, time, count, false);
System.out.println("Worst case without parsing took " + worstCaseTime + "ms for " + count + " iterations. (" + (worstCaseTime / (float) count) + "ms per call)");
} catch (ParseException e) {
}
}
/**
* Tests that a range of valid cron expressions get parsed correctly.
*/
public void testValidExpressionParsing() {
FastCronParser parser;
// Check the default constructor
parser = new FastCronParser();
assertNull(parser.getCronExpression());
try {
parser = new FastCronParser("* * * * *");
assertEquals("* * * * *", parser.getCronExpression()); // Should be the same as what we gave it
assertEquals("* * * * *", parser.getExpressionSummary());
parser.setCronExpression("0 * * * *");
assertEquals("0 * * * *", parser.getCronExpression()); // Should be the same as what we gave it
assertEquals("0 * * * *", parser.getExpressionSummary());
parser.setCronExpression("5 10 * * 1,4,6");
assertEquals("5 10 * * 1,4,6", parser.getExpressionSummary());
parser.setCronExpression("0,5-20,4-15,24-27 0 * 2-4,5,6-3 *"); // Overlapping ranges, backwards ranges
assertEquals("0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,24,25,26,27 0 * 2,3,4,5,6 *", parser.getExpressionSummary());
} catch (ParseException e) {
e.printStackTrace();
fail("Cron expression should have been valid: " + e);
}
}
/**
* Makes a call to the FastCronParser.
*
* @param dateStr The date string to use as the base date. The format must be
* <code>"dd/MM/yyyy HH:mm"</code>.
* @param cronExpr The cron expression to test.
* @param result The expected result. This should be a date in the same format
* as <code>dateStr</code>.
* @param expectException Pass in <code>true</code> if the {@link FastCronParser} is
* expected to throw a <code>ParseException</code>.
*/
private void cronCall(String dateStr, String cronExpr, String result, boolean expectException) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date = null;
try {
date = sdf.parse(dateStr);
} catch (ParseException e) {
fail("Failed to parse date " + dateStr + ". Please check your unit test code!");
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
long baseTime = calendar.getTimeInMillis();
FastCronParser parser = null;
try {
parser = new FastCronParser(cronExpr);
if (expectException) {
fail("Should have received a ParseException while parsing " + cronExpr);
}
long time = parser.getTimeBefore(baseTime);
assertEquals(result, sdf.format(new Date(time)));
} catch (ParseException e) {
if (!expectException) {
fail("Unexpected ParseException while parsing " + cronExpr + ": " + e);
}
}
}
/**
* Used by the benchmarking
*/
private long iterate(String cronExpr, long baseTime, long time, int count, boolean withParse) throws ParseException {
long startTime = System.currentTimeMillis();
if (withParse) {
FastCronParser parser = new FastCronParser();
for (int i = 0; i < count; i++) {
parser.setCronExpression(cronExpr);
time = parser.getTimeBefore(baseTime);
}
} else {
FastCronParser parser = new FastCronParser(cronExpr);
for (int i = 0; i < count; i++) {
time = parser.getTimeBefore(baseTime);
}
}
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);
duration += (time - time); // Use the time variable to prevent it getting optimized away
return duration;
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLConnection;
/**
* User: hani
* Date: Jun 12, 2003
* Time: 3:34:20 PM
*/
public class CheckDeployment {
public static void main(String[] args) {
if (args.length == 0) {
throw new IllegalArgumentException("No url specified to check");
}
try {
if (!args[0].endsWith("/")) {
args[0] = args[0] + "/";
}
URL url = new URL(args[0] + "oscache.txt");
URLConnection c = url.openConnection();
c.getInputStream();
System.exit(0);
} catch (java.net.MalformedURLException e) {
System.out.println("Invalid url for oscache webapp:" + args[0]);
} catch (ConnectException ex) {
System.out.println("Error connecting to server at '" + args[0] + "', ensure that the webserver for the oscache example application is running");
} catch (FileNotFoundException e) {
System.out.println("Error connecting to webapp at '" + args[0] + "', ensure that the example-war app is deployed correctly at the specified url");
} catch (IOException e) {
System.out.println("Error connecting to webapp at '" + args[0] + "', ensure that the example-war app is deployed correctly at the specified url");
}
System.exit(1);
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.web package.
* It invokes all the test suites of all the other classes of the package.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestCompleteWeb extends TestCase {
/**
* Constructor for the osCache project main test program
*/
public TestCompleteWeb(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestCompleteWeb.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
// Add all the tests suite of all the project classes
TestSuite suite = new TestSuite("Test all osCache web");
suite.addTest(TestOscacheJsp.suite());
suite.addTest(TestOscacheServlet.suite());
suite.addTest(TestOscacheFilter.suite());
return suite;
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import com.clarkware.junitperf.LoadTest;
import com.clarkware.junitperf.RandomTimer;
import junit.extensions.RepeatedTest;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test class for the com.opensymphony.oscache.web package.
* It invokes all the test suites of all the other classes of the package.
* The test methods will be invoked with many users and iterations to simulate
* load on request
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestLoadCompleteWeb extends TestCase {
/**
* Constructor for the osCache Cache project main test program
*/
public TestLoadCompleteWeb(String str) {
super(str);
}
/**
* Main method which is called to perform the tests
* <p>
* @param args Arguments received
*/
public static void main(String[] args) {
// Run the test suite
junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner();
testRunner.setLoading(false);
String[] args2 = {TestLoadCompleteWeb.class.getName()};
testRunner.start(args2);
}
/**
* Test suite required to test this project
* <p>
* @return suite The test suite
*/
public static Test suite() {
final int clientThreads = 10; // Simulate 10 client threads
final int iterations = 20; // Simulate each user doing 20 iterations
TestSuite suite = new TestSuite("Test all osCache web");
// Ramp up a thread each 500 ms (+-100ms) until total number of threads reached
RandomTimer tm = new RandomTimer(300, 100);
// JSP
Test repeatedTest = new RepeatedTest(new TestOscacheJsp("testOscacheBasicForLoad"), iterations);
Test loadTest = new LoadTest(repeatedTest, clientThreads, tm);
suite.addTest(loadTest);
// Servlet
repeatedTest = new RepeatedTest(new TestOscacheServlet("testOscacheServletBasicForLoad"), iterations);
loadTest = new LoadTest(repeatedTest, clientThreads, tm);
suite.addTest(loadTest);
// Filter
repeatedTest = new RepeatedTest(new TestOscacheFilter("testOscacheFilterBasicForLoad"), iterations);
loadTest = new LoadTest(repeatedTest, clientThreads, tm);
suite.addTest(loadTest);
return suite;
}
}

View file

@ -0,0 +1,215 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Tests the caching filter distributed with the package.
*
* $Id$
* @version $Revision$
* @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
*/
public final class TestOscacheFilter extends TestCase {
// The instance of a webconversation to invoke pages
WebConversation wc = null;
private final String BASE_PAGE = "filter/filterTest.jsp";
// Constants definition
private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL";
private final String PARAM_1 = "abc=123";
private final String PARAM_2 = "xyz=321";
private final String SESSION_ID = "jsessionid=12345678";
// Constants definition to access OscacheServlet
private final String SERVLET_URL = "cacheServlet/?";
private final String FORCE_REFRESH = "forceRefresh=true&";
/**
* Constructor required by JUnit
* <p>
* @param str Test name
*/
public TestOscacheFilter(String str) {
super(str);
}
/**
* Returns the test suite for the test class
* <p>
* @return Test suite for the class
*/
public static Test suite() {
return new TestSuite(TestOscacheFilter.class);
}
/**
* Setup method called before each testXXXX of the class
*/
public void setUp() {
// Create a web conversation to invoke our filter
if (wc == null) {
wc = new WebConversation();
}
compileJSP(constructURL(BASE_PAGE));
}
/**
* Test the OSCache filter
*/
public void testOscacheFilter() {
String baseUrl = constructURL(BASE_PAGE);
// Flush the cache to avoid getting refreshed content from previous tests
flushCache();
// Call the page for the second time
String stringResponse = invokeURL(baseUrl, 200);
// Connect again, we should have the same content
String newResponse = invokeURL(baseUrl, 0);
assertTrue("new response " + newResponse + " should be the same to " + stringResponse, stringResponse.equals(newResponse));
// Try again with a session ID this time. The session ID should get filtered
// out of the cache key so the content should be the same
newResponse = invokeURL(baseUrl + "?" + SESSION_ID, 200);
assertTrue("new response by a session id request " + newResponse + " should be the same to " + stringResponse, stringResponse.equals(newResponse));
// Connect again with extra params, the content should be different
newResponse = invokeURL(baseUrl + "?" + PARAM_1 + "&" + PARAM_2, 500);
assertFalse("new response " + newResponse + " expected it to be different to last one.", stringResponse.equals(newResponse));
stringResponse = newResponse;
// Connect again with the parameters in a different order. We should still
// get the same content.
newResponse = invokeURL(baseUrl + "?" + PARAM_2 + "&" + PARAM_1, 0);
assertTrue("order of parameters shouldn't change the response", stringResponse.equals(newResponse));
// Connect again with the same parameters, but throw the session ID into
// the mix again. The content should remain the same.
newResponse = invokeURL(baseUrl + "?" + SESSION_ID + "&" + PARAM_1 + "&" + PARAM_2, 0);
assertTrue("a session id shouldn't change the response either", stringResponse.equals(newResponse));
}
/**
* Test the OSCache filter with fast requests
*/
public void testOSCacheFilterFast() {
String baseUrl = constructURL(BASE_PAGE);
for (int i = 0; i < 10; i++) {
// Flush the cache to avoid getting refreshed content from previous tests
flushCache();
// build the url
String url = baseUrl + "?i=" + i;
String response = invokeURL(url, 100);
for (int j = 0; j < 5; j++) {
String newResponse = invokeURL(url, 100);
assertTrue("Fast: new response (i="+i+",j="+j+") " + newResponse + " should be the same to " + response, response.equals(newResponse));
}
}
}
/**
* Test the cache module using a filter and basic load
*/
public void testOscacheFilterBasicForLoad() {
String baseUrl = constructURL(BASE_PAGE);
for (int i = 0; i < 5; i++) {
String stringResponse = invokeURL(baseUrl, 0);
// Check we received something slightly sane
assertTrue(stringResponse.indexOf("Current Time") > 0);
}
}
/**
* Compile a JSP page by invoking it. We compile the page first to avoid
* the compilation delay when testing since the time is a crucial factor
*
* @param URL The JSP url to invoke
*/
private void compileJSP(String URL) {
try {
// Invoke the URL
wc.getResponse(URL);
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!!");
}
}
/**
* Flushes the cache to avoid recieving content from previous tests
*/
private void flushCache() {
String flushUrl = constructURL(SERVLET_URL + FORCE_REFRESH);
String stringResponse = invokeURL(flushUrl, 0);
assertTrue("Flushing the cache failed!", stringResponse.indexOf("This is some cache content") > 0);
// avoid that flush time is equal to last update time of a new entry
try {
Thread.sleep(5);
} catch (InterruptedException ignore) {
}
}
/**
* Reads the base url from the test.web.baseURL system property and
* append the given URL.
* <p>
* @param Url Url to append to the base.
* @return Complete URL
*/
private String constructURL(String url) {
String base = System.getProperty(BASE_URL_SYSTEM_PRP);
String constructedUrl = null;
if (base != null) {
if (!base.endsWith("/")) {
base = base + "/";
}
constructedUrl = base + url;
} else {
fail("System property test.web.baseURL needs to be set to the proper server to use.");
}
return constructedUrl;
}
/**
* Utility method to request a URL and then sleep some time before returning
* <p>
* @param url The URL of the page to invoke
* @param sleepTime The time to sleep before returning
* @return The text value of the reponse (HTML code)
*/
private String invokeURL(String url, int sleepTime) {
try {
// Invoke the JSP and wait the specified sleepTime
WebResponse resp = wc.getResponse(url);
Thread.sleep(sleepTime);
return resp.getText();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!!");
return null;
}
}
}

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test test the JSPs distributed with the package. It checks that the
* cache integration is OK.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestOscacheJsp extends TestCase {
// The instance of a webconversation to invoke pages
WebConversation wc = null;
private final String APPLICATION_SCOPE = "scope=application&";
// Constants definition
private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL";
private final String FIRST_PAGE = "oscacheTest.jsp?";
private final String FORCE_CACHE_USE = "forcecacheuse=yes&";
private final String FORCE_REFRESH = "refresh=true";
//private final String PAGE_SCOPE = "scope=page&";
//private final String REQUEST_SCOPE = "scope=request&";
private final String SECOND_PAGE = "oscacheTestMultipleTagNoKey.jsp?";
private final String SESSION_SCOPE = "scope=session&";
private final int CACHE_TAG_EXPIRATION = 2000;
private final int HALF_CACHE_TAG_EXPIRATION = CACHE_TAG_EXPIRATION / 2;
/**
* Constructor required by JUnit
* <p>
* @param str Test name
*/
public TestOscacheJsp(String str) {
super(str);
}
/**
* Returns the test suite for the test class
* <p>
* @return Test suite for the class
*/
public static Test suite() {
return new TestSuite(TestOscacheJsp.class);
}
/**
* Setup method called before each testXXXX of the class
*/
public void setUp() {
// Create a web conversation to invoke our JSP
if (wc == null) {
wc = new WebConversation();
}
}
/**
* Test the cache module under load
*/
public void testOscacheBasicForLoad() {
String baseUrl = constructURL(FIRST_PAGE);
// Connect to the JSP using the application scope
String stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION);
// Assert that a page was properly generated.
// This does not ensure that the cache is working properly.
// Though, it ensures that no exception or other weird problem occured
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
// Invoke the JSP page containing 2 cache tag
baseUrl = constructURL(SECOND_PAGE);
// Connect to the JSP using the application scope
stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION);
// Assert that a page was properly generated.
// This does not ensure that the cache is working properly.
// Though, it ensures that no exception or other weird problem occured
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
}
/**
* Test the cache module using a JSP
*/
public void testOscacheJsp() {
String baseUrl = constructURL(FIRST_PAGE);
// Connect to a session scope to allow the JSP compilation
compileJSP(baseUrl + SESSION_SCOPE);
// Connect to the JSP using the application scope
String stringResponse = invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION);
// Connect again, we should have the same content since it expires
// only each 2 seconds
assertTrue(stringResponse.equals(invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION)));
// Connect again, the content should be different
String newResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION + (CACHE_TAG_EXPIRATION / 4));
assertTrue(!stringResponse.equals(newResponse));
stringResponse = newResponse;
// Connect again, but request the cache content so no refresh should occur
assertTrue(stringResponse.equals(invokeJSP(baseUrl, FORCE_CACHE_USE, 0)));
// Connect again, the content should have changed
newResponse = invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION);
assertTrue(!stringResponse.equals(newResponse));
stringResponse = newResponse;
// Connect for the last time, force the cache
// refresh so the content should have changed
assertTrue(!stringResponse.equals(invokeJSP(baseUrl, FORCE_REFRESH, 0)));
// Invoke the JSP page containing 2 cache tag
baseUrl = constructURL(SECOND_PAGE);
compileJSP(baseUrl + SESSION_SCOPE);
stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION);
// Invoke the same page en check if it's identical
assertTrue(stringResponse.equals(invokeJSP(baseUrl, CACHE_TAG_EXPIRATION)));
}
/**
* Compile a JSP page by invoking it. We compile the page first to avoid
* the compilation delay when testing since the time is a crucial factor
* <p>
* @param URL The JSP url to invoke
*/
private void compileJSP(String URL) {
try {
// Invoke the JSP
wc.getResponse(URL);
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!!");
}
}
/**
* Reads the base url from the test.web.baseURL system property and
* append the given URL.
* <p>
* @param Url Url to append to the base.
* @return Complete URL
*/
private String constructURL(String Url) {
String base = System.getProperty(BASE_URL_SYSTEM_PRP);
String constructedUrl = null;
if (base != null) {
if (!base.endsWith("/")) {
base = base + "/";
}
constructedUrl = base + Url;
} else {
fail("System property test.web.baseURL needs to be set to the proper server to use.");
}
return constructedUrl;
}
/**
* Utility method to invoke a JSP page and then sleep some time before returning
* <p>
* @param baseUrl The URL of the JSP to invoke
* @param sleepTime THe time to sleep before returning
* @return The text value of the reponse (HTML code)
*/
private String invokeJSP(String baseUrl, int sleepTime) {
return invokeJSP(baseUrl, "", sleepTime);
}
/**
* Utility method to invoke a JSP page and then sleep some time before returning
* <p>
* @param baseUrl The URL of the JSP to invoke
* @param URLparam The URL parameters of the JSP to invoke
* @param sleepTime The time to sleep before returning
* @return The text value of the reponse (HTML code)
*/
private String invokeJSP(String baseUrl, String URLparam, int sleepTime) {
try {
// Invoke the JSP and wait the specified sleepTime
WebResponse resp = wc.getResponse(baseUrl + APPLICATION_SCOPE + URLparam);
Thread.sleep(sleepTime);
return resp.getText();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised!!");
return null;
}
}
}

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test test the osCacheServlet distributed with the package. It checks that the
* cache integration is OK.
*
* $Id$
* @version $Revision$
* @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
*/
public final class TestOscacheServlet extends TestCase {
// The instance of a webconversation to invoke pages
static WebConversation wc = null;
private final String APPLICATION_SCOPE = "scope=application&";
// Constants definition
private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL";
private final String FORCE_CACHE_USE = "forcecacheuse=yes&";
private final String FORCE_REFRESH = "forceRefresh=true&";
private final String KEY = "key=ServletKeyItem&";
private final String REFRESH_PERIOD = "refreshPeriod=";
private final String SERVLET_URL = "/cacheServlet/?";
private final int NO_REFRESH_WANTED = 2000;
private final int REFRESH_WANTED = 0;
/**
* Constructor required by JUnit
* <p>
* @param str Test name
*/
public TestOscacheServlet(String str) {
super(str);
}
/**
* Returns the test suite for the test class
* <p>
* @return Test suite for the class
*/
public static Test suite() {
return new TestSuite(TestOscacheServlet.class);
}
/**
* This method is invoked before each testXXXX methods of the
* class. It set ups the variables required for each tests.
*/
public void setUp() {
// Create a web conversation on first run
if (wc == null) {
wc = new WebConversation();
}
}
/**
* Test the cache module using a servlet
*/
public void testOscacheServlet() {
// Make a first call just to initialize the servlet
String newResponse = invokeServlet(NO_REFRESH_WANTED);
// Connect to the servlet using the application scope
String previousReponse = invokeServlet(NO_REFRESH_WANTED);
// Call again an verify that the content hasn't changed
newResponse = invokeServlet(NO_REFRESH_WANTED);
assertTrue("new response " + newResponse + " should be the same to " + previousReponse, previousReponse.equals(newResponse));
// Call again an verify that the content is updated
newResponse = invokeServlet(REFRESH_WANTED);
assertFalse("new response " + newResponse + " expected it to be different to last one.", previousReponse.equals(newResponse));
previousReponse = newResponse;
// Call short delay so content should be refresh, but it will not since
// we ask to use the item already in cache
newResponse = invokeServlet(REFRESH_WANTED, FORCE_CACHE_USE);
assertTrue("new response " + newResponse + " should be the same to " + previousReponse, previousReponse.equals(newResponse));
// Call with long delay so the item would not need refresh, but we'll ask
// a refresh anyway
newResponse = invokeServlet(NO_REFRESH_WANTED, FORCE_REFRESH);
assertFalse("new response " + newResponse + " expected it to be different to last one.", previousReponse.equals(newResponse));
// Verify that the cache key and the cache entry are present in the output and
// that their values are correct
assertTrue("response '" + previousReponse + "' does not contain oscache string", previousReponse.indexOf("oscache") != -1);
assertTrue("response '" + previousReponse + "' does not contain /Test_key string", previousReponse.indexOf("/Test_key") != -1);
}
/**
* Test the cache module using a servlet and basic load
*/
public void testOscacheServletBasicForLoad() {
// Call Servlet
String stringResponse = invokeServlet(NO_REFRESH_WANTED);
// Assert that a page was properly generated.
// This does not ensure that the cache is working properly.
// Though, it ensures that no exception or other weird problem occured
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
// Call again
stringResponse = invokeServlet(REFRESH_WANTED);
// idem comment
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
// Call again
stringResponse = invokeServlet(REFRESH_WANTED, FORCE_CACHE_USE);
// idem comment
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
// Call again
stringResponse = invokeServlet(NO_REFRESH_WANTED, FORCE_REFRESH);
// idem comment
assertTrue(stringResponse.indexOf("This is some cache content") > 0);
}
/**
* Reads the base url from the test.web.baseURL system property and
* append the given URL.
* <p>
* @param Url Url to append to the base.
* @return Complete URL
*/
private String constructURL(String Url) {
String base = System.getProperty(BASE_URL_SYSTEM_PRP);
String constructedUrl = null;
if (base != null) {
if (base.endsWith("/")) {
base = base.substring(0, base.length() - 1);
}
constructedUrl = base + Url;
} else {
fail("System property test.web.baseURL needs to be set to the proper server to use.");
}
return constructedUrl;
}
/**
* Utility method to invoke a servlet
* <p>
* @param refresh The time interval telling if the item needs refresh
* @return The HTML page returned by the servlet
*/
private String invokeServlet(int refresh) {
// Invoke the servlet
return invokeServlet(refresh, "");
}
/**
* Utility method to invoke a servlet
* <p>
* @param refresh The time interval telling if the item needs refresh
* @param URL The URL of the servlet
* @return The HTML page returned by the servlet
*/
private String invokeServlet(int refresh, String URL) {
// wait 10 millis to change the time, see System.currentTimeMillis() in OscacheServlet
try {
Thread.sleep(10);
} catch (InterruptedException ignore) {
}
// Invoke the servlet
try {
String request = constructURL(SERVLET_URL) + APPLICATION_SCOPE + KEY + REFRESH_PERIOD + refresh + "&" + URL;
WebResponse resp = wc.getResponse(request);
return resp.getText();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception raised! " + ex.getMessage());
return "";
}
}
}

View file

@ -0,0 +1,11 @@
# CACHE IN MEMORY
cache.memory=true
# CACHE SIZE
cache.capacity=100
# CACHE PERSISTENCE CLASS
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
# CACHE DIRECTORY
cache.path=/tmp/cachetagscache

View file

@ -0,0 +1,8 @@
# CACHE IN MEMORY
cache.memory=false
# CACHE PERSISTENCE CLASS
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
# CACHE DIRECTORY
cache.path=/tmp/cachetagscache

View file

@ -0,0 +1,8 @@
# CACHE IN MEMORY
cache.memory=false
# CACHE PERSISTENCE CLASS
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener
# CACHE DIRECTORY
cache.path=/tmp/cachetagscache

View file

@ -0,0 +1,11 @@
# CACHE IN MEMORY
cache.memory=true
# CACHE PERSISTENCE CLASS
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
# CACHE DIRECTORY
cache.path=/tmp/cachetagscache
# CACHE OVERFLOW
cache.persistence.overflow.only=true

View file

@ -0,0 +1,8 @@
# CACHE IN MEMORY
cache.memory=true
# CACHE LISTENERS
cache.event.listeners=com.opensymphony.oscache.extra.StatisticListenerImpl
# CACHE SIZE
cache.capacity=1000