KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > metadata > MetadataMultithreadedTest


1 package org.apache.ojb.broker.metadata;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Collection JavaDoc;
6 import java.util.Iterator JavaDoc;
7
8 import org.apache.commons.lang.ClassUtils;
9 import org.apache.ojb.broker.*;
10 import org.apache.ojb.broker.accesslayer.OJBIterator;
11 import org.apache.ojb.broker.query.Query;
12 import org.apache.ojb.broker.query.QueryByCriteria;
13 import org.apache.ojb.broker.query.QueryFactory;
14 import org.apache.ojb.broker.sequence.Repository;
15 import org.apache.ojb.broker.util.ClassHelper;
16 import org.apache.ojb.broker.util.logging.Logger;
17 import org.apache.ojb.broker.util.logging.LoggerFactory;
18 import org.apache.ojb.junit.JUnitExtensions;
19
20 /**
21  *
22  * @author <a HREF="mailto:armin@codeAuLait.de">Armin Waibel</a>
23  * @version $Id: MetadataMultithreadedTest.java,v 1.7.2.3 2005/03/03 21:38:12 mkalen Exp $
24  */

25 public class MetadataMultithreadedTest extends JUnitExtensions.MultiThreadedTestCase
26 {
27     // we change table name in test for target class
28
private String JavaDoc newTestObjectString = "SM_TAB_MAX_AA";
29     private Class JavaDoc targetTestClass = Repository.SMMaxA.class;
30     int loops = 7;
31     int threads = 4;
32     // need min 80% free memory after test campared with
33
// beginning, else test fails
34
int minimalFreeMemAfterTest = 80;
35
36     private String JavaDoc oldTestObjectString;
37     DescriptorRepository defaultRepository;
38
39     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
40
41     public MetadataMultithreadedTest(String JavaDoc s)
42     {
43         super(s);
44     }
45
46     public static void main(String JavaDoc[] args)
47     {
48         String JavaDoc[] arr = {MetadataMultithreadedTest.class.getName()};
49         junit.textui.TestRunner.main(arr);
50     }
51
52     private long getTotalMemory()
53     {
54         long result = Long.MAX_VALUE;
55         // TODO: find a solution for this problem, or uncomment if we cancel 1.2 support
56
// result = Runtime.getRuntime().maxMemory(); // not available in JDK 1.2
57
return result;
58     }
59
60     protected void setUp() throws Exception JavaDoc
61     {
62         super.setUp();
63         MetadataManager mm = MetadataManager.getInstance();
64         // enable the per thread changes of metadata
65
mm.setEnablePerThreadChanges(true);
66         defaultRepository = mm.copyOfGlobalRepository();
67     }
68
69     protected void tearDown() throws Exception JavaDoc
70     {
71         super.tearDown();
72         MetadataManager.getInstance().setEnablePerThreadChanges(false);
73     }
74
75     private String JavaDoc getTestObjectString()
76     {
77         return oldTestObjectString;
78     }
79
80     public void testProxiedLoading() throws Exception JavaDoc
81     {
82         PersistenceBroker broker = null;
83         try
84         {
85             MetadataManager mm = MetadataManager.getInstance();
86             // Store the current repository mappings under a profile key
87
DescriptorRepository repository = mm.getRepository();
88             String JavaDoc profileKey = "TestMappings";
89             mm.addProfile(profileKey, repository);
90
91             // "Destroy" this thread's mappings
92
mm.setDescriptor(defaultRepository);
93
94             ProductGroupWithCollectionProxy pgTemplate = new ProductGroupWithCollectionProxy();
95             pgTemplate.setGroupId(new Integer JavaDoc(6));
96             Query query = QueryFactory.newQueryByExample(pgTemplate);
97
98             broker = PersistenceBrokerFactory.defaultPersistenceBroker();
99             Collection JavaDoc groups;
100             Iterator JavaDoc groupIter;
101             ProductGroupWithCollectionProxy pg;
102
103             assertNotNull(groupIter = (OJBIterator) broker.getIteratorByQuery(query));
104             assertTrue(groupIter.hasNext());
105
106             // We have not named any OJB profiles, so using dynamic proxies at this stage is not
107
// supported
108
Throwable JavaDoc expectedThrowable = null;
109             try {
110                 System.err.println("------ The following exception is part of the tests...");
111                 groupIter.next();
112             } catch (Throwable JavaDoc t) {
113                 expectedThrowable = t;
114                 System.err.println("------");
115             }
116             assertNotNull("Should get metadata exception from proxy", expectedThrowable);
117             ((OJBIterator) groupIter).releaseDbResources();
118
119             // Load the repository profile and re-try loading.
120
broker.clearCache();
121             mm.loadProfile(profileKey);
122             assertNotNull(groups = broker.getCollectionByQuery(query));
123             assertEquals(1, groups.size());
124             assertNotNull(groupIter = groups.iterator());
125             assertTrue(groupIter.hasNext());
126             assertNotNull(pg = (ProductGroupWithCollectionProxy) groupIter.next());
127             assertFalse(groupIter.hasNext());
128             assertEquals(pgTemplate.getGroupId(), pg.getGroupId());
129             Collection JavaDoc articles;
130             assertNotNull(articles = pg.getAllArticlesInGroup());
131             assertEquals(6, articles.size());
132
133             TestCaseRunnable tct [] = new TestCaseRunnable[]{new LazyLoading(articles)};
134             runTestCaseRunnables(tct);
135         }
136         finally
137         {
138             if (broker != null) broker.close();
139         }
140
141     }
142
143     /**
144      * Regression test for loading CollectionProxy data in a thread where the profile
145      * is swapped, and the thread-local broker is closed, between CollectionProxy construction
146      * and retrieveCollections-call.
147      * @throws Exception on unexpected failure
148      */

149     public void testCollectionProxySwapProfiles() throws Exception JavaDoc
150     {
151         PersistenceBroker broker = null;
152         try
153         {
154             MetadataManager mm = MetadataManager.getInstance();
155
156             // Store the current repository mappings under a profile key and load it
157
DescriptorRepository repository = mm.getRepository();
158             String JavaDoc profileKey = "TestMappings";
159             mm.addProfile(profileKey, repository);
160             mm.loadProfile(profileKey);
161
162             // Load object and proxy
163
ProductGroupWithCollectionProxy pgTemplate = new ProductGroupWithCollectionProxy();
164             pgTemplate.setGroupId(new Integer JavaDoc(6));
165             Query query = QueryFactory.newQueryByExample(pgTemplate);
166             broker = PersistenceBrokerFactory.defaultPersistenceBroker();
167             ProductGroupWithCollectionProxy productGroup;
168             assertNotNull(productGroup =
169                     (ProductGroupWithCollectionProxy) broker.getObjectByQuery(query));
170
171             // Close broker to make sure proxy needs a new internal one
172
broker.close();
173
174             // Swap profile (to a completely empty one)
175
final String JavaDoc emptyKey = "EMPTY";
176             DescriptorRepository emptyDr = new DescriptorRepository();
177             mm.addProfile(emptyKey, emptyDr);
178             mm.loadProfile(emptyKey);
179
180             List JavaDoc collectionProxy = productGroup.getAllArticlesInGroup();
181             assertNotNull(collectionProxy);
182
183             // Load proxy data, will throw ClassNotPersistenceCapableException
184
// if not reactivating profile with new thread-local broker
185
assertNotNull(collectionProxy.get(0));
186         }
187         finally
188         {
189             if (broker != null) broker.close();
190         }
191     }
192
193     public void testRuntimeMetadataChanges() throws Exception JavaDoc
194     {
195         PersistenceBroker broker = null;
196         try
197         {
198             MetadataManager.getInstance().setDescriptor(defaultRepository);
199
200             ClassDescriptor cld;
201             long memoryUseBeforeTest;
202             long memoryUseAfterTest;
203             try
204             {
205                 // prepare for test
206
long period = System.currentTimeMillis();
207                 broker = PersistenceBrokerFactory.defaultPersistenceBroker();
208                 cld = broker.getClassDescriptor(targetTestClass);
209
210                 // we manipulate the schema name of the class
211
// thus we note the original value
212
oldTestObjectString = cld.getFullTableName();
213                 broker.close();
214
215                 // cleanup JVM
216
Runtime.getRuntime().gc();
217                 Thread.sleep(200);
218                 Runtime.getRuntime().gc();
219
220                 // start test
221
long memory = Runtime.getRuntime().freeMemory();
222                 long totalMemory = getTotalMemory();
223
224                 int count = 0;
225                 for (int k = 0; k < loops; k++)
226                 {
227                     TestCaseRunnable tct [] = new TestCaseRunnable[threads];
228                     for (int i = 0; i < threads; i++)
229                     {
230                         if (i % 2 == 0)
231                             tct[i] = new ThreadedUsingBroker(loops);
232                         else
233                             tct[i] = new GlobalUsingBroker(loops);
234                     }
235                     // run test classes
236
runTestCaseRunnables(tct);
237                     ++count;
238                     if (logger.isDebugEnabled())
239                     {
240                         logger.debug("Free/total Memory after loop " + count + ": "
241                                      + convertToMB(Runtime.getRuntime().freeMemory())
242                                      + "/" + convertToMB(getTotalMemory()) + "MB");
243                     }
244                 }
245                 period = System.currentTimeMillis() - period;
246                 if (logger.isDebugEnabled())
247                 {
248                     logger.debug(ClassUtils.getShortClassName(MetadataMultithreadedTest.class) + " take: "
249                                  + period + " ms for " + loops + " loops, creating each with " + threads + " threads");
250                     logger.debug("Free/total Memory before test: "
251                                  + convertToMB(memory) + "/" + convertToMB(totalMemory) + "MB");
252                 }
253                 Runtime.getRuntime().gc();
254                 Thread.sleep(200);
255                 Runtime.getRuntime().gc();
256                 Runtime.getRuntime().gc();
257
258                 memoryUseBeforeTest = convertToMB(memory);
259                 memoryUseAfterTest = convertToMB(Runtime.getRuntime().freeMemory());
260                 if (logger.isDebugEnabled())
261                 {
262                     logger.debug("Free/total Memory after test and gc: "
263                                  + memoryUseAfterTest
264                                  + "/" + convertToMB(getTotalMemory()) + "MB");
265                     logger.debug("Do cleanup now ...");
266                 }
267             }
268             finally
269             {
270                 MetadataManager.getInstance().setEnablePerThreadChanges(false);
271             }
272             // get new PB instance
273
broker = PersistenceBrokerFactory.defaultPersistenceBroker();
274             cld = broker.getClassDescriptor(targetTestClass);
275             String JavaDoc name = cld.getFullTableName();
276             assertEquals(oldTestObjectString, name);
277             assertFalse(MetadataManager.getInstance().isEnablePerThreadChanges());
278             double d = ((double) memoryUseAfterTest) / ((double) memoryUseBeforeTest);
279             int result = (int) (d * 100);
280             if (result < minimalFreeMemAfterTest)
281             {
282                 fail("** When using a offical version of OJB, ignore this failure! **" +
283                         " Memory usage after this test differs more than "+(100 - minimalFreeMemAfterTest)
284                         +"% from beginning, this may indicate" +
285                         " a memory leak (GC can't free unused metadata objects), but this could also be a result" +
286                         " of your JVM settings. Please re-run test.");
287             }
288         }
289         finally
290         {
291             if (broker != null) broker.close();
292         }
293     }
294
295     private long convertToMB(long byteValue)
296     {
297         return (byteValue / 1024) / 1024;
298     }
299
300     // ======================================================================
301
// inner test class
302
// ======================================================================
303
class ThreadedUsingBroker extends JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable
304     {
305         int loops;
306         String JavaDoc title = "ThreadedUsingBroker_" + System.currentTimeMillis();
307
308         public ThreadedUsingBroker()
309         {
310         }
311
312         public ThreadedUsingBroker(int loops)
313         {
314             this.loops = loops;
315         }
316
317         public void runTestCase() throws Exception JavaDoc
318         {
319             MetadataManager mm = MetadataManager.getInstance();
320             DescriptorRepository dr = mm.copyOfGlobalRepository();
321             ClassDescriptor cld = dr.getDescriptorFor(targetTestClass);
322             // we change a class descriptor value
323
cld.setTableName(newTestObjectString);
324             // set the changed repository for this thread
325
mm.setDescriptor(dr);
326
327             int k = 0;
328             while (k < loops)
329             {
330                 PersistenceBroker broker = null;
331                 try
332                 {
333                     broker = PersistenceBrokerFactory.defaultPersistenceBroker();
334                     cld = broker.getClassDescriptor(targetTestClass);
335                     String JavaDoc name = cld.getFullTableName();
336                     assertEquals(newTestObjectString, name);
337                     assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
338                 }
339                 finally
340                 {
341                     if (broker != null) broker.close();
342                 }
343
344                 try
345                 {
346                     broker = PersistenceBrokerFactory.defaultPersistenceBroker();
347                     // check made changes
348
cld = broker.getClassDescriptor(targetTestClass);
349                     String JavaDoc name = cld.getFullTableName();
350                     assertEquals(newTestObjectString, name);
351                     assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
352
353                     // query a test object
354
Query query = new QueryByCriteria(Person.class, null, true);
355                     broker.getCollectionByQuery(query);
356                     // store target object
357
/*
358                     store some complex objects to check if references to
359                     metadata classes are cached
360                     */

361                     Project project = new Project();
362                     project.setTitle(title);
363
364                     Person p1 = new Person();
365                     p1.setFirstname(title);
366                     List JavaDoc l1 = new ArrayList JavaDoc();
367                     l1.add(project);
368                     p1.setProjects(l1);
369
370                     Person p2 = new Person();
371                     p2.setFirstname(title);
372                     List JavaDoc l2 = new ArrayList JavaDoc();
373                     l2.add(project);
374                     p2.setProjects(l2);
375
376                     Role r1 = new Role();
377                     r1.setPerson(p1);
378                     r1.setRoleName(title);
379                     r1.setProject(project);
380                     List JavaDoc roles1 = new ArrayList JavaDoc();
381                     roles1.add(r1);
382
383                     Role r2 = new Role();
384                     r2.setPerson(p2);
385                     r2.setRoleName(title);
386                     r2.setProject(project);
387                     List JavaDoc roles2 = new ArrayList JavaDoc();
388                     roles2.add(r2);
389
390                     p1.setRoles(roles1);
391                     p2.setRoles(roles2);
392
393                     Object JavaDoc obj = ClassHelper.newInstance(targetTestClass);
394
395                     broker.beginTransaction();
396                     broker.store(obj);
397                     broker.store(p1);
398                     broker.store(p2);
399                     broker.commitTransaction();
400                     // delete target object
401
broker.beginTransaction();
402                     broker.delete(obj);
403                     //broker.delete(p1);
404
//broker.delete(p2);
405
broker.commitTransaction();
406                 }
407                 finally
408                 {
409                     if (broker != null) broker.close();
410                 }
411
412                 k++;
413                 try
414                 {
415                     Thread.sleep(5);
416                 }
417                 catch (InterruptedException JavaDoc e)
418                 {
419                 }
420             }
421
422         }
423     }
424
425     // ======================================================================
426
// inner test class
427
// ======================================================================
428
class GlobalUsingBroker extends JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable
429     {
430         int loops;
431
432         public GlobalUsingBroker(int loops)
433         {
434             this.loops = loops;
435         }
436
437         public void runTestCase()
438         {
439             PersistenceBroker broker = null;
440             int k = 0;
441             try
442             {
443                 while (k < loops)
444                 {
445                     try
446                     {
447                         MetadataManager.getInstance().setDescriptor(defaultRepository);
448                         broker = PersistenceBrokerFactory.defaultPersistenceBroker();
449                         ClassDescriptor cld = broker.getClassDescriptor(targetTestClass);
450                         assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
451                         String JavaDoc name = cld.getFullTableName();
452                         // this PB instance use unchanged global metadata repository
453
assertEquals(getTestObjectString(), name);
454                     }
455                     finally
456                     {
457                         if (broker != null) broker.close();
458                     }
459                     try
460                     {
461                         broker = PersistenceBrokerFactory.defaultPersistenceBroker();
462                         ClassDescriptor cld = broker.getClassDescriptor(targetTestClass);
463                         assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
464                         String JavaDoc name = cld.getFullTableName();
465                         // this PB instance use unchanged global metadata repository
466
assertEquals(getTestObjectString(), name);
467                         // System.out.println("Default: found "+name);
468

469                         // query a test object
470
Query query = new QueryByCriteria(Person.class, null, true);
471                         broker.getCollectionByQuery(query);
472                         // store target object
473
Object JavaDoc obj = ClassHelper.newInstance(targetTestClass);
474                         broker.beginTransaction();
475                         broker.store(obj);
476                         broker.commitTransaction();
477                         // delete target object
478
broker.beginTransaction();
479                         broker.delete(obj);
480                         broker.commitTransaction();
481                     }
482                     finally
483                     {
484                         if (broker != null) broker.close();
485                     }
486
487                     k++;
488                     try
489                     {
490                         Thread.sleep(5);
491                     }
492                     catch (InterruptedException JavaDoc e)
493                     {
494                     }
495                 }
496             }
497             catch (Exception JavaDoc e)
498             {
499                 e.printStackTrace();
500                 throw new OJBRuntimeException(e);
501             }
502         }
503     }
504
505     /**
506      * Inner test class for lazy materialization of CollectionProxy in different thread.
507      */

508     protected class LazyLoading extends JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable
509     {
510         private Collection JavaDoc articles;
511
512         public LazyLoading(Collection JavaDoc articles)
513         {
514             assertNotNull(this.articles = articles);
515         }
516
517         public void runTestCase() throws Throwable JavaDoc
518         {
519             // Explicitly clear descriptor repository in this thread (similar to loading
520
// profile with unrelated class-mappings).
521
DescriptorRepository dr = new DescriptorRepository();
522             MetadataManager.getInstance().setDescriptor(dr);
523             Article article;
524             int numArticles = 0;
525             for (Iterator JavaDoc iterator = articles.iterator(); iterator.hasNext();)
526             {
527                 assertNotNull(article = (Article) iterator.next());
528                 assertNotNull(article.getArticleId());
529                 assertFalse(new Integer JavaDoc(0).equals(article.getArticleId()));
530                 numArticles++;
531             }
532             assertEquals(6, numArticles);
533         }
534     }
535
536 }
537
Popular Tags