Skip to content

Commit

Permalink
Merge pull request googleapis#3148 from dhermes/make-ds-gapic-emulator
Browse files Browse the repository at this point in the history
Adding (back) support for datastore emulator.
  • Loading branch information
dhermes authored Mar 16, 2017
2 parents 3670b86 + f7641d8 commit 0656330
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 12 deletions.
13 changes: 10 additions & 3 deletions datastore/google/cloud/datastore/_gax.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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__)
33 changes: 29 additions & 4 deletions datastore/unit_tests/test__gax.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
21 changes: 17 additions & 4 deletions system_tests/system_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import sys
import time

import google.auth.credentials
from google.auth.environment_vars import CREDENTIALS as TEST_CREDENTIALS


Expand All @@ -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():
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down

0 comments on commit 0656330

Please sign in to comment.