
All service clients' name should not contain "JSON" because of Ic6d4c340e145a18cd45bc6fe750e9fdc8c5d2a8d of Tempest commit. This patch makes TokenClientJSON deprecated and recommends to use TokenClient instead. Partially implements blueprint consistent-service-method-names Change-Id: Icbf3bffddd22cb09628572c7a6d01735a123a0b0
409 lines
15 KiB
Python
409 lines
15 KiB
Python
# Copyright 2014 IBM Corp.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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 datetime
|
|
|
|
from oslotest import mockpatch
|
|
|
|
from tempest_lib import auth
|
|
from tempest_lib import exceptions
|
|
from tempest_lib.services.identity.v2 import token_client as v2_client
|
|
from tempest_lib.services.identity.v3 import token_client as v3_client
|
|
from tempest_lib.tests import base
|
|
from tempest_lib.tests import fake_credentials
|
|
from tempest_lib.tests import fake_http
|
|
from tempest_lib.tests import fake_identity
|
|
|
|
|
|
def fake_get_credentials(fill_in=True, identity_version='v2', **kwargs):
|
|
return fake_credentials.FakeCredentials()
|
|
|
|
|
|
class BaseAuthTestsSetUp(base.TestCase):
|
|
_auth_provider_class = None
|
|
credentials = fake_credentials.FakeCredentials()
|
|
|
|
def _auth(self, credentials, auth_url, **params):
|
|
"""returns auth method according to keystone"""
|
|
return self._auth_provider_class(credentials, auth_url, **params)
|
|
|
|
def setUp(self):
|
|
super(BaseAuthTestsSetUp, self).setUp()
|
|
self.fake_http = fake_http.fake_httplib2(return_type=200)
|
|
self.stubs.Set(auth, 'get_credentials', fake_get_credentials)
|
|
self.auth_provider = self._auth(self.credentials,
|
|
fake_identity.FAKE_AUTH_URL)
|
|
|
|
|
|
class TestBaseAuthProvider(BaseAuthTestsSetUp):
|
|
"""Tests for base AuthProvider
|
|
|
|
This tests auth.AuthProvider class which is base for the other so we
|
|
obviously don't test not implemented method or the ones which strongly
|
|
depends on them.
|
|
"""
|
|
|
|
class FakeAuthProviderImpl(auth.AuthProvider):
|
|
def _decorate_request(self):
|
|
pass
|
|
|
|
def _fill_credentials(self):
|
|
pass
|
|
|
|
def _get_auth(self):
|
|
pass
|
|
|
|
def base_url(self):
|
|
pass
|
|
|
|
def is_expired(self):
|
|
pass
|
|
|
|
_auth_provider_class = FakeAuthProviderImpl
|
|
|
|
def _auth(self, credentials, auth_url, **params):
|
|
"""returns auth method according to keystone"""
|
|
return self._auth_provider_class(credentials, **params)
|
|
|
|
def test_check_credentials_bad_type(self):
|
|
self.assertFalse(self.auth_provider.check_credentials([]))
|
|
|
|
def test_auth_data_property_when_cache_exists(self):
|
|
self.auth_provider.cache = 'foo'
|
|
self.useFixture(mockpatch.PatchObject(self.auth_provider,
|
|
'is_expired',
|
|
return_value=False))
|
|
self.assertEqual('foo', getattr(self.auth_provider, 'auth_data'))
|
|
|
|
def test_delete_auth_data_property_through_deleter(self):
|
|
self.auth_provider.cache = 'foo'
|
|
del self.auth_provider.auth_data
|
|
self.assertIsNone(self.auth_provider.cache)
|
|
|
|
def test_delete_auth_data_property_through_clear_auth(self):
|
|
self.auth_provider.cache = 'foo'
|
|
self.auth_provider.clear_auth()
|
|
self.assertIsNone(self.auth_provider.cache)
|
|
|
|
def test_set_and_reset_alt_auth_data(self):
|
|
self.auth_provider.set_alt_auth_data('foo', 'bar')
|
|
self.assertEqual(self.auth_provider.alt_part, 'foo')
|
|
self.assertEqual(self.auth_provider.alt_auth_data, 'bar')
|
|
|
|
self.auth_provider.reset_alt_auth_data()
|
|
self.assertIsNone(self.auth_provider.alt_part)
|
|
self.assertIsNone(self.auth_provider.alt_auth_data)
|
|
|
|
def test_auth_class(self):
|
|
self.assertRaises(TypeError,
|
|
auth.AuthProvider,
|
|
fake_credentials.FakeCredentials)
|
|
|
|
|
|
class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp):
|
|
_endpoints = fake_identity.IDENTITY_V2_RESPONSE['access']['serviceCatalog']
|
|
_auth_provider_class = auth.KeystoneV2AuthProvider
|
|
credentials = fake_credentials.FakeKeystoneV2Credentials()
|
|
|
|
def setUp(self):
|
|
super(TestKeystoneV2AuthProvider, self).setUp()
|
|
self.stubs.Set(v2_client.TokenClient, 'raw_request',
|
|
fake_identity._fake_v2_response)
|
|
self.target_url = 'test_api'
|
|
|
|
def _get_fake_alt_identity(self):
|
|
return fake_identity.ALT_IDENTITY_V2_RESPONSE['access']
|
|
|
|
def _get_result_url_from_endpoint(self, ep, endpoint_type='publicURL',
|
|
replacement=None):
|
|
if replacement:
|
|
return ep[endpoint_type].replace('v2', replacement)
|
|
return ep[endpoint_type]
|
|
|
|
def _get_token_from_fake_identity(self):
|
|
return fake_identity.TOKEN
|
|
|
|
def _get_from_fake_identity(self, attr):
|
|
access = fake_identity.IDENTITY_V2_RESPONSE['access']
|
|
if attr == 'user_id':
|
|
return access['user']['id']
|
|
elif attr == 'tenant_id':
|
|
return access['token']['tenant']['id']
|
|
|
|
def _test_request_helper(self, filters, expected):
|
|
url, headers, body = self.auth_provider.auth_request('GET',
|
|
self.target_url,
|
|
filters=filters)
|
|
|
|
self.assertEqual(expected['url'], url)
|
|
self.assertEqual(expected['token'], headers['X-Auth-Token'])
|
|
self.assertEqual(expected['body'], body)
|
|
|
|
def _auth_data_with_expiry(self, date_as_string):
|
|
token, access = self.auth_provider.auth_data
|
|
access['token']['expires'] = date_as_string
|
|
return token, access
|
|
|
|
def test_request(self):
|
|
filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion'
|
|
}
|
|
|
|
url = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][1]) + '/' + self.target_url
|
|
|
|
expected = {
|
|
'body': None,
|
|
'url': url,
|
|
'token': self._get_token_from_fake_identity(),
|
|
}
|
|
self._test_request_helper(filters, expected)
|
|
|
|
def test_request_with_alt_auth_cleans_alt(self):
|
|
self.auth_provider.set_alt_auth_data(
|
|
'body',
|
|
(fake_identity.ALT_TOKEN, self._get_fake_alt_identity()))
|
|
self.test_request()
|
|
# Assert alt auth data is clear after it
|
|
self.assertIsNone(self.auth_provider.alt_part)
|
|
self.assertIsNone(self.auth_provider.alt_auth_data)
|
|
|
|
def test_request_with_alt_part_without_alt_data(self):
|
|
"""Test empty alternate auth data
|
|
|
|
Assert that when alt_part is defined, the corresponding original
|
|
request element is kept the same.
|
|
"""
|
|
filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'fakeRegion'
|
|
}
|
|
self.auth_provider.set_alt_auth_data('url', None)
|
|
|
|
url, headers, body = self.auth_provider.auth_request('GET',
|
|
self.target_url,
|
|
filters=filters)
|
|
|
|
self.assertEqual(url, self.target_url)
|
|
self.assertEqual(self._get_token_from_fake_identity(),
|
|
headers['X-Auth-Token'])
|
|
self.assertEqual(body, None)
|
|
|
|
def test_request_with_bad_service(self):
|
|
filters = {
|
|
'service': 'BAD_SERVICE',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'fakeRegion'
|
|
}
|
|
self.assertRaises(exceptions.EndpointNotFound,
|
|
self.auth_provider.auth_request, 'GET',
|
|
self.target_url, filters=filters)
|
|
|
|
def test_request_without_service(self):
|
|
filters = {
|
|
'service': None,
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'fakeRegion'
|
|
}
|
|
self.assertRaises(exceptions.EndpointNotFound,
|
|
self.auth_provider.auth_request, 'GET',
|
|
self.target_url, filters=filters)
|
|
|
|
def test_check_credentials_missing_attribute(self):
|
|
for attr in ['username', 'password']:
|
|
cred = copy.copy(self.credentials)
|
|
del cred[attr]
|
|
self.assertFalse(self.auth_provider.check_credentials(cred))
|
|
|
|
def test_fill_credentials(self):
|
|
self.auth_provider.fill_credentials()
|
|
creds = self.auth_provider.credentials
|
|
for attr in ['user_id', 'tenant_id']:
|
|
self.assertEqual(self._get_from_fake_identity(attr),
|
|
getattr(creds, attr))
|
|
|
|
def _test_base_url_helper(self, expected_url, filters,
|
|
auth_data=None):
|
|
|
|
url = self.auth_provider.base_url(filters, auth_data)
|
|
self.assertEqual(url, expected_url)
|
|
|
|
def test_base_url(self):
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion'
|
|
}
|
|
expected = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][1])
|
|
self._test_base_url_helper(expected, self.filters)
|
|
|
|
def test_base_url_to_get_admin_endpoint(self):
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'adminURL',
|
|
'region': 'FakeRegion'
|
|
}
|
|
expected = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][1], endpoint_type='adminURL')
|
|
self._test_base_url_helper(expected, self.filters)
|
|
|
|
def test_base_url_unknown_region(self):
|
|
"""If the region is unknown, the first endpoint is returned."""
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'AintNoBodyKnowThisRegion'
|
|
}
|
|
expected = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][0])
|
|
self._test_base_url_helper(expected, self.filters)
|
|
|
|
def test_base_url_with_non_existent_service(self):
|
|
self.filters = {
|
|
'service': 'BAD_SERVICE',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion'
|
|
}
|
|
self.assertRaises(exceptions.EndpointNotFound,
|
|
self._test_base_url_helper, None, self.filters)
|
|
|
|
def test_base_url_without_service(self):
|
|
self.filters = {
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion'
|
|
}
|
|
self.assertRaises(exceptions.EndpointNotFound,
|
|
self._test_base_url_helper, None, self.filters)
|
|
|
|
def test_base_url_with_api_version_filter(self):
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion',
|
|
'api_version': 'v12'
|
|
}
|
|
expected = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][1], replacement='v12')
|
|
self._test_base_url_helper(expected, self.filters)
|
|
|
|
def test_base_url_with_skip_path_filter(self):
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'publicURL',
|
|
'region': 'FakeRegion',
|
|
'skip_path': True
|
|
}
|
|
expected = 'http://fake_url/'
|
|
self._test_base_url_helper(expected, self.filters)
|
|
|
|
def test_token_not_expired(self):
|
|
expiry_data = datetime.datetime.utcnow() + datetime.timedelta(days=1)
|
|
self._verify_expiry(expiry_data=expiry_data, should_be_expired=False)
|
|
|
|
def test_token_expired(self):
|
|
expiry_data = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
|
self._verify_expiry(expiry_data=expiry_data, should_be_expired=True)
|
|
|
|
def test_token_not_expired_to_be_renewed(self):
|
|
expiry_data = (datetime.datetime.utcnow() +
|
|
self.auth_provider.token_expiry_threshold / 2)
|
|
self._verify_expiry(expiry_data=expiry_data, should_be_expired=True)
|
|
|
|
def _verify_expiry(self, expiry_data, should_be_expired):
|
|
for expiry_format in self.auth_provider.EXPIRY_DATE_FORMATS:
|
|
auth_data = self._auth_data_with_expiry(
|
|
expiry_data.strftime(expiry_format))
|
|
self.assertEqual(self.auth_provider.is_expired(auth_data),
|
|
should_be_expired)
|
|
|
|
|
|
class TestKeystoneV3AuthProvider(TestKeystoneV2AuthProvider):
|
|
_endpoints = fake_identity.IDENTITY_V3_RESPONSE['token']['catalog']
|
|
_auth_provider_class = auth.KeystoneV3AuthProvider
|
|
credentials = fake_credentials.FakeKeystoneV3Credentials()
|
|
|
|
def setUp(self):
|
|
super(TestKeystoneV3AuthProvider, self).setUp()
|
|
self.stubs.Set(v3_client.V3TokenClient, 'raw_request',
|
|
fake_identity._fake_v3_response)
|
|
|
|
def _get_fake_alt_identity(self):
|
|
return fake_identity.ALT_IDENTITY_V3['token']
|
|
|
|
def _get_result_url_from_endpoint(self, ep, replacement=None):
|
|
if replacement:
|
|
return ep['url'].replace('v3', replacement)
|
|
return ep['url']
|
|
|
|
def _auth_data_with_expiry(self, date_as_string):
|
|
token, access = self.auth_provider.auth_data
|
|
access['expires_at'] = date_as_string
|
|
return token, access
|
|
|
|
def _get_from_fake_identity(self, attr):
|
|
token = fake_identity.IDENTITY_V3_RESPONSE['token']
|
|
if attr == 'user_id':
|
|
return token['user']['id']
|
|
elif attr == 'project_id':
|
|
return token['project']['id']
|
|
elif attr == 'user_domain_id':
|
|
return token['user']['domain']['id']
|
|
elif attr == 'project_domain_id':
|
|
return token['project']['domain']['id']
|
|
|
|
def test_check_credentials_missing_attribute(self):
|
|
# reset credentials to fresh ones
|
|
self.credentials.reset()
|
|
for attr in ['username', 'password', 'user_domain_name',
|
|
'project_domain_name']:
|
|
cred = copy.copy(self.credentials)
|
|
del cred[attr]
|
|
self.assertFalse(self.auth_provider.check_credentials(cred),
|
|
"Credentials should be invalid without %s" % attr)
|
|
|
|
def test_check_domain_credentials_missing_attribute(self):
|
|
# reset credentials to fresh ones
|
|
self.credentials.reset()
|
|
domain_creds = fake_credentials.FakeKeystoneV3DomainCredentials()
|
|
for attr in ['username', 'password', 'user_domain_name']:
|
|
cred = copy.copy(domain_creds)
|
|
del cred[attr]
|
|
self.assertFalse(self.auth_provider.check_credentials(cred),
|
|
"Credentials should be invalid without %s" % attr)
|
|
|
|
def test_fill_credentials(self):
|
|
self.auth_provider.fill_credentials()
|
|
creds = self.auth_provider.credentials
|
|
for attr in ['user_id', 'project_id', 'user_domain_id',
|
|
'project_domain_id']:
|
|
self.assertEqual(self._get_from_fake_identity(attr),
|
|
getattr(creds, attr))
|
|
|
|
# Overwrites v2 test
|
|
def test_base_url_to_get_admin_endpoint(self):
|
|
self.filters = {
|
|
'service': 'compute',
|
|
'endpoint_type': 'admin',
|
|
'region': 'MiddleEarthRegion'
|
|
}
|
|
expected = self._get_result_url_from_endpoint(
|
|
self._endpoints[0]['endpoints'][2])
|
|
self._test_base_url_helper(expected, self.filters)
|