Vehicle-Anti-Theft-Face-Rec.../venv/Lib/site-packages/gcloud/datastore/test_connection.py

874 lines
31 KiB
Python
Raw Normal View History

# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest2
class TestConnection(unittest2.TestCase):
def _getTargetClass(self):
from gcloud.datastore.connection import Connection
return Connection
def _make_key_pb(self, project, id_=1234):
from gcloud.datastore.key import Key
path_args = ('Kind',)
if id_ is not None:
path_args += (id_,)
return Key(*path_args, project=project).to_protobuf()
def _make_query_pb(self, kind):
from gcloud.datastore._generated import query_pb2
pb = query_pb2.Query()
pb.kind.add().name = kind
return pb
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
def _verifyProtobufCall(self, called_with, URI, conn):
self.assertEqual(called_with['uri'], URI)
self.assertEqual(called_with['method'], 'POST')
self.assertEqual(called_with['headers']['Content-Type'],
'application/x-protobuf')
self.assertEqual(called_with['headers']['User-Agent'],
conn.USER_AGENT)
def test_default_url(self):
klass = self._getTargetClass()
conn = self._makeOne()
self.assertEqual(conn.api_base_url, klass.API_BASE_URL)
def test_custom_url_from_env(self):
import os
from gcloud._testing import _Monkey
from gcloud.connection import API_BASE_URL
from gcloud.environment_vars import GCD_HOST
HOST = 'CURR_HOST'
fake_environ = {GCD_HOST: HOST}
with _Monkey(os, environ=fake_environ):
conn = self._makeOne()
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertEqual(conn.api_base_url, HOST + '/datastore')
def test_custom_url_from_constructor(self):
from gcloud.connection import API_BASE_URL
HOST = object()
conn = self._makeOne(api_base_url=HOST)
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertEqual(conn.api_base_url, HOST)
def test_custom_url_constructor_and_env(self):
import os
from gcloud._testing import _Monkey
from gcloud.connection import API_BASE_URL
from gcloud.environment_vars import GCD_HOST
HOST1 = object()
HOST2 = object()
fake_environ = {GCD_HOST: HOST1}
with _Monkey(os, environ=fake_environ):
conn = self._makeOne(api_base_url=HOST2)
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertNotEqual(conn.api_base_url, HOST1)
self.assertEqual(conn.api_base_url, HOST2)
def test_ctor_defaults(self):
conn = self._makeOne()
self.assertEqual(conn.credentials, None)
def test_ctor_explicit(self):
class Creds(object):
def create_scoped_required(self):
return False
creds = Creds()
conn = self._makeOne(creds)
self.assertTrue(conn.credentials is creds)
def test_http_w_existing(self):
conn = self._makeOne()
conn._http = http = object()
self.assertTrue(conn.http is http)
def test_http_wo_creds(self):
import httplib2
conn = self._makeOne()
self.assertTrue(isinstance(conn.http, httplib2.Http))
def test_http_w_creds(self):
import httplib2
authorized = object()
class Creds(object):
def authorize(self, http):
self._called_with = http
return authorized
def create_scoped_required(self):
return False
creds = Creds()
conn = self._makeOne(creds)
self.assertTrue(conn.http is authorized)
self.assertTrue(isinstance(creds._called_with, httplib2.Http))
def test__request_w_200(self):
PROJECT = 'PROJECT'
METHOD = 'METHOD'
DATA = b'DATA'
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':' + METHOD,
])
http = conn._http = Http({'status': '200'}, 'CONTENT')
self.assertEqual(conn._request(PROJECT, METHOD, DATA), 'CONTENT')
self._verifyProtobufCall(http._called_with, URI, conn)
self.assertEqual(http._called_with['body'], DATA)
def test__request_not_200(self):
from gcloud.exceptions import BadRequest
from google.rpc import status_pb2
error = status_pb2.Status()
error.message = 'Entity value is indexed.'
error.code = 9 # FAILED_PRECONDITION
PROJECT = 'PROJECT'
METHOD = 'METHOD'
DATA = 'DATA'
conn = self._makeOne()
conn._http = Http({'status': '400'}, error.SerializeToString())
with self.assertRaises(BadRequest) as e:
conn._request(PROJECT, METHOD, DATA)
expected_message = '400 Entity value is indexed.'
self.assertEqual(str(e.exception), expected_message)
def test__rpc(self):
class ReqPB(object):
def SerializeToString(self):
return REQPB
class RspPB(object):
def __init__(self, pb):
self._pb = pb
@classmethod
def FromString(cls, pb):
return cls(pb)
REQPB = b'REQPB'
PROJECT = 'PROJECT'
METHOD = 'METHOD'
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':' + METHOD,
])
http = conn._http = Http({'status': '200'}, 'CONTENT')
response = conn._rpc(PROJECT, METHOD, ReqPB(), RspPB)
self.assertTrue(isinstance(response, RspPB))
self.assertEqual(response._pb, 'CONTENT')
self._verifyProtobufCall(http._called_with, URI, conn)
self.assertEqual(http._called_with['body'], REQPB)
def test_build_api_url_w_default_base_version(self):
PROJECT = 'PROJECT'
METHOD = 'METHOD'
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':' + METHOD,
])
self.assertEqual(conn.build_api_url(PROJECT, METHOD), URI)
def test_build_api_url_w_explicit_base_version(self):
BASE = 'http://example.com/'
VER = '3.1415926'
PROJECT = 'PROJECT'
METHOD = 'METHOD'
conn = self._makeOne()
URI = '/'.join([
BASE,
VER,
'projects',
PROJECT + ':' + METHOD,
])
self.assertEqual(conn.build_api_url(PROJECT, METHOD, BASE, VER),
URI)
def test_lookup_single_key_empty_response(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
key_pb = self._make_key_pb(PROJECT)
rsp_pb = datastore_pb2.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
found, missing, deferred = conn.lookup(PROJECT, [key_pb])
self.assertEqual(len(found), 0)
self.assertEqual(len(missing), 0)
self.assertEqual(len(deferred), 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 1)
self.assertEqual(key_pb, keys[0])
def test_lookup_single_key_empty_response_w_eventual(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
key_pb = self._make_key_pb(PROJECT)
rsp_pb = datastore_pb2.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
found, missing, deferred = conn.lookup(PROJECT, [key_pb],
eventual=True)
self.assertEqual(len(found), 0)
self.assertEqual(len(missing), 0)
self.assertEqual(len(deferred), 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 1)
self.assertEqual(key_pb, keys[0])
self.assertEqual(request.read_options.read_consistency,
datastore_pb2.ReadOptions.EVENTUAL)
self.assertEqual(request.read_options.transaction, b'')
def test_lookup_single_key_empty_response_w_eventual_and_transaction(self):
PROJECT = 'PROJECT'
TRANSACTION = b'TRANSACTION'
key_pb = self._make_key_pb(PROJECT)
conn = self._makeOne()
self.assertRaises(ValueError, conn.lookup, PROJECT, key_pb,
eventual=True, transaction_id=TRANSACTION)
def test_lookup_single_key_empty_response_w_transaction(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
TRANSACTION = b'TRANSACTION'
key_pb = self._make_key_pb(PROJECT)
rsp_pb = datastore_pb2.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
found, missing, deferred = conn.lookup(PROJECT, [key_pb],
transaction_id=TRANSACTION)
self.assertEqual(len(found), 0)
self.assertEqual(len(missing), 0)
self.assertEqual(len(deferred), 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 1)
self.assertEqual(key_pb, keys[0])
self.assertEqual(request.read_options.transaction, TRANSACTION)
def test_lookup_single_key_nonempty_response(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import entity_pb2
PROJECT = 'PROJECT'
key_pb = self._make_key_pb(PROJECT)
rsp_pb = datastore_pb2.LookupResponse()
entity = entity_pb2.Entity()
entity.key.CopyFrom(key_pb)
rsp_pb.found.add(entity=entity)
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
(found,), missing, deferred = conn.lookup(PROJECT, [key_pb])
self.assertEqual(len(missing), 0)
self.assertEqual(len(deferred), 0)
self.assertEqual(found.key.path[0].kind, 'Kind')
self.assertEqual(found.key.path[0].id, 1234)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 1)
self.assertEqual(key_pb, keys[0])
def test_lookup_multiple_keys_empty_response(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
key_pb1 = self._make_key_pb(PROJECT)
key_pb2 = self._make_key_pb(PROJECT, id_=2345)
rsp_pb = datastore_pb2.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
found, missing, deferred = conn.lookup(PROJECT, [key_pb1, key_pb2])
self.assertEqual(len(found), 0)
self.assertEqual(len(missing), 0)
self.assertEqual(len(deferred), 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 2)
self.assertEqual(key_pb1, keys[0])
self.assertEqual(key_pb2, keys[1])
def test_lookup_multiple_keys_w_missing(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
key_pb1 = self._make_key_pb(PROJECT)
key_pb2 = self._make_key_pb(PROJECT, id_=2345)
rsp_pb = datastore_pb2.LookupResponse()
er_1 = rsp_pb.missing.add()
er_1.entity.key.CopyFrom(key_pb1)
er_2 = rsp_pb.missing.add()
er_2.entity.key.CopyFrom(key_pb2)
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
result, missing, deferred = conn.lookup(PROJECT, [key_pb1, key_pb2])
self.assertEqual(result, [])
self.assertEqual(len(deferred), 0)
self.assertEqual([missed.key for missed in missing],
[key_pb1, key_pb2])
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 2)
self.assertEqual(key_pb1, keys[0])
self.assertEqual(key_pb2, keys[1])
def test_lookup_multiple_keys_w_deferred(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
key_pb1 = self._make_key_pb(PROJECT)
key_pb2 = self._make_key_pb(PROJECT, id_=2345)
rsp_pb = datastore_pb2.LookupResponse()
rsp_pb.deferred.add().CopyFrom(key_pb1)
rsp_pb.deferred.add().CopyFrom(key_pb2)
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':lookup',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
result, missing, deferred = conn.lookup(PROJECT, [key_pb1, key_pb2])
self.assertEqual(result, [])
self.assertEqual(len(missing), 0)
self.assertEqual([def_key for def_key in deferred], [key_pb1, key_pb2])
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
self.assertEqual(cw['uri'], URI)
self.assertEqual(cw['method'], 'POST')
self.assertEqual(cw['headers']['Content-Type'],
'application/x-protobuf')
self.assertEqual(cw['headers']['User-Agent'], conn.USER_AGENT)
rq_class = datastore_pb2.LookupRequest
request = rq_class()
request.ParseFromString(cw['body'])
keys = list(request.keys)
self.assertEqual(len(keys), 2)
self.assertEqual(key_pb1, keys[0])
self.assertEqual(key_pb2, keys[1])
def test_run_query_w_eventual_no_transaction(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import query_pb2
PROJECT = 'PROJECT'
KIND = 'Nonesuch'
CURSOR = b'\x00'
q_pb = self._make_query_pb(KIND)
rsp_pb = datastore_pb2.RunQueryResponse()
rsp_pb.batch.end_cursor = CURSOR
no_more = query_pb2.QueryResultBatch.NO_MORE_RESULTS
rsp_pb.batch.more_results = no_more
rsp_pb.batch.entity_result_type = query_pb2.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':runQuery',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
pbs, end, more, skipped = conn.run_query(PROJECT, q_pb,
eventual=True)
self.assertEqual(pbs, [])
self.assertEqual(end, CURSOR)
self.assertTrue(more)
self.assertEqual(skipped, 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.RunQueryRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(request.partition_id.namespace_id, '')
self.assertEqual(request.query, q_pb)
self.assertEqual(request.read_options.read_consistency,
datastore_pb2.ReadOptions.EVENTUAL)
self.assertEqual(request.read_options.transaction, b'')
def test_run_query_wo_eventual_w_transaction(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import query_pb2
PROJECT = 'PROJECT'
KIND = 'Nonesuch'
CURSOR = b'\x00'
TRANSACTION = b'TRANSACTION'
q_pb = self._make_query_pb(KIND)
rsp_pb = datastore_pb2.RunQueryResponse()
rsp_pb.batch.end_cursor = CURSOR
no_more = query_pb2.QueryResultBatch.NO_MORE_RESULTS
rsp_pb.batch.more_results = no_more
rsp_pb.batch.entity_result_type = query_pb2.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':runQuery',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
pbs, end, more, skipped = conn.run_query(
PROJECT, q_pb, transaction_id=TRANSACTION)
self.assertEqual(pbs, [])
self.assertEqual(end, CURSOR)
self.assertTrue(more)
self.assertEqual(skipped, 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.RunQueryRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(request.partition_id.namespace_id, '')
self.assertEqual(request.query, q_pb)
self.assertEqual(
request.read_options.read_consistency,
datastore_pb2.ReadOptions.READ_CONSISTENCY_UNSPECIFIED)
self.assertEqual(request.read_options.transaction, TRANSACTION)
def test_run_query_w_eventual_and_transaction(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import query_pb2
PROJECT = 'PROJECT'
KIND = 'Nonesuch'
CURSOR = b'\x00'
TRANSACTION = b'TRANSACTION'
q_pb = self._make_query_pb(KIND)
rsp_pb = datastore_pb2.RunQueryResponse()
rsp_pb.batch.end_cursor = CURSOR
no_more = query_pb2.QueryResultBatch.NO_MORE_RESULTS
rsp_pb.batch.more_results = no_more
rsp_pb.batch.entity_result_type = query_pb2.EntityResult.FULL
conn = self._makeOne()
self.assertRaises(ValueError, conn.run_query, PROJECT, q_pb,
eventual=True, transaction_id=TRANSACTION)
def test_run_query_wo_namespace_empty_result(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import query_pb2
PROJECT = 'PROJECT'
KIND = 'Nonesuch'
CURSOR = b'\x00'
q_pb = self._make_query_pb(KIND)
rsp_pb = datastore_pb2.RunQueryResponse()
rsp_pb.batch.end_cursor = CURSOR
no_more = query_pb2.QueryResultBatch.NO_MORE_RESULTS
rsp_pb.batch.more_results = no_more
rsp_pb.batch.entity_result_type = query_pb2.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':runQuery',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
pbs, end, more, skipped = conn.run_query(PROJECT, q_pb)
self.assertEqual(pbs, [])
self.assertEqual(end, CURSOR)
self.assertTrue(more)
self.assertEqual(skipped, 0)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.RunQueryRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(request.partition_id.namespace_id, '')
self.assertEqual(request.query, q_pb)
def test_run_query_w_namespace_nonempty_result(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import entity_pb2
PROJECT = 'PROJECT'
KIND = 'Kind'
entity = entity_pb2.Entity()
q_pb = self._make_query_pb(KIND)
rsp_pb = datastore_pb2.RunQueryResponse()
rsp_pb.batch.entity_results.add(entity=entity)
rsp_pb.batch.entity_result_type = 1 # FULL
rsp_pb.batch.more_results = 3 # NO_MORE_RESULTS
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':runQuery',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
pbs = conn.run_query(PROJECT, q_pb, 'NS')[0]
self.assertEqual(len(pbs), 1)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.RunQueryRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(request.partition_id.namespace_id, 'NS')
self.assertEqual(request.query, q_pb)
def test_begin_transaction(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
TRANSACTION = b'TRANSACTION'
rsp_pb = datastore_pb2.BeginTransactionResponse()
rsp_pb.transaction = TRANSACTION
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':beginTransaction',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.begin_transaction(PROJECT), TRANSACTION)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.BeginTransactionRequest
request = rq_class()
request.ParseFromString(cw['body'])
def test_commit_wo_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.mutations.add()
insert = mutation.upsert
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,
conn.API_VERSION,
'projects',
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, None)
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'')
self.assertEqual(list(request.mutations), [mutation])
self.assertEqual(request.mode, rq_class.NON_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
PROJECT = 'PROJECT'
key_pb = self._make_key_pb(PROJECT)
rsp_pb = datastore_pb2.CommitResponse()
req_pb = datastore_pb2.CommitRequest()
mutation = req_pb.mutations.add()
insert = mutation.upsert
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,
conn.API_VERSION,
'projects',
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(list(request.mutations), [mutation])
self.assertEqual(request.mode, rq_class.TRANSACTIONAL)
self.assertEqual(_parsed, [rsp_pb])
def test_rollback_ok(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
TRANSACTION = b'xact'
rsp_pb = datastore_pb2.RollbackResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':rollback',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.rollback(PROJECT, TRANSACTION), None)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.RollbackRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(request.transaction, TRANSACTION)
def test_allocate_ids_empty(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
rsp_pb = datastore_pb2.AllocateIdsResponse()
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':allocateIds',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.allocate_ids(PROJECT, []), [])
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.AllocateIdsRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(list(request.keys), [])
def test_allocate_ids_non_empty(self):
from gcloud.datastore._generated import datastore_pb2
PROJECT = 'PROJECT'
before_key_pbs = [
self._make_key_pb(PROJECT, id_=None),
self._make_key_pb(PROJECT, id_=None),
]
after_key_pbs = [
self._make_key_pb(PROJECT),
self._make_key_pb(PROJECT, id_=2345),
]
rsp_pb = datastore_pb2.AllocateIdsResponse()
rsp_pb.keys.add().CopyFrom(after_key_pbs[0])
rsp_pb.keys.add().CopyFrom(after_key_pbs[1])
conn = self._makeOne()
URI = '/'.join([
conn.api_base_url,
conn.API_VERSION,
'projects',
PROJECT + ':allocateIds',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.allocate_ids(PROJECT, before_key_pbs),
after_key_pbs)
cw = http._called_with
self._verifyProtobufCall(cw, URI, conn)
rq_class = datastore_pb2.AllocateIdsRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(len(request.keys), len(before_key_pbs))
for key_before, key_after in zip(before_key_pbs, request.keys):
self.assertEqual(key_before, key_after)
class Test__parse_commit_response(unittest2.TestCase):
def _callFUT(self, commit_response_pb):
from gcloud.datastore.connection import _parse_commit_response
return _parse_commit_response(commit_response_pb)
def test_it(self):
from gcloud.datastore._generated import datastore_pb2
from gcloud.datastore._generated import entity_pb2
index_updates = 1337
keys = [
entity_pb2.Key(
path=[
entity_pb2.Key.PathElement(
kind='Foo',
id=1234,
),
],
),
entity_pb2.Key(
path=[
entity_pb2.Key.PathElement(
kind='Bar',
name='baz',
),
],
),
]
response = datastore_pb2.CommitResponse(
mutation_results=[
datastore_pb2.MutationResult(key=key) for key in keys
],
index_updates=index_updates,
)
result = self._callFUT(response)
self.assertEqual(result, (index_updates, keys))
class Http(object):
_called_with = None
def __init__(self, headers, content):
from httplib2 import Response
self._response = Response(headers)
self._content = content
def request(self, **kw):
self._called_with = kw
return self._response, self._content
class _PathElementProto(object):
def __init__(self, _id):
self.id = _id
class _KeyProto(object):
def __init__(self, id_):
self.path = [_PathElementProto(id_)]