diff --git a/regression/data/index.yaml b/regression/data/index.yaml index f46c999cdd683..5a2d2b1a8bc93 100644 --- a/regression/data/index.yaml +++ b/regression/data/index.yaml @@ -1,11 +1,23 @@ indexes: - kind: Character + ancestor: yes + properties: + - name: appearances + +- kind: Character + ancestor: yes + properties: + - name: alive + +- kind: Character + ancestor: yes properties: - name: family - name: appearances - kind: Character + ancestor: yes properties: - name: name - name: family diff --git a/regression/datastore.py b/regression/datastore.py index 93c45b15cabde..b66e31e4e3b5f 100644 --- a/regression/datastore.py +++ b/regression/datastore.py @@ -5,7 +5,7 @@ from gcloud import datastore # This assumes the command is being run via tox hence the # repository root is the current directory. -from regression.populate_datastore import CHARACTERS +from regression import populate_datastore from regression import regression_utils @@ -115,11 +115,16 @@ class TestDatastoreQuery(TestDatastore): @classmethod def setUpClass(cls): super(TestDatastoreQuery, cls).setUpClass() - cls.CHARACTERS = CHARACTERS + cls.CHARACTERS = populate_datastore.CHARACTERS + cls.ANCESTOR_KEY = datastore.key.Key( + path=[populate_datastore.ANCESTOR]) + + def _base_query(self): + return self.dataset.query('Character').ancestor(self.ANCESTOR_KEY) def test_limit_queries(self): limit = 5 - query = self.dataset.query('Character').limit(limit) + query = self._base_query().limit(limit) # Verify there is not cursor before fetch(). self.assertRaises(RuntimeError, query.cursor) @@ -132,49 +137,46 @@ def test_limit_queries(self): self.assertTrue(cursor is not None) # Fetch next batch of characters. - new_query = self.dataset.query('Character').with_cursor(cursor) + new_query = self._base_query().with_cursor(cursor) new_character_entities = new_query.fetch() characters_remaining = len(self.CHARACTERS) - limit self.assertEqual(len(new_character_entities), characters_remaining) def test_query_simple_filter(self): - query = self.dataset.query('Character') - query = query.filter('appearances >=', 20) + query = self._base_query().filter('appearances >=', 20) expected_matches = 6 # We expect 6, but allow the query to get 1 extra. entities = query.fetch(limit=expected_matches + 1) self.assertEqual(len(entities), expected_matches) def test_query_multiple_filters(self): - query = self.dataset.query('Character') - query = query.filter('appearances >=', 26).filter('family =', 'Stark') + query = self._base_query().filter( + 'appearances >=', 26).filter('family =', 'Stark') expected_matches = 4 # We expect 4, but allow the query to get 1 extra. entities = query.fetch(limit=expected_matches + 1) self.assertEqual(len(entities), expected_matches) def test_ancestor_query(self): - query = self.dataset.query('Character') - filtered_query = query.ancestor(['Character', 'Eddard']) + filtered_query = self._base_query() - expected_matches = 5 - # We expect 5, but allow the query to get 1 extra. + expected_matches = 8 + # We expect 8, but allow the query to get 1 extra. entities = filtered_query.fetch(limit=expected_matches + 1) self.assertEqual(len(entities), expected_matches) def test_query___key___filter(self): rickard_key = datastore.key.Key( - path=[{'kind': 'Character', 'name': 'Rickard'}]) + path=[populate_datastore.ANCESTOR, populate_datastore.RICKARD]) - query = self.dataset.query('Character').filter( - '__key__ =', rickard_key) + query = self._base_query().filter('__key__ =', rickard_key) expected_matches = 1 # We expect 1, but allow the query to get 1 extra. entities = query.fetch(limit=expected_matches + 1) self.assertEqual(len(entities), expected_matches) def test_ordered_query(self): - query = self.dataset.query('Character').order('appearances') + query = self._base_query().order('appearances') expected_matches = 8 # We expect 8, but allow the query to get 1 extra. entities = query.fetch(limit=expected_matches + 1) @@ -185,8 +187,7 @@ def test_ordered_query(self): self.assertEqual(entities[7]['name'], self.CHARACTERS[3]['name']) def test_projection_query(self): - query = self.dataset.query('Character') - filtered_query = query.projection(['name', 'family']) + filtered_query = self._base_query().projection(['name', 'family']) # NOTE: There are 9 responses because of Catelyn. She has both # Stark and Tully as her families, hence occurs twice in @@ -220,7 +221,7 @@ def test_projection_query(self): self.assertEqual(sansa_dict, {'name': 'Sansa', 'family': 'Stark'}) def test_query_paginate_with_offset(self): - query = self.dataset.query('Character') + query = self._base_query() offset = 2 limit = 3 page_query = query.offset(offset).limit(limit).order('appearances') @@ -246,7 +247,7 @@ def test_query_paginate_with_offset(self): self.assertEqual(entities[2]['name'], 'Arya') def test_query_paginate_with_start_cursor(self): - query = self.dataset.query('Character') + query = self._base_query() offset = 2 limit = 2 page_query = query.offset(offset).limit(limit).order('appearances') @@ -259,7 +260,7 @@ def test_query_paginate_with_start_cursor(self): # Use cursor to create a fresh query. cursor = page_query.cursor() - fresh_query = self.dataset.query('Character') + fresh_query = self._base_query() fresh_query = fresh_query.order('appearances').with_cursor(cursor) new_entities = fresh_query.fetch() @@ -269,7 +270,7 @@ def test_query_paginate_with_start_cursor(self): self.assertEqual(new_entities[3]['name'], 'Arya') def test_query_group_by(self): - query = self.dataset.query('Character').group_by(['alive']) + query = self._base_query().group_by(['alive']) expected_matches = 2 # We expect 2, but allow the query to get 1 extra. diff --git a/regression/populate_datastore.py b/regression/populate_datastore.py index 1631ae1ece2f1..c4c4ec23e787c 100644 --- a/regression/populate_datastore.py +++ b/regression/populate_datastore.py @@ -7,20 +7,23 @@ from regression import regression_utils +ANCESTOR = {'kind': 'Book', 'name': 'GoT'} +RICKARD = {'kind': 'Character', 'name': 'Rickard'} +EDDARD = {'kind': 'Character', 'name': 'Eddard'} KEY_PATHS = [ - [{'kind': 'Character', 'name': 'Rickard'}], - [{'kind': 'Character', 'name': 'Rickard'}, - {'kind': 'Character', 'name': 'Eddard'}], - [{'kind': 'Character', 'name': 'Catelyn'}], - [{'kind': 'Character', 'name': 'Eddard'}, + [ANCESTOR, RICKARD], + [ANCESTOR, RICKARD, EDDARD], + [ANCESTOR, + {'kind': 'Character', 'name': 'Catelyn'}], + [ANCESTOR, RICKARD, EDDARD, {'kind': 'Character', 'name': 'Arya'}], - [{'kind': 'Character', 'name': 'Eddard'}, + [ANCESTOR, RICKARD, EDDARD, {'kind': 'Character', 'name': 'Sansa'}], - [{'kind': 'Character', 'name': 'Eddard'}, + [ANCESTOR, RICKARD, EDDARD, {'kind': 'Character', 'name': 'Robb'}], - [{'kind': 'Character', 'name': 'Eddard'}, + [ANCESTOR, RICKARD, EDDARD, {'kind': 'Character', 'name': 'Bran'}], - [{'kind': 'Character', 'name': 'Eddard'}, + [ANCESTOR, RICKARD, EDDARD, {'kind': 'Character', 'name': 'Jon Snow'}], ] CHARACTERS = [