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

http://datanucleus-appengine.googlecode.com/ · Java · 213 lines · 150 code · 19 blank · 44 comment · 0 complexity · dec8f4491cfecacd366ae07e32c4c21f 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.DatastoreServiceConfig;
  15. import com.google.appengine.api.datastore.Entity;
  16. import com.google.appengine.api.datastore.EntityNotFoundException;
  17. import com.google.appengine.api.datastore.KeyFactory;
  18. import com.google.appengine.api.datastore.KeyRange;
  19. import com.google.appengine.datanucleus.BaseDatastoreServiceDelegate;
  20. import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
  21. import com.google.appengine.datanucleus.SequenceTestLock;
  22. import com.google.appengine.datanucleus.Utils;
  23. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequence;
  24. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequenceOnNonPkFields;
  25. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequenceWithNoSequenceName;
  26. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequenceWithSequenceGenerator;
  27. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequenceWithSequenceGenerator2;
  28. import com.google.appengine.datanucleus.test.jdo.SequenceExamplesJDO.HasSequenceWithUnencodedStringPk;
  29. import com.google.appengine.datanucleus.valuegenerator.SequenceGenerator;
  30. import java.util.List;
  31. import javax.jdo.datastore.Sequence;
  32. /**
  33. * @author Max Ross <maxr@google.com>
  34. */
  35. public class JDOSequenceTest extends JDOTestCase {
  36. private final List<String> sequenceNames = Utils.newArrayList();
  37. private final List<Long> sequenceBatchSizes = Utils.newArrayList();
  38. @Override
  39. protected void setUp() throws Exception {
  40. super.setUp();
  41. DatastoreServiceConfig config = getStoreManager().getDefaultDatastoreServiceConfigForReads();
  42. DatastoreServiceFactoryInternal.setDatastoreService(
  43. new BaseDatastoreServiceDelegate(DatastoreServiceFactoryInternal.getDatastoreService(config)) {
  44. @Override
  45. public KeyRange allocateIds(String kind, long size) {
  46. sequenceNames.add(kind);
  47. sequenceBatchSizes.add(size);
  48. return super.allocateIds(kind, size);
  49. }
  50. });
  51. SequenceTestLock.LOCK.acquire();
  52. SequenceGenerator.setSequencePostfixAppendage("JDO");
  53. }
  54. @Override
  55. protected void tearDown() throws Exception {
  56. SequenceGenerator.clearSequencePostfixAppendage();
  57. SequenceTestLock.LOCK.release();
  58. DatastoreServiceFactoryInternal.setDatastoreService(null);
  59. sequenceNames.clear();
  60. sequenceBatchSizes.clear();
  61. super.tearDown();
  62. }
  63. public void testSimpleInsert() throws EntityNotFoundException {
  64. String kind = getKind(HasSequence.class);
  65. HasSequence pojo = new HasSequence();
  66. pojo.setVal("jdo1");
  67. beginTxn();
  68. pm.makePersistent(pojo);
  69. commitTxn();
  70. Entity e = ds.get(KeyFactory.createKey(kind, pojo.getId()));
  71. assertEquals("jdo1", e.getProperty("val"));
  72. HasSequence pojo2 = new HasSequence();
  73. pojo2.setVal("jdo2");
  74. beginTxn();
  75. pm.makePersistent(pojo2);
  76. commitTxn();
  77. e = ds.get(KeyFactory.createKey(kind, pojo2.getId()));
  78. assertEquals("jdo2", e.getProperty("val"));
  79. // the local datastore id allocator is a single sequence so if there
  80. // are any other allocations happening we can't assert on exact values.
  81. // uncomment this check and the others below when we bring the local
  82. // allocator in line with the prod allocator
  83. assertTrue(pojo.getId() < pojo2.getId());
  84. assertEquals(Utils.newArrayList(kind + "_SEQUENCE__JDO", kind + "_SEQUENCE__JDO"), sequenceNames);
  85. assertEquals(Utils.newArrayList(1L, 1L), sequenceBatchSizes);
  86. }
  87. public void testInsertWithSequenceGenerator() throws EntityNotFoundException {
  88. String kind = getKind(HasSequenceWithSequenceGenerator.class);
  89. HasSequenceWithSequenceGenerator pojo = new HasSequenceWithSequenceGenerator();
  90. pojo.setVal("jdo1");
  91. beginTxn();
  92. pm.makePersistent(pojo);
  93. commitTxn();
  94. Entity e = ds.get(KeyFactory.createKey(kind, pojo.getId()));
  95. assertEquals("jdo1", e.getProperty("val"));
  96. assertEquals(Utils.newArrayList("jdothat"), sequenceNames);
  97. assertEquals(Utils.newArrayList(12L), sequenceBatchSizes);
  98. }
  99. public void testInsertWithSequenceGenerator_NoSequenceName() throws EntityNotFoundException {
  100. String kind = getKind(HasSequenceWithNoSequenceName.class);
  101. HasSequenceWithNoSequenceName pojo = new HasSequenceWithNoSequenceName();
  102. beginTxn();
  103. pm.makePersistent(pojo);
  104. commitTxn();
  105. ds.get(KeyFactory.createKey(kind, pojo.getId()));
  106. assertEquals(Utils.newArrayList(kind + "_SEQUENCE__JDO"), sequenceNames);
  107. assertEquals(Utils.newArrayList(12L), sequenceBatchSizes);
  108. }
  109. public void testDirectSequenceAccess() throws Exception {
  110. // in order to make sure we get a fresh block of ids when we persist
  111. // we need to make sure we don't reuse the pmf
  112. pmf.close();
  113. tearDown();
  114. setUp();
  115. KeyRange range = ds.allocateIds("jdothat2", 1);
  116. HasSequenceWithSequenceGenerator2 pojo = new HasSequenceWithSequenceGenerator2();
  117. beginTxn();
  118. pm.makePersistent(pojo);
  119. commitTxn();
  120. // the local datastore id allocator is a single sequence so if there
  121. // are any other allocations happening we can't assert on exact values.
  122. // uncomment this check and the others below when we bring the local
  123. // allocator in line with the prod allocator
  124. // assertEquals(range.getEnd().getId(), pojo.getId() - 1);
  125. assertTrue(range.getEnd().getId() < pojo.getId());
  126. Sequence seq = pm.getSequence("jdo1b");
  127. // assertEquals(pojo.getId() + 12, seq.nextValue());
  128. assertTrue(pojo.getId() + 12 <= seq.nextValue());
  129. // assertEquals(pojo.getId() + 13, seq.nextValue());
  130. assertTrue(pojo.getId() + 13 <= seq.nextValue());
  131. assertEquals(Utils.newArrayList("jdothat2", "jdothat2"), sequenceNames);
  132. assertEquals(Utils.newArrayList(12L, 12L), sequenceBatchSizes);
  133. sequenceNames.clear();
  134. sequenceBatchSizes.clear();
  135. // getting a sequence always gets you a fresh batch
  136. seq = pm.getSequence("jdo1b");
  137. // assertEquals(pojo.getId() + 24, seq.nextValue());
  138. assertTrue(pojo.getId() + 24 <= seq.nextValue());
  139. // assertEquals(pojo.getId() + 25, seq.nextValue());
  140. assertTrue(pojo.getId() + 25 <= seq.nextValue());
  141. assertEquals(Utils.newArrayList("jdothat2"), sequenceNames);
  142. assertEquals(Utils.newArrayList(12L), sequenceBatchSizes);
  143. }
  144. public void testSequenceWithUnencodedStringPk() throws EntityNotFoundException {
  145. String kind = getKind(HasSequenceWithUnencodedStringPk.class);
  146. HasSequenceWithUnencodedStringPk pojo = new HasSequenceWithUnencodedStringPk();
  147. beginTxn();
  148. pm.makePersistent(pojo);
  149. commitTxn();
  150. ds.get(KeyFactory.createKey(kind, pojo.getId()));
  151. HasSequenceWithUnencodedStringPk pojo2 = new HasSequenceWithUnencodedStringPk();
  152. beginTxn();
  153. pm.makePersistent(pojo2);
  154. commitTxn();
  155. ds.get(KeyFactory.createKey(kind, pojo2.getId()));
  156. // the local datastore id allocator is a single sequence so if there
  157. // are any other allocations happening we can't assert on exact values.
  158. // uncomment this check and the others below when we bring the local
  159. // allocator in line with the prod allocator
  160. // assertEquals(Long.parseLong(pojo.getId()), Long.parseLong(pojo2.getId()) - 1);
  161. assertTrue(Long.parseLong(pojo.getId()) < Long.parseLong(pojo2.getId()));
  162. assertEquals(Utils.newArrayList(kind + "_SEQUENCE__JDO", kind + "_SEQUENCE__JDO"), sequenceNames);
  163. assertEquals(Utils.newArrayList(1L, 1L), sequenceBatchSizes);
  164. }
  165. public void testSequenceOnNonPkFields() throws EntityNotFoundException {
  166. String kind = getKind(HasSequenceOnNonPkFields.class);
  167. HasSequenceOnNonPkFields pojo = new HasSequenceOnNonPkFields();
  168. pojo.setId("jdo");
  169. beginTxn();
  170. pm.makePersistent(pojo);
  171. // the local datastore id allocator is a single sequence so if there
  172. // are any other allocations happening we can't assert on exact values.
  173. // uncomment this check and the others below when we bring the local
  174. // allocator in line with the prod allocator
  175. assertTrue(pojo.getVal1() < pojo.getVal2());
  176. commitTxn();
  177. HasSequenceOnNonPkFields pojo2 = new HasSequenceOnNonPkFields();
  178. pojo2.setId("jdo");
  179. beginTxn();
  180. pm.makePersistent(pojo2);
  181. // assertEquals(pojo.getVal2(), pojo2.getVal1() - 1);
  182. assertTrue(pojo.getVal2() < pojo2.getVal1());
  183. commitTxn();
  184. assertEquals(Utils.newArrayList(kind + "_SEQUENCE__JDO", kind + "_SEQUENCE__JDO",
  185. kind + "_SEQUENCE__JDO", kind + "_SEQUENCE__JDO"), sequenceNames);
  186. assertEquals(Utils.newArrayList(1L, 1L, 1L, 1L), sequenceBatchSizes);
  187. }
  188. private String getKind(Class<?> cls) {
  189. return cls.getName().substring(cls.getName().lastIndexOf(".") + 1);
  190. }
  191. }