diff --git a/datastore/google/cloud/datastore/_gax.py b/datastore/google/cloud/datastore/_gax.py index 4f075330d3e5..1d1f96a432e4 100644 --- a/datastore/google/cloud/datastore/_gax.py +++ b/datastore/google/cloud/datastore/_gax.py @@ -22,6 +22,7 @@ from google.gax.errors import GaxError from google.gax.grpc import exc_to_code from google.gax.utils import metrics +from grpc import insecure_channel from grpc import StatusCode import six @@ -131,8 +132,14 @@ def make_datastore_api(client): :rtype: :class:`.datastore.v1.datastore_client.DatastoreClient` :returns: A datastore API instance with the proper credentials. """ - channel = make_secure_channel( - client._credentials, DEFAULT_USER_AGENT, - datastore_client.DatastoreClient.SERVICE_ADDRESS) + parse_result = six.moves.urllib_parse.urlparse( + client._base_url) + host = parse_result.netloc + if parse_result.scheme == 'https': + channel = make_secure_channel( + client._credentials, DEFAULT_USER_AGENT, host) + else: + channel = insecure_channel(host) + return GAPICDatastoreAPI( channel=channel, lib_name='gccl', lib_version=__version__) diff --git a/datastore/unit_tests/test__gax.py b/datastore/unit_tests/test__gax.py index bb7dd6ac1773..8ab1bcc6d1ac 100644 --- a/datastore/unit_tests/test__gax.py +++ b/datastore/unit_tests/test__gax.py @@ -158,19 +158,44 @@ def _call_fut(self, client): return_value=mock.sentinel.ds_client) @mock.patch('google.cloud.datastore._gax.make_secure_channel', return_value=mock.sentinel.channel) - def test_it(self, make_chan, mock_klass): + def test_live_api(self, make_chan, mock_klass): from google.cloud.gapic.datastore.v1 import datastore_client from google.cloud._http import DEFAULT_USER_AGENT from google.cloud.datastore import __version__ + host = datastore_client.DatastoreClient.SERVICE_ADDRESS + base_url = 'https://' + host client = mock.Mock( - _credentials=mock.sentinel.credentials, spec=['_credentials']) + _base_url=base_url, + _credentials=mock.sentinel.credentials, + spec=['_base_url', '_credentials']) ds_api = self._call_fut(client) self.assertIs(ds_api, mock.sentinel.ds_client) make_chan.assert_called_once_with( - mock.sentinel.credentials, DEFAULT_USER_AGENT, - datastore_client.DatastoreClient.SERVICE_ADDRESS) + mock.sentinel.credentials, DEFAULT_USER_AGENT, host) + mock_klass.assert_called_once_with( + channel=mock.sentinel.channel, lib_name='gccl', + lib_version=__version__) + + @mock.patch( + 'google.cloud.datastore._gax.GAPICDatastoreAPI', + return_value=mock.sentinel.ds_client) + @mock.patch('google.cloud.datastore._gax.insecure_channel', + return_value=mock.sentinel.channel) + def test_emulator(self, make_chan, mock_klass): + from google.cloud.datastore import __version__ + + host = 'localhost:8901' + base_url = 'http://' + host + client = mock.Mock( + _base_url=base_url, + _credentials=mock.sentinel.credentials, + spec=['_base_url', '_credentials']) + ds_api = self._call_fut(client) + self.assertIs(ds_api, mock.sentinel.ds_client) + + make_chan.assert_called_once_with(host) mock_klass.assert_called_once_with( channel=mock.sentinel.channel, lib_name='gccl', lib_version=__version__) diff --git a/system_tests/system_test_utils.py b/system_tests/system_test_utils.py index 56e8a9203292..6ee041f666ec 100644 --- a/system_tests/system_test_utils.py +++ b/system_tests/system_test_utils.py @@ -17,6 +17,7 @@ import sys import time +import google.auth.credentials from google.auth.environment_vars import CREDENTIALS as TEST_CREDENTIALS @@ -29,16 +30,28 @@ """ -class EmulatorCreds(object): +class EmulatorCreds(google.auth.credentials.Credentials): """A mock credential object. Used to avoid unnecessary token refreshing or reliance on the network while an emulator is running. """ - @staticmethod - def create_scoped_required(): - return False + def __init__(self): # pylint: disable=super-init-not-called + self.token = b'seekrit' + self.expiry = None + + @property + def valid(self): + """Would-be validity check of the credentials. + + Always is :data:`True`. + """ + return True + + def refresh(self, unused_request): # pylint: disable=unused-argument + """Off-limits implementation for abstract method.""" + raise RuntimeError('Should never be refreshed.') def check_environ(): diff --git a/tox.ini b/tox.ini index 401b2d07ea07..bf86d15715ac 100644 --- a/tox.ini +++ b/tox.ini @@ -300,7 +300,9 @@ commands = {[emulator]emulatorcmd} --package=datastore setenv = {[emulator]setenv} passenv = {[testing]passenv} -deps = {[emulator]deps} +deps = + {[emulator]deps} + Sphinx [testenv:pubsub-emulator] commands =