001: /*
002: * $Id: PersistenceManagerFactoryImplTest.java,v 1.5 2003/11/27 00:22:51 jackknifebarber Exp $
003: */
004:
005: package com.triactive.jdo.test;
006:
007: import java.io.BufferedInputStream;
008: import java.io.BufferedOutputStream;
009: import java.io.ByteArrayInputStream;
010: import java.io.ByteArrayOutputStream;
011: import java.io.IOException;
012: import java.io.ObjectInputStream;
013: import java.io.ObjectOutputStream;
014: import java.sql.Connection;
015: import java.util.Properties;
016: import javax.jdo.JDOUserException;
017: import javax.jdo.JDOHelper;
018: import javax.jdo.JDOUnsupportedOptionException;
019: import javax.jdo.PersistenceManager;
020: import javax.jdo.PersistenceManagerFactory;
021: import junit.framework.Assert;
022: import com.triactive.jdo.DatabaseProperties;
023: import com.triactive.jdo.PersistenceManagerFactoryImpl;
024:
025: /**
026: * Tests the basic functionality of creating <code>PersistenceManagerFactory</code>s
027: * and setting properties on them.
028: *
029: * @author <a href="mailto:kgrizzle@triactive.com">Kelly Grizzle</a>
030: * @version $Revision: 1.5 $
031: */
032:
033: public class PersistenceManagerFactoryImplTest extends
034: PersistenceTestCase {
035:
036: /**
037: * This class allows us to create a Properties to pass to
038: * JDOHelper.getPersistenceManagerFactory() easily.
039: */
040: public class PMFProperties extends Properties {
041: private boolean optimistic = false;
042: private boolean retainValues = false;
043: private boolean restoreValues = false;
044: private boolean ignoreCache = false;
045: private boolean nontransactionalRead = false;
046: private boolean nontransactionalWrite = false;
047: private boolean multithreaded = false;
048:
049: private String driverName = null;
050: private String url = null;
051: private String userName = null;
052: private String password = null;
053: private String factoryName = null;
054: private String factory2Name = null;
055:
056: private boolean validateTables;
057: private boolean validateConstraints;
058: private boolean autoCreateTables;
059: private int isolationLevel;
060:
061: /**
062: * Constructor. This sets the "javax.jdo.option.PersistenceManagerFactoryClass"
063: * for us.
064: */
065: public PMFProperties() {
066: super ();
067: this .setProperty(
068: "javax.jdo.PersistenceManagerFactoryClass",
069: "com.triactive.jdo.PersistenceManagerFactoryImpl");
070:
071: /*
072: * Set expected defaults. These can vary based on system
073: * properties.
074: */
075: PersistenceManagerFactoryImpl pmf = new PersistenceManagerFactoryImpl();
076: validateTables = pmf.getValidateTables();
077: validateConstraints = pmf.getValidateConstraints();
078: autoCreateTables = pmf.getAutoCreateTables();
079: isolationLevel = pmf.getTransactionIsolation();
080: }
081:
082: public void setOptimistic(boolean b) {
083: this .optimistic = b;
084: this .setProperty("javax.jdo.option.Optimistic",
085: new Boolean(b).toString());
086: }
087:
088: public void setRetainValues(boolean b) {
089: this .retainValues = b;
090: this .setProperty("javax.jdo.option.RetainValues",
091: new Boolean(b).toString());
092: }
093:
094: public void setRestoreValues(boolean b) {
095: this .restoreValues = b;
096: this .setProperty("javax.jdo.option.RestoreValues",
097: new Boolean(b).toString());
098: }
099:
100: public void setIgnoreCache(boolean b) {
101: this .ignoreCache = b;
102: this .setProperty("javax.jdo.option.IgnoreCache",
103: new Boolean(b).toString());
104: }
105:
106: public void setNontransactionalRead(boolean b) {
107: this .nontransactionalRead = b;
108: this .setProperty("javax.jdo.option.NontransactionalRead",
109: new Boolean(b).toString());
110: }
111:
112: public void setNontransactionalWrite(boolean b) {
113: this .nontransactionalWrite = b;
114: this .setProperty("javax.jdo.option.NontransactionalWrite",
115: new Boolean(b).toString());
116: }
117:
118: public void setMultithreaded(boolean b) {
119: this .multithreaded = b;
120: this .setProperty("javax.jdo.option.Multithreaded",
121: new Boolean(b).toString());
122: }
123:
124: public void setDriverName(String s) {
125: this .driverName = s;
126: this
127: .setProperty(
128: "javax.jdo.option.ConnectionDriverName", s);
129: }
130:
131: public void setUserName(String s) {
132: this .userName = s;
133: this .setProperty("javax.jdo.option.ConnectionUserName", s);
134: }
135:
136: public void setPassword(String s) {
137: this .password = s;
138: this .setProperty("javax.jdo.option.ConnectionPassword", s);
139: }
140:
141: public void setURL(String s) {
142: this .url = s;
143: this .setProperty("javax.jdo.option.ConnectionURL", s);
144: }
145:
146: public void setFactoryName(String s) {
147: this .factoryName = s;
148: this .setProperty("javax.jdo.option.ConnectionFactoryName",
149: s);
150: }
151:
152: public void setFactory2Name(String s) {
153: this .factory2Name = s;
154: this .setProperty("javax.jdo.option.ConnectionFactory2Name",
155: s);
156: }
157:
158: public void setValidateTables(boolean b) {
159: this .validateTables = b;
160: this
161: .setProperty(
162: PersistenceManagerFactoryImpl.VALIDATE_TABLES_PROPERTY,
163: new Boolean(b).toString());
164: }
165:
166: public void setValidateConstraints(boolean b) {
167: this .validateConstraints = b;
168: this
169: .setProperty(
170: PersistenceManagerFactoryImpl.VALIDATE_CONSTRAINTS_PROPERTY,
171: new Boolean(b).toString());
172: }
173:
174: public void setAutoCreateTables(boolean b) {
175: this .autoCreateTables = b;
176: this
177: .setProperty(
178: PersistenceManagerFactoryImpl.AUTO_CREATE_TABLES_PROPERTY,
179: new Boolean(b).toString());
180: }
181:
182: public void setTransactionIsolation(int i) {
183: this .isolationLevel = i;
184: String name;
185:
186: switch (i) {
187: case Connection.TRANSACTION_READ_UNCOMMITTED:
188: name = "read uncommitted";
189: break;
190: case Connection.TRANSACTION_READ_COMMITTED:
191: name = "read committed";
192: break;
193: case Connection.TRANSACTION_REPEATABLE_READ:
194: name = "repeatable read";
195: break;
196: case Connection.TRANSACTION_SERIALIZABLE:
197: name = "serializable";
198: break;
199: default:
200: name = "bad level " + Integer.toString(i);
201: break;
202: }
203:
204: this
205: .setProperty(
206: PersistenceManagerFactoryImpl.TRANSACTION_ISOLATION_PROPERTY,
207: name);
208: }
209:
210: public void assertMatchesPMF(PersistenceManagerFactory pmf,
211: Assert a) {
212: a.assertEquals(optimistic, pmf.getOptimistic());
213: a.assertEquals(retainValues, pmf.getRetainValues());
214: a.assertEquals(restoreValues, pmf.getRestoreValues());
215: a.assertEquals(ignoreCache, pmf.getIgnoreCache());
216: a.assertEquals(nontransactionalRead, pmf
217: .getNontransactionalRead());
218: a.assertEquals(nontransactionalWrite, pmf
219: .getNontransactionalWrite());
220: a.assertEquals(multithreaded, pmf.getMultithreaded());
221: a.assertEquals(driverName, pmf.getConnectionDriverName());
222: a.assertEquals(url, pmf.getConnectionURL());
223: a.assertEquals(userName, pmf.getConnectionUserName());
224: a.assertEquals(factoryName, pmf.getConnectionFactoryName());
225: a.assertEquals(factory2Name, pmf
226: .getConnectionFactory2Name());
227:
228: PersistenceManagerFactoryImpl myPMF = (PersistenceManagerFactoryImpl) pmf;
229: a.assertEquals(validateTables, myPMF.getValidateTables());
230: a.assertEquals(validateConstraints, myPMF
231: .getValidateConstraints());
232: a.assertEquals(autoCreateTables, myPMF
233: .getAutoCreateTables());
234: a.assertEquals(isolationLevel, myPMF
235: .getTransactionIsolation());
236: }
237: }
238:
239: /**
240: * Used by the JUnit framework to construct tests. Normally, programmers
241: * would never explicitly use this constructor.
242: *
243: * @param name Name of the <tt>TestCase</tt>.
244: */
245:
246: public PersistenceManagerFactoryImplTest(String name) {
247: super (name);
248: }
249:
250: /**
251: * Test instantiating a <code>PersistenceManagerFactory</code> via
252: * <code>JDOHelper.getPersistenceManagerFactory(Properties)</code>.
253: */
254: public void testJDOHelperInstantiation() {
255: /*
256: * Things to consider:
257: * - Unknown properties should do nothing.
258: * - Setting Optimistic or RetainValues to true sets NontransactionalRead
259: * to true.
260: * - TransactionIsolation has valid values of Connection.TRANSACTION_*;
261: * anything else will throw an Exception.
262: * - A PersistenceManagerFactory obtained via JDOHelper should be
263: * nonconfigurable.
264: */
265:
266: /*
267: * 1) Test setting all propers to valid values.
268: */
269: boolean optimistic = true;
270: boolean retainValues = true;
271: boolean restoreValues = true;
272: boolean ignoreCache = true;
273: boolean nontransactionalRead = true;
274: boolean nontransactionalWrite = true;
275: boolean multithreaded = true;
276: String driverName = DatabaseProperties.dbDriver;
277: String url = DatabaseProperties.dbURL;
278: String userName = DatabaseProperties.dbUser;
279: String password = DatabaseProperties.dbPassword;
280: //String factory1 = "factory1";
281: //String factory2 = "factory2";
282: boolean validateTables = true;
283: boolean validateConstraints = true;
284: boolean autoCreate = true;
285: int transactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
286:
287: PMFProperties props = new PMFProperties();
288: props.setOptimistic(optimistic);
289: props.setRetainValues(retainValues);
290: props.setRestoreValues(restoreValues);
291: props.setIgnoreCache(ignoreCache);
292: props.setNontransactionalRead(nontransactionalRead);
293: props.setNontransactionalWrite(nontransactionalWrite);
294: props.setMultithreaded(multithreaded);
295: props.setDriverName(driverName);
296: props.setUserName(userName);
297: props.setPassword(password);
298: props.setURL(url);
299: //props.setFactoryName(factory1); // Setting this uses jndi which blows up w/out
300: //props.setFactory2Name(factory2); // a managed environment (ie - no JNDI).
301: props.setValidateTables(validateTables);
302: props.setValidateConstraints(validateConstraints);
303: props.setAutoCreateTables(autoCreate);
304: props.setTransactionIsolation(transactionIsolation);
305:
306: PersistenceManagerFactory pmf = JDOHelper
307: .getPersistenceManagerFactory(props);
308: assertTrue(
309: "PMF should be com.triactive.jdo.PersistenceManagerFactoryImpl.",
310: (pmf instanceof PersistenceManagerFactoryImpl));
311: props.assertMatchesPMF(pmf, this );
312:
313: /*
314: * Flip a bunch of flags to assert that the PMF is still configurable.
315: */
316: pmf.setOptimistic(!optimistic);
317: pmf.setRetainValues(!retainValues);
318: pmf.setRestoreValues(!restoreValues);
319: pmf.setIgnoreCache(!ignoreCache);
320: pmf.setNontransactionalRead(!nontransactionalRead);
321: pmf.setNontransactionalWrite(!nontransactionalWrite);
322: pmf.setMultithreaded(!multithreaded);
323:
324: /* Scale back to a minimal set of properties for the following tests. */
325: props = new PMFProperties();
326: props.setDriverName(driverName);
327: props.setUserName(userName);
328: props.setPassword(password);
329: props.setURL(url);
330:
331: /*
332: * 2) Test that an invalid driver name throws an exception
333: */
334: props.setDriverName("my.test.driver.should.not.exist");
335: pmf = JDOHelper.getPersistenceManagerFactory(props);
336:
337: try {
338: pmf.getPersistenceManager();
339: fail("Invalid driver name should have thrown exception");
340: } catch (Exception e) { /* Ignore */
341: }
342: props.setDriverName(driverName); // restore
343:
344: /*
345: * 3) Test that setting an invalid transaction isolation throws an exception.
346: */
347: props.setTransactionIsolation(8738);
348:
349: try {
350: pmf = JDOHelper.getPersistenceManagerFactory(props);
351: fail("Setting invalid transaction isolation should have thrown exception");
352: } catch (Exception e) { /* Ignore */
353: }
354: props.setTransactionIsolation(transactionIsolation); // restore
355:
356: /*
357: * 4) Test that a PMF is not configurable after getting a PM.
358: */
359: pmf = JDOHelper.getPersistenceManagerFactory(props);
360: PersistenceManager pm = pmf.getPersistenceManager();
361:
362: try {
363: pmf.setRetainValues(!retainValues);
364: fail("Setting properties after frozen should throw exception");
365: } catch (JDOUserException e) { /* Ignore */
366: } finally {
367: pm.close();
368: }
369:
370: /*
371: * 5) Test that setting an unknown property does nothing weird.
372: */
373: props.setProperty("com.triactive.jdo.MyTestUnknownProperty",
374: "unknown");
375: pmf = JDOHelper.getPersistenceManagerFactory(props);
376: props.assertMatchesPMF(pmf, this );
377: }
378:
379: public void testSerialization() throws Exception {
380: /* Make a PMF to play with. */
381: PersistenceManagerFactory pmf1 = makeNonpooledPMF();
382: /* Clone it via serialization. */
383: PersistenceManagerFactory pmf2 = toPMF(toByteArray(pmf1));
384:
385: assertTrue("PMF did not deserialize into a different object",
386: pmf1 != pmf2);
387: assertEquals("PMF did not survive serialization intact", pmf1,
388: pmf2);
389: }
390:
391: private static byte[] toByteArray(PersistenceManagerFactory pmf)
392: throws IOException {
393: ByteArrayOutputStream bout = new ByteArrayOutputStream();
394: ObjectOutputStream oout = new ObjectOutputStream(
395: new BufferedOutputStream(bout));
396: oout.writeObject(pmf);
397: oout.close();
398:
399: return bout.toByteArray();
400: }
401:
402: private static PersistenceManagerFactory toPMF(byte[] ba)
403: throws IOException, ClassNotFoundException {
404: ByteArrayInputStream bin = new ByteArrayInputStream(ba);
405: ObjectInputStream oin = new ObjectInputStream(
406: new BufferedInputStream(bin));
407:
408: return (PersistenceManagerFactory) oin.readObject();
409: }
410:
411: public void testClose() throws Exception {
412: /* Make a PMF to play with. */
413: PersistenceManagerFactory pmf1 = makeNonpooledPMF();
414: PersistenceManager[] pms = new PersistenceManager[5];
415:
416: for (int i = 0; i < pms.length; ++i)
417: pms[i] = pmf1.getPersistenceManager();
418:
419: pms[2].currentTransaction().begin();
420:
421: try {
422: pmf1.close();
423: fail("PMF.close() should have failed, a TX is active");
424: } catch (JDOUserException e) {
425: Throwable nested[] = e.getNestedExceptions();
426:
427: assertNotNull("No nested exceptions: " + e, nested);
428: assertEquals("Wrong number of nested exceptions: " + e, 1,
429: nested.length);
430: }
431:
432: pms[2].currentTransaction().rollback();
433:
434: for (int i = 0; i < pms.length; ++i)
435: assertTrue("Failed PMF.close() errnoneously closed a PM: "
436: + pms[i], !pms[i].isClosed());
437:
438: pmf1.close();
439:
440: for (int i = 0; i < pms.length; ++i)
441: assertTrue("PMF.close() did not close PM: " + pms[i],
442: pms[i].isClosed());
443:
444: try {
445: pmf1.getPersistenceManager();
446: fail("PMF.getPersistenceManager() should have failed after PMF.close()");
447: } catch (JDOUserException e) {
448: // expected
449: }
450: }
451: }
|