001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * CacheRegistryTest.java
020: *
021: * JUnit based test
022: */
023:
024: package com.rift.coad.lib.cache;
025:
026: import junit.framework.*;
027: import java.util.Date;
028: import java.util.HashMap;
029: import java.util.HashSet;
030: import java.util.Iterator;
031: import java.util.Map;
032: import java.util.Set;
033: import java.util.Vector;
034: import java.net.URL;
035: import java.net.URLClassLoader;
036: import org.apache.log4j.Logger;
037: import com.rift.coad.lib.configuration.ConfigurationFactory;
038: import com.rift.coad.lib.configuration.Configuration;
039: import com.rift.coad.lib.thread.BasicThread;
040: import com.rift.coad.lib.thread.ThreadStateMonitor;
041: import com.rift.coad.lib.thread.CoadunationThreadGroup;
042: import com.rift.coad.lib.security.UserSession;
043: import com.rift.coad.lib.security.user.UserSessionManager;
044: import com.rift.coad.lib.security.user.UserStoreManager;
045: import com.rift.coad.lib.security.ThreadsPermissionContainer;
046: import com.rift.coad.lib.security.login.handlers.PasswordInfoHandler;
047: import com.rift.coad.lib.security.SessionManager;
048: import com.rift.coad.lib.security.RoleManager;
049: import com.rift.coad.lib.security.Validator;
050: import com.rift.coad.lib.security.login.LoginManager;
051:
052: /**
053: *
054: * @author mincemeat
055: */
056: public class CacheRegistryTest extends TestCase {
057:
058: public static class CacheEntry {
059: // the member variables
060: private Date touchTime = new Date();
061: private String name = null;
062:
063: /**
064: * The constructor of the cache entry.
065: *
066: * @param name The name of the entry.
067: */
068: public CacheEntry(String name) {
069: this .name = name;
070: }
071:
072: /**
073: * This method returns the name of this object.
074: */
075: public String getName() {
076: return name;
077: }
078:
079: /**
080: * The touch time.
081: */
082: public synchronized void touch() {
083: touchTime = new Date();
084: }
085:
086: /**
087: * This method returns true if this object is expired.
088: *
089: * @return TRUE if expired FALSE if not.
090: * @param expiryDate The date to be new than in order to remain in
091: * memory.
092: */
093: public synchronized boolean isExpired(Date expiryDate) {
094: if (touchTime.getTime() < expiryDate.getTime()) {
095: return true;
096: }
097: return false;
098: }
099: }
100:
101: public static class TestCache implements Cache {
102:
103: private Map cacheEntries = new HashMap();
104:
105: /**
106: * The constructor of the test cache.
107: */
108: public TestCache() {
109:
110: }
111:
112: /**
113: * This method is called to perform garbage collection on the cache entries.
114: */
115: public synchronized void garbageCollect() {
116: Iterator iter = cacheEntries.keySet().iterator();
117: Date expiryDate = new Date(new Date().getTime() - 500);
118: while (iter.hasNext()) {
119: String key = (String) iter.next();
120: CacheEntry entry = (CacheEntry) cacheEntries.get(key);
121: if (entry.isExpired(expiryDate)) {
122: // remove an reset
123: cacheEntries.remove(key);
124: iter = cacheEntries.keySet().iterator();
125: }
126: }
127: }
128:
129: /**
130: * This method is called to forcibly remove everything from the cache.
131: */
132: public synchronized void clear() {
133: cacheEntries.clear();
134: }
135:
136: /**
137: * This mehtod returns true if the cache contains the checked entry.
138: *
139: * @return TRUE if the cache contains the checked entry.
140: * @param cacheEntry The entry to perform the check for.
141: */
142: public boolean contains(Object cacheEntry) {
143: return cacheEntries.containsValue(cacheEntry);
144: }
145:
146: /**
147: * This method is responsible for adding an entry to the cache.
148: *
149: * @param entry The entry to add to the cache.
150: */
151: public synchronized void add(CacheEntry entry) {
152: cacheEntries.put(entry.getName(), entry);
153: }
154:
155: /**
156: * This method returns the cache entry by name
157: *
158: * @return The CacheEntry to retrieve.
159: * @param name The name of the cache entry to retrieve.
160: */
161: public synchronized CacheEntry get(String name) {
162: return (CacheEntry) cacheEntries.get(name);
163: }
164:
165: }
166:
167: public static class TestCache2 implements Cache {
168:
169: private Map cacheEntries = new HashMap();
170:
171: /**
172: * The constructor of the test cache.
173: */
174: public TestCache2() {
175:
176: }
177:
178: /**
179: * This method is called to perform garbage collection on the cache entries.
180: */
181: public synchronized void garbageCollect() {
182: Iterator iter = cacheEntries.keySet().iterator();
183: Date expiryDate = new Date(new Date().getTime() - 500);
184: while (iter.hasNext()) {
185: String key = (String) iter.next();
186: CacheEntry entry = (CacheEntry) cacheEntries.get(key);
187: if (entry.isExpired(expiryDate)) {
188: // remove an reset
189: cacheEntries.remove(key);
190: iter = cacheEntries.keySet().iterator();
191: }
192: }
193: }
194:
195: /**
196: * This method is called to forcibly remove everything from the cache.
197: */
198: public synchronized void clear() {
199: cacheEntries.clear();
200: }
201:
202: /**
203: * This mehtod returns true if the cache contains the checked entry.
204: *
205: * @return TRUE if the cache contains the checked entry.
206: * @param cacheEntry The entry to perform the check for.
207: */
208: public boolean contains(Object cacheEntry) {
209: return cacheEntries.containsValue(cacheEntry);
210: }
211:
212: /**
213: * This method is responsible for adding an entry to the cache.
214: *
215: * @param entry The entry to add to the cache.
216: */
217: public synchronized void add(CacheEntry entry) {
218: cacheEntries.put(entry.getName(), entry);
219: }
220:
221: /**
222: * This method returns the cache entry by name
223: *
224: * @return The CacheEntry to retrieve.
225: * @param name The name of the cache entry to retrieve.
226: */
227: public synchronized CacheEntry get(String name) {
228: return (CacheEntry) cacheEntries.get(name);
229: }
230:
231: }
232:
233: public CacheRegistryTest(String testName) {
234: super (testName);
235: }
236:
237: protected void setUp() throws Exception {
238: }
239:
240: protected void tearDown() throws Exception {
241: }
242:
243: public static Test suite() {
244: TestSuite suite = new TestSuite(CacheRegistryTest.class);
245:
246: return suite;
247: }
248:
249: /**
250: * Test of init method, of class com.rift.coad.lib.cache.CacheRegistry.
251: */
252: public void testCache() throws Exception {
253: System.out.println("init");
254:
255: // initialize the thread permissions
256: ThreadsPermissionContainer permissions = new ThreadsPermissionContainer();
257: SessionManager.init(permissions);
258: UserStoreManager userStoreManager = new UserStoreManager();
259: UserSessionManager sessionManager = new UserSessionManager(
260: permissions, userStoreManager);
261: LoginManager.init(sessionManager, userStoreManager);
262:
263: // add a user to the session for the current thread
264: RoleManager.getInstance();
265:
266: // instanciate the thread group
267: CoadunationThreadGroup threadGroup = new CoadunationThreadGroup(
268: sessionManager, userStoreManager);
269:
270: // check the singleton
271: CacheRegistry result = CacheRegistry.init(threadGroup);
272: assertEquals(CacheRegistry.getInstance(), result);
273:
274: // init class loaders
275: ClassLoader loader1 = new URLClassLoader(new URL[] {});
276: ClassLoader loader2 = new URLClassLoader(new URL[] {});
277:
278: // set the current thread
279: Thread.currentThread().setContextClassLoader(loader1);
280: result.initCache();
281: TestCache testCache = (TestCache) result
282: .getCache(TestCache.class);
283: TestCache2 testCache2 = (TestCache2) result
284: .getCache(TestCache2.class);
285: testCache.add(new CacheEntry("bob"));
286: testCache.add(new CacheEntry("fred"));
287: testCache2.add(new CacheEntry("mary"));
288: testCache2.add(new CacheEntry("jill"));
289:
290: CacheEntry fred = testCache.get("fred");
291: CacheEntry mary = testCache2.get("mary");
292:
293: Thread.currentThread().setContextClassLoader(loader2);
294: result.initCache();
295: TestCache testCache_2 = (TestCache) result
296: .getCache(TestCache.class);
297: TestCache2 testCache2_2 = (TestCache2) result
298: .getCache(TestCache2.class);
299: testCache_2.add(new CacheEntry("ben"));
300: testCache_2.add(new CacheEntry("john"));
301: testCache2_2.add(new CacheEntry("tamzin"));
302: testCache2_2.add(new CacheEntry("chevaughn"));
303:
304: CacheEntry ben = testCache_2.get("ben");
305: CacheEntry chevaughn = testCache2_2.get("chevaughn");
306:
307: // loop for 2 seconds
308: for (int index = 0; index < 4; index++) {
309: fred.touch();
310: mary.touch();
311: ben.touch();
312: chevaughn.touch();
313: Thread.sleep(450);
314: }
315:
316: Thread.currentThread().setContextClassLoader(loader1);
317: assertEquals(result.getCache(TestCache.class), testCache);
318: assertEquals(result.getCache(TestCache2.class), testCache2);
319:
320: assertEquals(testCache.get("bob"), null);
321: assertEquals(testCache.get("fred"), fred);
322: assertEquals(testCache2.get("mary"), mary);
323: assertEquals(testCache2.get("jill"), null);
324:
325: Thread.currentThread().setContextClassLoader(loader2);
326: assertEquals(result.getCache(TestCache.class), testCache_2);
327: assertEquals(result.getCache(TestCache2.class), testCache2_2);
328:
329: assertEquals(testCache_2.get("ben"), ben);
330: assertEquals(testCache_2.get("john"), null);
331: assertEquals(testCache2_2.get("tamzin"), null);
332: assertEquals(testCache2_2.get("chevaughn"), chevaughn);
333:
334: result.terminateCache();
335: Thread.sleep(100);
336: assertEquals(testCache_2.get("ben"), null);
337: assertEquals(testCache_2.get("john"), null);
338: assertEquals(testCache2_2.get("tamzin"), null);
339: assertEquals(testCache2_2.get("chevaughn"), null);
340:
341: try {
342: result.getCache(TestCache.class);
343: fail("The cache is still valid for this class loader");
344: } catch (CacheException ex) {
345: // ignore
346: }
347:
348: Thread.currentThread().setContextClassLoader(loader1);
349: result.shutdown();
350:
351: assertEquals(testCache_2.get("ben"), null);
352: assertEquals(testCache_2.get("john"), null);
353: assertEquals(testCache2_2.get("tamzin"), null);
354: assertEquals(testCache2_2.get("chevaughn"), null);
355: try {
356: result.getCache(TestCache.class);
357: fail("The cache is still valid for this class loader");
358: } catch (CacheException ex) {
359: // ignore
360: }
361: }
362:
363: }
|