Skip to content

Commit

Permalink
Merge pull request #565 from dhermes/fix-flaky-datastore-query
Browse files Browse the repository at this point in the history
Fixing flaky datastore queries in regression tests.
  • Loading branch information
dhermes committed Jan 27, 2015
2 parents 3e89521 + 0489094 commit d03d218
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
13 changes: 8 additions & 5 deletions gcloud/datastore/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,18 @@ def _clone(self):
"""Duplicates the Key.
Most attributes are simple types, so don't require copying. Other
attributes like ``parent`` are long-lived and so we re-use them rather
than creating copies.
attributes like ``parent`` are long-lived and so we re-use them.
:rtype: :class:`gcloud.datastore.key.Key`
:returns: A new ``Key`` instance with the same data as the current one.
"""
return self.__class__(*self.flat_path, parent=self.parent,
dataset_id=self.dataset_id,
namespace=self.namespace)
cloned_self = self.__class__(*self.flat_path,
dataset_id=self.dataset_id,
namespace=self.namespace)
# If the current parent has already been set, we re-use
# the same instance
cloned_self._parent = self._parent
return cloned_self

def completed_key(self, id_or_name):
"""Creates new key from existing partial key by adding final ID/name.
Expand Down
19 changes: 19 additions & 0 deletions gcloud/datastore/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,25 @@ def test__clone(self):
self.assertEqual(clone.kind, _KIND)
self.assertEqual(clone.path, _PATH)

def test__clone_with_parent(self):
_DATASET = 'DATASET-ALT'
_NAMESPACE = 'NAMESPACE'
_KIND1 = 'PARENT'
_KIND2 = 'KIND'
_ID1 = 1234
_ID2 = 2345
_PATH = [{'kind': _KIND1, 'id': _ID1}, {'kind': _KIND2, 'id': _ID2}]

parent = self._makeOne(_KIND1, _ID1, namespace=_NAMESPACE,
dataset_id=_DATASET)
key = self._makeOne(_KIND2, _ID2, parent=parent)
self.assertTrue(key.parent is parent)
clone = key._clone()
self.assertTrue(clone.parent is key.parent)
self.assertEqual(clone.dataset_id, _DATASET)
self.assertEqual(clone.namespace, _NAMESPACE)
self.assertEqual(clone.path, _PATH)

def test_completed_key_on_partial_w_id(self):
key = self._makeOne('KIND', dataset_id=self._DEFAULT_DATASET)
_ID = 1234
Expand Down
19 changes: 13 additions & 6 deletions regression/datastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def test_allocate_ids(self):

class TestDatastoreSave(TestDatastore):

PARENT = datastore.Key('Blog', 'PizzaMan')

def _get_post(self, id_or_name=None, post_content=None):
post_content = post_content or {
'title': u'How to make the perfect pizza in your grill',
Expand All @@ -66,7 +68,10 @@ def _get_post(self, id_or_name=None, post_content=None):
'rating': 5.0,
}
# Create an entity with the given content.
entity = datastore.Entity(key=datastore.Key('Post'))
# NOTE: Using a parent to ensure consistency for query
# in `test_empty_kind`.
key = datastore.Key('Post', parent=self.PARENT)
entity = datastore.Entity(key=key)
entity.update(post_content)

# Update the entity key.
Expand All @@ -77,8 +82,7 @@ def _get_post(self, id_or_name=None, post_content=None):

def _generic_test_post(self, name=None, key_id=None):
entity = self._get_post(id_or_name=(name or key_id))
with datastore.Transaction():
datastore.put([entity])
datastore.put([entity])

# Register entity to be deleted.
self.case_entities_to_delete.append(entity)
Expand Down Expand Up @@ -135,23 +139,26 @@ def test_save_multiple(self):

def test_empty_kind(self):
query = datastore.Query(kind='Post')
query.ancestor = self.PARENT
posts = list(query.fetch(limit=2))
self.assertEqual(posts, [])


class TestDatastoreSaveKeys(TestDatastore):

def test_save_key_self_reference(self):
key = datastore.Key('Person', 'name')
parent_key = datastore.Key('Residence', 'NewYork')
key = datastore.Key('Person', 'name', parent=parent_key)
entity = datastore.Entity(key=key)
entity['fullName'] = u'Full name'
entity['linkedTo'] = key # Self reference.

with datastore.Transaction():
datastore.put([entity])
datastore.put([entity])
self.case_entities_to_delete.append(entity)

query = datastore.Query(kind='Person')
# Adding ancestor to ensure consistency.
query.ancestor = parent_key
query.add_filter('linkedTo', '=', key)

stored_persons = list(query.fetch(limit=2))
Expand Down

0 comments on commit d03d218

Please sign in to comment.