Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 89ea04c

Browse filesBrowse files
author
Jonathan Wayne Parrott
committed
Merge pull request GoogleCloudPlatform#167 from GoogleCloudPlatform/flaky-tests
Trying to improve datastore flaky tests.
2 parents 59b4ba0 + a44cf01 commit 89ea04c
Copy full SHA for 89ea04c

File tree

Expand file treeCollapse file tree

5 files changed

+70
-27
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+70
-27
lines changed

‎datastore/api/snippets_test.py

Copy file name to clipboardExpand all lines: datastore/api/snippets_test.py
+44-8Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,39 @@
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+
1617
from gcloud import datastore
17-
from nose.plugins.attrib import attr
18-
from tests import CloudBaseTest
18+
from tests import CloudBaseTest, mark_flaky
1919

2020
from . 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
2947
class 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())

‎datastore/api/tasks_test.py

Copy file name to clipboardExpand all lines: datastore/api/tasks_test.py
+3-11Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,14 @@
1010
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
13-
#
14-
from flaky import flaky
15-
import gcloud
13+
1614
from gcloud import datastore
17-
from nose.plugins.attrib import attr
18-
from tests import CloudBaseTest
15+
from tests import CloudBaseTest, mark_flaky
1916

2017
from . import tasks
2118

2219

23-
def flaky_filter(e, *args):
24-
return isinstance(e, gcloud.exceptions.GCloudError)
25-
26-
27-
@attr('slow')
28-
@flaky(rerun_filter=flaky_filter)
20+
@mark_flaky
2921
class DatastoreTasksTest(CloudBaseTest):
3022

3123
def setUp(self):

‎tests/__init__.py

Copy file name to clipboardExpand all lines: tests/__init__.py
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616
AppEngineTestbedCase,
1717
capture_stdout,
1818
CloudBaseTest,
19+
flaky_filter,
1920
Http2Mock,
21+
mark_flaky,
2022
RESOURCE_PATH)
2123

2224

2325
__all__ = [
2426
'AppEngineTestbedCase',
2527
'capture_stdout',
2628
'CloudBaseTest',
29+
'flaky_filter',
2730
'Http2Mock',
31+
'mark_flaky',
2832
'RESOURCE_PATH'
2933
]

‎tests/utils.py

Copy file name to clipboardExpand all lines: tests/utils.py
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
import tempfile
2222
import unittest
2323

24+
from flaky import flaky
25+
import gcloud
2426
import httplib2
27+
from nose.plugins.attrib import attr
2528
from nose.plugins.skip import SkipTest
2629
from six.moves import cStringIO
2730

@@ -40,6 +43,18 @@
4043
BUCKET_NAME_ENV_VAR = 'TEST_BUCKET_NAME'
4144

4245

46+
def flaky_filter(e, *args):
47+
exception_class, exception_instance, traceback = e
48+
return isinstance(
49+
exception_instance,
50+
(gcloud.exceptions.GCloudError,))
51+
52+
53+
def mark_flaky(f):
54+
return flaky(max_runs=3, rerun_filter=flaky_filter)(
55+
attr('flaky')(f))
56+
57+
4358
class CloudBaseTest(unittest.TestCase):
4459

4560
def setUp(self):

‎tox.ini

Copy file name to clipboardExpand all lines: tox.ini
+4-8Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ deps =
5252
commands =
5353
nosetests \
5454
--exclude-dir=appengine \
55-
-a '!slow' \
5655
{[testenv]commonargs} \
57-
{posargs}
56+
{posargs:-a '!slow,!flaky'}
5857

5958
[testenv:py34]
6059
basepython = python3.4
@@ -63,28 +62,25 @@ deps =
6362
commands =
6463
nosetests \
6564
--exclude-dir=appengine \
66-
-a '!slow' \
6765
{[testenv]commonargs} \
68-
{posargs}
66+
{posargs:-a '!slow,!flaky'}
6967

70-
[testenv:py27-slow]
68+
[testenv:py27-all]
7169
deps =
7270
{[testenv]deps}
7371
commands =
7472
nosetests \
7573
--exclude-dir=appengine \
76-
-a 'slow' \
7774
{[testenv]commonargs} \
7875
{posargs}
7976

80-
[testenv:py34-slow]
77+
[testenv:py34-all]
8178
basepython = python3.4
8279
deps =
8380
{[testenv]deps}
8481
commands =
8582
nosetests \
8683
--exclude-dir=appengine \
87-
-a 'slow' \
8884
{[testenv]commonargs} \
8985
{posargs}
9086

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.