Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding (back) support for datastore emulator. #3148

Merged
merged 1 commit into from
Mar 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

[testenv:pubsub-emulator]
commands =
Expand Down