Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(522)

Side by Side Diff: appengine/findit/model/test/versioned_model_test.py

Issue 2345093002: [Findit] Extending versioned_model.py to support versioning multiple entities of the same class. (Closed)
Patch Set: Changing versioning mechanism to use integer for version number and fixing concurrency issue Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from google.appengine.api import datastore_errors 5 from google.appengine.api import datastore_errors
6 from google.appengine.ext import ndb 6 from google.appengine.ext import ndb
7 7
8 from testing_utils import testing 8 from testing_utils import testing
9 9
10 from model.versioned_model import VersionedModel 10 from model.versioned_model import VersionedModel
11 11
12 12
13 class _Entity(VersionedModel): 13 class _SingularEntity(VersionedModel):
14 value = ndb.IntegerProperty(indexed=False)
15
16
17 class _MultipleEntity(VersionedModel):
18
19 @staticmethod
20 def Create(string_id):
21 return _MultipleEntity(key=ndb.Key('_MultipleEntity', string_id))
22
14 value = ndb.IntegerProperty(indexed=False) 23 value = ndb.IntegerProperty(indexed=False)
15 24
16 25
17 class VersionedModelTest(testing.AppengineTestCase): 26 class VersionedModelTest(testing.AppengineTestCase):
18 27
19 def testGetRootModel(self): 28 def testGetRootModel(self):
20 root_model_class = _Entity._GetRootModel() 29 root_model_class = _SingularEntity._GetRootModel()
21 self.assertEqual('_EntityRoot', root_model_class._get_kind()) 30 self.assertEqual('_SingularEntityRoot', root_model_class._get_kind())
22 self.assertTrue(issubclass(root_model_class, ndb.Model)) 31 self.assertTrue(issubclass(root_model_class, ndb.Model))
23 self.assertEqual(3, root_model_class(current=3).current) 32 self.assertEqual(3, root_model_class(current=3).current)
24 33
25 def testDefaultVersionIsZero(self): 34 def testDefaultVersionIsZero(self):
26 entity = _Entity() 35 self.assertEqual(0, _SingularEntity().version)
27 self.assertEqual(0, entity.version) 36 self.assertEqual(0, _MultipleEntity().version)
28 37
29 def testGetMostRecentVersionWhenNoData(self): 38 def testVersionForMultipleEntity(self):
30 entity = _Entity.GetVersion() 39 multiple_entity = _MultipleEntity.Create('m1')
31 self.assertIsNone(entity) 40 self.assertEqual(0, multiple_entity.version)
32 41
33 def testGetMostRecentVersionWhenDataExists(self): 42 def testGetMostRecentVersionWhenDataExistsForSingularEntity(self):
34 root_key = ndb.Key('_EntityRoot', 1) 43 root_key = ndb.Key('_SingularEntityRoot', 1)
35 _Entity._GetRootModel()(key=root_key, current=2).put() 44 _SingularEntity._GetRootModel()(key=root_key, current=2).put()
36 _Entity(key=ndb.Key('_Entity', 1, parent=root_key), value=1).put() 45 _SingularEntity(
37 _Entity(key=ndb.Key('_Entity', 2, parent=root_key), value=2).put() 46 key=ndb.Key('_SingularEntity', 1, parent=root_key), value=1).put()
47 _SingularEntity(
48 key=ndb.Key('_SingularEntity', 2, parent=root_key), value=2).put()
38 49
39 entity = _Entity.GetVersion() 50 entity = _SingularEntity.GetVersion()
40 self.assertEqual(2, entity.version) 51 self.assertEqual(2, entity.version)
41 self.assertEqual(2, entity.value) 52 self.assertEqual(2, entity.value)
42 53
43 def testGetNextVersionWhenDataExists(self): 54 def testGetMostRecentVersionWhenNoData(self):
44 root_key = ndb.Key('_EntityRoot', 1) 55 self.assertIsNone(_SingularEntity.GetVersion())
45 _Entity._GetRootModel()(key=root_key, current=2).put() 56 self.assertIsNone(_MultipleEntity.Create('m1').GetVersion())
46 _Entity(key=ndb.Key('_Entity', 1, parent=root_key), value=1).put()
47 _Entity(key=ndb.Key('_Entity', 2, parent=root_key), value=2).put()
48 57
49 entity = _Entity.GetVersion(2) 58 def testCreateMultipleEntity(self):
59 # Tests creating multiple versioned entities of the same model type.
60 multiple_entity_1 = _MultipleEntity.Create('m1')
61 multiple_entity_1.value = 1
62 multiple_entity_1.Save()
63
64 multiple_entity_2 = _MultipleEntity.Create('m2')
65 multiple_entity_2.value = 2
66 multiple_entity_2.Save()
67
68 self.assertEqual(multiple_entity_1.version, 1)
69 self.assertEqual(multiple_entity_1.value, 1)
70 self.assertEqual(multiple_entity_2.version, 1)
71 self.assertEqual(multiple_entity_2.value, 2)
72
73 def testUpdateMultipleEntity(self):
74 multiple_entity = _MultipleEntity.Create('m1')
75 multiple_entity.value = 1
76 multiple_entity.Save()
77 multiple_entity.value = 3
78 multiple_entity.Save()
79
80 self.assertEqual(multiple_entity.version, 2)
81 self.assertEqual(multiple_entity.value, 3)
82
83 def testGetNextVersionWhenDataExistsForSingularEntity(self):
84 root_key = ndb.Key('_SingularEntityRoot', 1)
85 _SingularEntity._GetRootModel()(key=root_key, current=2).put()
86 _SingularEntity(
87 key=ndb.Key('_SingularEntity', 1, parent=root_key), value=1).put()
88 _SingularEntity(
89 key=ndb.Key('_SingularEntity', 2, parent=root_key), value=2).put()
90
91 entity = _SingularEntity.GetVersion(version=2)
50 self.assertEqual(2, entity.version) 92 self.assertEqual(2, entity.version)
51 self.assertEqual(2, entity.value) 93 self.assertEqual(2, entity.value)
52 self.assertIsNone(_Entity.GetVersion(0)) 94 self.assertIsNone(_SingularEntity.GetVersion(version=0))
53 self.assertIsNone(_Entity.GetVersion(3)) 95 self.assertIsNone(_SingularEntity.GetVersion(version=3))
54 96
55 def testGetLatestVersionNumber(self): 97 def testGetLatestVersionNumberForSingularEntity(self):
56 root_key = ndb.Key('_EntityRoot', 1) 98 root_key = ndb.Key('_SingularEntityRoot', 1)
57 _Entity._GetRootModel()(key=root_key, current=1).put() 99 _SingularEntity._GetRootModel()(key=root_key, current=1).put()
58 _Entity(key=ndb.Key('_Entity', 1, parent=root_key), value=2).put() 100 _SingularEntity(
101 key=ndb.Key('_SingularEntity', 1, parent=root_key), value=2).put()
59 102
60 self.assertEqual(1, _Entity.GetLatestVersionNumber()) 103 self.assertEqual(1, _SingularEntity.GetLatestVersionNumber())
104
105 def testGetVersionForMultipleEntity(self):
106 entity = _MultipleEntity.Create('m1')
107 entity.value = 1
108 entity.Save()
109 entity.value = 2
110 entity.Save()
111 self.assertEqual(2, _MultipleEntity.GetVersion('m1').version)
112 self.assertEqual(2, _MultipleEntity.GetVersion('m1').value)
113 self.assertIsNone(_MultipleEntity.GetVersion('m1', version=0))
114 self.assertIsNone(_MultipleEntity.GetVersion('m1', version=3))
61 115
62 def testGetLatestVersionNumberWhenNoRecordYet(self): 116 def testGetLatestVersionNumberWhenNoRecordYet(self):
63 self.assertEqual(-1, _Entity.GetLatestVersionNumber()) 117 self.assertEqual(-1, _SingularEntity.GetLatestVersionNumber())
118 self.assertEqual(-1, _MultipleEntity.GetLatestVersionNumber('m1'))
64 119
65 def testSaveNewVersion(self): 120 def testSaveNewVersionForSingularEntity(self):
66 entity = _Entity() 121 entity = _SingularEntity()
67 entity.value = 1 122 entity.value = 1
68 key = entity.Save() 123 key, saved = entity.Save()
69 124
70 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) 125 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 1)
71 self.assertEqual(expected_key, key) 126 self.assertEqual(expected_key, key)
127 self.assertTrue(saved)
72 128
73 entity = _Entity.GetVersion() 129 entity = _SingularEntity.GetVersion()
74 self.assertEqual(1, entity.version) 130 self.assertEqual(1, entity.version)
75 self.assertEqual(1, entity.value) 131 self.assertEqual(1, entity.value)
76 132
77 def testSaveNewVersionAlreadyExist(self): 133 def testSaveNewVersionForMultipleEntity(self):
134 entity = _MultipleEntity.Create('m1')
135 entity.value = 1
136 key, saved = entity.Save()
137
138 expected_key = ndb.Key(
139 '_MultipleEntityRoot', 'm1', '_MultipleEntity', 1)
140 self.assertEqual(expected_key, key)
141 self.assertTrue(saved)
142
143 def testSaveNewVersionAlreadyExistsTryNextVersion(self):
78 original_ndb_transaction = ndb.transaction 144 original_ndb_transaction = ndb.transaction
79 145
80 def MockNdbTransaction(func, **options): 146 def MockNdbTransaction(func, **options):
81 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 1), value=1).put() 147 _SingularEntity(
82 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 2), value=2).put() 148 key=ndb.Key(
149 '_SingularEntityRoot', 1, '_SingularEntity', 1), value=1).put()
150 _SingularEntity(
151 key=ndb.Key(
152 '_SingularEntityRoot', 1, '_SingularEntity', 2), value=2).put()
83 return original_ndb_transaction(func, **options) 153 return original_ndb_transaction(func, **options)
84 self.mock(ndb, 'transaction', MockNdbTransaction) 154 self.mock(ndb, 'transaction', MockNdbTransaction)
85 155
86 entity = _Entity() 156 entity = _SingularEntity()
87 key = entity.Save() 157 key, saved = entity.Save()
88 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 3) 158 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 3)
89 self.assertEqual(expected_key, key) 159 self.assertEqual(expected_key, key)
160 self.assertTrue(saved)
161
162 def testSaveDataNewVersionAlreadyExistsNotTryNextVersion(self):
163 # When the call to SaveData() starts, another transaction had just beat this
164 # one to it. The expected result is the saved version from the first
165 # transaction.
166 original_ndb_transaction = ndb.transaction
167
168 def MockNdbTransaction(func, **options):
169 _SingularEntity(
170 key=ndb.Key(
171 '_SingularEntityRoot', 1, '_SingularEntity', 1), value=1).put()
172 return original_ndb_transaction(func, **options)
173 self.mock(ndb, 'transaction', MockNdbTransaction)
174
175 entity = _SingularEntity()
176 key, saved = entity.Save(should_try_next_version_number=False)
177 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 1)
178 self.assertEqual(expected_key, key)
179 self.assertFalse(saved)
180
181 def testSaveNewVersionAlreadyExistsNotTryNextVersion(self):
182 # When the call to Save() starts, another transaction had just beat this
183 # one to it. The expected result is the saved version from the first
184 # transaction should be returned.
185 original_save = VersionedModel.Save
186
187 def MockSave(*args, **kwargs):
188 _SingularEntity(
189 key=ndb.Key(
190 '_SingularEntityRoot', 1, '_SingularEntity', 1), value=1).put()
191 return original_save(*args, **kwargs)
192 self.mock(VersionedModel, 'Save', MockSave)
193
194 entity = _SingularEntity()
195 key, saved = entity.Save(should_try_next_version_number=False)
196 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 1)
197 self.assertEqual(expected_key, key)
198 self.assertFalse(saved)
90 199
91 def testLikelyTransactionFailure(self): 200 def testLikelyTransactionFailure(self):
92 original_ndb_transaction = ndb.transaction 201 original_ndb_transaction = ndb.transaction
93 202
94 calls = [] 203 calls = []
95 def MockNdbTransaction(func, **options): 204 def MockNdbTransaction(func, **options):
96 if len(calls) < 1: 205 if len(calls) < 1:
97 calls.append(1) 206 calls.append(1)
98 raise datastore_errors.Timeout() 207 raise datastore_errors.Timeout()
99 return original_ndb_transaction(func, **options) 208 return original_ndb_transaction(func, **options)
100 self.mock(ndb, 'transaction', MockNdbTransaction) 209 self.mock(ndb, 'transaction', MockNdbTransaction)
101 210
102 entity = _Entity() 211 entity = _SingularEntity()
103 key = entity.Save() 212 key, saved = entity.Save()
104 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) 213 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 1)
105 self.assertEqual(expected_key, key) 214 self.assertEqual(expected_key, key)
215 self.assertTrue(saved)
106 self.assertEqual([1], calls) 216 self.assertEqual([1], calls)
107 217
108 def testTransactionFailure(self): 218 def testTransactionFailure(self):
109 original_ndb_transaction = ndb.transaction 219 original_ndb_transaction = ndb.transaction
110 220
111 calls = [] 221 calls = []
112 def MockNdbTransaction(func, **options): 222 def MockNdbTransaction(func, **options):
113 if len(calls) < 1: 223 if len(calls) < 1:
114 calls.append(1) 224 calls.append(1)
115 raise datastore_errors.BadRequestError() 225 raise datastore_errors.BadRequestError()
116 return original_ndb_transaction(func, **options) 226 return original_ndb_transaction(func, **options)
117 self.mock(ndb, 'transaction', MockNdbTransaction) 227 self.mock(ndb, 'transaction', MockNdbTransaction)
118 228
119 entity = _Entity() 229 entity = _SingularEntity()
120 key = entity.Save() 230 key, saved = entity.Save()
121 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) 231 expected_key = ndb.Key('_SingularEntityRoot', 1, '_SingularEntity', 1)
122 self.assertEqual(expected_key, key) 232 self.assertEqual(expected_key, key)
123 self.assertEqual([1], calls) 233 self.assertEqual([1], calls)
234 self.assertTrue(saved)
235
236 def testRootStringId(self):
237 self.assertIsNone(_SingularEntity().root_string_id)
238 self.assertIsNone(
239 _SingularEntity(key=ndb.Key('_SingularEntity', 1)).root_string_id)
240 self.assertEqual('m1', _MultipleEntity.Create('m1').root_string_id)
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/model/versioned_config.py » ('j') | appengine/findit/model/versioned_model.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698