diff --git a/tests/keystone_client_fixtures.py b/tests/keystone_client_fixtures.py deleted file mode 100644 index b28b5e21..00000000 --- a/tests/keystone_client_fixtures.py +++ /dev/null @@ -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 diff --git a/tests/test_shell.py b/tests/test_shell.py index e961fe23..a96911d7 100644 --- a/tests/test_shell.py +++ b/tests/test_shell.py @@ -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())