Remove keystoneclient mocks
The majority of the mocks on keystoneclient are not needed. Instead we use the fixtures that keystoneclient provides to create well formed responses and use requests_mock to stub out those values when accessed. This is a closer to real usage pattern and the way that most client projects are now handling keystoneclient auth. Change-Id: I294aca1d11c9c5cfb4b82ad16476af4000efee1c
This commit is contained in:
parent
02b1a05226
commit
27f70bbd58
@ -1,188 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
import uuid
|
||||
|
||||
|
||||
# these are copied from python-keystoneclient tests
|
||||
BASE_HOST = 'http://keystone.example.com'
|
||||
BASE_URL = "%s:5000/" % BASE_HOST
|
||||
UPDATED = '2013-03-06T00:00:00Z'
|
||||
|
||||
V2_URL = "%sv2.0" % BASE_URL
|
||||
V2_DESCRIBED_BY_HTML = {'href': 'http://docs.openstack.org/api/'
|
||||
'openstack-identity-service/2.0/content/',
|
||||
'rel': 'describedby',
|
||||
'type': 'text/html'}
|
||||
V2_DESCRIBED_BY_PDF = {'href': 'http://docs.openstack.org/api/openstack-ident'
|
||||
'ity-service/2.0/identity-dev-guide-2.0.pdf',
|
||||
'rel': 'describedby',
|
||||
'type': 'application/pdf'}
|
||||
|
||||
V2_VERSION = {'id': 'v2.0',
|
||||
'links': [{'href': V2_URL, 'rel': 'self'},
|
||||
V2_DESCRIBED_BY_HTML, V2_DESCRIBED_BY_PDF],
|
||||
'status': 'stable',
|
||||
'updated': UPDATED}
|
||||
|
||||
V3_URL = "%sv3" % BASE_URL
|
||||
V3_MEDIA_TYPES = [{'base': 'application/json',
|
||||
'type': 'application/vnd.openstack.identity-v3+json'},
|
||||
{'base': 'application/xml',
|
||||
'type': 'application/vnd.openstack.identity-v3+xml'}]
|
||||
|
||||
V3_VERSION = {'id': 'v3.0',
|
||||
'links': [{'href': V3_URL, 'rel': 'self'}],
|
||||
'media-types': V3_MEDIA_TYPES,
|
||||
'status': 'stable',
|
||||
'updated': UPDATED}
|
||||
|
||||
|
||||
def _create_version_list(versions):
|
||||
return json.dumps({'versions': {'values': versions}})
|
||||
|
||||
|
||||
def _create_single_version(version):
|
||||
return json.dumps({'version': version})
|
||||
|
||||
|
||||
V3_VERSION_LIST = _create_version_list([V3_VERSION, V2_VERSION])
|
||||
V2_VERSION_LIST = _create_version_list([V2_VERSION])
|
||||
|
||||
V3_VERSION_ENTRY = _create_single_version(V3_VERSION)
|
||||
V2_VERSION_ENTRY = _create_single_version(V2_VERSION)
|
||||
|
||||
GLANCE_ENDPOINT = 'http://glance.example.com/v1'
|
||||
|
||||
|
||||
def _get_normalized_token_data(**kwargs):
|
||||
ref = copy.deepcopy(kwargs)
|
||||
# normalized token data
|
||||
ref['user_id'] = ref.get('user_id', uuid.uuid4().hex)
|
||||
ref['username'] = ref.get('username', uuid.uuid4().hex)
|
||||
ref['project_id'] = ref.get('project_id',
|
||||
ref.get('tenant_id', uuid.uuid4().hex))
|
||||
ref['project_name'] = ref.get('tenant_name',
|
||||
ref.get('tenant_name', uuid.uuid4().hex))
|
||||
ref['user_domain_id'] = ref.get('user_domain_id', uuid.uuid4().hex)
|
||||
ref['user_domain_name'] = ref.get('user_domain_name', uuid.uuid4().hex)
|
||||
ref['project_domain_id'] = ref.get('project_domain_id', uuid.uuid4().hex)
|
||||
ref['project_domain_name'] = ref.get('project_domain_name',
|
||||
uuid.uuid4().hex)
|
||||
ref['roles'] = ref.get('roles', [{'name': uuid.uuid4().hex,
|
||||
'id': uuid.uuid4().hex}])
|
||||
ref['roles_link'] = ref.get('roles_link', [])
|
||||
ref['glance_url'] = ref.get('glance_url', GLANCE_ENDPOINT)
|
||||
|
||||
return ref
|
||||
|
||||
|
||||
def generate_v2_project_scoped_token(**kwargs):
|
||||
"""Generate a Keystone V2 token based on auth request."""
|
||||
ref = _get_normalized_token_data(**kwargs)
|
||||
|
||||
o = {'access': {'token': {'id': uuid.uuid4().hex,
|
||||
'expires': '2099-05-22T00:02:43.941430Z',
|
||||
'issued_at': '2013-05-21T00:02:43.941473Z',
|
||||
'tenant': {'enabled': True,
|
||||
'id': ref.get('project_id'),
|
||||
'name': ref.get('project_id')
|
||||
}
|
||||
},
|
||||
'user': {'id': ref.get('user_id'),
|
||||
'name': uuid.uuid4().hex,
|
||||
'username': ref.get('username'),
|
||||
'roles': ref.get('roles'),
|
||||
'roles_links': ref.get('roles_links')
|
||||
}
|
||||
}}
|
||||
|
||||
# we only care about Glance and Keystone endpoints
|
||||
o['access']['serviceCatalog'] = [
|
||||
{'endpoints': [
|
||||
{'publicURL': ref.get('glance_url'),
|
||||
'id': uuid.uuid4().hex,
|
||||
'region': 'RegionOne'
|
||||
}],
|
||||
'endpoints_links': [],
|
||||
'name': 'Glance',
|
||||
'type': 'keystore'},
|
||||
{'endpoints': [
|
||||
{'publicURL': ref.get('auth_url'),
|
||||
'adminURL': ref.get('auth_url'),
|
||||
'id': uuid.uuid4().hex,
|
||||
'region': 'RegionOne'
|
||||
}],
|
||||
'endpoint_links': [],
|
||||
'name': 'keystone',
|
||||
'type': 'identity'}]
|
||||
|
||||
return o
|
||||
|
||||
|
||||
def generate_v3_project_scoped_token(**kwargs):
|
||||
"""Generate a Keystone V3 token based on auth request."""
|
||||
ref = _get_normalized_token_data(**kwargs)
|
||||
|
||||
o = {'token': {'expires_at': '2099-05-22T00:02:43.941430Z',
|
||||
'issued_at': '2013-05-21T00:02:43.941473Z',
|
||||
'methods': ['password'],
|
||||
'project': {'id': ref.get('project_id'),
|
||||
'name': ref.get('project_name'),
|
||||
'domain': {'id': ref.get('project_domain_id'),
|
||||
'name': ref.get(
|
||||
'project_domain_name')
|
||||
}
|
||||
},
|
||||
'user': {'id': ref.get('user_id'),
|
||||
'name': ref.get('username'),
|
||||
'domain': {'id': ref.get('user_domain_id'),
|
||||
'name': ref.get('user_domain_name')
|
||||
}
|
||||
},
|
||||
'roles': ref.get('roles')
|
||||
}}
|
||||
|
||||
# we only care about Glance and Keystone endpoints
|
||||
o['token']['catalog'] = [
|
||||
{'endpoints': [
|
||||
{
|
||||
'id': uuid.uuid4().hex,
|
||||
'interface': 'public',
|
||||
'region': 'RegionTwo',
|
||||
'url': ref.get('glance_url')
|
||||
}],
|
||||
'id': uuid.uuid4().hex,
|
||||
'type': 'keystore'},
|
||||
{'endpoints': [
|
||||
{
|
||||
'id': uuid.uuid4().hex,
|
||||
'interface': 'public',
|
||||
'region': 'RegionTwo',
|
||||
'url': ref.get('auth_url')
|
||||
},
|
||||
{
|
||||
'id': uuid.uuid4().hex,
|
||||
'interface': 'admin',
|
||||
'region': 'RegionTwo',
|
||||
'url': ref.get('auth_url')
|
||||
}],
|
||||
'id': uuid.uuid4().hex,
|
||||
'type': 'identity'}]
|
||||
|
||||
# token ID is conveyed via the X-Subject-Token header so we are generating
|
||||
# one to stash there
|
||||
token_id = uuid.uuid4().hex
|
||||
|
||||
return token_id, o
|
@ -19,7 +19,11 @@ import os
|
||||
import sys
|
||||
|
||||
import fixtures
|
||||
from keystoneclient import exceptions as ks_exc
|
||||
from keystoneclient import fixture as ks_fixture
|
||||
import mock
|
||||
import requests
|
||||
from requests_mock.contrib import fixture as rm_fixture
|
||||
import six
|
||||
|
||||
from glanceclient import exc
|
||||
@ -28,12 +32,8 @@ from glanceclient import shell as openstack_shell
|
||||
#NOTE (esheffield) Used for the schema caching tests
|
||||
from glanceclient.v2 import schemas as schemas
|
||||
import json
|
||||
from tests import keystone_client_fixtures
|
||||
from tests import utils
|
||||
|
||||
import keystoneclient
|
||||
from keystoneclient.openstack.common.apiclient import exceptions as ks_exc
|
||||
|
||||
|
||||
DEFAULT_IMAGE_URL = 'http://127.0.0.1:5000/'
|
||||
DEFAULT_USERNAME = 'username'
|
||||
@ -43,8 +43,8 @@ DEFAULT_TENANT_NAME = 'tenant_name'
|
||||
DEFAULT_PROJECT_ID = '0123456789'
|
||||
DEFAULT_USER_DOMAIN_NAME = 'user_domain_name'
|
||||
DEFAULT_UNVERSIONED_AUTH_URL = 'http://127.0.0.1:5000/'
|
||||
DEFAULT_V2_AUTH_URL = 'http://127.0.0.1:5000/v2.0/'
|
||||
DEFAULT_V3_AUTH_URL = 'http://127.0.0.1:5000/v3/'
|
||||
DEFAULT_V2_AUTH_URL = '%sv2.0' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
DEFAULT_V3_AUTH_URL = '%sv3' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
DEFAULT_AUTH_TOKEN = ' 3bcc3d3a03f44e3d8377f9247b0ad155'
|
||||
TEST_SERVICE_URL = 'http://127.0.0.1:5000/'
|
||||
|
||||
@ -66,6 +66,7 @@ class ShellTest(utils.TestCase):
|
||||
# auth environment to use
|
||||
auth_env = FAKE_V2_ENV.copy()
|
||||
# expected auth plugin to invoke
|
||||
token_url = DEFAULT_V2_AUTH_URL + '/tokens'
|
||||
auth_plugin = 'keystoneclient.auth.identity.v2.Password'
|
||||
|
||||
# Patch os.environ to avoid required auth info
|
||||
@ -78,6 +79,17 @@ class ShellTest(utils.TestCase):
|
||||
global _old_env
|
||||
_old_env, os.environ = os.environ, self.auth_env
|
||||
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
|
||||
json_list = ks_fixture.DiscoveryList(DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
self.requests.get(DEFAULT_IMAGE_URL, json=json_list, status_code=300)
|
||||
|
||||
json_v2 = {'version': ks_fixture.V2Discovery(DEFAULT_V2_AUTH_URL)}
|
||||
self.requests.get(DEFAULT_V2_AUTH_URL, json=json_v2)
|
||||
|
||||
json_v3 = {'version': ks_fixture.V3Discovery(DEFAULT_V3_AUTH_URL)}
|
||||
self.requests.get(DEFAULT_V3_AUTH_URL, json=json_v3)
|
||||
|
||||
global shell, _shell, assert_called, assert_called_anytime
|
||||
_shell = openstack_shell.OpenStackImagesShell()
|
||||
shell = lambda cmd: _shell.main(cmd.split())
|
||||
@ -187,20 +199,14 @@ class ShellTest(utils.TestCase):
|
||||
def _assert_auth_plugin_args(self, mock_auth_plugin):
|
||||
# make sure our auth plugin is invoked with the correct args
|
||||
mock_auth_plugin.assert_called_once_with(
|
||||
keystone_client_fixtures.V2_URL,
|
||||
DEFAULT_V2_AUTH_URL,
|
||||
self.auth_env['OS_USERNAME'],
|
||||
self.auth_env['OS_PASSWORD'],
|
||||
tenant_name=self.auth_env['OS_TENANT_NAME'],
|
||||
tenant_id='')
|
||||
|
||||
@mock.patch('glanceclient.v1.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[keystone_client_fixtures.V2_URL, None])
|
||||
def test_auth_plugin_invocation_with_v1(self,
|
||||
v1_client,
|
||||
ks_session,
|
||||
url_for):
|
||||
def test_auth_plugin_invocation_with_v1(self, v1_client):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = 'image-list'
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
@ -208,14 +214,9 @@ class ShellTest(utils.TestCase):
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('glanceclient.v2.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[keystone_client_fixtures.V2_URL, None])
|
||||
def test_auth_plugin_invocation_with_v2(self,
|
||||
v2_client,
|
||||
ks_session,
|
||||
url_for,
|
||||
cache_schemas):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = '--os-image-api-version 2 image-list'
|
||||
@ -224,40 +225,29 @@ class ShellTest(utils.TestCase):
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('glanceclient.v1.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[keystone_client_fixtures.V2_URL,
|
||||
keystone_client_fixtures.V3_URL])
|
||||
def test_auth_plugin_invocation_with_unversioned_auth_url_with_v1(
|
||||
self, v1_client, ks_session, url_for):
|
||||
self, v1_client):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = '--os-auth-url %s image-list' % (
|
||||
keystone_client_fixtures.BASE_URL)
|
||||
args = '--os-auth-url %s image-list' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('glanceclient.v2.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[keystone_client_fixtures.V2_URL,
|
||||
keystone_client_fixtures.V3_URL])
|
||||
def test_auth_plugin_invocation_with_unversioned_auth_url_with_v2(
|
||||
self, v2_client, ks_session, cache_schemas, url_for):
|
||||
self, v2_client, cache_schemas):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = ('--os-auth-url %s --os-image-api-version 2 '
|
||||
'image-list') % (keystone_client_fixtures.BASE_URL)
|
||||
'image-list') % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('sys.stdin', side_effect=mock.MagicMock)
|
||||
@mock.patch('getpass.getpass', return_value='password')
|
||||
@mock.patch('keystoneclient.session.Session.get_token',
|
||||
side_effect=ks_exc.ConnectionRefused)
|
||||
def test_password_prompted_with_v2(self, mock_session, mock_getpass,
|
||||
mock_stdin):
|
||||
def test_password_prompted_with_v2(self, mock_getpass, mock_stdin):
|
||||
self.requests.post(self.token_url, exc=requests.ConnectionError)
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
self.make_env(exclude='OS_PASSWORD')
|
||||
self.assertRaises(ks_exc.ConnectionRefused,
|
||||
@ -352,12 +342,13 @@ class ShellTest(utils.TestCase):
|
||||
class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
# auth environment to use
|
||||
auth_env = FAKE_V3_ENV.copy()
|
||||
token_url = DEFAULT_V3_AUTH_URL + '/auth/tokens'
|
||||
# expected auth plugin to invoke
|
||||
auth_plugin = 'keystoneclient.auth.identity.v3.Password'
|
||||
|
||||
def _assert_auth_plugin_args(self, mock_auth_plugin):
|
||||
mock_auth_plugin.assert_called_once_with(
|
||||
keystone_client_fixtures.V3_URL,
|
||||
DEFAULT_V3_AUTH_URL,
|
||||
user_id='',
|
||||
username=self.auth_env['OS_USERNAME'],
|
||||
password=self.auth_env['OS_PASSWORD'],
|
||||
@ -369,13 +360,7 @@ class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
project_domain_name='')
|
||||
|
||||
@mock.patch('glanceclient.v1.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[None, keystone_client_fixtures.V3_URL])
|
||||
def test_auth_plugin_invocation_with_v1(self,
|
||||
v1_client,
|
||||
ks_session,
|
||||
url_for):
|
||||
def test_auth_plugin_invocation_with_v1(self, v1_client):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = 'image-list'
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
@ -383,29 +368,19 @@ class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('glanceclient.v2.client.Client')
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas')
|
||||
@mock.patch.object(keystoneclient.discover.Discover, 'url_for',
|
||||
side_effect=[None, keystone_client_fixtures.V3_URL])
|
||||
def test_auth_plugin_invocation_with_v2(self,
|
||||
v2_client,
|
||||
ks_session,
|
||||
url_for,
|
||||
cache_schemas):
|
||||
def test_auth_plugin_invocation_with_v2(self, v2_client, cache_schemas):
|
||||
with mock.patch(self.auth_plugin) as mock_auth_plugin:
|
||||
args = '--os-image-api-version 2 image-list'
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
self._assert_auth_plugin_args(mock_auth_plugin)
|
||||
|
||||
@mock.patch('keystoneclient.session.Session')
|
||||
@mock.patch('keystoneclient.discover.Discover',
|
||||
side_effect=ks_exc.ClientException())
|
||||
def test_api_discovery_failed_with_unversioned_auth_url(self,
|
||||
ks_session,
|
||||
discover):
|
||||
args = '--os-auth-url %s image-list' % (
|
||||
keystone_client_fixtures.BASE_URL)
|
||||
args = '--os-auth-url %s image-list' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
self.assertRaises(exc.CommandError, glance_shell.main, args.split())
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user