def test_nested_entity_no_key(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb PROJECT = 's~FOO' KIND = 'KIND' INSIDE_NAME = 'IFOO' OUTSIDE_NAME = 'OBAR' INSIDE_VALUE = 1337 entity_inside = entity_pb2.Entity() inside_val_pb = _new_value_pb(entity_inside, INSIDE_NAME) inside_val_pb.integer_value = INSIDE_VALUE entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = PROJECT element = entity_pb.key.path_element.add() element.kind = KIND outside_val_pb = _new_value_pb(entity_pb, OUTSIDE_NAME) outside_val_pb.entity_value.CopyFrom(entity_inside) entity = self._callFUT(entity_pb) self.assertEqual(entity.key.project, PROJECT) self.assertEqual(entity.key.flat_path, (KIND,)) self.assertEqual(len(entity), 1) inside_entity = entity[OUTSIDE_NAME] self.assertEqual(inside_entity.key, None) self.assertEqual(len(inside_entity), 1) self.assertEqual(inside_entity[INSIDE_NAME], INSIDE_VALUE)
def test_nested_entity_no_key(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb PROJECT = 'FOO' KIND = 'KIND' INSIDE_NAME = 'IFOO' OUTSIDE_NAME = 'OBAR' INSIDE_VALUE = 1337 entity_inside = entity_pb2.Entity() inside_val_pb = _new_value_pb(entity_inside, INSIDE_NAME) inside_val_pb.integer_value = INSIDE_VALUE entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = PROJECT element = entity_pb.key.path.add() element.kind = KIND outside_val_pb = _new_value_pb(entity_pb, OUTSIDE_NAME) outside_val_pb.entity_value.CopyFrom(entity_inside) entity = self._callFUT(entity_pb) self.assertEqual(entity.key.project, PROJECT) self.assertEqual(entity.key.flat_path, (KIND,)) self.assertEqual(len(entity), 1) inside_entity = entity[OUTSIDE_NAME] self.assertEqual(inside_entity.key, None) self.assertEqual(len(inside_entity), 1) self.assertEqual(inside_entity[INSIDE_NAME], INSIDE_VALUE)
def test_it(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = _PROJECT entity_pb.key.path_element.add(kind=_KIND, id=_ID) value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' unindexed_val_pb = _new_value_pb(entity_pb, 'bar') unindexed_val_pb.integer_value = 10 unindexed_val_pb.indexed = False list_val_pb1 = _new_value_pb(entity_pb, 'baz') list_pb1 = list_val_pb1.list_value unindexed_list_val_pb = list_pb1.add() unindexed_list_val_pb.integer_value = 11 unindexed_list_val_pb.indexed = False list_val_pb2 = _new_value_pb(entity_pb, 'qux') list_pb2 = list_val_pb2.list_value indexed_list_val_pb = list_pb2.add() indexed_list_val_pb.integer_value = 12 indexed_list_val_pb.indexed = True entity = self._callFUT(entity_pb) self.assertEqual(entity.kind, _KIND) self.assertEqual(entity.exclude_from_indexes, frozenset(['bar', 'baz'])) entity_props = dict(entity) self.assertEqual(entity_props, { 'foo': 'Foo', 'bar': 10, 'baz': [11], 'qux': [12] }) # Also check the key. key = entity.key self.assertEqual(key.project, _PROJECT) self.assertEqual(key.namespace, None) self.assertEqual(key.kind, _KIND) self.assertEqual(key.id, _ID)
def test_it(self): import types from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() name1 = 'foo' name2 = 'bar' val_pb1 = _new_value_pb(entity_pb, name1) val_pb2 = _new_value_pb(entity_pb, name2) result = self._callFUT(entity_pb) self.assertTrue(isinstance(result, types.GeneratorType)) self.assertEqual(list(result), [(name1, val_pb1), (name2, val_pb2)])
def test_variable_meanings(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name = 'quux' entity[name] = values = [1, 20, 300] meaning = 9 entity._meanings[name] = ([None, meaning, None], values) entity_pb = self._callFUT(entity) # Construct the expected protobuf. expected_pb = entity_pb2.Entity() value_pb = _new_value_pb(expected_pb, name) value0 = value_pb.array_value.values.add() value0.integer_value = values[0] # The only array entry with a meaning is the middle one. value1 = value_pb.array_value.values.add() value1.integer_value = values[1] value1.meaning = meaning value2 = value_pb.array_value.values.add() value2.integer_value = values[2] self._compareEntityProto(entity_pb, expected_pb)
def _addQueryResults(self, connection, cursor=_END, more=False, skipped_results=None, no_entity=False): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore._generated import query_pb2 from gcloud.datastore.helpers import _new_value_pb if more: more_enum = query_pb2.QueryResultBatch.NOT_FINISHED else: more_enum = query_pb2.QueryResultBatch.MORE_RESULTS_AFTER_LIMIT _ID = 123 if no_entity: entities = [] else: entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = self._PROJECT path_element = entity_pb.key.path.add() path_element.kind = self._KIND path_element.id = _ID value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = u'Foo' entities = [entity_pb] connection._results.append( (entities, cursor, more_enum, skipped_results))
def test_it(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = _PROJECT entity_pb.key.path_element.add(kind=_KIND, id=_ID) value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' unindexed_val_pb = _new_value_pb(entity_pb, 'bar') unindexed_val_pb.integer_value = 10 unindexed_val_pb.indexed = False list_val_pb1 = _new_value_pb(entity_pb, 'baz') list_pb1 = list_val_pb1.list_value unindexed_list_val_pb = list_pb1.add() unindexed_list_val_pb.integer_value = 11 unindexed_list_val_pb.indexed = False list_val_pb2 = _new_value_pb(entity_pb, 'qux') list_pb2 = list_val_pb2.list_value indexed_list_val_pb = list_pb2.add() indexed_list_val_pb.integer_value = 12 indexed_list_val_pb.indexed = True entity = self._callFUT(entity_pb) self.assertEqual(entity.kind, _KIND) self.assertEqual(entity.exclude_from_indexes, frozenset(['bar', 'baz'])) entity_props = dict(entity) self.assertEqual(entity_props, {'foo': 'Foo', 'bar': 10, 'baz': [11], 'qux': [12]}) # Also check the key. key = entity.key self.assertEqual(key.project, _PROJECT) self.assertEqual(key.namespace, None) self.assertEqual(key.kind, _KIND) self.assertEqual(key.id, _ID)
def test_simple_fields(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name1 = 'foo' entity[name1] = value1 = 42 name2 = 'bar' entity[name2] = value2 = u'some-string' entity_pb = self._callFUT(entity) expected_pb = entity_pb2.Entity() val_pb1 = _new_value_pb(expected_pb, name1) val_pb1.integer_value = value1 val_pb2 = _new_value_pb(expected_pb, name2) val_pb2.string_value = value2 self._compareEntityProto(entity_pb, expected_pb)
def test_entity_with_meaning(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() name = 'hello' value_pb = _new_value_pb(entity_pb, name) value_pb.meaning = meaning = 9 value_pb.string_value = val = u'something' entity = self._callFUT(entity_pb) self.assertEqual(entity.key, None) self.assertEqual(dict(entity), {name: val}) self.assertEqual(entity._meanings, {name: (meaning, val)})
def _make_entity_pb(project, kind, integer_id, name=None, str_val=None): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = project path_element = entity_pb.key.path.add() path_element.kind = kind path_element.id = integer_id if name is not None and str_val is not None: value_pb = _new_value_pb(entity_pb, name) value_pb.string_value = str_val return entity_pb
def _make_entity_pb(project, kind, integer_id, name=None, str_val=None): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = project path_element = entity_pb.key.path_element.add() path_element.kind = kind path_element.id = integer_id if name is not None and str_val is not None: value_pb = _new_value_pb(entity_pb, name) value_pb.string_value = str_val return entity_pb
def test_entity(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb pb = entity_pb2.Value() entity_pb = pb.entity_value entity_pb.key.path_element.add(kind='KIND') entity_pb.key.partition_id.dataset_id = 'PROJECT' value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' entity = self._callFUT(pb) self.assertTrue(isinstance(entity, Entity)) self.assertEqual(entity['foo'], 'Foo')
def test_entity(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb pb = entity_pb2.Value() entity_pb = pb.entity_value entity_pb.key.path.add(kind='KIND') entity_pb.key.partition_id.project_id = 'PROJECT' value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' entity = self._callFUT(pb) self.assertTrue(isinstance(entity, Entity)) self.assertEqual(entity['foo'], 'Foo')
def test_commit_w_transaction(self): from gcloud._testing import _Monkey from gcloud.datastore._generated import datastore_pb2 from gcloud.datastore import connection as MUT from gcloud.datastore.helpers import _new_value_pb PROJECT = 'PROJECT' key_pb = self._make_key_pb(PROJECT) rsp_pb = datastore_pb2.CommitResponse() req_pb = datastore_pb2.CommitRequest() mutation = req_pb.mutation insert = mutation.upsert.add() insert.key.CopyFrom(key_pb) value_pb = _new_value_pb(insert, 'foo') value_pb.string_value = u'Foo' conn = self._makeOne() URI = '/'.join([ conn.api_base_url, 'datastore', conn.API_VERSION, 'datasets', PROJECT, 'commit', ]) http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString()) # Set up mock for parsing the response. expected_result = object() _parsed = [] def mock_parse(response): _parsed.append(response) return expected_result with _Monkey(MUT, _parse_commit_response=mock_parse): result = conn.commit(PROJECT, req_pb, b'xact') self.assertTrue(result is expected_result) cw = http._called_with self._verifyProtobufCall(cw, URI, conn) rq_class = datastore_pb2.CommitRequest request = rq_class() request.ParseFromString(cw['body']) self.assertEqual(request.transaction, b'xact') self.assertEqual(request.mutation, mutation) self.assertEqual(request.mode, rq_class.TRANSACTIONAL) self.assertEqual(_parsed, [rsp_pb])
def test_commit_w_transaction(self): from gcloud._testing import _Monkey from gcloud.datastore._generated import datastore_pb2 from gcloud.datastore import connection as MUT from gcloud.datastore.helpers import _new_value_pb DATASET_ID = 'DATASET' key_pb = self._make_key_pb(DATASET_ID) rsp_pb = datastore_pb2.CommitResponse() req_pb = datastore_pb2.CommitRequest() mutation = req_pb.mutation insert = mutation.upsert.add() insert.key.CopyFrom(key_pb) value_pb = _new_value_pb(insert, 'foo') value_pb.string_value = u'Foo' conn = self._makeOne() URI = '/'.join([ conn.api_base_url, 'datastore', conn.API_VERSION, 'datasets', DATASET_ID, 'commit', ]) http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString()) # Set up mock for parsing the response. expected_result = object() _parsed = [] def mock_parse(response): _parsed.append(response) return expected_result with _Monkey(MUT, _parse_commit_response=mock_parse): result = conn.commit(DATASET_ID, req_pb, b'xact') self.assertTrue(result is expected_result) cw = http._called_with self._verifyProtobufCall(cw, URI, conn) rq_class = datastore_pb2.CommitRequest request = rq_class() request.ParseFromString(cw['body']) self.assertEqual(request.transaction, b'xact') self.assertEqual(request.mutation, mutation) self.assertEqual(request.mode, rq_class.TRANSACTIONAL) self.assertEqual(_parsed, [rsp_pb])
def _addQueryResults(self, connection, cursor=_END, more=False): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore._generated import query_pb2 from gcloud.datastore.helpers import _new_value_pb MORE = query_pb2.QueryResultBatch.NOT_FINISHED NO_MORE = query_pb2.QueryResultBatch.MORE_RESULTS_AFTER_LIMIT _ID = 123 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = self._PROJECT path_element = entity_pb.key.path_element.add() path_element.kind = self._KIND path_element.id = _ID value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = u'Foo' connection._results.append( ([entity_pb], cursor, MORE if more else NO_MORE))
def test_meaning_with_change(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name = 'foo' entity[name] = value = 42 entity._meanings[name] = (9, 1337) entity_pb = self._callFUT(entity) expected_pb = entity_pb2.Entity() value_pb = _new_value_pb(expected_pb, name) value_pb.integer_value = value # NOTE: No meaning is used since the value differs from the # value stored. self._compareEntityProto(entity_pb, expected_pb)
def test_inverts_to_protobuf(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb from gcloud.datastore.helpers import entity_from_protobuf original_pb = entity_pb2.Entity() # Add a key. original_pb.key.partition_id.project_id = project = 'PROJECT' elem1 = original_pb.key.path.add() elem1.kind = 'Family' elem1.id = 1234 elem2 = original_pb.key.path.add() elem2.kind = 'King' elem2.name = 'Spades' # Add an integer property. val_pb1 = _new_value_pb(original_pb, 'foo') val_pb1.integer_value = 1337 val_pb1.exclude_from_indexes = True # Add a string property. val_pb2 = _new_value_pb(original_pb, 'bar') val_pb2.string_value = u'hello' # Add a nested (entity) property. val_pb3 = _new_value_pb(original_pb, 'entity-baz') sub_pb = entity_pb2.Entity() sub_val_pb1 = _new_value_pb(sub_pb, 'x') sub_val_pb1.double_value = 3.14 sub_val_pb2 = _new_value_pb(sub_pb, 'y') sub_val_pb2.double_value = 2.718281828 val_pb3.meaning = 9 val_pb3.entity_value.CopyFrom(sub_pb) # Add a list property. val_pb4 = _new_value_pb(original_pb, 'list-quux') array_val1 = val_pb4.array_value.values.add() array_val1.exclude_from_indexes = False array_val1.meaning = meaning = 22 array_val1.blob_value = b'\xe2\x98\x83' array_val2 = val_pb4.array_value.values.add() array_val2.exclude_from_indexes = False array_val2.meaning = meaning array_val2.blob_value = b'\xe2\x98\x85' # Convert to the user-space Entity. entity = entity_from_protobuf(original_pb) # Convert the user-space Entity back to a protobuf. new_pb = self._callFUT(entity) # NOTE: entity_to_protobuf() strips the project so we "cheat". new_pb.key.partition_id.project_id = project self._compareEntityProto(original_pb, new_pb)
def test_inverts_to_protobuf(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb from gcloud.datastore.helpers import entity_from_protobuf original_pb = entity_pb2.Entity() # Add a key. original_pb.key.partition_id.dataset_id = project = 'PROJECT' elem1 = original_pb.key.path_element.add() elem1.kind = 'Family' elem1.id = 1234 elem2 = original_pb.key.path_element.add() elem2.kind = 'King' elem2.name = 'Spades' # Add an integer property. val_pb1 = _new_value_pb(original_pb, 'foo') val_pb1.integer_value = 1337 val_pb1.indexed = False # Add a string property. val_pb2 = _new_value_pb(original_pb, 'bar') val_pb2.string_value = u'hello' # Add a nested (entity) property. val_pb3 = _new_value_pb(original_pb, 'entity-baz') sub_pb = entity_pb2.Entity() sub_val_pb1 = _new_value_pb(sub_pb, 'x') sub_val_pb1.double_value = 3.14 sub_val_pb2 = _new_value_pb(sub_pb, 'y') sub_val_pb2.double_value = 2.718281828 val_pb3.meaning = 9 val_pb3.entity_value.CopyFrom(sub_pb) # Add a list property. val_pb4 = _new_value_pb(original_pb, 'list-quux') list_val1 = val_pb4.list_value.add() list_val1.indexed = False list_val1.meaning = meaning = 22 list_val1.blob_value = b'\xe2\x98\x83' list_val2 = val_pb4.list_value.add() list_val2.indexed = False list_val2.meaning = meaning list_val2.blob_value = b'\xe2\x98\x85' # Convert to the user-space Entity. entity = entity_from_protobuf(original_pb) # Convert the user-space Entity back to a protobuf. new_pb = self._callFUT(entity) # NOTE: entity_to_protobuf() strips the project so we "cheat". new_pb.key.partition_id.dataset_id = project self._compareEntityProto(original_pb, new_pb)
def test_mismatched_value_indexed(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = _PROJECT entity_pb.key.path.add(kind=_KIND, id=_ID) array_val_pb = _new_value_pb(entity_pb, 'baz') array_pb = array_val_pb.array_value.values unindexed_value_pb1 = array_pb.add() unindexed_value_pb1.integer_value = 10 unindexed_value_pb1.exclude_from_indexes = True unindexed_value_pb2 = array_pb.add() unindexed_value_pb2.integer_value = 11 with self.assertRaises(ValueError): self._callFUT(entity_pb)
def test_mismatched_value_indexed(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.dataset_id = _PROJECT entity_pb.key.path_element.add(kind=_KIND, id=_ID) list_val_pb = _new_value_pb(entity_pb, 'baz') list_pb = list_val_pb.list_value unindexed_value_pb1 = list_pb.add() unindexed_value_pb1.integer_value = 10 unindexed_value_pb1.indexed = False unindexed_value_pb2 = list_pb.add() unindexed_value_pb2.integer_value = 11 unindexed_value_pb2.indexed = True with self.assertRaises(ValueError): self._callFUT(entity_pb)
def _callFUT(self, entity_pb, name): from gcloud.datastore.helpers import _new_value_pb return _new_value_pb(entity_pb, name)