OLD | NEW |
| (Empty) |
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 | |
3 # found in the LICENSE file. | |
4 | |
5 from google.appengine.api import datastore_errors | |
6 from google.appengine.ext import ndb | |
7 | |
8 from testing_utils import testing | |
9 | |
10 from model.versioned_model import VersionedModel | |
11 | |
12 | |
13 class _Entity(VersionedModel): | |
14 value = ndb.IntegerProperty(indexed=False) | |
15 | |
16 | |
17 class VersionedModelTest(testing.AppengineTestCase): | |
18 | |
19 def testGetRootModel(self): | |
20 root_model_class = _Entity._GetRootModel() | |
21 self.assertEqual('_EntityRoot', root_model_class._get_kind()) | |
22 self.assertTrue(issubclass(root_model_class, ndb.Model)) | |
23 self.assertEqual(3, root_model_class(current=3).current) | |
24 | |
25 def testDefaultVersionIsZero(self): | |
26 self.assertEqual(0, _Entity.Create().version_number) | |
27 self.assertEqual(0, _Entity.Create('m1').version_number) | |
28 | |
29 def testRootId(self): | |
30 self.assertEqual(1, _Entity.Create()._root_id) | |
31 self.assertEqual( | |
32 1, _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 2))._root_id) | |
33 self.assertEqual('m1', _Entity.Create('m1')._root_id) | |
34 | |
35 def testCreate(self): | |
36 self.assertEqual(_Entity(key=ndb.Key('_EntityRoot', 'm1', '_Entity', 0)), | |
37 _Entity.Create('m1')) | |
38 | |
39 def testGetMostRecentVersionWhenNoData(self): | |
40 self.assertIsNone(_Entity.GetVersion()) | |
41 self.assertIsNone(_Entity.GetVersion('m1')) | |
42 | |
43 def testGetMostRecentVersionWhenDataExists(self): | |
44 entity = _Entity.Create() | |
45 entity.value = 1 | |
46 entity.Save() | |
47 entity.value = 2 | |
48 entity.Save() | |
49 | |
50 entity = _Entity.GetVersion() | |
51 self.assertEqual(2, entity.version_number) | |
52 self.assertEqual(2, entity.value) | |
53 | |
54 def testGetSpecificVersion(self): | |
55 entity = _Entity.Create() | |
56 entity.value = 1 | |
57 entity.Save() | |
58 entity.value = 2 | |
59 entity.Save() | |
60 | |
61 entity_version_2 = _Entity.GetVersion(version=2) | |
62 self.assertEqual(2, entity_version_2.version_number) | |
63 self.assertEqual(2, entity_version_2.value) | |
64 self.assertIsNone(_Entity.GetVersion(version=0)) | |
65 self.assertIsNone(_Entity.GetVersion(version=3)) | |
66 | |
67 def testGetLatestVersionNumber(self): | |
68 entity = _Entity.Create() | |
69 entity.Save() | |
70 self.assertEqual(1, _Entity.GetLatestVersionNumber()) | |
71 | |
72 def testGetVersionForEntityWithKeyId(self): | |
73 entity = _Entity.Create('m1') | |
74 entity.value = 1 | |
75 entity.Save() | |
76 entity.value = 2 | |
77 entity.Save() | |
78 | |
79 self.assertEqual(2, _Entity.GetVersion('m1').version_number) | |
80 self.assertEqual(2, _Entity.GetVersion('m1').value) | |
81 self.assertIsNone(_Entity.GetVersion('m1', version=0)) | |
82 self.assertIsNone(_Entity.GetVersion('m1', version=3)) | |
83 | |
84 def testGetLatestVersionNumberWhenNoRecordYet(self): | |
85 self.assertEqual(-1, _Entity.GetLatestVersionNumber()) | |
86 self.assertEqual(-1, _Entity.GetLatestVersionNumber('m1')) | |
87 | |
88 def testSaveNewVersion(self): | |
89 entity = _Entity.Create() | |
90 entity.value = 1 | |
91 key, saved = entity.Save() | |
92 | |
93 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) | |
94 self.assertEqual(expected_key, key) | |
95 self.assertTrue(saved) | |
96 | |
97 entity = _Entity.GetVersion() | |
98 self.assertEqual(1, entity.version_number) | |
99 self.assertEqual(1, entity.value) | |
100 | |
101 def testSaveEntityWithRootId(self): | |
102 entity = _Entity.Create('m1') | |
103 entity.value = 1 | |
104 entity.Save() | |
105 entity.value = 3 | |
106 entity.Save() | |
107 | |
108 self.assertEqual(entity.version_number, 2) | |
109 self.assertEqual(entity.value, 3) | |
110 | |
111 def testSaveNewVersionOfEntityWithKeyId(self): | |
112 entity = _Entity.Create('m1') | |
113 entity.value = 1 | |
114 key, saved = entity.Save() | |
115 expected_key = ndb.Key('_EntityRoot', 'm1', '_Entity', 1) | |
116 self.assertEqual(expected_key, key) | |
117 self.assertTrue(saved) | |
118 | |
119 def testSaveNewVersionWithConflictRetry(self): | |
120 original_ndb_transaction = ndb.transaction | |
121 | |
122 def MockNdbTransaction(func, **options): | |
123 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 1), value=1).put() | |
124 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 2), value=2).put() | |
125 return original_ndb_transaction(func, **options) | |
126 self.mock(ndb, 'transaction', MockNdbTransaction) | |
127 | |
128 entity = _Entity.Create() | |
129 key, saved = entity.Save() | |
130 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 3) | |
131 self.assertEqual(expected_key, key) | |
132 self.assertTrue(saved) | |
133 | |
134 def testSaveNewVersionWithConflictBeforeTransactionNoRetry(self): | |
135 original_ndb_transaction = ndb.transaction | |
136 | |
137 def MockNdbTransaction(func, **options): | |
138 # To simulate another transaction occuring before this one, write a new | |
139 # version first before the transaction is called. | |
140 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 1), value=1).put() | |
141 return original_ndb_transaction(func, **options) | |
142 self.mock(ndb, 'transaction', MockNdbTransaction) | |
143 | |
144 entity = _Entity.Create() | |
145 key, saved = entity.Save(retry_on_conflict=False) | |
146 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) | |
147 self.assertEqual(expected_key, key) | |
148 self.assertFalse(saved) | |
149 | |
150 def testSaveNewVersionConflictBeforeSaving(self): | |
151 original_save = VersionedModel.Save | |
152 | |
153 def MockSave(*args, **kwargs): | |
154 # Smulate another transaction beating this call to Save() to creating a | |
155 # new entity. | |
156 _Entity(key=ndb.Key('_EntityRoot', 1, '_Entity', 1), value=1).put() | |
157 return original_save(*args, **kwargs) | |
158 self.mock(VersionedModel, 'Save', MockSave) | |
159 | |
160 entity = _Entity.Create() | |
161 key, saved = entity.Save(retry_on_conflict=False) | |
162 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) | |
163 self.assertEqual(expected_key, key) | |
164 self.assertFalse(saved) | |
165 | |
166 def testLikelyTransactionFailure(self): | |
167 original_ndb_transaction = ndb.transaction | |
168 | |
169 calls = [] | |
170 def MockNdbTransaction(func, **options): | |
171 if len(calls) < 1: | |
172 calls.append(1) | |
173 raise datastore_errors.Timeout() | |
174 return original_ndb_transaction(func, **options) | |
175 self.mock(ndb, 'transaction', MockNdbTransaction) | |
176 | |
177 entity = _Entity.Create() | |
178 key, saved = entity.Save() | |
179 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) | |
180 self.assertEqual(expected_key, key) | |
181 self.assertTrue(saved) | |
182 self.assertEqual([1], calls) | |
183 | |
184 def testTransactionFailure(self): | |
185 original_ndb_transaction = ndb.transaction | |
186 | |
187 calls = [] | |
188 def MockNdbTransaction(func, **options): | |
189 if len(calls) < 1: | |
190 calls.append(1) | |
191 raise datastore_errors.BadRequestError() | |
192 return original_ndb_transaction(func, **options) | |
193 self.mock(ndb, 'transaction', MockNdbTransaction) | |
194 | |
195 entity = _Entity.Create() | |
196 key, saved = entity.Save() | |
197 expected_key = ndb.Key('_EntityRoot', 1, '_Entity', 1) | |
198 self.assertEqual(expected_key, key) | |
199 self.assertEqual([1], calls) | |
200 self.assertTrue(saved) | |
OLD | NEW |