monasca-agent/tests/test_keystone.py
Tomasz Trębski b71fd4bef4 Integrate with keystoneauth
Following commit makes enhancements to the
keystone handling inside monasca-agent:

* using generic password approach that abstracts from underlying
keystone version thus allows agent to be used seamlessly with
either v2.0 or v3. The only relevant part is the set of parameters
that one needs to supply to either monasca-reconfigure or agent.yaml
configuration file
* using keystone discovery - it simply means that agent will no longer
enforce particular keystone version but will allow keystoneauth
to pick the best match for given environment

Extra:
* extracted methods get_session and get_client utilize an aproach
presented above and can be used outside of monasca_agent.common.keystone
inside checks or detection plugins
* make imports to import only modules instead specific objects
* removed some redundant methods

Story: 2000995
Task: 4191

Needed-By: I579f6bcd5975a32af2a255be41c9b6c4043fa1dc
Needed-By: Ifee5b88ccb632222310aafb1081ecb9c9d085150
Change-Id: Iec97e50089ed31ae7ad8244b37cec128817871a5
2017-07-11 09:02:34 +02:00

184 lines
6.7 KiB
Python

# Copyright 2017 FUJITSU LIMITED
#
# 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 mock
import random
from oslotest import base
from monasca_agent.common import keystone
from tests.common import base_config
class TestUtils(base.BaseTestCase):
def test_should_sanitize_config(self):
config_keys = [
'keystone_url', 'username', 'password', 'project_name',
'service_type', 'url', 'endpoint_type', 'region_name'
]
config = {c: mock.NonCallableMock() for c in config_keys}
random_key_for_no_value = random.choice(config_keys)
config[random_key_for_no_value] = None
clean = keystone.get_args(config)
self.assertNotIn(random_key_for_no_value, clean)
@mock.patch('monasca_agent.common.keystone.discover.Discover')
@mock.patch('monasca_agent.common.keystone.get_session')
def test_get_client_should_use_existing_session_if_present(self,
get_session,
_):
sess = mock.Mock()
sess.auth = mock.PropertyMock()
sess.auth.get_auth_ref = mock.Mock()
config = {
'session': sess
}
keystone.get_client(**config)
get_session.assert_not_called()
@mock.patch('monasca_agent.common.keystone.discover.Discover')
@mock.patch('monasca_agent.common.keystone.get_session')
def test_get_client_should_create_session_if_missing(self,
get_session,
_):
sess = mock.Mock()
sess.auth = mock.PropertyMock()
sess.auth.get_auth_ref = mock.Mock()
config = {
'username': __name__,
'password': str(random.randint(10, 20))
}
keystone.get_client(**config)
get_session.assert_called_once_with(**config)
class TestKeystone(base.BaseTestCase):
default_endpoint_type = mock.NonCallableMock()
default_service_type = mock.NonCallableMock()
default_region_name = mock.NonCallableMock()
def test_keystone_should_be_singleton(self):
keystone_1 = keystone.Keystone({})
keystone_2 = keystone.Keystone({})
keystone_3 = keystone.Keystone({})
self.assertTrue(keystone_1 is keystone_2)
self.assertTrue(keystone_1 is keystone_3)
def test_should_call_service_catalog_for_endpoint(self):
keystone.Keystone.instance = None
with mock.patch('keystoneauth1.identity.Password') as password, \
mock.patch('keystoneauth1.session.Session') as session, \
mock.patch('keystoneclient.discover.Discover') as discover:
client = mock.Mock()
discover.return_value = d = mock.Mock()
d.create_client = mock.Mock(return_value=client)
config = base_config.get_config('Api')
config.update({
'url': None,
'service_type': self.default_service_type,
'endpoint_type': self.default_endpoint_type,
'region_name': self.default_region_name
})
k = keystone.Keystone(config)
k.get_monasca_url()
password.assert_called_once()
session.assert_called_once()
discover.assert_called_once()
client.auth_ref.service_catalog.url_for.assert_called_once_with(**{
'service_type': self.default_service_type,
'interface': self.default_endpoint_type,
'region_name': self.default_region_name
})
def test_should_use_url_from_config_catalog_config_present(self):
keystone.Keystone.instance = None
with mock.patch('keystoneauth1.identity.Password') as password, \
mock.patch('keystoneauth1.session.Session') as session, \
mock.patch('keystoneclient.discover.Discover') as discover:
client = mock.Mock()
discover.return_value = d = mock.Mock()
d.create_client = mock.Mock(return_value=client)
monasca_url = mock.NonCallableMock()
config = base_config.get_config('Api')
config.update({
'url': monasca_url,
'service_type': self.default_service_type,
'endpoint_type': self.default_endpoint_type,
'region_name': self.default_region_name
})
k = keystone.Keystone(config)
k.get_monasca_url()
password.assert_not_called()
session.assert_not_called()
discover.assert_not_called()
client.auth_ref.service_catalog.url_for.assert_not_called()
def test_should_use_url_from_config_if_catalog_config_missing(self):
keystone.Keystone.instance = None
with mock.patch('keystoneauth1.identity.Password') as password, \
mock.patch('keystoneauth1.session.Session') as session, \
mock.patch('keystoneclient.discover.Discover') as discover:
client = mock.Mock()
discover.return_value = d = mock.Mock()
d.create_client = mock.Mock(return_value=client)
monasca_url = mock.NonCallableMock()
config = base_config.get_config('Api')
config.update({
'url': monasca_url,
'service_type': None,
'endpoint_type': None,
'region_name': None
})
k = keystone.Keystone(config)
k.get_monasca_url()
password.assert_not_called()
session.assert_not_called()
discover.assert_not_called()
client.auth_ref.service_catalog.url_for.assert_not_called()
def test_should_init_client_just_once(self):
keystone.Keystone.instance = None
k = keystone.Keystone(config=base_config.get_config('Api'))
client = mock.Mock()
with mock.patch('monasca_agent.common.keystone.get_client') as gc:
gc.return_value = client
for _ in range(random.randint(5, 50)):
k._init_client()
self.assertIsNotNone(k._keystone_client)
self.assertEqual(client, k._keystone_client)
gc.assert_called_once()