KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > api > ObjectManagerTest


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.objectserver.api;
6
7 import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
8
9 import com.tc.exception.ImplementMe;
10 import com.tc.lang.TCThreadGroup;
11 import com.tc.lang.ThrowableHandler;
12 import com.tc.logging.TCLogger;
13 import com.tc.logging.TCLogging;
14 import com.tc.management.beans.object.MockObjectManagementMonitor;
15 import com.tc.net.protocol.tcm.ChannelID;
16 import com.tc.object.BaseDSOTestCase;
17 import com.tc.object.ObjectID;
18 import com.tc.object.SerializationUtil;
19 import com.tc.object.cache.EvictionPolicy;
20 import com.tc.object.cache.LRUEvictionPolicy;
21 import com.tc.object.cache.NullCache;
22 import com.tc.object.cache.TestCacheStats;
23 import com.tc.object.dna.api.DNA;
24 import com.tc.object.dna.api.DNACursor;
25 import com.tc.object.dna.api.DNAException;
26 import com.tc.object.dna.api.LiteralAction;
27 import com.tc.object.dna.api.LogicalAction;
28 import com.tc.object.dna.api.PhysicalAction;
29 import com.tc.object.dna.impl.DNAEncoding;
30 import com.tc.object.dna.impl.UTF8ByteDataHolder;
31 import com.tc.object.tx.TransactionID;
32 import com.tc.objectserver.context.ManagedObjectFaultingContext;
33 import com.tc.objectserver.context.ManagedObjectFlushingContext;
34 import com.tc.objectserver.context.ObjectManagerResultsContext;
35 import com.tc.objectserver.core.api.Filter;
36 import com.tc.objectserver.core.api.GarbageCollector;
37 import com.tc.objectserver.core.api.ManagedObject;
38 import com.tc.objectserver.core.api.TestDNA;
39 import com.tc.objectserver.core.impl.MarkAndSweepGarbageCollector;
40 import com.tc.objectserver.core.impl.TestManagedObject;
41 import com.tc.objectserver.impl.InMemoryManagedObjectStore;
42 import com.tc.objectserver.impl.ObjectInstanceMonitorImpl;
43 import com.tc.objectserver.impl.ObjectManagerConfig;
44 import com.tc.objectserver.impl.ObjectManagerImpl;
45 import com.tc.objectserver.impl.ObjectManagerStatsImpl;
46 import com.tc.objectserver.impl.PersistentManagedObjectStore;
47 import com.tc.objectserver.l1.api.ClientStateManager;
48 import com.tc.objectserver.l1.impl.ClientStateManagerImpl;
49 import com.tc.objectserver.managedobject.BackReferences;
50 import com.tc.objectserver.managedobject.ManagedObjectStateFactory;
51 import com.tc.objectserver.managedobject.NullManagedObjectChangeListenerProvider;
52 import com.tc.objectserver.mgmt.ManagedObjectFacade;
53 import com.tc.objectserver.mgmt.MapEntryFacade;
54 import com.tc.objectserver.persistence.api.ManagedObjectPersistor;
55 import com.tc.objectserver.persistence.api.ManagedObjectStore;
56 import com.tc.objectserver.persistence.api.PersistenceTransaction;
57 import com.tc.objectserver.persistence.api.PersistenceTransactionProvider;
58 import com.tc.objectserver.persistence.api.Persistor;
59 import com.tc.objectserver.persistence.impl.InMemoryPersistor;
60 import com.tc.objectserver.persistence.impl.TestPersistenceTransaction;
61 import com.tc.objectserver.persistence.impl.TestPersistenceTransactionProvider;
62 import com.tc.objectserver.persistence.sleepycat.CustomSerializationAdapterFactory;
63 import com.tc.objectserver.persistence.sleepycat.DBEnvironment;
64 import com.tc.objectserver.persistence.sleepycat.SerializationAdapterFactory;
65 import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor;
66 import com.tc.objectserver.persistence.sleepycat.SleepycatSerializationAdapterFactory;
67 import com.tc.stats.counter.sampled.SampledCounter;
68 import com.tc.stats.counter.sampled.SampledCounterConfig;
69 import com.tc.stats.counter.sampled.SampledCounterImpl;
70 import com.tc.text.PrettyPrinter;
71 import com.tc.util.concurrent.LifeCycleState;
72 import com.tc.util.concurrent.StoppableThread;
73 import com.tc.util.concurrent.ThreadUtil;
74
75 import java.io.File JavaDoc;
76 import java.util.ArrayList JavaDoc;
77 import java.util.Arrays JavaDoc;
78 import java.util.Collection JavaDoc;
79 import java.util.Collections JavaDoc;
80 import java.util.Date JavaDoc;
81 import java.util.HashMap JavaDoc;
82 import java.util.HashSet JavaDoc;
83 import java.util.Iterator JavaDoc;
84 import java.util.List JavaDoc;
85 import java.util.Map JavaDoc;
86 import java.util.Set JavaDoc;
87
88 import javax.management.NotCompliantMBeanException JavaDoc;
89
90 /**
91  * @author steve
92  */

93 public class ObjectManagerTest extends BaseDSOTestCase {
94
95   private Map JavaDoc managed;
96   private ObjectManagerImpl objectManager;
97   private TestObjectManagerConfig config;
98   private ClientStateManager clientStateManager;
99   private ManagedObjectStore objectStore;
100   private TCLogger logger;
101   private ObjectManagerStatsImpl stats;
102   private SampledCounter newObjectCounter;
103   private SampledCounterImpl objectfaultCounter;
104   private TestPersistenceTransactionProvider persistenceTransactionProvider;
105   private TestPersistenceTransaction NULL_TRANSACTION;
106
107   /**
108    * Constructor for ObjectManagerTest.
109    *
110    * @param arg0
111    */

112   public ObjectManagerTest(String JavaDoc arg0) {
113     super(arg0);
114   }
115
116   protected void setUp() throws Exception JavaDoc {
117     super.setUp();
118     this.logger = TCLogging.getLogger(getClass());
119     this.managed = new HashMap JavaDoc();
120     config = new TestObjectManagerConfig();
121     clientStateManager = new ClientStateManagerImpl(TCLogging.getLogger(ClientStateManager.class));
122     ManagedObjectStateFactory.disableSingleton(true);
123     ManagedObjectStateFactory.createInstance(new NullManagedObjectChangeListenerProvider(), new InMemoryPersistor());
124     this.newObjectCounter = new SampledCounterImpl(new SampledCounterConfig(1, 1, true, 0L));
125     this.objectfaultCounter = new SampledCounterImpl(new SampledCounterConfig(1, 1, true, 0L));
126     stats = new ObjectManagerStatsImpl(newObjectCounter, objectfaultCounter);
127     persistenceTransactionProvider = new TestPersistenceTransactionProvider();
128     NULL_TRANSACTION = TestPersistenceTransaction.NULL_TRANSACTION;
129   }
130
131   private void initObjectManager() {
132     initObjectManager(createThreadGroup());
133   }
134
135   private TCThreadGroup createThreadGroup() {
136     return new TCThreadGroup(new ThrowableHandler(TCLogging.getLogger(ObjectManagerImpl.class)));
137   }
138
139   private void initObjectManager(ThreadGroup JavaDoc threadGroup) {
140     initObjectManager(threadGroup, new NullCache());
141   }
142
143   private void initObjectManager(ThreadGroup JavaDoc threadGroup, EvictionPolicy cache) {
144     this.objectStore = new InMemoryManagedObjectStore(this.managed);
145     initObjectManager(threadGroup, cache, this.objectStore);
146   }
147
148   private void initObjectManager(ThreadGroup JavaDoc threadGroup, EvictionPolicy cache, ManagedObjectStore store) {
149     TestSink faultSink = new TestSink();
150     TestSink flushSink = new TestSink();
151     try {
152       this.objectManager = new ObjectManagerImpl(config, threadGroup, clientStateManager, store, cache,
153                                                  persistenceTransactionProvider, faultSink, flushSink,
154                                                  new MockObjectManagementMonitor());
155     } catch (NotCompliantMBeanException JavaDoc e) {
156       throw new RuntimeException JavaDoc(e);
157     }
158     new TestMOFaulter(this.objectManager, store, faultSink).start();
159     new TestMOFlusher(this.objectManager, flushSink).start();
160   }
161
162   public void testShutdownAndSetGarbageCollector() throws Exception JavaDoc {
163     initObjectManager();
164     objectManager.stop();
165     try {
166       objectManager.setGarbageCollector(null);
167       fail("Should have thrown a ShutdownError.");
168     } catch (ShutdownError e) {
169       // ok.
170
}
171   }
172
173   public void testShutdownAndLookup() throws Exception JavaDoc {
174     initObjectManager();
175     objectManager.stop();
176     try {
177       objectManager.getObjectByID(null);
178       fail("Should have thrown a ShutdownError.");
179     } catch (ShutdownError e) {
180       // ok;
181
}
182   }
183
184   public void testShutdownAndLookupRootID() throws Exception JavaDoc {
185     initObjectManager();
186     objectManager.stop();
187     try {
188       objectManager.lookupRootID(null);
189       fail("Should have thrown a ShutdownError.");
190     } catch (ShutdownError e) {
191       // ok.
192
}
193   }
194
195   public void testShutdownAndCreateRoot() throws Exception JavaDoc {
196     initObjectManager();
197     objectManager.stop();
198     try {
199       objectManager.createRoot(null, null);
200       fail("Should have thrown a ShutdownError.");
201     } catch (ShutdownError e) {
202       // ok.
203
}
204   }
205
206   public void testShutdownAndCreateObject() throws Exception JavaDoc {
207     initObjectManager();
208     objectManager.stop();
209     try {
210       objectManager.createObject(null);
211       fail("Should have thrown a ShutdownError.");
212     } catch (ShutdownError e) {
213       // ok.
214
}
215   }
216
217   public void testShutdownAndGetRoots() throws Exception JavaDoc {
218     initObjectManager();
219     objectManager.stop();
220     try {
221       objectManager.getRoots();
222       fail("Should have thrown a ShutdownError");
223     } catch (ShutdownError e) {
224       // ok.
225
}
226
227   }
228
229   public void testShutdownAndLookupObjectsForCreateIfNecessary() throws Exception JavaDoc {
230     initObjectManager();
231
232     objectManager.stop();
233
234     try {
235       objectManager.lookupObjectsForCreateIfNecessary(null, null);
236       fail("Should have thrown a ShutdownError.");
237     } catch (ShutdownError e) {
238       // ok.
239
}
240   }
241
242   public void testShutdownAndLookupObjectsFor() throws Exception JavaDoc {
243     initObjectManager();
244
245     objectManager.stop();
246
247     try {
248       objectManager.lookupObjectsAndSubObjectsFor(null, null, -1);
249       fail("Should have thrown a ShutdownError.");
250     } catch (ShutdownError e) {
251       // ok.
252
}
253   }
254
255   public void testNewObjectIDs() {
256     // this test is to make sure that the list of newly created objects IDs is
257
// accurate in the lookup results
258
initObjectManager();
259
260     Set JavaDoc ids = new HashSet JavaDoc(); // important to use a Set here
261

262     ObjectID id1;
263     ids.add((id1 = new ObjectID(1)));
264     ObjectID id2;
265     ids.add((id2 = new ObjectID(2)));
266     ChannelID key = new ChannelID(0);
267
268     TestResultsContext results = new TestResultsContext(ids, ids);
269     this.objectManager.lookupObjectsForCreateIfNecessary(key, results);
270     assertEquals(2, results.objects.size());
271
272     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
273
274     ManagedObject mo = (ManagedObject) results.objects.get(id1);
275     TestArrayDNA ta;
276     mo.apply((ta = new TestArrayDNA(id1)), new TransactionID(1), new BackReferences(), imo);
277     mo = (ManagedObject) results.objects.get(id2);
278     mo.apply(new TestArrayDNA(id2), new TransactionID(2), new BackReferences(), imo);
279
280     Map JavaDoc ic = imo.getInstanceCounts();
281     assertEquals(1, ic.size());
282     assertEquals(new Integer JavaDoc(2), ic.get(ta.getTypeName()));
283
284     this.objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
285
286     ids.add(new ObjectID(3));
287     ids.add(new ObjectID(4));
288     Set JavaDoc newIDs = new HashSet JavaDoc();
289     newIDs.add(new ObjectID(3));
290     newIDs.add(new ObjectID(4));
291
292     results = new TestResultsContext(ids, newIDs);
293
294     this.objectManager.lookupObjectsForCreateIfNecessary(key, results);
295     assertEquals(4, results.objects.size());
296
297     int count = 100;
298     for (Iterator JavaDoc i = ids.iterator(); i.hasNext();) {
299       ObjectID id = (ObjectID) i.next();
300       mo = (ManagedObject) results.objects.get(id);
301       mo.apply(new TestArrayDNA(id), new TransactionID(count++), new BackReferences(), imo);
302     }
303     ic = imo.getInstanceCounts();
304     assertEquals(1, ic.size());
305     assertEquals(new Integer JavaDoc(4), ic.get(ta.getTypeName()));
306
307     this.objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
308   }
309
310   public void testArrayFacade() throws Exception JavaDoc {
311     initObjectManager();
312
313     ObjectID id = new ObjectID(1);
314     HashSet JavaDoc ids = new HashSet JavaDoc();
315     ids.add(id);
316
317     TestResultsContext responseContext = new TestResultsContext(ids, ids);
318     final Map JavaDoc lookedUpObjects = responseContext.objects;
319
320     this.objectManager.lookupObjectsForCreateIfNecessary(null, responseContext);
321     assertEquals(ids.size(), lookedUpObjects.size());
322
323     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
324     ManagedObject mo = (ManagedObject) lookedUpObjects.get(id);
325     mo.apply(new TestArrayDNA(id), new TransactionID(1), new BackReferences(), imo);
326     objectManager.releaseAll(NULL_TRANSACTION, lookedUpObjects.values());
327
328     ManagedObjectFacade facade;
329
330     facade = objectManager.lookupFacade(id, -1);
331     assertTrue(facade.isArray());
332     assertFalse(facade.isInnerClass());
333     assertFalse(facade.isMap());
334     assertFalse(facade.isList());
335     assertFalse(facade.isSet());
336     assertEquals(3, facade.getArrayLength());
337     assertTrue(Arrays.equals(new String JavaDoc[] { "0", "1", "2" }, facade.getFields()));
338     assertEquals("[Ljava/lang/String;", facade.getClassName());
339
340     for (int i = 0; i < 3; i++) {
341       assertEquals("String", facade.getFieldType("" + i));
342     }
343
344     assertEquals("tim", facade.getFieldValue("0"));
345     assertEquals("is", facade.getFieldValue("1"));
346     assertEquals("here", facade.getFieldValue("2"));
347
348     // test that limit is working okay
349
facade = objectManager.lookupFacade(id, 1);
350     assertEquals(1, facade.getArrayLength());
351     assertEquals("tim", facade.getFieldValue("0"));
352
353     facade = objectManager.lookupFacade(id, 19212);
354     assertEquals(3, facade.getArrayLength());
355     assertEquals("tim", facade.getFieldValue("0"));
356     assertEquals("is", facade.getFieldValue("1"));
357     assertEquals("here", facade.getFieldValue("2"));
358   }
359
360   public void testDateFacades() throws NoSuchObjectException {
361     initObjectManager();
362
363     ObjectID dateID = new ObjectID(1);
364
365     Set JavaDoc ids = new HashSet JavaDoc();
366     ids.add(dateID);
367
368     TestResultsContext responseContext = new TestResultsContext(ids, ids);
369     final Map JavaDoc lookedUpObjects = responseContext.objects;
370
371     this.objectManager.lookupObjectsForCreateIfNecessary(null, responseContext);
372     assertEquals(ids.size(), lookedUpObjects.size());
373
374     ManagedObject dateManagedObject = (ManagedObject) lookedUpObjects.get(dateID);
375
376     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
377     dateManagedObject.apply(new TestDateDNA("java.util.Date", dateID), new TransactionID(1), new BackReferences(), imo);
378
379     objectManager.releaseAll(NULL_TRANSACTION, lookedUpObjects.values());
380
381     ManagedObjectFacade facade;
382
383     facade = objectManager.lookupFacade(dateID, 1);
384     validateDateFacade(facade);
385
386   }
387
388   public void testLiteralFacades() throws NoSuchObjectException {
389     initObjectManager();
390
391     ObjectID literalID = new ObjectID(1);
392
393     Set JavaDoc ids = new HashSet JavaDoc();
394     ids.add(literalID);
395
396     TestResultsContext responseContext = new TestResultsContext(ids, ids);
397     final Map JavaDoc lookedUpObjects = responseContext.objects;
398
399     this.objectManager.lookupObjectsForCreateIfNecessary(null, responseContext);
400     assertEquals(ids.size(), lookedUpObjects.size());
401
402     ManagedObject managedObject = (ManagedObject) lookedUpObjects.get(literalID);
403
404     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
405     managedObject.apply(new TestLiteralValuesDNA(literalID), new TransactionID(1), new BackReferences(), imo);
406
407     objectManager.releaseAll(NULL_TRANSACTION, lookedUpObjects.values());
408
409     ManagedObjectFacade facade;
410
411     facade = objectManager.lookupFacade(literalID, 1);
412     validateLiteralFacade(facade);
413
414   }
415
416   private void validateLiteralFacade(ManagedObjectFacade literalFacade) {
417     assertFalse(literalFacade.isArray());
418     assertFalse(literalFacade.isMap());
419     assertFalse(literalFacade.isSet());
420     assertFalse(literalFacade.isList());
421     assertEquals("java.lang.Integer", literalFacade.getClassName());
422
423     Object JavaDoc value = literalFacade.getFieldValue("java.lang.Integer");
424
425     assertTrue(value instanceof Integer JavaDoc);
426   }
427
428   public void testLogicalFacades() throws NoSuchObjectException {
429     initObjectManager();
430
431     ObjectID mapID = new ObjectID(1);
432     ObjectID listID = new ObjectID(2);
433     ObjectID setID = new ObjectID(3);
434
435     Set JavaDoc ids = new HashSet JavaDoc();
436     ids.add(mapID);
437     ids.add(listID);
438     ids.add(setID);
439
440     TestResultsContext responseContext = new TestResultsContext(ids, ids);
441     final Map JavaDoc lookedUpObjects = responseContext.objects;
442
443     this.objectManager.lookupObjectsForCreateIfNecessary(null, responseContext);
444     assertEquals(ids.size(), lookedUpObjects.size());
445
446     ManagedObject list = (ManagedObject) lookedUpObjects.get(listID);
447     ManagedObject set = (ManagedObject) lookedUpObjects.get(setID);
448     ManagedObject map = (ManagedObject) lookedUpObjects.get(mapID);
449
450     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
451     map.apply(new TestMapDNA(mapID), new TransactionID(1), new BackReferences(), imo);
452     set.apply(new TestListSetDNA("java.util.HashSet", setID), new TransactionID(1), new BackReferences(), imo);
453     list.apply(new TestListSetDNA("java.util.LinkedList", listID), new TransactionID(1), new BackReferences(), imo);
454
455     objectManager.releaseAll(NULL_TRANSACTION, lookedUpObjects.values());
456
457     ManagedObjectFacade facade;
458
459     facade = objectManager.lookupFacade(mapID, -1);
460     validateMapFacade(facade, 3, 3);
461     facade = objectManager.lookupFacade(mapID, 5);
462     validateMapFacade(facade, 3, 3);
463     facade = objectManager.lookupFacade(mapID, 1);
464     validateMapFacade(facade, 1, 3);
465     facade = objectManager.lookupFacade(mapID, 0);
466     validateMapFacade(facade, 0, 3);
467
468     facade = objectManager.lookupFacade(setID, -1);
469     validateSetFacade(facade, 3, 3);
470     facade = objectManager.lookupFacade(setID, 5);
471     validateSetFacade(facade, 3, 3);
472     facade = objectManager.lookupFacade(setID, 1);
473     validateSetFacade(facade, 1, 3);
474     facade = objectManager.lookupFacade(setID, 0);
475     validateSetFacade(facade, 0, 3);
476
477     facade = objectManager.lookupFacade(listID, -1);
478     validateListFacade(facade, 3, 3);
479     facade = objectManager.lookupFacade(listID, 5);
480     validateListFacade(facade, 3, 3);
481     facade = objectManager.lookupFacade(listID, 1);
482     validateListFacade(facade, 1, 3);
483     facade = objectManager.lookupFacade(listID, 0);
484     validateListFacade(facade, 0, 3);
485
486   }
487
488   private void validateListFacade(ManagedObjectFacade listFacade, int facadeSize, int totalSize) {
489     assertFalse(listFacade.isArray());
490     assertFalse(listFacade.isMap());
491     assertFalse(listFacade.isSet());
492     assertTrue(listFacade.isList());
493     assertEquals("java.util.LinkedList", listFacade.getClassName());
494     assertEquals(facadeSize, listFacade.getFacadeSize());
495     assertEquals(totalSize, listFacade.getTrueObjectSize());
496
497     for (int i = 0; i < facadeSize; i++) {
498       String JavaDoc fName = String.valueOf(i);
499       Object JavaDoc value = listFacade.getFieldValue(fName);
500       assertTrue(value instanceof String JavaDoc);
501       assertEquals("item" + (i + 1), value);
502     }
503   }
504
505   private void validateSetFacade(ManagedObjectFacade setFacade, int facadeSize, int totalSize) {
506     assertFalse(setFacade.isArray());
507     assertFalse(setFacade.isMap());
508     assertTrue(setFacade.isSet());
509     assertFalse(setFacade.isList());
510     assertEquals("java.util.HashSet", setFacade.getClassName());
511     assertEquals(facadeSize, setFacade.getFacadeSize());
512     assertEquals(totalSize, setFacade.getTrueObjectSize());
513
514     Set JavaDoc expect = new HashSet JavaDoc();
515     expect.add("item1");
516     expect.add("item2");
517     expect.add("item3");
518
519     Set JavaDoc actual = new HashSet JavaDoc();
520     for (int i = 0; i < facadeSize; i++) {
521       String JavaDoc fName = String.valueOf(i);
522       Object JavaDoc value = setFacade.getFieldValue(fName);
523       assertTrue(value instanceof String JavaDoc);
524       actual.add(value);
525     }
526
527     assertTrue(expect.containsAll(actual));
528   }
529
530   private void validateMapFacade(ManagedObjectFacade mapFacade, int facadeSize, int totalSize) {
531     assertFalse(mapFacade.isArray());
532     assertTrue(mapFacade.isMap());
533     assertFalse(mapFacade.isSet());
534     assertFalse(mapFacade.isList());
535     assertEquals("java.util.HashMap", mapFacade.getClassName());
536     assertEquals(facadeSize, mapFacade.getFacadeSize());
537     assertEquals(totalSize, mapFacade.getTrueObjectSize());
538
539     Map JavaDoc expect = new HashMap JavaDoc();
540     expect.put("key1", "val1");
541     expect.put("key2", "val2");
542     expect.put("key3", "val3");
543
544     Map JavaDoc actual = new HashMap JavaDoc();
545
546     for (int i = 0; i < facadeSize; i++) {
547       String JavaDoc fName = String.valueOf(i);
548       Object JavaDoc value = mapFacade.getFieldValue(fName);
549       assertTrue(value instanceof MapEntryFacade);
550       MapEntryFacade entry = (MapEntryFacade) value;
551       actual.put(entry.getKey(), entry.getValue());
552     }
553
554     for (Iterator JavaDoc iter = actual.keySet().iterator(); iter.hasNext();) {
555       Object JavaDoc key = iter.next();
556       assertEquals(expect.get(key), actual.get(key));
557     }
558   }
559
560   private void validateDateFacade(ManagedObjectFacade dateFacade) {
561     assertFalse(dateFacade.isArray());
562     assertFalse(dateFacade.isMap());
563     assertFalse(dateFacade.isSet());
564     assertFalse(dateFacade.isList());
565     assertEquals("java.util.Date", dateFacade.getClassName());
566
567     Object JavaDoc value = dateFacade.getFieldValue("date");
568
569     assertTrue(value instanceof Date JavaDoc);
570   }
571
572   private DBEnvironment newDBEnvironment(boolean paranoid) throws Exception JavaDoc {
573     File JavaDoc dbHome;
574     int count = 0;
575     do {
576       dbHome = new File JavaDoc(this.getTempDirectory(), getClass().getName() + "db" + (++count));
577     } while (dbHome.exists());
578     dbHome.mkdir();
579     assertTrue(dbHome.exists());
580     assertTrue(dbHome.isDirectory());
581     System.out.println("DB Home: " + dbHome);
582     DBEnvironment env = new DBEnvironment(paranoid, dbHome);
583     return env;
584   }
585
586   private Persistor newPersistor(boolean paranoid, DBEnvironment dbEnv,
587                                  SerializationAdapterFactory serializationAdapterFactory) throws Exception JavaDoc {
588     Persistor persistor = new SleepycatPersistor(logger, dbEnv, serializationAdapterFactory);
589     return persistor;
590   }
591
592   private SerializationAdapterFactory newSleepycatSerializationAdapterFactory(DBEnvironment dbEnv) {
593     return new SleepycatSerializationAdapterFactory();
594   }
595
596   private SerializationAdapterFactory newCustomSerializationAdapterFactory() {
597     return new CustomSerializationAdapterFactory();
598   }
599
600   public void testLookupInPersistentContext() throws Exception JavaDoc {
601     boolean paranoid = false;
602     // sleepycat serializer, not paranoid
603
DBEnvironment dbEnv = newDBEnvironment(paranoid);
604     SerializationAdapterFactory saf = newSleepycatSerializationAdapterFactory(dbEnv);
605     Persistor persistor = newPersistor(paranoid, dbEnv, saf);
606
607     testLookupInPersistentContext(persistor, paranoid);
608
609     // custom serializer, not paranoid
610
dbEnv = newDBEnvironment(paranoid);
611     saf = newCustomSerializationAdapterFactory();
612     persistor = newPersistor(paranoid, dbEnv, saf);
613     testLookupInPersistentContext(persistor, paranoid);
614
615     // sleepycat serializer, paranoid
616
paranoid = true;
617     dbEnv = newDBEnvironment(paranoid);
618     saf = newSleepycatSerializationAdapterFactory(dbEnv);
619     persistor = newPersistor(paranoid, dbEnv, saf);
620     testLookupInPersistentContext(persistor, paranoid);
621
622     // custom serializer, paranoid
623
dbEnv = newDBEnvironment(paranoid);
624     saf = newCustomSerializationAdapterFactory();
625     persistor = newPersistor(paranoid, dbEnv, saf);
626     testLookupInPersistentContext(persistor, paranoid);
627   }
628
629   private void testLookupInPersistentContext(Persistor persistor, boolean paranoid) throws Exception JavaDoc {
630     ManagedObjectPersistor mop = persistor.getManagedObjectPersistor();
631     PersistenceTransactionProvider ptp = persistor.getPersistenceTransactionProvider();
632     PersistentManagedObjectStore store = new PersistentManagedObjectStore(mop);
633     TestSink faultSink = new TestSink();
634     TestSink flushSink = new TestSink();
635     config.paranoid = paranoid;
636     objectManager = new ObjectManagerImpl(config, createThreadGroup(), clientStateManager, store,
637                                           new LRUEvictionPolicy(100), persistenceTransactionProvider, faultSink,
638                                           flushSink, new MockObjectManagementMonitor());
639     new TestMOFaulter(this.objectManager, store, faultSink).start();
640     new TestMOFlusher(this.objectManager, flushSink).start();
641
642     ObjectID id = new ObjectID(1);
643     Set JavaDoc ids = new HashSet JavaDoc();
644     ids.add(id);
645     ChannelID key = new ChannelID(0);
646
647     TestResultsContext responseContext = new TestResultsContext(ids, ids);
648     Map JavaDoc lookedUpObjects = responseContext.objects;
649
650     objectManager.lookupObjectsForCreateIfNecessary(key, responseContext);
651
652     ManagedObject lookedUpViaLookupObjectsForCreateIfNecessary = (ManagedObject) lookedUpObjects.get(id);
653
654     final String JavaDoc fieldName = "myField";
655     final List JavaDoc countSlot = new ArrayList JavaDoc(1);
656     countSlot.add(new Integer JavaDoc(1));
657     final List JavaDoc fieldValueSlot = new ArrayList JavaDoc(1);
658     fieldValueSlot.add(new ObjectID(100));
659
660     DNACursor cursor = new DNACursor() {
661       public LogicalAction getLogicalAction() {
662         return null;
663       }
664
665       public PhysicalAction getPhysicalAction() {
666         return new PhysicalAction(fieldName, fieldValueSlot.get(0), true);
667       }
668
669       public boolean next() {
670         int count = ((Integer JavaDoc) countSlot.get(0)).intValue();
671         count--;
672         countSlot.set(0, new Integer JavaDoc(count));
673         return count >= 0;
674       }
675
676       public boolean next(DNAEncoding encoding) {
677         throw new ImplementMe();
678       }
679
680       public Object JavaDoc getAction() {
681         throw new ImplementMe();
682       }
683
684       public int getActionCount() {
685         return 1;
686       }
687
688       public void reset() throws UnsupportedOperationException JavaDoc {
689         countSlot.set(0, new Integer JavaDoc(1));
690       }
691     };
692
693     DNA dna = new TestDNA(cursor);
694
695     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
696     lookedUpViaLookupObjectsForCreateIfNecessary.apply(dna, new TransactionID(1), new BackReferences(), imo);
697
698     PersistenceTransaction tx = ptp.newTransaction();
699     objectManager.release(tx, lookedUpViaLookupObjectsForCreateIfNecessary);
700     tx.commit();
701
702     ManagedObject lookedUpViaLookup = objectManager.getObjectByID(id);
703     assertEquals(1, lookedUpViaLookupObjectsForCreateIfNecessary.getObjectReferences().size());
704     assertEquals(lookedUpViaLookup.getObjectReferences(), lookedUpViaLookupObjectsForCreateIfNecessary
705         .getObjectReferences());
706
707     tx = ptp.newTransaction();
708     objectManager.release(tx, lookedUpViaLookup);
709     tx.commit();
710
711     // now do another lookup, change, and commit cycle
712
responseContext = new TestResultsContext(ids, Collections.EMPTY_SET);
713     lookedUpObjects = responseContext.objects;
714
715     objectManager.lookupObjectsForCreateIfNecessary(key, responseContext);
716     lookedUpViaLookupObjectsForCreateIfNecessary = (ManagedObject) lookedUpObjects.get(id);
717     countSlot.set(0, new Integer JavaDoc(1));
718     ObjectID newReferenceID = new ObjectID(9324);
719     fieldValueSlot.set(0, newReferenceID);
720     dna = new TestDNA(cursor);
721     lookedUpViaLookupObjectsForCreateIfNecessary.apply(dna, new TransactionID(2), new BackReferences(), imo);
722     // lookedUpViaLookupObjectsForCreateIfNecessary.commit();
723
tx = ptp.newTransaction();
724     objectManager.release(tx, lookedUpViaLookupObjectsForCreateIfNecessary);
725     tx.commit();
726
727     lookedUpViaLookup = objectManager.getObjectByID(id);
728     assertEquals(1, lookedUpViaLookupObjectsForCreateIfNecessary.getObjectReferences().size());
729     assertTrue(lookedUpViaLookupObjectsForCreateIfNecessary.getObjectReferences().contains(newReferenceID));
730
731     assertEquals(lookedUpViaLookup.getObjectReferences(), lookedUpViaLookupObjectsForCreateIfNecessary
732         .getObjectReferences());
733
734     // to work around timing problem with this test, let's look up some object id...
735
// this should block this thread until trasaction reading all object ids from bdb completes,
736
// at which point, it's ok to close the DB
737
persistor.getManagedObjectPersistor().getAllObjectIDs().size();
738     store.shutdown();
739     persistor.close();
740   }
741
742   public void testExplodingGarbageCollector() throws Exception JavaDoc {
743     LinkedQueue exceptionQueue = new LinkedQueue();
744     TestThreadGroup tg = new TestThreadGroup(exceptionQueue);
745     initObjectManager(tg);
746     RuntimeException JavaDoc toThrow = new RuntimeException JavaDoc();
747     this.objectManager.setGarbageCollector(new ExplodingGarbageCollector(toThrow));
748     this.objectManager.start();
749     Object JavaDoc o = exceptionQueue.poll(30 * 1000);
750     assertEquals(toThrow, o);
751   }
752
753   public void testObjectManagerBasics() {
754     initObjectManager();
755     final ObjectID id = new ObjectID(0);
756     ManagedObject mo = new TestManagedObject(id, new ObjectID[0]);
757     objectManager.createObject(mo);
758     assertFalse(objectManager.isReferenced(id));
759     ManagedObject mo2 = objectManager.getObjectByID(id);
760     assertTrue(mo == mo2);
761     assertTrue(objectManager.isReferenced(id));
762     objectManager.release(NULL_TRANSACTION, mo);
763     assertFalse(objectManager.isReferenced(id));
764
765     objectManager.getObjectByID(id);
766
767     final boolean[] gotIt = new boolean[1];
768     gotIt[0] = false;
769
770     Thread JavaDoc t = new Thread JavaDoc() {
771       public void run() {
772         objectManager.getObjectByID(id);
773         gotIt[0] = true;
774       }
775     };
776
777     t.start();
778     ThreadUtil.reallySleep(1000);
779     assertFalse(gotIt[0]);
780     objectManager.release(NULL_TRANSACTION, mo);
781     ThreadUtil.reallySleep(1000);
782     assertTrue(gotIt[0]);
783   }
784
785   public void testPhysicalObjectFacade() throws Exception JavaDoc {
786     testPhysicalObjectFacade(false);
787     testPhysicalObjectFacade(true);
788   }
789
790   private void testPhysicalObjectFacade(boolean paranoid) throws Exception JavaDoc {
791     DBEnvironment dbEnv = newDBEnvironment(paranoid);
792     SerializationAdapterFactory saf = newCustomSerializationAdapterFactory();
793     Persistor persistor = newPersistor(paranoid, dbEnv, saf);
794     PersistenceTransactionProvider ptp = persistor.getPersistenceTransactionProvider();
795     this.objectStore = new PersistentManagedObjectStore(persistor.getManagedObjectPersistor());
796     this.config.paranoid = paranoid;
797     initObjectManager(new TCThreadGroup(new ThrowableHandler(TCLogging.getTestingLogger(getClass()))), new NullCache(),
798                       this.objectStore);
799
800     HashSet JavaDoc oids = new HashSet JavaDoc();
801     oids.add(new ObjectID(1));
802
803     final TestResultsContext context = new TestResultsContext(oids, oids);
804     this.objectManager.lookupObjectsForCreateIfNecessary(null, context);
805     context.waitTillComplete();
806     ManagedObject mo = (ManagedObject) (context.objects).get(new ObjectID(1));
807     assertTrue(mo.isNew());
808     ObjectInstanceMonitor imo = new ObjectInstanceMonitorImpl();
809     mo.apply(new TestPhysicalDNA(new ObjectID(1)), new TransactionID(1), new BackReferences(), imo);
810
811     PersistenceTransaction tx = ptp.newTransaction();
812     this.objectManager.release(tx, mo);
813     tx.commit();
814
815     ManagedObjectFacade facade;
816     try {
817       facade = this.objectManager.lookupFacade(new ObjectID(1), -1);
818     } catch (NoSuchObjectException e1) {
819       fail(e1.getMessage());
820       return;
821     }
822
823     String JavaDoc[] fieldNames = facade.getFields();
824     assertEquals(6, fieldNames.length);
825     // NOTE: the order of the object fields should be alphabetic
826
assertTrue(Arrays.asList(fieldNames).toString(), Arrays.equals(fieldNames, new String JavaDoc[] { "access$0", "this$0",
827         "intField", "objField", "stringField", "zzzField" }));
828     assertEquals("TestPhysicalDNA.class.name", facade.getClassName());
829     assertEquals("Integer", facade.getFieldType("intField"));
830     assertEquals("ObjectID", facade.getFieldType("objField"));
831     assertEquals("Byte", facade.getFieldType("zzzField"));
832     assertEquals("String", facade.getFieldType("stringField"));
833     assertEquals(new Integer JavaDoc(42), facade.getFieldValue("intField"));
834     assertEquals(new Byte JavaDoc((byte) 1), facade.getFieldValue("zzzField"));
835     assertEquals(new ObjectID(696969), facade.getFieldValue("objField"));
836     assertEquals("yo yo yo", facade.getFieldValue("stringField"));
837     assertEquals(new ObjectID(1), facade.getObjectId());
838     assertTrue(facade.isPrimitive("intField"));
839     assertTrue(facade.isPrimitive("zzzField"));
840     assertTrue(facade.isPrimitive("stringField"));
841     assertFalse(facade.isPrimitive("objField"));
842
843     try {
844       facade.getFieldType("does not exist");
845       fail();
846     } catch (IllegalArgumentException JavaDoc iae) {
847       // expected
848
}
849
850     try {
851       facade.getFieldValue("does not exist");
852       fail();
853     } catch (IllegalArgumentException JavaDoc iae) {
854       // expected
855
}
856
857     try {
858       facade.isPrimitive("does not exist");
859       fail();
860     } catch (IllegalArgumentException JavaDoc iae) {
861       // expected
862
}
863
864     this.objectStore.shutdown();
865
866     // XXX: change the object again, make sure the facade is "stable" (ie.
867
// doesn't change)
868
}
869
870   public void testObjectManagerAsync() {
871     initObjectManager();
872     final ObjectID id = new ObjectID(0);
873     final ObjectID id1 = new ObjectID(1);
874
875     Set JavaDoc objectIDs = new HashSet JavaDoc();
876
877     ManagedObject mo = new TestManagedObject(id, new ObjectID[0]);
878     ManagedObject mo1 = new TestManagedObject(id1, new ObjectID[0]);
879     objectManager.createObject(mo);
880     objectManager.createObject(mo1);
881
882     assertFalse(objectManager.isReferenced(id));
883
884     objectIDs.add(id);
885
886     TestObjectManagerResultsContext context;
887     assertTrue(objectManager
888         .lookupObjectsAndSubObjectsFor(null, context = new TestObjectManagerResultsContext(new HashMap JavaDoc(), objectIDs),
889                                        -1));
890
891     ManagedObject retrievedMo = (ManagedObject) context.getResults().values().iterator().next();
892     assertTrue(mo == retrievedMo);
893     assertTrue(objectManager.isReferenced(id));
894     objectManager.release(NULL_TRANSACTION, mo);
895     assertFalse(objectManager.isReferenced(id));
896
897     objectManager.getObjectByID(id);
898
899     objectIDs.add(id1);
900
901     boolean notPending = objectManager
902         .lookupObjectsAndSubObjectsFor(null, context = new TestObjectManagerResultsContext(new HashMap JavaDoc(), objectIDs),
903                                        -1);
904     assertFalse(notPending);
905     assertEquals(0, context.getResults().size());
906     objectManager.release(NULL_TRANSACTION, mo);
907     assertEquals(objectIDs.size(), context.getResults().size());
908
909     Collection JavaDoc objs = context.getResults().values();
910     assertTrue(objs.contains(mo));
911     assertTrue(objs.contains(mo1));
912     assertTrue(objs.size() == 2);
913   }
914
915   public void testNewObjectCounter() {
916     initObjectManager();
917     objectManager.setStatsListener(stats);
918     createObjects(666);
919     assertEquals(666, stats.getTotalObjectsCreated());
920     assertEquals(666, newObjectCounter.getValue());
921
922     // roots count as "new" objects too
923
objectManager.createRoot("root", new ObjectID(4444));
924     assertEquals(667, stats.getTotalObjectsCreated());
925     assertEquals(667, newObjectCounter.getValue());
926   }
927
928   public void testCacheStats() throws Exception JavaDoc {
929     config.paranoid = true;
930     initObjectManager(new TCThreadGroup(new ThrowableHandler(TCLogging.getTestingLogger(getClass()))),
931                       new LRUEvictionPolicy(-1));
932     objectManager.setStatsListener(this.stats);
933
934     assertEquals(0, stats.getTotalRequests());
935     assertEquals(0, stats.getTotalCacheHits());
936     assertEquals(0, stats.getTotalCacheMisses());
937
938     createObjects(50, 10);
939     Set JavaDoc ids = makeObjectIDSet(0, 10);
940     // ThreadUtil.reallySleep(5000);
941
TestResultsContext results = new TestResultsContext(ids, Collections.EMPTY_SET);
942
943     objectManager.lookupObjectsAndSubObjectsFor(null, results, -1);
944     results.waitTillComplete();
945     objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
946
947     assertEquals(10, stats.getTotalRequests());
948     assertEquals(0, stats.getTotalCacheHits());
949     assertEquals(10, stats.getTotalCacheMisses());
950
951     results = new TestResultsContext(ids, Collections.EMPTY_SET);
952     objectManager.lookupObjectsAndSubObjectsFor(null, results, -1);
953     results.waitTillComplete();
954     objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
955     assertEquals(20, stats.getTotalRequests());
956     assertEquals(10, stats.getTotalCacheHits());
957     assertEquals(10, stats.getTotalCacheMisses());
958
959     ids = makeObjectIDSet(10, 20);
960     results = new TestResultsContext(ids, Collections.EMPTY_SET);
961     objectManager.lookupObjectsAndSubObjectsFor(null, results, -1);
962     results.waitTillComplete();
963     objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
964     assertEquals(30, stats.getTotalRequests());
965     assertEquals(10, stats.getTotalCacheHits());
966     assertEquals(20, stats.getTotalCacheMisses());
967
968     evictCache(10);
969
970     ids = makeObjectIDSet(14, 4);
971     results = new TestResultsContext(ids, Collections.EMPTY_SET);
972     objectManager.lookupObjectsAndSubObjectsFor(null, results, -1);
973     results.waitTillComplete();
974     objectManager.releaseAll(NULL_TRANSACTION, results.objects.values());
975     assertEquals(40, stats.getTotalRequests());
976     assertEquals(15, stats.getTotalCacheHits());
977     assertEquals(25, stats.getTotalCacheMisses());
978
979     double hitRate = ((double) 15) / ((double) 40);
980     assertEquals(hitRate, stats.getCacheHitRatio(), 0D);
981   }
982
983   private void evictCache(int inCache) {
984     TestCacheStats tc = new TestCacheStats();
985     tc.toKeep = inCache;
986     objectManager.evictCache(tc);
987     tc.validate();
988   }
989
990   private void createObjects(int num, int inCache) {
991     createObjects(num);
992     evictCache(inCache);
993   }
994
995   private Set JavaDoc makeObjectIDSet(int begin, int end) {
996     Set JavaDoc rv = new HashSet JavaDoc();
997
998     if (begin > end) {
999       for (int i = begin; i > end; i--) {
1000        rv.add(new ObjectID(i));
1001      }
1002    } else {
1003      for (int i = begin; i < end; i++) {
1004        rv.add(new ObjectID(i));
1005      }
1006    }
1007    return rv;
1008  }
1009
1010  private void createObjects(int num) {
1011    for (int i = 0; i < num; i++) {
1012      TestManagedObject mo = new TestManagedObject(new ObjectID(i), new ObjectID[] {});
1013      objectManager.createObject(mo);
1014    }
1015  }
1016
1017  public void testGCStats() {
1018    initObjectManager();
1019
1020    // this should disable the internal gc thread, allowing us to control when
1021
// objMgr.gc() happens
1022
this.config.myGCThreadSleepTime = -1;
1023
1024    GarbageCollector gc = new MarkAndSweepGarbageCollector(objectManager, clientStateManager, true);
1025    objectManager.setGarbageCollector(gc);
1026
1027    Listener listener = new Listener();
1028    this.objectManager.addListener(listener);
1029
1030    objectManager.createRoot("root-me", new ObjectID(0));
1031    ManagedObject root = new TestManagedObject(new ObjectID(0), new ObjectID[] { new ObjectID(1) });
1032    objectManager.createObject(root);
1033
1034    TestManagedObject mo1 = new TestManagedObject(new ObjectID(1), new ObjectID[] { new ObjectID(2) });
1035    TestManagedObject mo2 = new TestManagedObject(new ObjectID(2), new ObjectID[] { new ObjectID(3) });
1036    TestManagedObject mo3 = new TestManagedObject(new ObjectID(3), new ObjectID[] {});
1037    objectManager.createObject(mo1);
1038    objectManager.createObject(mo2);
1039    objectManager.createObject(mo3);
1040
1041    ChannelID cid1 = new ChannelID(1);
1042    clientStateManager.addReference(cid1, root.getID());
1043    clientStateManager.addReference(cid1, mo1.getID());
1044    clientStateManager.addReference(cid1, mo2.getID());
1045    clientStateManager.addReference(cid1, mo3.getID());
1046
1047    assertEquals(0, objectManager.getGarbageCollectorStats().length);
1048    assertEquals(0, listener.gcEvents.size());
1049
1050    long start = System.currentTimeMillis();
1051
1052    objectManager.gc();
1053
1054    assertEquals(1, objectManager.getGarbageCollectorStats().length);
1055    assertEquals(1, listener.gcEvents.size());
1056
1057    GCStats stats1 = (GCStats) listener.gcEvents.get(0);
1058    final int firstIterationNumber = stats1.getIteration();
1059    assertSame(stats1, objectManager.getGarbageCollectorStats()[0]);
1060    assertTrue("external: " + start + ", reported: " + stats1.getStartTime(), stats1.getStartTime() >= start);
1061    assertTrue(String.valueOf(stats1.getElapsedTime()), stats1.getElapsedTime() >= 0);
1062    assertEquals(4, stats1.getBeginObjectCount());
1063    assertEquals(0, stats1.getCandidateGarbageCount());
1064    assertEquals(0, stats1.getActualGarbageCount());
1065
1066    listener.gcEvents.clear();
1067    objectManager.gc();
1068    assertEquals(2, objectManager.getGarbageCollectorStats().length);
1069    assertEquals(1, listener.gcEvents.size());
1070    assertEquals(firstIterationNumber + 1, objectManager.getGarbageCollectorStats()[0].getIteration());
1071
1072    listener.gcEvents.clear();
1073    Set JavaDoc removed = new HashSet JavaDoc();
1074    removed.add(mo3.getID());
1075    clientStateManager.removeReferences(cid1, removed);
1076    mo2.setReferences(new ObjectID[] {});
1077    objectManager.gc();
1078    assertEquals(3, objectManager.getGarbageCollectorStats().length);
1079    assertEquals(1, listener.gcEvents.size());
1080    GCStats stats3 = (GCStats) listener.gcEvents.get(0);
1081    assertEquals(4, stats3.getBeginObjectCount());
1082    assertEquals(1, stats3.getActualGarbageCount());
1083    assertEquals(1, stats3.getCandidateGarbageCount());
1084  }
1085
1086  public void testLookupFacadeForMissingObject() {
1087    initObjectManager();
1088
1089    try {
1090      this.objectManager.lookupFacade(new ObjectID(1), -1);
1091      fail("lookup didn't throw exception");
1092    } catch (NoSuchObjectException e) {
1093      // expected
1094
}
1095  }
1096
1097  public void testObjectManagerGC() throws Exception JavaDoc {
1098    initObjectManager();
1099    // this should disable the gc thread.
1100
this.config.myGCThreadSleepTime = -1;
1101    TestGarbageCollector gc = new TestGarbageCollector(objectManager);
1102    objectManager.setGarbageCollector(gc);
1103    final ObjectID id = new ObjectID(0);
1104    ManagedObject mo = new TestManagedObject(id, new ObjectID[3]);
1105    objectManager.createObject(mo);
1106
1107    assertFalse(gc.isCollected());
1108
1109    gc.allow_blockUntilReadyToGC_ToProceed();
1110
1111    objectManager.gc();
1112    assertTrue(gc.isCollected());
1113
1114    gc.reset();
1115
1116    // call lookup to check out an object...
1117
objectManager.getObjectByID(id);
1118
1119    // make sure our queues are clean
1120
assertFalse(gc.collectWasCalled());
1121    assertFalse(gc.blockUntilReadyToGC_WasCalled());
1122
1123    Thread JavaDoc gcCaller = new Thread JavaDoc(new GCCaller(), "GCCaller");
1124    gcCaller.start();
1125
1126    // give the thread some time to start and call collect()...
1127
assertTrue(gc.waitForCollectToBeCalled(5000));
1128
1129    // give the thread some time to call blockUntilReadyToGC()...
1130
assertTrue(gc.waitFor_blockUntilReadyToGC_ToBeCalled(5000));
1131
1132    // ////////////////////////////////////////////////////
1133
// now call release and make sure it calls the appropriate GC methods...
1134

1135    assertFalse(gc.notifyReadyToGC_WasCalled());
1136    objectManager.release(NULL_TRANSACTION, mo);
1137
1138    // make sure release calls notifyReadyToGC
1139
assertTrue(gc.waitFor_notifyReadyToGC_ToBeCalled(5000));
1140
1141    // unblock the caller...
1142
gc.allow_blockUntilReadyToGC_ToProceed();
1143
1144    // make sure the object manager calls notifyGCComplete
1145
assertTrue(gc.waitFor_notifyGCComplete_ToBeCalled(5000));
1146    gcCaller.join();
1147  }
1148
1149  private static class TestArrayDNA implements DNA {
1150
1151    private final ObjectID id;
1152
1153    public TestArrayDNA(ObjectID id) {
1154      this.id = id;
1155    }
1156
1157    public long getVersion() {
1158      return 0;
1159    }
1160
1161    public boolean hasLength() {
1162      return true;
1163    }
1164
1165    public int getArraySize() {
1166      return 3;
1167    }
1168
1169    public String JavaDoc getDefiningLoaderDescription() {
1170      return "";
1171    }
1172
1173    public String JavaDoc getTypeName() {
1174      return "[Ljava/lang/String;";
1175    }
1176
1177    public ObjectID getObjectID() throws DNAException {
1178      return id;
1179    }
1180
1181    public ObjectID getParentObjectID() throws DNAException {
1182      return ObjectID.NULL_ID;
1183    }
1184
1185    public DNACursor getCursor() {
1186      return new DNACursor() {
1187        int count = 0;
1188
1189        public boolean next() {
1190          count++;
1191          return count <= 2;
1192        }
1193
1194        public LogicalAction getLogicalAction() {
1195          throw new ImplementMe();
1196        }
1197
1198        public Object JavaDoc getAction() {
1199          throw new ImplementMe();
1200        }
1201
1202        public PhysicalAction getPhysicalAction() {
1203          switch (count) {
1204            case 1:
1205              return new PhysicalAction(new String JavaDoc[] { "tim", "was", "here" });
1206            case 2:
1207              return new PhysicalAction(1, "is", false);
1208            default:
1209              throw new RuntimeException JavaDoc("bad count: " + count);
1210          }
1211        }
1212
1213        public boolean next(DNAEncoding encoding) {
1214          throw new ImplementMe();
1215        }
1216
1217        public int getActionCount() {
1218          return 2;
1219        }
1220
1221        public void reset() throws UnsupportedOperationException JavaDoc {
1222          throw new ImplementMe();
1223        }
1224      };
1225    }
1226
1227    public boolean isDelta() {
1228      return false;
1229    }
1230  }
1231
1232  private static class TestListSetDNA implements DNA {
1233
1234    final ObjectID setID;
1235    final String JavaDoc className;
1236
1237    public TestListSetDNA(String JavaDoc className, ObjectID setID) {
1238      this.className = className;
1239      this.setID = setID;
1240    }
1241
1242    public long getVersion() {
1243      return 0;
1244    }
1245
1246    public boolean hasLength() {
1247      return false;
1248    }
1249
1250    public int getArraySize() {
1251      return -1;
1252    }
1253
1254    public String JavaDoc getDefiningLoaderDescription() {
1255      return "";
1256    }
1257
1258    public String JavaDoc getTypeName() {
1259      return this.className;
1260    }
1261
1262    public ObjectID getObjectID() throws DNAException {
1263      return this.setID;
1264    }
1265
1266    public ObjectID getParentObjectID() throws DNAException {
1267      return ObjectID.NULL_ID;
1268    }
1269
1270    public DNACursor getCursor() {
1271      return new DNACursor() {
1272        int count;
1273
1274        public boolean next() {
1275          count++;
1276          return count <= 3;
1277        }
1278
1279        public LogicalAction getLogicalAction() {
1280          switch (count) {
1281            case 1:
1282            case 2:
1283            case 3:
1284              Object JavaDoc item = new UTF8ByteDataHolder("item" + count);
1285              return new LogicalAction(SerializationUtil.ADD, new Object JavaDoc[] { item });
1286            default:
1287              throw new RuntimeException JavaDoc("bad count: " + count);
1288          }
1289        }
1290
1291        public PhysicalAction getPhysicalAction() {
1292          throw new ImplementMe();
1293        }
1294
1295        public boolean next(DNAEncoding encoding) {
1296          throw new ImplementMe();
1297        }
1298
1299        public Object JavaDoc getAction() {
1300          throw new ImplementMe();
1301        }
1302
1303        public int getActionCount() {
1304          return 3;
1305        }
1306
1307        public void reset() throws UnsupportedOperationException JavaDoc {
1308          throw new ImplementMe();
1309        }
1310      };
1311    }
1312
1313    public boolean isDelta() {
1314      return false;
1315    }
1316
1317  }
1318
1319  private static class TestMapDNA implements DNA {
1320
1321    final ObjectID objectID;
1322
1323    TestMapDNA(ObjectID id) {
1324      this.objectID = id;
1325    }
1326
1327    public long getVersion() {
1328      return 0;
1329    }
1330
1331    public boolean hasLength() {
1332      return false;
1333    }
1334
1335    public int getArraySize() {
1336      return -1;
1337    }
1338
1339    public String JavaDoc getDefiningLoaderDescription() {
1340      return "";
1341    }
1342
1343    public String JavaDoc getTypeName() {
1344      return "java.util.HashMap";
1345    }
1346
1347    public ObjectID getObjectID() throws DNAException {
1348      return this.objectID;
1349    }
1350
1351    public ObjectID getParentObjectID() throws DNAException {
1352      return ObjectID.NULL_ID;
1353    }
1354
1355    public DNACursor getCursor() {
1356      return new DNACursor() {
1357
1358        int count = 0;
1359
1360        public boolean next() {
1361          count++;
1362          return count <= 3;
1363        }
1364
1365        public LogicalAction getLogicalAction() {
1366          switch (count) {
1367            case 1:
1368            case 2:
1369            case 3:
1370              Object JavaDoc key = new UTF8ByteDataHolder("key" + count);
1371              Object JavaDoc val = new UTF8ByteDataHolder("val" + count);
1372              return new LogicalAction(SerializationUtil.PUT, new Object JavaDoc[] { key, val });
1373            default:
1374              throw new RuntimeException JavaDoc("bad count: " + count);
1375          }
1376        }
1377
1378        public PhysicalAction getPhysicalAction() {
1379          throw new ImplementMe();
1380        }
1381
1382        public boolean next(DNAEncoding encoding) {
1383          throw new ImplementMe();
1384        }
1385
1386        public Object JavaDoc getAction() {
1387          throw new ImplementMe();
1388        }
1389
1390        public int getActionCount() {
1391          return 3;
1392        }
1393
1394        public void reset() throws UnsupportedOperationException JavaDoc {
1395          throw new ImplementMe();
1396        }
1397      };
1398    }
1399
1400    public boolean isDelta() {
1401      return false;
1402    }
1403
1404  }
1405
1406  private static class TestDateDNA implements DNA {
1407
1408    final ObjectID setID;
1409    final String JavaDoc className;
1410
1411    public TestDateDNA(String JavaDoc className, ObjectID setID) {
1412      this.className = className;
1413      this.setID = setID;
1414    }
1415
1416    public long getVersion() {
1417      return 0;
1418    }
1419
1420    public boolean hasLength() {
1421      return false;
1422    }
1423
1424    public int getArraySize() {
1425      return -1;
1426    }
1427
1428    public String JavaDoc getDefiningLoaderDescription() {
1429      return "";
1430    }
1431
1432    public String JavaDoc getTypeName() {
1433      return this.className;
1434    }
1435
1436    public ObjectID getObjectID() throws DNAException {
1437      return this.setID;
1438    }
1439
1440    public ObjectID getParentObjectID() throws DNAException {
1441      return ObjectID.NULL_ID;
1442    }
1443
1444    public DNACursor getCursor() {
1445      return new DNACursor() {
1446        int count;
1447
1448        public boolean next() {
1449          count++;
1450          return count <= 1;
1451        }
1452
1453        public LogicalAction getLogicalAction() {
1454          switch (count) {
1455            case 1:
1456              return new LogicalAction(SerializationUtil.SET_TIME,
1457                                       new Object JavaDoc[] { new Long JavaDoc(System.currentTimeMillis()) });
1458            default:
1459              throw new RuntimeException JavaDoc("bad count: " + count);
1460          }
1461        }
1462
1463        public PhysicalAction getPhysicalAction() {
1464          throw new ImplementMe();
1465        }
1466
1467        public boolean next(DNAEncoding encoding) {
1468          throw new ImplementMe();
1469        }
1470
1471        public Object JavaDoc getAction() {
1472          throw new ImplementMe();
1473        }
1474
1475        public int getActionCount() {
1476          return 1;
1477        }
1478
1479        public void reset() throws UnsupportedOperationException JavaDoc {
1480          throw new ImplementMe();
1481        }
1482      };
1483    }
1484
1485    public boolean isDelta() {
1486      return false;
1487    }
1488
1489  }
1490
1491  private static class TestResultsContext implements ObjectManagerResultsContext {
1492    public Map JavaDoc objects = new HashMap JavaDoc();
1493    boolean complete = false;
1494    private final Set JavaDoc ids;
1495    private final Set JavaDoc newIDS;
1496
1497    public TestResultsContext(Set JavaDoc ids, Set JavaDoc newIDS) {
1498      this.ids = ids;
1499      this.newIDS = newIDS;
1500    }
1501
1502    public synchronized void waitTillComplete() {
1503      while (!complete) {
1504        try {
1505          wait();
1506        } catch (InterruptedException JavaDoc e) {
1507          throw new AssertionError JavaDoc(e);
1508        }
1509      }
1510    }
1511
1512    public synchronized void setResults(ObjectManagerLookupResults results) {
1513      complete = true;
1514      this.objects.putAll(results.getObjects());
1515      notifyAll();
1516    }
1517
1518    public Set JavaDoc getLookupIDs() {
1519      return ids;
1520    }
1521
1522    public Set JavaDoc getNewObjectIDs() {
1523      return newIDS;
1524    }
1525
1526  }
1527
1528  private static class TestPhysicalDNA implements DNA {
1529    private final ObjectID id;
1530
1531    TestPhysicalDNA(ObjectID id) {
1532      this.id = id;
1533    }
1534
1535    public long getVersion() {
1536      return 0;
1537    }
1538
1539    public boolean hasLength() {
1540      return false;
1541    }
1542
1543    public String JavaDoc getDefiningLoaderDescription() {
1544      return "System";
1545    }
1546
1547    public int getArraySize() {
1548      return -1;
1549    }
1550
1551    public String JavaDoc getTypeName() {
1552      return "TestPhysicalDNA.class.name";
1553    }
1554
1555    public ObjectID getObjectID() throws DNAException {
1556      return this.id;
1557    }
1558
1559    public ObjectID getParentObjectID() throws DNAException {
1560      return new ObjectID(25);
1561    }
1562
1563    public void setHeaderInformation(ObjectID id, ObjectID parentID, String JavaDoc typeName, int length, long version) {
1564      //
1565
}
1566
1567    public void addLogicalAction(int method, Object JavaDoc[] parameters) {
1568      //
1569
}
1570
1571    public void addPhysicalAction(String JavaDoc field, Object JavaDoc value) throws DNAException {
1572      //
1573
}
1574
1575    public DNACursor getCursor() {
1576      return new DNACursor() {
1577
1578        int count = 0;
1579
1580        public boolean next() {
1581          count++;
1582          return count < 7;
1583        }
1584
1585        public LogicalAction getLogicalAction() {
1586          return null;
1587        }
1588
1589        public Object JavaDoc getAction() {
1590          throw new ImplementMe();
1591        }
1592
1593        public PhysicalAction getPhysicalAction() {
1594          switch (count) {
1595            case 1: {
1596              return new PhysicalAction("intField", new Integer JavaDoc(42), false);
1597            }
1598            case 2: {
1599              return new PhysicalAction("zzzField", new Byte JavaDoc((byte) 1), false);
1600            }
1601            case 3: {
1602              return new PhysicalAction("objField", new ObjectID(696969), true);
1603            }
1604            case 4: {
1605              return new PhysicalAction("this$0", new ObjectID(25), true);
1606            }
1607            case 5: {
1608              return new PhysicalAction("access$0", new Float JavaDoc(2.4), false);
1609            }
1610            case 6: {
1611              return new PhysicalAction("stringField", new UTF8ByteDataHolder("yo yo yo"), false);
1612            }
1613            default: {
1614              throw new RuntimeException JavaDoc();
1615            }
1616          }
1617
1618        }
1619
1620        public boolean next(DNAEncoding encoding) {
1621          throw new ImplementMe();
1622        }
1623
1624        public int getActionCount() {
1625          return 6;
1626        }
1627
1628        public void reset() throws UnsupportedOperationException JavaDoc {
1629          count = 0;
1630        }
1631
1632      };
1633    }
1634
1635    public boolean isDelta() {
1636      return false;
1637    }
1638  }
1639
1640  private static class TestLiteralValuesDNA implements DNA {
1641    private final ObjectID id;
1642
1643    TestLiteralValuesDNA(ObjectID id) {
1644      this.id = id;
1645    }
1646
1647    public long getVersion() {
1648      return 0;
1649    }
1650
1651    public boolean hasLength() {
1652      return false;
1653    }
1654
1655    public String JavaDoc getDefiningLoaderDescription() {
1656      return "";
1657    }
1658
1659    public int getArraySize() {
1660      return -1;
1661    }
1662
1663    public String JavaDoc getTypeName() {
1664      return "java.lang.Integer";
1665    }
1666
1667    public ObjectID getObjectID() throws DNAException {
1668      return this.id;
1669    }
1670
1671    public ObjectID getParentObjectID() throws DNAException {
1672      return new ObjectID(25);
1673    }
1674
1675    public void setHeaderInformation(ObjectID id, ObjectID parentID, String JavaDoc typeName, int length, long version) {
1676      //
1677
}
1678
1679    public void addLogicalAction(int method, Object JavaDoc[] parameters) {
1680      //
1681
}
1682
1683    public void addPhysicalAction(String JavaDoc field, Object JavaDoc value) throws DNAException {
1684      //
1685
}
1686
1687    public DNACursor getCursor() {
1688      return new DNACursor() {
1689
1690        int count = 0;
1691
1692        public boolean next() {
1693          count++;
1694          return count < 2;
1695        }
1696
1697        public LogicalAction getLogicalAction() {
1698          return null;
1699        }
1700
1701        public Object JavaDoc getAction() {
1702          switch (count) {
1703            case 1: {
1704              return new LiteralAction(new Integer JavaDoc(42));
1705            }
1706            default: {
1707              throw new RuntimeException JavaDoc();
1708            }
1709          }
1710        }
1711
1712        public PhysicalAction getPhysicalAction() {
1713          throw new ImplementMe();
1714        }
1715
1716        public boolean next(DNAEncoding encoding) {
1717          throw new ImplementMe();
1718        }
1719
1720        public int getActionCount() {
1721          return 1;
1722        }
1723
1724        public void reset() throws UnsupportedOperationException JavaDoc {
1725          throw new ImplementMe();
1726        }
1727      };
1728    }
1729
1730    public boolean isDelta() {
1731      return false;
1732    }
1733
1734  }
1735
1736  private static class Listener implements ObjectManagerEventListener {
1737    final List JavaDoc gcEvents = new ArrayList JavaDoc();
1738
1739    public void garbageCollectionComplete(GCStats stats) {
1740      gcEvents.add(stats);
1741    }
1742  }
1743
1744  private class ExplodingGarbageCollector implements GarbageCollector {
1745
1746    private final RuntimeException JavaDoc toThrow;
1747    private LifeCycleState gcState;
1748
1749    public ExplodingGarbageCollector(RuntimeException JavaDoc toThrow) {
1750      this.toThrow = toThrow;
1751    }
1752
1753    public boolean isPausingOrPaused() {
1754      return false;
1755    }
1756
1757    public boolean isPaused() {
1758      return false;
1759    }
1760
1761    public void notifyReadyToGC() {
1762      return;
1763    }
1764
1765    public void requestGCPause() {
1766      return;
1767    }
1768
1769    public void notifyGCComplete() {
1770      return;
1771    }
1772
1773    public void blockUntilReadyToGC() {
1774      return;
1775    }
1776
1777    public Set JavaDoc collect(Filter traverser, Collection JavaDoc roots, Set JavaDoc managedObjectIds) {
1778      throw toThrow;
1779    }
1780
1781    public PrettyPrinter prettyPrint(PrettyPrinter out) {
1782      return out.print(getClass().getName());
1783    }
1784
1785    public Set JavaDoc collect(Filter traverser, Collection JavaDoc roots, Set JavaDoc managedObjectIds, LifeCycleState state) {
1786      return collect(traverser, roots, managedObjectIds);
1787    }
1788
1789    public void changed(ObjectID changedObject, ObjectID oldReference, ObjectID newReference) {
1790      // do nothing
1791

1792    }
1793
1794    public void gc() {
1795      throw toThrow;
1796    }
1797
1798    public void addNewReferencesTo(Set JavaDoc rescueIds) {
1799      // do nothing
1800

1801    }
1802
1803    public void start() {
1804      gcState.start();
1805    }
1806
1807    public void stop() {
1808      // do nothing
1809
}
1810
1811    public void setState(StoppableThread st) {
1812      this.gcState = st;
1813    }
1814
1815    public void addListener(ObjectManagerEventListener listener) {
1816      // do nothing
1817

1818    }
1819
1820    public GCStats[] getGarbageCollectorStats() {
1821      return null;
1822    }
1823
1824  }
1825
1826  private class TestThreadGroup extends ThreadGroup JavaDoc {
1827
1828    private final LinkedQueue exceptionQueue;
1829
1830    public TestThreadGroup(LinkedQueue exceptionQueue) {
1831      super("test thread group");
1832      this.exceptionQueue = exceptionQueue;
1833    }
1834
1835    public void uncaughtException(Thread JavaDoc t, Throwable JavaDoc e) {
1836      try {
1837        exceptionQueue.put(e);
1838      } catch (InterruptedException JavaDoc ie) {
1839        fail(ie);
1840      }
1841    }
1842
1843  }
1844
1845  private class GCCaller implements Runnable JavaDoc {
1846
1847    public void run() {
1848      objectManager.gc();
1849    }
1850  }
1851
1852  /*
1853   * @see TestCase#tearDown()
1854   */

1855  protected void tearDown() throws Exception JavaDoc {
1856    super.tearDown();
1857  }
1858
1859  private static class TestObjectManagerConfig extends ObjectManagerConfig {
1860
1861    public long myGCThreadSleepTime = 100;
1862    public boolean paranoid;
1863
1864    public TestObjectManagerConfig() {
1865      super(10000, true, true, true, 1000);
1866    }
1867
1868    TestObjectManagerConfig(long gcThreadSleepTime, boolean doGC) {
1869      super(gcThreadSleepTime, doGC, true, true, 1000);
1870      throw new RuntimeException JavaDoc("Don't use me.");
1871    }
1872
1873    public long gcThreadSleepTime() {
1874      return myGCThreadSleepTime;
1875    }
1876
1877    public boolean paranoid() {
1878      return paranoid;
1879    }
1880  }
1881
1882  private static class TestMOFaulter extends Thread JavaDoc {
1883
1884    private final ObjectManagerImpl objectManager;
1885    private final ManagedObjectStore store;
1886    private final TestSink faultSink;
1887
1888    public TestMOFaulter(ObjectManagerImpl objectManager, ManagedObjectStore store, TestSink faultSink) {
1889      this.store = store;
1890      this.faultSink = faultSink;
1891      this.objectManager = objectManager;
1892      setName("TestMOFaulter");
1893      setDaemon(true);
1894    }
1895
1896    public void run() {
1897      while (true) {
1898        try {
1899          ManagedObjectFaultingContext ec = (ManagedObjectFaultingContext) faultSink.take();
1900          objectManager.addFaultedObject(ec.getId(), store.getObjectByID(ec.getId()), ec.isRemoveOnRelease());
1901        } catch (InterruptedException JavaDoc e) {
1902          throw new AssertionError JavaDoc(e);
1903        }
1904      }
1905    }
1906  }
1907
1908  private static class TestMOFlusher extends Thread JavaDoc {
1909
1910    private final ObjectManagerImpl objectManager;
1911    private final TestSink flushSink;
1912
1913    public TestMOFlusher(ObjectManagerImpl objectManager, TestSink flushSink) {
1914      this.objectManager = objectManager;
1915      this.flushSink = flushSink;
1916      setName("TestMOFlusher");
1917      setDaemon(true);
1918    }
1919
1920    public void run() {
1921      while (true) {
1922        try {
1923          ManagedObjectFlushingContext ec = (ManagedObjectFlushingContext) flushSink.take();
1924          objectManager.flushAndEvict(ec.getObjectToFlush());
1925        } catch (InterruptedException JavaDoc e) {
1926          throw new AssertionError JavaDoc(e);
1927        }
1928      }
1929    }
1930  }
1931}
1932
Popular Tags