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