1111# See the License for the specific language governing permissions and
1212# limitations under the License.
1313#
14- from flaky import flaky
15- import gcloud
14+ from functools import wraps
15+ import time
16+
1617from gcloud import datastore
17- from nose .plugins .attrib import attr
18- from tests import CloudBaseTest
18+ from tests import CloudBaseTest , mark_flaky
1919
2020from . import snippets
2121
2222
23- def flaky_filter (e , * args ):
24- return isinstance (e , gcloud .exceptions .GCloudError )
23+ def eventually_consistent (f ):
24+ @wraps (f )
25+ def inner (self , * args , ** kwargs ):
26+ # This is pretty hacky, but make datastore wait 1s after any
27+ # put operation to in order to account for eventual consistency.
28+ original_put_multi = self .client .put_multi
29+
30+ def put_multi (* args , ** kwargs ):
31+ result = original_put_multi (* args , ** kwargs )
32+ time .sleep (1 )
33+ return result
34+
35+ self .client .put_multi = put_multi
36+
37+ try :
38+ result = f (self , * args , ** kwargs )
39+ finally :
40+ self .client .put_multi = original_put_multi
41+
42+ return result
43+ return inner
2544
2645
27- @attr ('slow' )
28- @flaky (rerun_filter = flaky_filter )
46+ @mark_flaky
2947class DatastoreSnippetsTest (CloudBaseTest ):
3048
3149 def setUp (self ):
@@ -110,16 +128,19 @@ def test_batch_lookup(self):
110128 def test_batch_delete (self ):
111129 snippets .batch_delete (self .client )
112130
131+ @eventually_consistent
113132 def test_unindexed_property_query (self ):
114133 tasks = snippets .unindexed_property_query (self .client )
115134 self .to_delete_entities .extend (tasks )
116135 self .assertTrue (tasks )
117136
137+ @eventually_consistent
118138 def test_basic_query (self ):
119139 tasks = snippets .basic_query (self .client )
120140 self .to_delete_entities .extend (tasks )
121141 self .assertTrue (tasks )
122142
143+ @eventually_consistent
123144 def test_projection_query (self ):
124145 priorities , percents = snippets .projection_query (self .client )
125146 self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
@@ -131,9 +152,11 @@ def test_ancestor_query(self):
131152 self .to_delete_entities .extend (tasks )
132153 self .assertTrue (tasks )
133154
155+ @eventually_consistent
134156 def test_run_query (self ):
135157 snippets .run_query (self .client )
136158
159+ @eventually_consistent
137160 def test_cursor_paging (self ):
138161 for n in range (6 ):
139162 self .to_delete_entities .append (
@@ -147,46 +170,55 @@ def test_cursor_paging(self):
147170 self .assertTrue (cursor_one )
148171 self .assertTrue (cursor_two )
149172
173+ @eventually_consistent
150174 def test_property_filter (self ):
151175 tasks = snippets .property_filter (self .client )
152176 self .to_delete_entities .extend (tasks )
153177 self .assertTrue (tasks )
154178
179+ @eventually_consistent
155180 def test_composite_filter (self ):
156181 tasks = snippets .composite_filter (self .client )
157182 self .to_delete_entities .extend (tasks )
158183 self .assertTrue (tasks )
159184
185+ @eventually_consistent
160186 def test_key_filter (self ):
161187 tasks = snippets .key_filter (self .client )
162188 self .to_delete_entities .extend (tasks )
163189 self .assertTrue (tasks )
164190
191+ @eventually_consistent
165192 def test_ascending_sort (self ):
166193 tasks = snippets .ascending_sort (self .client )
167194 self .to_delete_entities .extend (tasks )
168195 self .assertTrue (tasks )
169196
197+ @eventually_consistent
170198 def test_descending_sort (self ):
171199 tasks = snippets .descending_sort (self .client )
172200 self .to_delete_entities .extend (tasks )
173201 self .assertTrue (tasks )
174202
203+ @eventually_consistent
175204 def test_multi_sort (self ):
176205 tasks = snippets .multi_sort (self .client )
177206 self .to_delete_entities .extend (tasks )
178207 self .assertTrue (tasks )
179208
209+ @eventually_consistent
180210 def test_keys_only_query (self ):
181211 keys = snippets .keys_only_query (self .client )
182212 self .to_delete_keys .extend (keys )
183213 self .assertTrue (keys )
184214
215+ @eventually_consistent
185216 def test_distinct_query (self ):
186217 tasks = snippets .distinct_query (self .client )
187218 self .to_delete_entities .extend (tasks )
188219 self .assertTrue (tasks )
189220
221+ @eventually_consistent
190222 def test_distinct_on_query (self ):
191223 tasks = snippets .distinct_on_query (self .client )
192224 self .to_delete_entities .extend (tasks )
@@ -241,25 +273,29 @@ def transactional_single_entity_group_read_only(self):
241273 self .assertTrue (task_list )
242274 self .assertTrue (tasks_in_list )
243275
276+ @eventually_consistent
244277 def test_namespace_run_query (self ):
245278 all_namespaces , filtered_namespaces = snippets .namespace_run_query (
246279 self .client )
247280 self .assertTrue (all_namespaces )
248281 self .assertTrue (filtered_namespaces )
249282 self .assertTrue ('google' in filtered_namespaces )
250283
284+ @eventually_consistent
251285 def test_kind_run_query (self ):
252286 kinds = snippets .kind_run_query (self .client )
253287 self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
254288 self .assertTrue (kinds )
255289 self .assertTrue ('Task' in kinds )
256290
291+ @eventually_consistent
257292 def test_property_run_query (self ):
258293 kinds = snippets .property_run_query (self .client )
259294 self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
260295 self .assertTrue (kinds )
261296 self .assertTrue ('Task' in kinds )
262297
298+ @eventually_consistent
263299 def test_property_by_kind_run_query (self ):
264300 reprs = snippets .property_by_kind_run_query (self .client )
265301 self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
0 commit comments