Initial import from https://bitbucket.org/opensymphony/oscache/
This commit is contained in:
commit
bd8f23d7d6
268 changed files with 34908 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
275
src/test/java/com/opensymphony/oscache/base/TestCache.java
Normal file
275
src/test/java/com/opensymphony/oscache/base/TestCache.java
Normal 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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
136
src/test/java/com/opensymphony/oscache/base/TestCacheEntry.java
Normal file
136
src/test/java/com/opensymphony/oscache/base/TestCacheEntry.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
489
src/test/java/com/opensymphony/oscache/base/TestConcurrency.java
Normal file
489
src/test/java/com/opensymphony/oscache/base/TestConcurrency.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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();
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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="mailto:chris@swebtec.com">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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
208
src/test/java/com/opensymphony/oscache/web/TestOscacheJsp.java
Normal file
208
src/test/java/com/opensymphony/oscache/web/TestOscacheJsp.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
}
|
11
src/test/java/oscacheDiskAndMemory.properties
Normal file
11
src/test/java/oscacheDiskAndMemory.properties
Normal 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
|
8
src/test/java/oscacheDiskOnly.properties
Normal file
8
src/test/java/oscacheDiskOnly.properties
Normal 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
|
8
src/test/java/oscacheDiskOnlyHash.properties
Normal file
8
src/test/java/oscacheDiskOnlyHash.properties
Normal 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
|
11
src/test/java/oscacheMemoryAndOverflowToDisk.properties
Normal file
11
src/test/java/oscacheMemoryAndOverflowToDisk.properties
Normal 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
|
8
src/test/java/oscacheMemoryOnly.properties
Normal file
8
src/test/java/oscacheMemoryOnly.properties
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue