From 8e4adb110eb9c2d54a0f26c95f982aff35a7653e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Tr=C4=99bski?= Date: Wed, 2 Aug 2017 14:47:27 +0200 Subject: [PATCH] Allow to reuse the session Add possibility to reuse the session, passed as kwarg, passed from a component that initializes the client. Change-Id: I35bb752680f499dac163305cd81daa2c7b7a817b --- monascaclient/client.py | 52 +++++++++++++++++++++++------- monascaclient/tests/test_client.py | 34 +++++++++++++++++++ 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/monascaclient/client.py b/monascaclient/client.py index 1c0dfa6..ee9bf6b 100644 --- a/monascaclient/client.py +++ b/monascaclient/client.py @@ -14,15 +14,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging import warnings from keystoneauth1 import identity -from keystoneauth1 import session +from keystoneauth1 import session as k_session +from osc_lib import session as o_session from monascaclient.osc import migration from monascaclient import version +LOG = logging.getLogger(__name__) _NO_VALUE_MARKER = object() @@ -30,12 +33,9 @@ def Client(api_version, *args, **kwargs): handle_deprecated(args, kwargs) - auth = _get_auth_handler(kwargs) - sess = _get_session(auth, kwargs) - client = migration.make_client( api_version=api_version, - session=sess, + session=_session(kwargs), endpoint=kwargs.get('endpoint'), service_type=kwargs.get('service_type', 'monitoring') ) @@ -43,8 +43,36 @@ def Client(api_version, *args, **kwargs): return client +def _session(kwargs): + """Returns or reuses session. + + Method takes care of providing instance of + session object for the client. + + :param kwargs: all params (without api_version) client was initialized with + :type kwargs: dict + + :returns: session object + :rtype union(keystoneauth1.session.Session, osc_lib.session.TimingSession) + + """ + if 'session' in kwargs: + LOG.debug('Reusing session') + sess = kwargs.get('session') + expected_cls = (k_session.Session, o_session.TimingSession) + if not isinstance(sess, expected_cls): + msg = ('session should be an instance of [%s, %s]' % expected_cls) + LOG.error(msg) + raise RuntimeError(msg) + else: + LOG.debug('Initializing new session') + auth = _get_auth_handler(kwargs) + sess = _get_session(auth, kwargs) + return sess + + def handle_deprecated(args, kwargs): - """Handles all deprecations + """Handles all deprecations. Method goes through passed args and kwargs and handles all values that are invalid from POV @@ -100,12 +128,12 @@ def _handle_deprecated_args(args): def _get_session(auth, kwargs): - return session.Session(auth=auth, - app_name='monascaclient', - app_version=version.version_string, - cert=kwargs.get('cert', None), - timeout=kwargs.get('timeout', None), - verify=kwargs.get('verify', True)) + return k_session.Session(auth=auth, + app_name='monascaclient', + app_version=version.version_string, + cert=kwargs.get('cert', None), + timeout=kwargs.get('timeout', None), + verify=kwargs.get('verify', True)) def _get_auth_handler(kwargs): diff --git a/monascaclient/tests/test_client.py b/monascaclient/tests/test_client.py index 7c63521..ebc1021 100644 --- a/monascaclient/tests/test_client.py +++ b/monascaclient/tests/test_client.py @@ -136,3 +136,37 @@ class TestMonascaClient(base.BaseTestCase): 'verify': not insecure }) get_auth.reset_mock() + + @mock.patch('monascaclient.client.migration') + @mock.patch('monascaclient.client._get_auth_handler') + @mock.patch('monascaclient.client._get_session') + def test_should_reuse_the_session_if_initialized_with_one(self, + get_session, + get_auth, + _): + from keystoneauth1 import session as k_session + + api_version = mock.Mock() + session = mock.Mock(spec=k_session.Session) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + client.Client(api_version, session=session) + self.assertEqual(0, len(w)) + + get_auth.assert_not_called() + get_session.assert_not_called() + + @mock.patch('monascaclient.client.migration') + @mock.patch('monascaclient.client._get_auth_handler') + @mock.patch('monascaclient.client._get_session') + def test_should_error_if_session_is_not_in_correct_type(self, + _, + __, + ___): + + api_version = mock.Mock() + for cls in [str, int, float]: + session = mock.Mock(spec=cls) + self.assertRaises(RuntimeError, client.Client, + api_version, session=session)