001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * TransactionBeanCacheTest.java
020: *
021: * JUnit based test
022: */
023:
024: // package path
025: package com.rift.coad.lib.bean;
026:
027: // java imports
028: import javax.naming.InitialContext;
029: import javax.naming.Context;
030: import java.sql.PreparedStatement;
031: import java.sql.ResultSet;
032: import java.sql.Statement;
033: import javax.sql.DataSource;
034: import java.util.Set;
035: import java.util.HashSet;
036: import javax.transaction.UserTransaction;
037: import java.sql.Timestamp;
038: import java.util.ArrayList;
039: import java.util.Date;
040: import java.util.Enumeration;
041: import java.util.HashSet;
042: import java.util.Iterator;
043: import java.util.List;
044: import java.util.Set;
045: import javax.transaction.xa.XAException;
046: import javax.transaction.xa.XAResource;
047: import javax.transaction.xa.Xid;
048: import org.apache.log4j.Logger;
049: import org.apache.log4j.BasicConfigurator;
050:
051: // junit imports
052: import junit.framework.*;
053:
054: // object web imports
055: import org.objectweb.jotm.Jotm;
056:
057: // coadunation imports
058: import com.rift.coad.lib.naming.NamingDirector;
059: import com.rift.coad.lib.naming.ContextManager;
060: import com.rift.coad.lib.db.DBSourceManager;
061: import com.rift.coad.lib.common.ObjectSerializer;
062: import com.rift.coad.lib.cache.CacheEntry;
063: import com.rift.coad.lib.interceptor.InterceptorFactory;
064: import com.rift.coad.lib.security.RoleManager;
065: import com.rift.coad.lib.security.ThreadsPermissionContainer;
066: import com.rift.coad.lib.security.ThreadPermissionSession;
067: import com.rift.coad.lib.security.UserSession;
068: import com.rift.coad.lib.security.user.UserSessionManager;
069: import com.rift.coad.lib.security.user.UserStoreManager;
070: import com.rift.coad.lib.security.SessionManager;
071: import com.rift.coad.lib.security.login.LoginManager;
072: import com.rift.coad.lib.thread.CoadunationThreadGroup;
073: import com.rift.coad.lib.transaction.TransactionDirector;
074: import com.rift.coad.util.lock.ObjectLockFactory;
075: import com.rift.coad.util.transaction.TransactionManager;
076:
077: /**
078: *
079: * @author Brett Chaldecott
080: */
081: public class TransactionBeanCacheTest extends TestCase {
082:
083: /**
084: * The cache entry to add
085: */
086: public static class TestCacheEntry implements CacheEntry,
087: java.rmi.Remote {
088:
089: // touch date
090: private Date touchTime = new Date();
091: public static int count = 0;
092:
093: /**
094: * The constructor of the test cache entry object.
095: */
096: public TestCacheEntry() {
097:
098: }
099:
100: /**
101: * The touch method of the test cache entry object.
102: */
103: public void touch() {
104: touchTime = new Date();
105: }
106:
107: /**
108: * This method returns true if this object has expired.
109: *
110: * @return TRUE if expired FALSE if not.
111: * @param expiryDate The date of the expiry.
112: */
113: public boolean isExpired(Date expiryDate) {
114: System.out.println("Touch time : " + touchTime.getTime()
115: + " expiry date : " + expiryDate.getTime());
116: return touchTime.getTime() < expiryDate.getTime();
117: }
118:
119: /**
120: * Release the cache
121: */
122: public void cacheRelease() {
123: count++;
124: }
125: }
126:
127: // private member variables
128: private TransactionBeanCache instance = null;
129: private UserTransaction ut = null;
130: private boolean addedEntry = false;
131: private boolean caughtException = false;
132: private boolean gotCacheEntry = false;
133:
134: public TransactionBeanCacheTest(String testName) {
135: super (testName);
136: }
137:
138: protected void setUp() throws Exception {
139: }
140:
141: protected void tearDown() throws Exception {
142: }
143:
144: public static Test suite() {
145: TestSuite suite = new TestSuite(TransactionBeanCacheTest.class);
146:
147: return suite;
148: }
149:
150: /**
151: * Test of class com.rift.coad.lib.bean.BeanCache.
152: */
153: public void testCache() throws Exception {
154: System.out.println("TransactionBeanCacheTest");
155:
156: // init the session information
157: ThreadsPermissionContainer permissions = new ThreadsPermissionContainer();
158: SessionManager.init(permissions);
159: UserStoreManager userStoreManager = new UserStoreManager();
160: UserSessionManager sessionManager = new UserSessionManager(
161: permissions, userStoreManager);
162: LoginManager.init(sessionManager, userStoreManager);
163: // instanciate the thread manager
164: CoadunationThreadGroup threadGroup = new CoadunationThreadGroup(
165: sessionManager, userStoreManager);
166:
167: // add a user to the session for the current thread
168: RoleManager.getInstance();
169:
170: InterceptorFactory.init(permissions, sessionManager,
171: userStoreManager);
172:
173: // add a new user object and add to the permission
174: Set set = new HashSet();
175: set.add("test");
176: UserSession user = new UserSession("test1", set);
177: permissions.putSession(
178: new Long(Thread.currentThread().getId()),
179: new ThreadPermissionSession(new Long(Thread
180: .currentThread().getId()), user));
181:
182: // init the naming director
183: NamingDirector.init(threadGroup);
184:
185: // instanciate the transaction director
186: TransactionDirector transactionDirector = TransactionDirector
187: .init();
188:
189: // init the database source
190: DBSourceManager.init();
191: Context context = new InitialContext();
192: ObjectLockFactory.init();
193: TransactionManager.init();
194:
195: ut = (UserTransaction) context
196: .lookup("java:comp/UserTransaction");
197:
198: // the transaction bean cache
199: instance = new TransactionBeanCache();
200:
201: ut.begin();
202: TestCacheEntry bob = new TestCacheEntry();
203: instance.addCacheEntry(500, "bob", "bob", bob);
204: Thread testThread = new Thread(new Runnable() {
205: public void run() {
206: try {
207: ut.begin();
208: instance.addCacheEntry(500, "bob", "bob",
209: new TestCacheEntry());
210: addedEntry = true;
211: ut.commit();
212: } catch (Exception ex) {
213: System.out
214: .println("Failed to get the queue reference : "
215: + ex.getMessage());
216: ex.printStackTrace(System.out);
217: caughtException = true;
218: try {
219: ut.rollback();
220: } catch (Exception ex2) {
221: System.out
222: .println("Failed to roll the transaction back : "
223: + ex2.getMessage());
224: }
225: }
226: }
227: });
228: testThread.start();
229:
230: Thread.sleep(500);
231: if (addedEntry) {
232: fail("An entry was added");
233: } else if (caughtException) {
234: fail("Caught an exception");
235: }
236: ut.commit();
237: Thread.sleep(500);
238: if (addedEntry) {
239: fail("An entry was added");
240: } else if (caughtException == false) {
241: fail("Failed to catch an exception");
242: }
243:
244: ut.begin();
245: try {
246: instance.addCacheEntry(500, "bob", "bob", bob);
247: fail("The second add must fail");
248: } catch (BeanException ex) {
249: System.out.println(ex.getMessage());
250: }
251:
252: ut.commit();
253: TestCacheEntry fred = new TestCacheEntry();
254: ut.begin();
255: instance.addCacheEntry(500, "fred", "fred", fred);
256: try {
257: instance.addCacheEntry(500, "fred", "fred", fred);
258: fail("The second add must fail");
259: } catch (BeanException ex) {
260: System.out.println(ex.getMessage());
261: }
262: ut.commit();
263: TestCacheEntry mary = new TestCacheEntry();
264: ut.begin();
265: instance.addCacheEntry(500, "mary", "mary", "mary", mary);
266: ut.commit();
267:
268: ut.begin();
269: if (bob != instance.getCacheEntry("bob").getCacheEntry()) {
270: fail("bob could not be found");
271: }
272: instance.getCacheEntry("bob").setCacheEntry(mary);
273: caughtException = false;
274: testThread = new Thread(new Runnable() {
275: public void run() {
276: try {
277: ut.begin();
278: instance.getCacheEntry("bob");
279: gotCacheEntry = true;
280: ut.commit();
281: } catch (Exception ex) {
282: System.out
283: .println("Failed to get the queue reference : "
284: + ex.getMessage());
285: ex.printStackTrace(System.out);
286: caughtException = true;
287: try {
288: ut.rollback();
289: } catch (Exception ex2) {
290: System.out
291: .println("Failed to roll the transaction back : "
292: + ex2.getMessage());
293: }
294: }
295: }
296: });
297: testThread.start();
298:
299: Thread.sleep(500);
300: if (gotCacheEntry) {
301: fail("Managed to retrieve the cache entry");
302: } else if (caughtException) {
303: fail("Caught an exception");
304: }
305: ut.commit();
306: Thread.sleep(500);
307: if (!gotCacheEntry) {
308: fail("Failed to retrieve the cache entry");
309: } else if (caughtException) {
310: fail("Caught an exception");
311: }
312:
313: ut.begin();
314: if (mary != instance.getCacheEntry("bob").getCacheEntry()) {
315: fail("mary could not be found");
316: }
317: ut.commit();
318: ut.begin();
319: if (mary != instance.getCacheEntry("mary").getBeanHandler()) {
320: fail("mary could not be found");
321: }
322: instance.getCacheEntry("mary").setBeanHandler(bob);
323: ut.commit();
324: ut.begin();
325: if (bob != instance.getCacheEntry("mary").getBeanHandler()) {
326: fail("bob could not be found");
327: }
328: if (!instance.getCacheEntry("mary").getProxy().equals("mary")) {
329: fail("mary could not be found");
330: }
331: instance.getCacheEntry("mary").setProxy("mary1");
332: if (!instance.getCacheEntry("mary").getProxy().equals("mary1")) {
333: fail("mary1 could not be found");
334: }
335: ut.commit();
336:
337: for (int count = 0; count < 4; count++) {
338: Thread.sleep(500);
339: bob.touch();
340: mary.touch();
341: }
342:
343: instance.garbageCollect();
344:
345: ut.begin();
346: if (!instance.contains("bob")) {
347: fail("bob could not be found");
348: }
349: if (!instance.contains("mary")) {
350: fail("mary could not be found");
351: }
352: if (instance.contains("fred")) {
353: fail("fred was found");
354: }
355: ut.commit();
356:
357: ut.begin();
358: instance.removeCacheEntry("bob");
359: instance.addCacheEntry(500, "fred", "fred",
360: new TestCacheEntry());
361: if (!instance.contains("fred")) {
362: fail("fred was found");
363: }
364: if (instance.contains("bob")) {
365: fail("bob was found");
366: }
367: ut.rollback();
368: ut.begin();
369: if (instance.contains("fred")) {
370: fail("fred was found");
371: }
372: if (!instance.contains("bob")) {
373: fail("bob was not found");
374: }
375: ut.commit();
376: instance.clear();
377: ut.begin();
378: if (instance.contains("bob")) {
379: fail("bob could still be found");
380: }
381:
382: if (instance.contains("mary")) {
383: fail("bob could still be found");
384: }
385: try {
386: instance.addCacheEntry(500, "mary", "mary", "mary", mary);
387: fail("Could add an entry should not be allowed");
388: } catch (BeanException ex) {
389: // ingore
390: }
391: try {
392: instance.addCacheEntry(500, "bob", "bob", bob);
393: fail("Could add an entry should not be allowed");
394: } catch (BeanException ex) {
395: // ingore
396: }
397:
398: if (TestCacheEntry.count != 4) {
399: fail("Release not called on all classes ["
400: + TestCacheEntry.count + "]");
401: }
402: ut.rollback();
403: }
404:
405: }
|