11
11
# See the License for the specific language governing permissions and
12
12
# limitations under the License.
13
13
#
14
- from flaky import flaky
15
- import gcloud
14
+ from functools import wraps
15
+ import time
16
+
16
17
from gcloud import datastore
17
- from nose .plugins .attrib import attr
18
- from tests import CloudBaseTest
18
+ from tests import CloudBaseTest , mark_flaky
19
19
20
20
from . import snippets
21
21
22
22
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
25
44
26
45
27
- @attr ('slow' )
28
- @flaky (rerun_filter = flaky_filter )
46
+ @mark_flaky
29
47
class DatastoreSnippetsTest (CloudBaseTest ):
30
48
31
49
def setUp (self ):
@@ -110,16 +128,19 @@ def test_batch_lookup(self):
110
128
def test_batch_delete (self ):
111
129
snippets .batch_delete (self .client )
112
130
131
+ @eventually_consistent
113
132
def test_unindexed_property_query (self ):
114
133
tasks = snippets .unindexed_property_query (self .client )
115
134
self .to_delete_entities .extend (tasks )
116
135
self .assertTrue (tasks )
117
136
137
+ @eventually_consistent
118
138
def test_basic_query (self ):
119
139
tasks = snippets .basic_query (self .client )
120
140
self .to_delete_entities .extend (tasks )
121
141
self .assertTrue (tasks )
122
142
143
+ @eventually_consistent
123
144
def test_projection_query (self ):
124
145
priorities , percents = snippets .projection_query (self .client )
125
146
self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
@@ -131,9 +152,11 @@ def test_ancestor_query(self):
131
152
self .to_delete_entities .extend (tasks )
132
153
self .assertTrue (tasks )
133
154
155
+ @eventually_consistent
134
156
def test_run_query (self ):
135
157
snippets .run_query (self .client )
136
158
159
+ @eventually_consistent
137
160
def test_cursor_paging (self ):
138
161
for n in range (6 ):
139
162
self .to_delete_entities .append (
@@ -147,46 +170,55 @@ def test_cursor_paging(self):
147
170
self .assertTrue (cursor_one )
148
171
self .assertTrue (cursor_two )
149
172
173
+ @eventually_consistent
150
174
def test_property_filter (self ):
151
175
tasks = snippets .property_filter (self .client )
152
176
self .to_delete_entities .extend (tasks )
153
177
self .assertTrue (tasks )
154
178
179
+ @eventually_consistent
155
180
def test_composite_filter (self ):
156
181
tasks = snippets .composite_filter (self .client )
157
182
self .to_delete_entities .extend (tasks )
158
183
self .assertTrue (tasks )
159
184
185
+ @eventually_consistent
160
186
def test_key_filter (self ):
161
187
tasks = snippets .key_filter (self .client )
162
188
self .to_delete_entities .extend (tasks )
163
189
self .assertTrue (tasks )
164
190
191
+ @eventually_consistent
165
192
def test_ascending_sort (self ):
166
193
tasks = snippets .ascending_sort (self .client )
167
194
self .to_delete_entities .extend (tasks )
168
195
self .assertTrue (tasks )
169
196
197
+ @eventually_consistent
170
198
def test_descending_sort (self ):
171
199
tasks = snippets .descending_sort (self .client )
172
200
self .to_delete_entities .extend (tasks )
173
201
self .assertTrue (tasks )
174
202
203
+ @eventually_consistent
175
204
def test_multi_sort (self ):
176
205
tasks = snippets .multi_sort (self .client )
177
206
self .to_delete_entities .extend (tasks )
178
207
self .assertTrue (tasks )
179
208
209
+ @eventually_consistent
180
210
def test_keys_only_query (self ):
181
211
keys = snippets .keys_only_query (self .client )
182
212
self .to_delete_keys .extend (keys )
183
213
self .assertTrue (keys )
184
214
215
+ @eventually_consistent
185
216
def test_distinct_query (self ):
186
217
tasks = snippets .distinct_query (self .client )
187
218
self .to_delete_entities .extend (tasks )
188
219
self .assertTrue (tasks )
189
220
221
+ @eventually_consistent
190
222
def test_distinct_on_query (self ):
191
223
tasks = snippets .distinct_on_query (self .client )
192
224
self .to_delete_entities .extend (tasks )
@@ -241,25 +273,29 @@ def transactional_single_entity_group_read_only(self):
241
273
self .assertTrue (task_list )
242
274
self .assertTrue (tasks_in_list )
243
275
276
+ @eventually_consistent
244
277
def test_namespace_run_query (self ):
245
278
all_namespaces , filtered_namespaces = snippets .namespace_run_query (
246
279
self .client )
247
280
self .assertTrue (all_namespaces )
248
281
self .assertTrue (filtered_namespaces )
249
282
self .assertTrue ('google' in filtered_namespaces )
250
283
284
+ @eventually_consistent
251
285
def test_kind_run_query (self ):
252
286
kinds = snippets .kind_run_query (self .client )
253
287
self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
254
288
self .assertTrue (kinds )
255
289
self .assertTrue ('Task' in kinds )
256
290
291
+ @eventually_consistent
257
292
def test_property_run_query (self ):
258
293
kinds = snippets .property_run_query (self .client )
259
294
self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
260
295
self .assertTrue (kinds )
261
296
self .assertTrue ('Task' in kinds )
262
297
298
+ @eventually_consistent
263
299
def test_property_by_kind_run_query (self ):
264
300
reprs = snippets .property_by_kind_run_query (self .client )
265
301
self .to_delete_entities .extend (self .client .query (kind = 'Task' ).fetch ())
0 commit comments