forked from googleapis/google-cloud-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ideas commit for better (implicit) auth story in datastore.
Also - Integrates this idea into the datastore regression tests. - Creates a (temporarily ignored) cyclic import - Has an uncovered statement that confuses nosetests - Implements a friendlier (more gcloud-node like) version of allocated_ids - DOES NOT update CONTRIBUTING to explain change to regression tests or ditch unneeded helper / environ code for regressions - Creates a datastore cleanup script for when tests get broken
- Loading branch information
Showing
14 changed files
with
410 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,50 @@ def test_it(self): | |
self.assertEqual(client._called_with, expected_called_with) | ||
|
||
|
||
class Test_get_local_dataset_settings(unittest2.TestCase): | ||
|
||
def _callFUT(self): | ||
from gcloud.datastore import get_local_dataset_settings | ||
return get_local_dataset_settings() | ||
|
||
def _test_with_environ(self, environ, expected_result): | ||
import os | ||
from gcloud._testing import _Monkey | ||
|
||
def custom_getenv(key): | ||
return environ.get(key) | ||
|
||
with _Monkey(os, getenv=custom_getenv): | ||
result = self._callFUT() | ||
|
||
self.assertEqual(result, expected_result) | ||
|
||
def test_all_set(self): | ||
# Fake auth variables. | ||
DATASET = 'dataset' | ||
CLIENT_EMAIL = '[email protected]' | ||
TEMP_PATH = 'fakepath' | ||
|
||
# Make a custom getenv function to Monkey. | ||
VALUES = { | ||
'GCLOUD_DATASET_ID': DATASET, | ||
'GCLOUD_CLIENT_EMAIL': CLIENT_EMAIL, | ||
'GCLOUD_KEY_FILE': TEMP_PATH, | ||
} | ||
expected_result = (DATASET, CLIENT_EMAIL, TEMP_PATH) | ||
self._test_with_environ(VALUES, expected_result) | ||
|
||
def test_partial_set(self): | ||
# Fake auth variables. | ||
DATASET = 'dataset' | ||
|
||
# Make a custom getenv function to Monkey. | ||
VALUES = { | ||
'GCLOUD_DATASET_ID': DATASET, | ||
} | ||
self._test_with_environ(VALUES, None) | ||
|
||
|
||
class Test_get_dataset(unittest2.TestCase): | ||
|
||
def _callFUT(self, dataset_id, client_email, private_key_path): | ||
|
@@ -66,3 +110,160 @@ def test_it(self): | |
'scope': SCOPE, | ||
} | ||
self.assertEqual(client._called_with, expected_called_with) | ||
|
||
|
||
class Test_implicit_behavior(unittest2.TestCase): | ||
|
||
def test__require_dataset(self): | ||
import gcloud.datastore | ||
original_dataset = gcloud.datastore.DATASET | ||
|
||
try: | ||
gcloud.datastore.DATASET = None | ||
self.assertRaises(EnvironmentError, | ||
gcloud.datastore._require_dataset) | ||
gcloud.datastore.DATASET = object() | ||
self.assertEqual(gcloud.datastore._require_dataset(), None) | ||
finally: | ||
gcloud.datastore.DATASET = original_dataset | ||
|
||
def test_get_entity(self): | ||
import gcloud.datastore | ||
from gcloud.datastore.test_entity import _Dataset | ||
from gcloud._testing import _Monkey | ||
|
||
CUSTOM_DATASET = _Dataset() | ||
DUMMY_KEY = object() | ||
DUMMY_VAL = object() | ||
CUSTOM_DATASET[DUMMY_KEY] = DUMMY_VAL | ||
with _Monkey(gcloud.datastore, DATASET=CUSTOM_DATASET): | ||
result = gcloud.datastore.get_entity(DUMMY_KEY) | ||
self.assertTrue(result is DUMMY_VAL) | ||
|
||
def test_get_entities(self): | ||
import gcloud.datastore | ||
from gcloud.datastore.test_entity import _Dataset | ||
from gcloud._testing import _Monkey | ||
|
||
class _ExtendedDataset(_Dataset): | ||
def get_entities(self, keys): | ||
return [self.get(key) for key in keys] | ||
|
||
CUSTOM_DATASET = _ExtendedDataset() | ||
DUMMY_KEYS = [object(), object()] | ||
DUMMY_VALS = [object(), object()] | ||
for key, val in zip(DUMMY_KEYS, DUMMY_VALS): | ||
CUSTOM_DATASET[key] = val | ||
|
||
with _Monkey(gcloud.datastore, DATASET=CUSTOM_DATASET): | ||
result = gcloud.datastore.get_entities(DUMMY_KEYS) | ||
self.assertTrue(result == DUMMY_VALS) | ||
|
||
def test_allocate_ids(self): | ||
import gcloud.datastore | ||
from gcloud.datastore.test_entity import _Connection | ||
from gcloud.datastore.test_entity import _DATASET_ID | ||
from gcloud.datastore.test_entity import _Dataset | ||
from gcloud.datastore.test_entity import _Key | ||
from gcloud._testing import _Monkey | ||
|
||
class _PathElementProto(object): | ||
COUNTER = 0 | ||
|
||
def __init__(self): | ||
_PathElementProto.COUNTER += 1 | ||
self.id = _PathElementProto.COUNTER | ||
|
||
class _KeyProto(object): | ||
|
||
def __init__(self): | ||
self.path_element = [_PathElementProto()] | ||
|
||
class _ExtendedKey(_Key): | ||
def id(self, id_to_set): | ||
self._called_id = id_to_set | ||
return id_to_set | ||
|
||
INCOMPLETE_KEY = _ExtendedKey() | ||
INCOMPLETE_KEY._key = _KeyProto() | ||
INCOMPLETE_KEY._partial = True | ||
NUM_IDS = 2 | ||
|
||
class _ExtendedConnection(_Connection): | ||
def allocate_ids(self, dataset_id, key_pbs): | ||
self._called_dataset_id = dataset_id | ||
self._called_key_pbs = key_pbs | ||
return key_pbs | ||
|
||
CUSTOM_CONNECTION = _ExtendedConnection() | ||
CUSTOM_DATASET = _Dataset(connection=CUSTOM_CONNECTION) | ||
with _Monkey(gcloud.datastore, DATASET=CUSTOM_DATASET): | ||
result = gcloud.datastore.allocate_ids(INCOMPLETE_KEY, NUM_IDS) | ||
|
||
self.assertEqual(_PathElementProto.COUNTER, 1) | ||
self.assertEqual(result, [1, 1]) | ||
self.assertEqual(CUSTOM_CONNECTION._called_dataset_id, _DATASET_ID) | ||
self.assertEqual(len(CUSTOM_CONNECTION._called_key_pbs), 2) | ||
key_paths = [key_pb.path_element[-1].id | ||
for key_pb in CUSTOM_CONNECTION._called_key_pbs] | ||
self.assertEqual(key_paths, [1, 1]) | ||
|
||
def test_allocate_ids_with_complete(self): | ||
import gcloud.datastore | ||
from gcloud.datastore.test_entity import _Connection | ||
from gcloud.datastore.test_entity import _Dataset | ||
from gcloud.datastore.test_entity import _Key | ||
from gcloud._testing import _Monkey | ||
|
||
COMPLETE_KEY = _Key() | ||
NUM_IDS = 2 | ||
CUSTOM_CONNECTION = _Connection() | ||
CUSTOM_DATASET = _Dataset(connection=CUSTOM_CONNECTION) | ||
with _Monkey(gcloud.datastore, DATASET=CUSTOM_DATASET): | ||
self.assertRaises(ValueError, gcloud.datastore.allocate_ids, | ||
COMPLETE_KEY, NUM_IDS) | ||
|
||
def test_set_DATASET(self): | ||
import os | ||
import tempfile | ||
from gcloud import credentials | ||
from gcloud.test_credentials import _Client | ||
from gcloud._testing import _Monkey | ||
|
||
# Make custom client for doing auth. | ||
client = _Client() | ||
|
||
# Fake auth variables. | ||
CLIENT_EMAIL = '[email protected]' | ||
PRIVATE_KEY = 'SEEkR1t' | ||
DATASET = 'dataset' | ||
|
||
# Write the fake key to a temp file. | ||
TEMP_PATH = tempfile.mktemp() | ||
with open(TEMP_PATH, 'w') as file_obj: | ||
file_obj.write(PRIVATE_KEY) | ||
file_obj.flush() | ||
|
||
# Make a custom getenv function to Monkey. | ||
VALUES = { | ||
'GCLOUD_DATASET_ID': DATASET, | ||
'GCLOUD_CLIENT_EMAIL': CLIENT_EMAIL, | ||
'GCLOUD_KEY_FILE': TEMP_PATH, | ||
} | ||
|
||
def custom_getenv(key): | ||
return VALUES.get(key) | ||
|
||
# Perform the import again with our test patches. | ||
with _Monkey(credentials, client=client): | ||
with _Monkey(os, getenv=custom_getenv): | ||
import gcloud.datastore | ||
reload(gcloud.datastore) | ||
|
||
# Check that the DATASET was correctly implied from the environ. | ||
implicit_dataset = gcloud.datastore.DATASET | ||
self.assertEqual(implicit_dataset.id(), DATASET) | ||
# Check that the credentials on the implicit DATASET was set on the | ||
# fake client. | ||
credentials = implicit_dataset.connection().credentials | ||
self.assertTrue(credentials is client._signed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.