PageRenderTime 71ms CodeModel.GetById 39ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/com/google/appengine/datanucleus/jdo/JDOTransactionTest.java

http://datanucleus-appengine.googlecode.com/
Java | 669 lines | 560 code | 72 blank | 37 comment | 26 complexity | 8b0187d96aad6a6b7f19957d7041a4f7 MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus.jdo;
 17
 18import com.google.appengine.api.datastore.DatastoreService;
 19import com.google.appengine.api.datastore.DatastoreServiceFactory;
 20import com.google.appengine.api.datastore.Entity;
 21import com.google.appengine.api.datastore.EntityNotFoundException;
 22import com.google.appengine.api.datastore.Key;
 23import com.google.appengine.api.datastore.KeyFactory;
 24import com.google.appengine.api.datastore.TransactionOptions;
 25import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
 26import com.google.appengine.datanucleus.DatastoreServiceRecordingImpl;
 27import com.google.appengine.datanucleus.DatastoreTestCase;
 28import com.google.appengine.datanucleus.Inner;
 29import com.google.appengine.datanucleus.TxnIdAnswer;
 30import com.google.appengine.datanucleus.test.jdo.Flight;
 31import com.google.appengine.datanucleus.test.jdo.HasKeyAncestorKeyPkJDO;
 32
 33import org.datanucleus.api.jdo.exceptions.TransactionNotReadableException;
 34import org.datanucleus.api.jdo.exceptions.TransactionNotWritableException;
 35import org.easymock.EasyMock;
 36
 37import javax.jdo.JDOHelper;
 38import javax.jdo.PersistenceManager;
 39import javax.jdo.PersistenceManagerFactory;
 40import javax.jdo.Query;
 41import javax.jdo.Transaction;
 42
 43/**
 44 * Verifies jdo txn behavior across the following variables:
 45 * datasource type (txn | nontxn)
 46 * programmatic txn demarcation (yes | no)
 47 * operation (read | write)
 48 * support for that operation outside a txn (yes | no)
 49 * 
 50 * See https://spreadsheets.google.com/a/google.com/pub?key=p8C3zgqqUfpstFKZ4ns1bQg
 51 * for all the gory details.
 52 *
 53 * @author Erick Armbrust <earmbrust@google.com>
 54 * @author Max Ross <maxr@google.com>
 55 */
 56public class JDOTransactionTest extends DatastoreTestCase {
 57
 58  private DatastoreService mockDatastoreService = EasyMock.createMock(DatastoreService.class);
 59  private com.google.appengine.api.datastore.Transaction mockTxn = EasyMock.createMock(
 60      com.google.appengine.api.datastore.Transaction.class);
 61  private DatastoreServiceRecordingImpl recordingImpl;
 62  private TxnIdAnswer txnIdAnswer;
 63  private DatastoreService ds;
 64
 65  @Override
 66  protected void setUp() throws Exception {
 67    super.setUp();
 68    txnIdAnswer = new TxnIdAnswer();
 69    ds = DatastoreServiceFactory.getDatastoreService();
 70    recordingImpl =
 71        new DatastoreServiceRecordingImpl(mockDatastoreService, ds, mockTxn, txnIdAnswer);
 72    DatastoreServiceFactoryInternal.setDatastoreService(recordingImpl);
 73  }
 74
 75  @Override
 76  protected void tearDown() throws Exception {
 77    EasyMock.reset(mockDatastoreService, mockTxn);
 78    DatastoreServiceFactoryInternal.setDatastoreService(null);
 79    recordingImpl = null;
 80    super.tearDown();
 81  }
 82
 83  /**
 84   * A new PersistenceManagerFactory should be fetched on a per-test basis.  The
 85   * DatastoreService within the DatastorePersistenceHandler is obtained via the
 86   * DatastoreServiceFactory, so this ensures that the "injected" factory impl
 87   * is returned.
 88   */
 89  private PersistenceManagerFactory getPersistenceManagerFactory(String pmfName) {
 90    return JDOHelper.getPersistenceManagerFactory(pmfName);
 91  }
 92
 93  private void testWritePermutationWithExpectedDatastoreTxn(
 94      PersistenceManager pm, boolean explicitDemarcation,
 95      boolean nonTransactionalWrite) {
 96    EasyMock.expect(mockDatastoreService.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(mockTxn);
 97    EasyMock.expect(mockDatastoreService.put(
 98        EasyMock.isA(com.google.appengine.api.datastore.Transaction.class),
 99        EasyMock.isA(Entity.class))).andReturn(null);
100    EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer).anyTimes();
101    EasyMock.expect(mockTxn.isActive()).andReturn(true).anyTimes();
102    EasyMock.expect(mockTxn.getApp()).andReturn("test").anyTimes();
103    mockTxn.commit();
104    EasyMock.replay(mockDatastoreService, mockTxn);
105
106    Flight f1 = new Flight();
107    f1.setName("Harold");
108    f1.setOrigin("BOS");
109    f1.setDest("MIA");
110    f1.setYou(1);
111    f1.setMe(2);
112
113    Transaction txn = pm.currentTransaction();
114    txn.setNontransactionalWrite(nonTransactionalWrite);
115    if (explicitDemarcation) {
116      txn.begin();
117    }
118    try {
119      pm.makePersistent(f1);
120    } finally {
121      if (explicitDemarcation) {
122        txn.commit();
123      }
124    }
125    EasyMock.verify(mockDatastoreService, mockTxn);
126    EasyMock.reset(mockDatastoreService, mockTxn);
127  }
128
129  private void testUpdatePermutationWithExpectedDatastoreTxn(
130      PersistenceManagerFactory pmf, boolean explicitDemarcation, boolean nonTransactionalWrite)
131      throws EntityNotFoundException {
132    Entity flightEntity = Flight.newFlightEntity("Harold", "BOS", "MIA", 1, 2);
133    ds.put(flightEntity);
134    EasyMock.expect(mockDatastoreService.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(mockTxn);
135    EasyMock.expect(mockDatastoreService.get(
136        EasyMock.isA(com.google.appengine.api.datastore.Transaction.class),
137        EasyMock.isA(Key.class))).andReturn(flightEntity);
138    EasyMock.expect(mockDatastoreService.get(
139        EasyMock.isA(Key.class))).andReturn(flightEntity);
140    EasyMock.expect(mockDatastoreService.put(
141        EasyMock.isA(com.google.appengine.api.datastore.Transaction.class),
142        EasyMock.isA(Entity.class))).andReturn(null);
143    EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer).anyTimes();
144    EasyMock.expect(mockTxn.isActive()).andReturn(true).anyTimes();
145    EasyMock.expect(mockTxn.getApp()).andReturn("test").anyTimes();
146    mockTxn.commit();
147    EasyMock.replay(mockDatastoreService, mockTxn);
148
149    PersistenceManager pm = pmf.getPersistenceManager();
150    Transaction txn = pm.currentTransaction();
151    txn.setNontransactionalWrite(nonTransactionalWrite);
152    if (explicitDemarcation) {
153      txn.begin();
154    }
155    try {
156      Flight f1 = pm.getObjectById(Flight.class, KeyFactory.keyToString(flightEntity.getKey()));
157      f1.setYou(88);
158    } finally {
159      if (explicitDemarcation) {
160        txn.commit();
161      }
162      pm.close();
163    }
164    EasyMock.verify(mockDatastoreService, mockTxn);
165    EasyMock.reset(mockDatastoreService, mockTxn);
166  }
167
168  private void testReadPermutationWithExpectedDatastoreTxn(
169      PersistenceManager pm, boolean explicitDemarcation,
170      boolean nonTransactionalRead) throws EntityNotFoundException {
171
172    EasyMock.expect(mockDatastoreService.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(mockTxn);
173    EasyMock.expect(mockDatastoreService.get(
174        EasyMock.isA(com.google.appengine.api.datastore.Transaction.class),
175        EasyMock.isA(Key.class))).andReturn(null);
176    EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer).anyTimes();
177    EasyMock.expect(mockTxn.isActive()).andReturn(true).anyTimes();
178    EasyMock.expect(mockTxn.getApp()).andReturn("test").anyTimes();
179    mockTxn.commit();
180    EasyMock.replay(mockDatastoreService, mockTxn);
181
182    Entity f1 = Flight.newFlightEntity("foo", "bar", "baz", 1, 2);
183    ds.put(f1);
184
185    Transaction txn = pm.currentTransaction();
186    txn.setNontransactionalRead(nonTransactionalRead);
187    if (explicitDemarcation) {
188      txn.begin();
189    }
190    try {
191      pm.getObjectById(Flight.class, KeyFactory.keyToString(f1.getKey()));
192    } finally {
193      if (explicitDemarcation) {
194        txn.commit();
195      }
196    }
197
198    EasyMock.verify(mockDatastoreService, mockTxn);
199    EasyMock.reset(mockDatastoreService, mockTxn);
200  }
201
202  private void testWritePermutationWithoutExpectedDatastoreTxn(
203      PersistenceManager pm, boolean explicitDemarcation, boolean nonTransactionalOpAllowed) {
204    EasyMock.expect(mockDatastoreService.put(EasyMock.isA(Entity.class))).andReturn(null);
205    EasyMock.replay(mockDatastoreService, mockTxn);
206
207    Flight f1 = new Flight();
208    f1.setName("Harold");
209    f1.setOrigin("BOS");
210    f1.setDest("MIA");
211    f1.setYou(1);
212    f1.setMe(2);
213
214    Transaction txn = pm.currentTransaction();
215    txn.setNontransactionalWrite(nonTransactionalOpAllowed);
216    txn.setNontransactionalRead(nonTransactionalOpAllowed);
217    if (explicitDemarcation) {
218      txn.begin();
219    }
220    try {
221      pm.makePersistent(f1);
222    } finally {
223      if (explicitDemarcation) {
224        txn.commit();
225      }
226    }
227
228    EasyMock.verify(mockDatastoreService, mockTxn);
229    EasyMock.reset(mockDatastoreService, mockTxn);
230  }
231
232  private void testUpdatePermutationWithoutExpectedDatastoreTxn(
233      PersistenceManagerFactory pmf, boolean explicitDemarcation, boolean nonTransactionalOp)
234      throws EntityNotFoundException {
235    Entity flightEntity = Flight.newFlightEntity("Harold", "BOS", "MIA", 1, 2);
236    ds.put(flightEntity);
237    EasyMock.expect(mockDatastoreService.get(
238        EasyMock.isA(Key.class))).andReturn(flightEntity);
239    EasyMock.expect(mockDatastoreService.get(
240        EasyMock.isA(Key.class))).andReturn(flightEntity);
241    EasyMock.expect(mockDatastoreService.put(
242        EasyMock.isA(Entity.class))).andReturn(null);
243    EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer).anyTimes();
244    EasyMock.replay(mockDatastoreService, mockTxn);
245
246    PersistenceManager pm = pmf.getPersistenceManager();
247    Transaction txn = pm.currentTransaction();
248    txn.setNontransactionalWrite(nonTransactionalOp);
249    txn.setNontransactionalRead(nonTransactionalOp);
250    if (explicitDemarcation) {
251      txn.begin();
252    }
253    try {
254      Flight f1 = pm.getObjectById(Flight.class, KeyFactory.keyToString(flightEntity.getKey()));
255      f1.setYou(88);
256    } finally {
257      if (explicitDemarcation) {
258        txn.commit();
259      }
260      pm.close();
261    }
262    EasyMock.verify(mockDatastoreService, mockTxn);
263    EasyMock.reset(mockDatastoreService, mockTxn);
264  }
265
266  private void testReadPermutationWithoutExpectedDatastoreTxn(
267      PersistenceManager pm, boolean explicitDemarcation,
268      boolean nonTransactionalRead) throws EntityNotFoundException {
269    EasyMock.expect(mockDatastoreService.get(EasyMock.isA(Key.class))).andReturn(null);
270    EasyMock.replay(mockDatastoreService, mockTxn);
271
272    Entity f1 = Flight.newFlightEntity("foo", "bar", "baz", 1, 2);
273    ds.put(f1);
274
275    Transaction txn = pm.currentTransaction();
276    txn.setNontransactionalRead(nonTransactionalRead);
277    if (explicitDemarcation) {
278      txn.begin();
279    }
280    try {
281      pm.getObjectById(Flight.class, KeyFactory.keyToString(f1.getKey()));
282    } finally {
283      if (explicitDemarcation) {
284        txn.commit();
285      }
286    }
287    EasyMock.verify(mockDatastoreService, mockTxn);
288    EasyMock.reset(mockDatastoreService, mockTxn);
289  }
290
291  private interface QueryRunner {
292    void runQuery(PersistenceManager pm);
293    boolean isAncestor();
294  }
295
296  private void testQueryPermutationWithoutExpectedDatastoreTxn(
297      PersistenceManager pm, boolean explicitDemarcation,
298      boolean nonTransactionalRead, QueryRunner queryRunner) throws EntityNotFoundException {
299    if (queryRunner.isAncestor()) {
300      EasyMock.expect(mockDatastoreService.getCurrentTransaction(null)).andReturn(null);
301    }
302    EasyMock.expect(mockDatastoreService.prepare(
303        (com.google.appengine.api.datastore.Transaction) EasyMock.isNull(),
304        EasyMock.isA(com.google.appengine.api.datastore.Query.class))).andReturn(null);
305    EasyMock.replay(mockDatastoreService, mockTxn);
306
307    Transaction txn = pm.currentTransaction();
308    txn.setNontransactionalRead(nonTransactionalRead);
309    if (explicitDemarcation) {
310      txn.begin();
311    }
312    try {
313      queryRunner.runQuery(pm);
314    } finally {
315      if (explicitDemarcation) {
316        txn.commit();
317      }
318    }
319    EasyMock.verify(mockDatastoreService, mockTxn);
320    EasyMock.reset(mockDatastoreService, mockTxn);
321  }
322
323  private void testQueryPermutationWithExpectedDatastoreTxn(
324      PersistenceManager pm, boolean explicitDemarcation,
325      boolean nonTransactionalRead, QueryRunner queryRunner) throws EntityNotFoundException {
326
327    EasyMock.expect(mockDatastoreService.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(mockTxn);
328    if (queryRunner.isAncestor()) {
329      EasyMock.expect(mockDatastoreService.getCurrentTransaction(null)).andReturn(mockTxn);
330    }
331    if (queryRunner.isAncestor()) {
332      EasyMock.expect(mockDatastoreService.prepare(
333          EasyMock.isA(com.google.appengine.api.datastore.Transaction.class),
334          EasyMock.isA(com.google.appengine.api.datastore.Query.class))).andReturn(null);
335      EasyMock.expect(mockTxn.isActive()).andReturn(true).times(3);
336    } else {
337      EasyMock.expect(mockDatastoreService.prepare(
338          (com.google.appengine.api.datastore.Transaction) EasyMock.isNull(),
339          EasyMock.isA(com.google.appengine.api.datastore.Query.class))).andReturn(null);
340    }
341    EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer).anyTimes();
342    EasyMock.expect(mockTxn.getApp()).andReturn("test").anyTimes();
343    mockTxn.commit();
344    EasyMock.replay(mockDatastoreService, mockTxn);
345
346    Transaction txn = pm.currentTransaction();
347    txn.setNontransactionalRead(nonTransactionalRead);
348    if (explicitDemarcation) {
349      txn.begin();
350    }
351    try {
352      queryRunner.runQuery(pm);
353    } finally {
354      if (explicitDemarcation) {
355        txn.commit();
356      }
357    }
358
359    EasyMock.verify(mockDatastoreService, mockTxn);
360    EasyMock.reset(mockDatastoreService, mockTxn);
361  }
362
363
364  private void testIllegalWritePermutation(
365      PersistenceManager pm, boolean explicitDemarcation, boolean nonTransactionalWrite) {
366
367    EasyMock.replay(mockDatastoreService, mockTxn);
368
369    Flight f1 = new Flight();
370    f1.setName("Harold");
371    f1.setOrigin("BOS");
372    f1.setDest("MIA");
373    f1.setYou(1);
374    f1.setMe(2);
375
376    Transaction txn = pm.currentTransaction();
377    txn.setNontransactionalWrite(nonTransactionalWrite);
378    if (explicitDemarcation) {
379      txn.begin();
380    }
381    try {
382      pm.makePersistent(f1);
383      fail("Expected exception");
384    } catch (TransactionNotWritableException e) {
385      // good
386    }
387    EasyMock.verify(mockDatastoreService, mockTxn);
388    EasyMock.reset(mockDatastoreService, mockTxn);
389  }
390
391  private void testIllegalUpdatePermutation(
392      PersistenceManagerFactory pmf, boolean explicitDemarcation, boolean nonTransactionalOp)
393      throws EntityNotFoundException {
394    Entity flightEntity = Flight.newFlightEntity("Harold", "BOS", "MIA", 1, 2);
395    ds.put(flightEntity);
396    EasyMock.replay(mockDatastoreService, mockTxn);
397
398    PersistenceManager pm = pmf.getPersistenceManager();
399    Transaction txn = pm.currentTransaction();
400    txn.setNontransactionalWrite(nonTransactionalOp);
401    txn.setNontransactionalRead(nonTransactionalOp);
402    if (explicitDemarcation) {
403      txn.begin();
404    }
405    try {
406      /*Flight f =*/ pm.getObjectById(Flight.class, KeyFactory.keyToString(flightEntity.getKey()));
407      fail("expected exception");
408    } catch (TransactionNotReadableException tnre) {
409      // good
410    } finally {
411      if (explicitDemarcation) {
412        txn.commit();
413      }
414      pm.close();
415    }
416    EasyMock.verify(mockDatastoreService, mockTxn);
417    EasyMock.reset(mockDatastoreService, mockTxn);
418
419  }
420
421  private void testIllegalReadPermutation(
422      PersistenceManager pm, boolean explicitDemarcation,
423      boolean nonTransactionalRead) throws EntityNotFoundException {
424
425    EasyMock.replay(mockDatastoreService, mockTxn);
426
427    Entity f1 = Flight.newFlightEntity("foo", "bar", "baz", 1, 2);
428    ds.put(f1);
429
430    Transaction txn = pm.currentTransaction();
431    txn.setNontransactionalRead(nonTransactionalRead);
432    if (explicitDemarcation) {
433      txn.begin();
434    }
435    try {
436      pm.getObjectById(Flight.class, KeyFactory.keyToString(f1.getKey()));
437      fail("Expected exception");
438    } catch (TransactionNotReadableException e) {
439      // good
440    }
441    EasyMock.verify(mockDatastoreService, mockTxn);
442    EasyMock.reset(mockDatastoreService, mockTxn);
443  }
444
445  private static final boolean EXPLICIT_DEMARCATION = true;
446  private static final boolean NO_EXPLICIT_DEMARCATION = false;
447  private static final boolean NON_TXN_OP_ALLOWED = true;
448  private static final boolean NON_TXN_OP_NOT_ALLOWED = false;
449
450  public void testWritesWithDatastoreTxn() throws Exception {
451    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
452        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
453    PersistenceManager pm = pmf.getPersistenceManager();
454    testWritePermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
455    testWritePermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
456    pm.close();
457    pmf.close();
458  }
459
460  public void testUpdatesWithDatastoreTxn() throws Exception {
461    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
462        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
463    testUpdatePermutationWithExpectedDatastoreTxn(pmf, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
464    testUpdatePermutationWithExpectedDatastoreTxn(pmf, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
465    pmf.close();
466  }
467
468  public void testReadsWithDatastoreTxn() throws Exception {
469    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
470        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
471    PersistenceManager pm = pmf.getPersistenceManager();
472    testReadPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
473    testReadPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
474    pm.close();
475    pmf.close();
476  }
477
478  public void testWritesWithoutDatastoreTxn() throws Exception {
479    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
480        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
481    PersistenceManager pm = pmf.getPersistenceManager();
482    testWritePermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
483    pm.close();
484    pmf.close();
485
486    pmf = getPersistenceManagerFactory(
487        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
488    pm = pmf.getPersistenceManager();
489    testWritePermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
490    testWritePermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
491    testWritePermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
492
493    pm.close();
494    pmf.close();
495  }
496
497  public void testUpdatesWithoutDatastoreTxn() throws Exception {
498    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
499        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
500    testUpdatePermutationWithoutExpectedDatastoreTxn(pmf, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
501    pmf.close();
502
503    pmf = getPersistenceManagerFactory(
504        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
505    testUpdatePermutationWithoutExpectedDatastoreTxn(pmf, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
506    testUpdatePermutationWithoutExpectedDatastoreTxn(pmf, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
507    testUpdatePermutationWithoutExpectedDatastoreTxn(pmf, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
508
509    pmf.close();
510  }
511
512  public void testReadsWithoutDatastoreTxn() throws Exception {
513    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
514        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
515    PersistenceManager pm = pmf.getPersistenceManager();
516    testReadPermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
517    pm.close();
518    pmf.close();
519
520    pmf = getPersistenceManagerFactory(
521        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
522    pm = pmf.getPersistenceManager();
523    testReadPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
524    testReadPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
525    testReadPermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED);
526
527    pm.close();
528    pmf.close();
529  }
530
531  public void testIllegalWrites() throws Exception {
532    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
533        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
534    PersistenceManager pm = pmf.getPersistenceManager();
535    testIllegalWritePermutation(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
536    pm.close();
537    pmf.close();
538    pmf = getPersistenceManagerFactory(
539        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
540    pm = pmf.getPersistenceManager();
541    testIllegalWritePermutation(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
542    pm.close();
543    pmf.close();
544  }
545
546  public void testIllegalUpdates() throws Exception {
547    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
548        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
549    testIllegalUpdatePermutation(pmf, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
550    pmf.close();
551    pmf = getPersistenceManagerFactory(
552        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
553    testIllegalUpdatePermutation(pmf, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
554    pmf.close();
555  }
556
557  public void testIllegalReads() throws Exception {
558    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
559        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
560    PersistenceManager pm = pmf.getPersistenceManager();
561    testIllegalReadPermutation(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
562    pm.close();
563    pmf.close();
564    pmf = getPersistenceManagerFactory(
565        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
566    pm = pmf.getPersistenceManager();
567    testIllegalReadPermutation(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED);
568    pm.close();
569    pmf.close();
570  }
571
572  private static final QueryRunner ANCESTOR = new QueryRunner() {
573    public void runQuery(PersistenceManager pm) {
574      Query q = pm.newQuery(HasKeyAncestorKeyPkJDO.class, "ancestorKey == :p");
575      q.execute(KeyFactory.createKey("yar", 23));
576    }
577
578    public boolean isAncestor() {
579      return true;
580    }
581  };
582
583  private static final QueryRunner NON_ANCESTOR = new QueryRunner() {
584    public void runQuery(PersistenceManager pm) {
585      Query q = pm.newQuery(Flight.class);
586      q.execute();
587    }
588
589    public boolean isAncestor() {
590      return false;
591    }
592  };
593
594  @Inner("TODO -- see if we can avoid this tx mock check")
595  public void testQueriesWithDatastoreTxn() throws Exception {
596    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
597        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
598    PersistenceManager pm = pmf.getPersistenceManager();
599    testQueryPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, ANCESTOR);
600    testQueryPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED, ANCESTOR);
601    testQueryPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, NON_ANCESTOR);
602    testQueryPermutationWithExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED, NON_ANCESTOR);
603    pm.close();
604    pmf.close();
605  }
606
607  public void testQueriesWithoutDatastoreTxn() throws Exception {
608    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
609        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
610    PersistenceManager pm = pmf.getPersistenceManager();
611    testQueryPermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, ANCESTOR);
612    pm.close();
613    pmf.close();
614
615    pmf = getPersistenceManagerFactory(
616        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
617    pm = pmf.getPersistenceManager();
618    testQueryPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, ANCESTOR);
619    testQueryPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED, ANCESTOR);
620    testQueryPermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, ANCESTOR);
621    testQueryPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, NON_ANCESTOR);
622    testQueryPermutationWithoutExpectedDatastoreTxn(pm, EXPLICIT_DEMARCATION, NON_TXN_OP_NOT_ALLOWED, NON_ANCESTOR);
623    testQueryPermutationWithoutExpectedDatastoreTxn(pm, NO_EXPLICIT_DEMARCATION, NON_TXN_OP_ALLOWED, NON_ANCESTOR);
624
625    pm.close();
626    pmf.close();
627  }
628
629  public void testEmptyTxnBlock_Txn() {
630    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
631        JDOTestCase.PersistenceManagerFactoryName.transactional.name());
632    PersistenceManager pm = pmf.getPersistenceManager();
633    try {
634      EasyMock.expect(mockDatastoreService.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(mockTxn);
635      EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer);
636      EasyMock.expect(mockTxn.getId()).andAnswer(txnIdAnswer);
637      mockTxn.commit();
638      EasyMock.expectLastCall();
639      EasyMock.replay(mockDatastoreService, mockTxn);
640      pm.currentTransaction().begin();
641      pm.currentTransaction().commit();
642      EasyMock.verify(mockDatastoreService, mockTxn);
643    } finally {
644      if (pm.currentTransaction().isActive()) {
645        pm.currentTransaction().rollback();
646      }
647      pm.close();
648      pmf.close();
649    }
650  }
651
652  public void testEmptyTxnBlock_NoTxn() {
653    PersistenceManagerFactory pmf = getPersistenceManagerFactory(
654        JDOTestCase.PersistenceManagerFactoryName.nontransactional.name());
655    PersistenceManager pm = pmf.getPersistenceManager();
656    try {
657      EasyMock.replay(mockDatastoreService, mockTxn);
658      pm.currentTransaction().begin();
659      pm.currentTransaction().commit();
660      EasyMock.verify(mockDatastoreService, mockTxn);
661    } finally {
662      if (pm.currentTransaction().isActive()) {
663        pm.currentTransaction().rollback();
664      }
665      pm.close();
666      pmf.close();
667    }
668  }
669}