001: package org.apache.ojb.broker.cache;
002:
003: import java.io.Serializable;
004: import java.util.Properties;
005:
006: import org.apache.ojb.broker.Article;
007: import org.apache.ojb.broker.Identity;
008: import org.apache.ojb.broker.InterfaceArticle;
009: import org.apache.ojb.broker.PBKey;
010: import org.apache.ojb.broker.PersistenceBroker;
011: import org.apache.ojb.broker.PersistenceBrokerFactory;
012: import org.apache.ojb.broker.metadata.ConnectionRepository;
013: import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
014: import org.apache.ojb.broker.metadata.MetadataManager;
015: import org.apache.ojb.broker.metadata.MetadataTest;
016: import org.apache.ojb.broker.query.QueryByIdentity;
017: import org.apache.ojb.broker.sequence.Repository;
018: import org.apache.ojb.broker.util.ClassHelper;
019: import org.apache.ojb.broker.util.GUID;
020: import org.apache.ojb.junit.OJBTestCase;
021:
022: /**
023: * Do some basic tests using ObjectCache implementations.
024: *
025: * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
026: * @author <a href="mailto:thma@apache.org">Thomas Mahler</a>
027: * @version $Id: ObjectCacheTest.java,v 1.1.2.2 2005/07/24 23:57:42 arminw Exp $
028: */
029: public class ObjectCacheTest extends OJBTestCase {
030: static final String EXCLUDE_PACKAGE = "org.apache.ojb.broker.sequence";
031: static final String EXCLUDE_PACKAGE_NOT_EXIST = "org.apache.ojb.broker.sequence.xyz";
032:
033: Class[] objectCacheImpls = new Class[] {
034: // ObjectCacheEmptyImpl.class,
035: ObjectCacheDefaultImpl.class,
036: ObjectCacheTwoLevelImpl.class,
037: ObjectCachePerBrokerImpl.class, ObjectCacheJCSImpl.class,
038: ObjectCacheJCSPerClassImpl.class,
039: ObjectCachePerClassImpl.class };
040:
041: Class old_ObjectCache;
042: String[] old_CacheFilter;
043:
044: public ObjectCacheTest(String s) {
045: super (s);
046: }
047:
048: public static void main(String[] args) {
049: String[] arr = { ObjectCacheTest.class.getName() };
050: junit.textui.TestRunner.main(arr);
051: }
052:
053: protected void setUp() throws Exception {
054: super .setUp();
055: }
056:
057: protected void tearDown() throws Exception {
058: super .tearDown();
059: }
060:
061: /**
062: * Test the JCS cache implementation. In JCS config file the following
063: * properties are set:
064: * <br/>
065: * jcs.region.org.apache.ojb.broker.cache.ObjectCacheTest$CacheObject.cacheattributes.MaxObjects=3
066: * jcs.region.org.apache.ojb.broker.cache.ObjectCacheTest$CacheObject.cacheattributes.MaxMemoryIdleTimeSeconds=2
067: * jcs.region.org.apache.ojb.broker.cache.ObjectCacheTest$CacheObject.cacheattributes.UseMemoryShrinker=true
068: * jcs.region.org.apache.ojb.broker.cache.ObjectCacheTest$CacheObject.cacheattributes.ShrinkerIntervalSeconds=1
069: */
070: public void testJCSPerClassObjectCacheImplementation()
071: throws Exception {
072: PersistenceBroker broker = PersistenceBrokerFactory
073: .defaultPersistenceBroker();
074: try {
075: ObjectCache cache = new ObjectCacheJCSPerClassImpl(broker,
076: null);
077:
078: CacheObject obj_1 = new CacheObject(null,
079: "testJCSPerClassObjectCacheImplementation_1");
080: Identity oid_1 = new Identity(obj_1, broker);
081: CacheObject obj_2 = new CacheObject(null,
082: "testJCSPerClassObjectCacheImplementation_2");
083: Identity oid_2 = new Identity(obj_2, broker);
084: CacheObject obj_3 = new CacheObject(null,
085: "testJCSPerClassObjectCacheImplementation_2");
086: Identity oid_3 = new Identity(obj_3, broker);
087:
088: cache.cache(oid_1, obj_1);
089: cache.cache(oid_2, obj_2);
090:
091: // two objects should be found
092: assertNotNull(cache.lookup(oid_1));
093: assertNotNull(cache.lookup(oid_2));
094: cache.cache(oid_3, obj_3);
095: // we only allow two objects in cache region
096: boolean bool = cache.lookup(oid_1) != null;
097: bool = bool && cache.lookup(oid_2) != null;
098: bool = bool && cache.lookup(oid_3) != null;
099: assertFalse("We should not found all cached objects", bool);
100: // idle time is 2 sec
101: Thread.sleep(4000);
102: assertNull(cache.lookup(oid_1));
103: assertNull(cache.lookup(oid_2));
104: assertNull(cache.lookup(oid_3));
105:
106: } catch (Exception e) {
107: e.printStackTrace();
108: throw e;
109: } finally {
110: if (broker != null)
111: broker.close();
112: }
113: }
114:
115: public void testObjectCacheDefaultImplTimeout() throws Exception {
116: TestObjectDefaultCache obj = new TestObjectDefaultCache();
117: PersistenceBroker broker = PersistenceBrokerFactory
118: .defaultPersistenceBroker();
119: try {
120: broker.beginTransaction();
121: broker.store(obj);
122: broker.commitTransaction();
123:
124: Identity oid = new Identity(obj, broker);
125: obj = (TestObjectDefaultCache) broker.serviceObjectCache()
126: .lookup(oid);
127: assertNotNull(obj);
128:
129: Thread.sleep(5000);
130: obj = (TestObjectDefaultCache) broker.serviceObjectCache()
131: .lookup(oid);
132: assertNull(obj);
133: } finally {
134: if (broker != null)
135: broker.close();
136: }
137: }
138:
139: public void testObjectCacheDefaultImpl() throws Exception {
140: String name = "testObjectCacheDefaultImpl_"
141: + System.currentTimeMillis();
142: TestObjectDefaultCache obj = new TestObjectDefaultCache();
143: obj.setName(name);
144: PersistenceBroker broker = PersistenceBrokerFactory
145: .defaultPersistenceBroker();
146: try {
147: broker.beginTransaction();
148: broker.store(obj);
149: broker.commitTransaction();
150:
151: Identity oid = new Identity(obj, broker);
152: obj = (TestObjectDefaultCache) broker.serviceObjectCache()
153: .lookup(oid);
154: assertNotNull(obj);
155: assertEquals(name, obj.getName());
156:
157: // modify name
158: String new_name = "modified_" + name;
159: obj.setName(new_name);
160: obj = (TestObjectDefaultCache) broker
161: .getObjectByIdentity(oid);
162: assertNotNull(obj);
163: assertEquals(
164: "current version of cache should return the modified object",
165: new_name, obj.getName());
166:
167: broker.removeFromCache(oid);
168: obj = (TestObjectDefaultCache) broker.serviceObjectCache()
169: .lookup(oid);
170: assertNull("Should be removed from cache", obj);
171: obj = (TestObjectDefaultCache) broker
172: .getObjectByIdentity(oid);
173: assertNotNull(obj);
174: assertEquals("Should return the unmodified object", name,
175: obj.getName());
176: } finally {
177: if (broker != null)
178: broker.close();
179: }
180: }
181:
182: /**
183: * This test check the 'cacheExcludes' property and try to exclude a whole package from
184: * caching.
185: * @throws Exception
186: */
187: public void testCacheFilterFunctions() throws Exception {
188: PersistenceBrokerFactory.releaseAllInstances();
189: String old = null;
190: try {
191: MetadataManager mm = MetadataManager.getInstance();
192: JdbcConnectionDescriptor jcd = mm.connectionRepository()
193: .getDescriptor(mm.getDefaultPBKey());
194: if (jcd.getObjectCacheDescriptor().getObjectCache().equals(
195: ObjectCacheEmptyImpl.class)) {
196: ojbSkipTestMessage("Doesn't work with "
197: + ObjectCacheEmptyImpl.class
198: + " as default cache.");
199: return;
200: }
201: old = jcd
202: .getAttribute(CacheDistributor.CACHE_EXCLUDES_STRING);
203: jcd.addAttribute(CacheDistributor.CACHE_EXCLUDES_STRING,
204: "org.apache.ojb.broker.sequence");
205:
206: PersistenceBroker broker = PersistenceBrokerFactory
207: .defaultPersistenceBroker();
208: try {
209: ObjectCache cache = broker.serviceObjectCache();
210: CacheObject obj = new CacheObject(null,
211: "CacheObject persistent obj");
212: Identity oid = new Identity(obj, broker);
213:
214: Repository.SMKey filterOutPackageObject = new Repository.SMKey();
215: filterOutPackageObject
216: .setName("ObjectCacheTest: package filter");
217: Identity filterOutPackageOid = new Identity(
218: filterOutPackageObject, broker);
219:
220: Object result = null;
221: cache.clear();
222: result = cache.lookup(oid);
223: assertNull(result);
224: result = cache.lookup(filterOutPackageOid);
225: assertNull(result);
226:
227: // cache it
228: cache.cache(oid, obj);
229: cache
230: .cache(filterOutPackageOid,
231: filterOutPackageObject);
232:
233: // lookup things
234: result = cache.lookup(oid);
235: assertNotNull(result);
236: assertEquals(obj, result);
237: result = cache.lookup(filterOutPackageOid);
238: assertNull(result);
239: } finally {
240: jcd.addAttribute(
241: CacheDistributor.CACHE_EXCLUDES_STRING, old);
242: if (broker != null)
243: broker.close();
244: }
245: } finally {
246: PersistenceBrokerFactory.releaseAllInstances();
247: PersistenceBroker broker = PersistenceBrokerFactory
248: .defaultPersistenceBroker();
249: broker.close();
250: }
251: }
252:
253: /**
254: * Check base caching functions of some cache implementations.
255: *
256: * @throws Exception
257: */
258: public void testSimpleObjectCacheFunctions() throws Exception {
259: for (int i = 0; i < objectCacheImpls.length; i++) {
260: PersistenceBroker broker = PersistenceBrokerFactory
261: .defaultPersistenceBroker();
262: try {
263: ObjectCache cache = (ObjectCache) ClassHelper
264: .newInstance(objectCacheImpls[i], new Class[] {
265: PersistenceBroker.class,
266: Properties.class }, new Object[] {
267: broker, null });
268: checkBaseFunctions(broker, cache);
269: } finally {
270: if (broker != null)
271: broker.close();
272: }
273: }
274: }
275:
276: /**
277: * Checks the base functions of the current ObjectCache implementation.
278: *
279: * @throws Exception
280: */
281: private void checkBaseFunctions(PersistenceBroker broker,
282: ObjectCache cache) throws Exception {
283: CacheObject obj = new CacheObject(null, "ObjectCache test");
284: Identity oid = new Identity(obj, broker);
285: CacheObject obj2 = new CacheObject(null, "ObjectCache test 2");
286: Identity oid2 = new Identity(obj2, broker);
287: cache.clear();
288: Object result = cache.lookup(oid);
289: assertNull(result);
290:
291: cache.cache(oid, obj);
292: cache.cache(oid2, obj2);
293: result = cache.lookup(oid);
294: assertNotNull(result);
295: assertEquals(obj, result);
296: assertNotSame(obj2, result);
297:
298: cache.remove(oid);
299: result = cache.lookup(oid);
300: Object result2 = cache.lookup(oid2);
301: assertNull(result);
302: assertNotNull(result2);
303:
304: cache.clear();
305: result = cache.lookup(oid);
306: assertNull(result);
307: result = cache.lookup(oid2);
308: assertNull(result);
309: // cache.clear();
310: }
311:
312: /**
313: * Test per class ObjectCache declaration. 'TestObjectEmptyCache'
314: * class metadata declare an 'empty ObjectCache' implementation
315: * as cache, CacheObject use the default ObjectCache implementation.
316: * Thus we should found 'CacheObject' instance in cache, but NOT found
317: * 'TestObjectEmptyCache' instance.
318: */
319: public void testPerClassCache() throws Exception {
320: PersistenceBroker broker = PersistenceBrokerFactory
321: .defaultPersistenceBroker();
322: JdbcConnectionDescriptor jcd = broker
323: .serviceConnectionManager().getConnectionDescriptor();
324: if (jcd.getObjectCacheDescriptor().getObjectCache().equals(
325: ObjectCacheEmptyImpl.class)) {
326: ojbSkipTestMessage("Doesn't work with "
327: + ObjectCacheEmptyImpl.class + " as default cache.");
328: return;
329: }
330: String name = "testPerClassCache_" + System.currentTimeMillis();
331:
332: TestObjectEmptyCache obj = new TestObjectEmptyCache();
333: obj.setName(name);
334: CacheObject dummy = new CacheObject();
335: dummy.setName(name);
336:
337: try {
338: broker.beginTransaction();
339: broker.store(obj);
340: broker.store(dummy);
341: broker.commitTransaction();
342:
343: Identity obj_oid = new Identity(obj, broker);
344: Identity dummy_oid = new Identity(dummy, broker);
345: ObjectCache cache = broker.serviceObjectCache();
346: Object ret_obj = cache.lookup(obj_oid);
347: Object ret_dummy = cache.lookup(dummy_oid);
348: assertNotNull(ret_dummy);
349: assertNull(ret_obj);
350: } finally {
351: if (broker != null && broker.isInTransaction())
352: broker.abortTransaction();
353: if (broker != null)
354: broker.close();
355: }
356: }
357:
358: /**
359: * Read a specific jdbc-connction-descriptor at runtime, merge it with current
360: * ConnectionRepository, lookup a specific PersistenceBroker instance, get ObjectCache.
361: * This should be ObjectCacheEmptyImpl, because this is declared at jdbc-connection-descriptor
362: * level.
363: */
364: public void testPerDatabaseCache() {
365: ConnectionRepository cr = MetadataManager.getInstance()
366: .readConnectionRepository(MetadataTest.TEST_REPOSITORY);
367: MetadataManager.getInstance().mergeConnectionRepository(cr);
368:
369: PersistenceBroker pb = PersistenceBrokerFactory
370: .createPersistenceBroker(new PBKey("runtime_2"));
371: try {
372: ObjectCache oc = pb.serviceObjectCache();
373: CacheObject testObj = new CacheObject(null,
374: "testPerDatabaseCache");
375: Identity oid = new Identity(testObj, pb);
376: oc.cache(oid, testObj);
377: Object result = oc.lookup(oid);
378: assertNull("We should not found this object in cache",
379: result);
380: } finally {
381: if (pb != null && !pb.isClosed())
382: pb.close();
383: MetadataManager.getInstance().connectionRepository()
384: .removeDescriptor(cr.getAllDescriptor().get(0));
385: }
386: }
387:
388: /**
389: * This test checks if the caches of two different brokers are properly isolated.
390: * changes made to an object in tx1 should not be visible in tx2 !
391: * TODO: once we work without global cache only (e.g. intern temporary cache), this test should pass!
392: */
393: public void YYYtestCacheIsolation() throws Exception {
394: Object[] pk = new Object[] { new Long(42) };
395: Identity oid = new Identity(Article.class,
396: InterfaceArticle.class, pk);
397:
398: GUID guid = new GUID();
399:
400: PersistenceBroker broker1 = PersistenceBrokerFactory
401: .defaultPersistenceBroker();
402: broker1.beginTransaction();
403:
404: Article a1 = (Article) broker1
405: .getObjectByQuery(new QueryByIdentity(oid));
406: String originalName = a1.getArticleName();
407: a1.setArticleName(guid.toString());
408:
409: // start a second transaction
410: PersistenceBroker broker2 = PersistenceBrokerFactory
411: .defaultPersistenceBroker();
412: broker2.beginTransaction();
413:
414: Article a2 = (Article) broker2
415: .getObjectByQuery(new QueryByIdentity(oid));
416:
417: assertEquals(guid.toString(), a1.getArticleName());
418: assertEquals(originalName, a2.getArticleName());
419: assertNotSame(a1, a2);
420:
421: broker1.commitTransaction();
422: broker1.close();
423:
424: broker2.commitTransaction();
425: broker2.close();
426: }
427:
428: // **********************************************************************
429: // inner class
430: // **********************************************************************
431: public static class CacheObject implements Serializable {
432: private Integer objId;
433: private String name;
434:
435: public CacheObject(Integer objId, String name) {
436: this .objId = objId;
437: this .name = name;
438: }
439:
440: public CacheObject() {
441: }
442:
443: public Integer getObjId() {
444: return objId;
445: }
446:
447: public void setObjId(Integer objId) {
448: this .objId = objId;
449: }
450:
451: public String getName() {
452: return name;
453: }
454:
455: public void setName(String name) {
456: this .name = name;
457: }
458: }
459:
460: /**
461: * in class-descriptor ObjectCacheEmptyImpl class is declared
462: * as cache implementation.
463: */
464: public static class TestObjectEmptyCache {
465: private Integer id;
466: private String name;
467:
468: public TestObjectEmptyCache() {
469: }
470:
471: public Integer getId() {
472: return id;
473: }
474:
475: public void setId(Integer id) {
476: this .id = id;
477: }
478:
479: public String getName() {
480: return name;
481: }
482:
483: public void setName(String name) {
484: this .name = name;
485: }
486: }
487:
488: public static class TestObjectDefaultCache extends
489: TestObjectEmptyCache {
490: }
491: }
|