Last active
August 29, 2015 14:05
-
-
Save BenjamenMeyer/1a0712c10fc6beb01a84 to your computer and use it in GitHub Desktop.
Keystone Mocking issue...
This file contains hidden or 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
import base64 | |
import binascii | |
import simplejson as json | |
import redis | |
from keystoneclient.v2_0 import client as keystonev2_client | |
import keystone.exceptions | |
import keystoneclient.access as keystone_access | |
LOG = logging.getLogger(__name__) | |
def _send_data_to_cache(redis_client, url, access_info): | |
"""Stores the authentication data to memcache | |
:param redis_client: redis.Redis object connected to the redis cache | |
:param url: URL used for authentication | |
:param access_info: keystoneclient.access.AccessInfo containing | |
the auth data | |
:returns: True on success, otherwise False | |
""" | |
try: | |
# Convert the access_info dictionary into a string for storage | |
data = {} | |
data.update(access_info) | |
cache_data = json.dumps(data) | |
cache_data_utf8 = cache_data.encode(encoding='utf-8', errors='strict') | |
cache_data_b64 = base64.b64encode(cache_data_utf8) | |
tenant = access_info.tenant_id | |
token = access_info.auth_token | |
# Guild the cache key and store the value | |
# Use the token's expiration time for the cache expiration | |
cache_key = _tuple_to_cache_key((tenant, token, url)) | |
redis_client.set(cache_key, cache_data) | |
redis_client.pexpire(cache_key, access_info.expires) | |
return True | |
except Exception as ex: | |
msg = _('Failed to cache the data - Exception: %(s_except)s') % { | |
's_except': ex, | |
} | |
LOG.error(msg) | |
return False | |
def _retrieve_data_from_keystone(redis_client, url, tenant, token): | |
"""Retrieve the authentication data from OpenStack Keystone | |
:param redis_client: redis.Redis object connected to the redis cache | |
:param url: Keystone Identity URL to authenticate against | |
:param tenant: tenant id of user data to retrieve | |
:param token: auth_token for the tenant_id | |
:returns: a keystoneclient.access.AccessInfo on success or None on error | |
""" | |
try: | |
keystone = keystonev2_client.Client(tenant_id=tenant, token=token, auth_url=url) | |
except Exception as ex: | |
msg = _('Failed to retrieve Keystone client - %(s_except)s') % { | |
's_except': ex | |
} | |
LOG.debug(msg) | |
return None | |
# Now try to authenticate the user and get the user information using | |
# only the data provided, no special administrative tokens required | |
try: | |
access_info = keystone.get_raw_token_from_identity_service( | |
auth_url=url, tenant_id=tenant, token=token) | |
# cache the data so it is easier to access next time | |
_send_data_to_cache(redis_client, url, access_info) | |
return access_info | |
except keystoneclient.exceptions.AuthorizationFailure as ex: | |
# Provided data was invalid | |
msg = _('Failed to authenticate against %(s_url) - %(s_except)s') % { | |
's_url' : auth_url, | |
's_except' : ex | |
} | |
LOG.debug( msg ) | |
return None |
This file contains hidden or 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
from __future__ import division | |
from wsgiref import simple_server | |
import fakeredis | |
import mock | |
import base64 | |
import binascii | |
import simplejson as json | |
import keystoneclient.exceptions | |
from keystoneclient.access import AccessInfoV2 | |
from eom import auth | |
import tests | |
from . import util | |
from .mocks import servicecatalog | |
def fakeredis_connection(): | |
return fakeredis.FakeRedis() | |
def run_server(app, host, port): | |
httpd = simple_server.make_server(host, port, app) | |
httpd.serve_forever() | |
class TestAuth(tests.util.TestCase): | |
def setUp(self): | |
super(TestAuth, self).setUp() | |
redis_client = fakeredis_connection() | |
self.auth = auth.wrap(tests.util.app, redis_client) | |
self.test_url = '/v2/vault' | |
#config = auth.CONF['eom:auth'] | |
#self.runtime_url = config['auth_url'] | |
#config['auth_url'] = 'localhost/v2' | |
def tearDown(self): | |
super(TestAuth, self).tearDown() | |
redis_client = fakeredis_connection() | |
redis_client.flushall() | |
#config = auth.CONF['eom:auth'] | |
#config['auth_url'] = self.runtime_url | |
def test_retrieve_keystone_stone(self): | |
url = 'myurl' | |
tenant_id = '789012345' | |
token = 'abcdefABCDEF' | |
redis_client = fakeredis_connection() | |
with mock.patch( | |
'keystoneclient.v2_0.client.Client', autospec=True) as MockKeystoneClient: | |
MockKeystoneClient.side_effect = Exception('Mock - invalid client object') | |
keystone_create_error = auth._retrieve_data_from_keystone(redis_client, url, tenant_id, token) | |
self.assertIsNone(keystone_create_error) | |
with mock.patch( | |
'keystoneclient.v2_0.client.Client', autospec=True) as MockKeystoneClient: | |
reload(keystoneclient) | |
# Fail to get a valid Client object | |
# Note: Client() uses the requests package to do an auth; | |
# on failure it is the requests module that fails. | |
MockKeystoneClient.get_raw_token_from_identity_service = mock.Mock(side_effect = \ | |
keystoneclient.exceptions.AuthorizationFailure('mock Keystone error')) | |
keystone_error = auth._retrieve_data_from_keystone(redis_client, url, tenant_id, token) | |
self.assertIsNone(keystone_error) | |
# Note: This fails because the side effect on get_raw_token_from_identity_service is not happening. Why??? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's the run:
(py27)bmeyer@ben-linux-ubuntu:~/rackspace/envs/eom$ nosetests tests.test_auth
tests.test_auth.TestAuth.test_cache_key ... ok
tests.test_auth.TestAuth.test_retrieve_cache_data ... ok
tests.test_auth.TestAuth.test_retrieve_keystone_stone ... FAIL
tests.test_auth.TestAuth.test_store_data_to_cache ... ok
FAIL: tests.test_auth.TestAuth.test_retrieve_keystone_stone
_StringException: Traceback (most recent call last):
File "/home/bmeyer/rackspace/envs/eom/tests/test_auth.py", line 231, in test_retrieve_keystone_stone
self.assertIsNone(keystone_error)
File "/home/bmeyer/rackspace/envs/eom/.tox/py27/local/lib/python2.7/site-packages/testtools/testcase.py", line 353, in assertIsNone
self.assertThat(observed, matcher, message)
File "/home/bmeyer/rackspace/envs/eom/.tox/py27/local/lib/python2.7/site-packages/testtools/testcase.py", line 423, in assertThat
raise mismatch_error
MismatchError: is not:
reference = None
actual =
-------------------- >> begin captured logging << --------------------
eom.auth: DEBUG: Failed to retrieve Keystone client - Mock - invalid client object
eom.auth: ERROR: Failed to cache the data - Exception: sequence item 0: expected string, MagicMock found
--------------------- >> end captured logging << ---------------------
Note: the eom.auth.ERROR is generated by line 43 in implementation.py because the parameter access_info in line 77 is a mock object due to the exception not happening