diff --git a/tobiko/openstack/_client.py b/tobiko/openstack/_client.py index e831d0c88..7cf82c6f8 100644 --- a/tobiko/openstack/_client.py +++ b/tobiko/openstack/_client.py @@ -28,29 +28,26 @@ class OpenstackClientFixture(tobiko.SharedFixture): client = None session = None - session_fixture = None - def __init__(self, session=None): + def __init__(self, session=None, client=None): super(OpenstackClientFixture, self).__init__() if session: - if tobiko.is_fixture(session): - self.session_fixture = session - else: - self.session = session + self.session = session + if client: + self.client = client def setup_fixture(self): - self.setup_session() self.setup_client() - def setup_session(self): - session_fixture = self.session_fixture - if session_fixture: - self.session = tobiko.setup_fixture(session_fixture).session - elif not self.session: - self.session = keystone.get_keystone_session() - def setup_client(self): - self.client = self.init_client(session=self.session) + client = self.client + if not client: + self.session = session = self.get_session() + self.client = client = self.init_client(session=session) + return client + + def get_session(self): + return keystone.keystone_session(self.session) @abc.abstractmethod def init_client(self, session): @@ -59,9 +56,8 @@ class OpenstackClientFixture(tobiko.SharedFixture): class OpenstackClientManager(object): - def __init__(self, init_client=None): - self._clients = {} - self.init_client = init_client + def __init__(self): + self.clients = {} def get_client(self, session=None, shared=True, init_client=None): if shared: @@ -70,17 +66,19 @@ class OpenstackClientManager(object): else: key = session - client = self._clients.get(key) + client = self.clients.get(key) if client: return client - session = session or keystone.get_keystone_session() - init_client = init_client or self.init_client + init_client = init_client or self.create_client assert callable(init_client) LOG.debug('Initialize OpenStack client: %r(session=%r)', init_client, session) client = init_client(session=session) if shared: - self._clients[key] = client + self.clients[key] = client return client + + def create_client(self, session): + raise NotImplementedError diff --git a/tobiko/openstack/heat/__init__.py b/tobiko/openstack/heat/__init__.py index 6aa198357..dfbe88d5b 100644 --- a/tobiko/openstack/heat/__init__.py +++ b/tobiko/openstack/heat/__init__.py @@ -18,7 +18,10 @@ from tobiko.openstack.heat import _template from tobiko.openstack.heat import _stack +heat_client = _client.heat_client +default_heat_client = _client.default_heat_client get_heat_client = _client.get_heat_client +heat_client = _client.heat_client HeatClientFixture = _client.HeatClientFixture heat_template = _template.heat_template diff --git a/tobiko/openstack/heat/_client.py b/tobiko/openstack/heat/_client.py index 5d3814c6e..8fbd4fe42 100644 --- a/tobiko/openstack/heat/_client.py +++ b/tobiko/openstack/heat/_client.py @@ -13,26 +13,51 @@ # under the License. from __future__ import absolute_import -from heatclient import client as heatclient +from heatclient.v1 import client as heatclient +import tobiko from tobiko.openstack import _client class HeatClientFixture(_client.OpenstackClientFixture): def init_client(self, session): - return heatclient.Client( - '1', session=session, endpoint_type='public', - service_type='orchestration') + return heatclient.Client(session=session, + endpoint_type='public', + service_type='orchestration') -CLIENTS = _client.OpenstackClientManager(init_client=HeatClientFixture) +class HeatClientManager(_client.OpenstackClientManager): + + def create_client(self, session): + return HeatClientFixture(session=session) + + +CLIENTS = HeatClientManager() + + +def heat_client(obj=None): + if obj is None: + return default_heat_client() + + if isinstance(obj, heatclient.Client): + return obj + + fixture = tobiko.get_fixture(obj) + if isinstance(fixture, HeatClientFixture): + return tobiko.setup_fixture(fixture).client + + message = "Object {!r} is not a NeutronClientFixture".format(obj) + raise TypeError(message) + + +def default_heat_client(): + return get_heat_client() def get_heat_client(session=None, shared=True, init_client=None, manager=None): manager = manager or CLIENTS - client = manager.get_client(session=session, shared=shared, + fixture = manager.get_client(session=session, shared=shared, init_client=init_client) - client.setUp() - return client.client + return tobiko.setup_fixture(fixture).client diff --git a/tobiko/openstack/keystone/_credentials.py b/tobiko/openstack/keystone/_credentials.py index 42466c68a..44bcc43ea 100644 --- a/tobiko/openstack/keystone/_credentials.py +++ b/tobiko/openstack/keystone/_credentials.py @@ -131,8 +131,8 @@ class KeystoneCredentialsFixture(tobiko.SharedFixture): try: credentials.validate() except InvalidKeystoneCredentials as ex: - LOG.info("No such valid credentials from environment: %r", - ex) + LOG.info("No such valid credentials from %r (%r)", + self, ex) else: self.addCleanup(self.cleanup_credentials) self.credentials = credentials @@ -141,7 +141,7 @@ class KeystoneCredentialsFixture(tobiko.SharedFixture): del self.credentials def get_credentials(self): - return None + return self.credentials class EnvironKeystoneCredentialsFixture(KeystoneCredentialsFixture): diff --git a/tobiko/openstack/neutron/_client.py b/tobiko/openstack/neutron/_client.py index 2a984a16f..316100cc1 100644 --- a/tobiko/openstack/neutron/_client.py +++ b/tobiko/openstack/neutron/_client.py @@ -27,7 +27,13 @@ class NeutronClientFixture(_client.OpenstackClientFixture): return neutronclient.Client(session=session) -CLIENTS = _client.OpenstackClientManager(init_client=NeutronClientFixture) +class NeutronClientManatger(_client.OpenstackClientManager): + + def create_client(self, session): + return NeutronClientFixture(session=session) + + +CLIENTS = NeutronClientManatger() def neutron_client(obj): diff --git a/tobiko/openstack/nova/__init__.py b/tobiko/openstack/nova/__init__.py index 28e08ab30..9bebfcb57 100644 --- a/tobiko/openstack/nova/__init__.py +++ b/tobiko/openstack/nova/__init__.py @@ -15,5 +15,6 @@ from __future__ import absolute_import from tobiko.openstack.nova import _client +nova_client = _client.nova_client get_nova_client = _client.get_nova_client NovaClientFixture = _client.NovaClientFixture diff --git a/tobiko/openstack/nova/_client.py b/tobiko/openstack/nova/_client.py index 291dad78e..8cfddf2fa 100644 --- a/tobiko/openstack/nova/_client.py +++ b/tobiko/openstack/nova/_client.py @@ -15,6 +15,7 @@ from __future__ import absolute_import from novaclient import client as novaclient +import tobiko from tobiko.openstack import _client @@ -24,7 +25,28 @@ class NovaClientFixture(_client.OpenstackClientFixture): return novaclient.Client('2', session=session) -CLIENTS = _client.OpenstackClientManager(init_client=NovaClientFixture) +class NovaClientManager(_client.OpenstackClientManager): + + def create_client(self, session): + return NovaClientFixture(session=session) + + +CLIENTS = NovaClientManager() + + +def nova_client(obj): + if not obj: + return get_nova_client() + + if isinstance(obj, novaclient.Client): + return obj + + fixture = tobiko.setup_fixture(obj) + if isinstance(fixture, NovaClientFixture): + return fixture.client + + message = "Object {!r} is not a NovaClientFixture".format(obj) + raise TypeError(message) def get_nova_client(session=None, shared=True, init_client=None, @@ -32,5 +54,5 @@ def get_nova_client(session=None, shared=True, init_client=None, manager = manager or CLIENTS client = manager.get_client(session=session, shared=shared, init_client=init_client) - client.setUp() + tobiko.setup_fixture(client) return client.client diff --git a/tobiko/tests/unit/openstack/heat/test_client.py b/tobiko/tests/unit/openstack/heat/test_client.py index 79a96b1b4..ff9e81806 100644 --- a/tobiko/tests/unit/openstack/heat/test_client.py +++ b/tobiko/tests/unit/openstack/heat/test_client.py @@ -14,6 +14,7 @@ from __future__ import absolute_import from heatclient.v1 import client as heatclient +import mock from tobiko.openstack import keystone from tobiko.openstack import heat @@ -21,6 +22,9 @@ from tobiko.tests.unit import openstack from tobiko.tests.unit.openstack import test_client +MockClient = mock.create_autospec(heatclient.Client) + + class HeatClientFixtureTest(test_client.OpenstackClientFixtureTest): def create_client(self, session=None): @@ -45,3 +49,22 @@ class GetHeatClientTest(openstack.OpenstackTest): def test_get_heat_client_with_session(self): session = keystone.get_keystone_session() self.test_get_heat_client(session=session) + + +class HeatClientTest(openstack.OpenstackTest): + + def test_heat_client(self, obj=None): + client = heat.heat_client(obj) + self.assertIsInstance(client, heatclient.Client) + if obj is None: + self.assertIs(heat.default_heat_client(), client) + elif isinstance(obj, heatclient.Client): + self.assertIs(obj, client) + elif isinstance(obj, heat.HeatClientFixture): + self.assertIs(obj.client, client) + + def test_heat_client_with_client(self): + self.test_heat_client(obj=MockClient()) + + def test_heat_client_with_fixture(self): + self.test_heat_client(obj=heat.HeatClientFixture()) diff --git a/tobiko/tests/unit/openstack/test_client.py b/tobiko/tests/unit/openstack/test_client.py index b1ba48401..47c8ccc30 100644 --- a/tobiko/tests/unit/openstack/test_client.py +++ b/tobiko/tests/unit/openstack/test_client.py @@ -16,6 +16,7 @@ from __future__ import absolute_import import inspect +from keystoneauth1 import session as _session import mock import tobiko @@ -33,17 +34,7 @@ class ClientFixture(_client.OpenstackClientFixture): return CLIENT -SESSION = object() - -DEFAULT_SESSION = object() - - -class SessionFixture(tobiko.SharedFixture): - - session = None - - def setup_fixture(self): - self.session = SESSION +MockSession = mock.create_autospec(_session.Session) class OpenstackClientFixtureTest(openstack.OpenstackTest): @@ -53,10 +44,10 @@ class OpenstackClientFixtureTest(openstack.OpenstackTest): def test_init(self, session=None): client = self.create_client(session=session) - self.check_client_session(client=client, session=session) + self.assertIs(session or None, client.session) def test_init_with_credentials(self): - self.test_init(session=SESSION) + self.test_init(session=MockSession) def test_init_with_credentials_fixture(self): self.test_init(session=keystone.KeystoneSessionFixture()) @@ -78,25 +69,19 @@ class OpenstackClientFixtureTest(openstack.OpenstackTest): self.assertIs(keystone.get_keystone_session(), client.session) def test_setup_with_session(self): - self.test_setup(session=SESSION) + self.test_setup(session=MockSession()) def test_setup_with_session_fixture(self): - self.test_setup(session=SessionFixture()) + self.test_setup(session=keystone.KeystoneSessionFixture()) def test_setup_with_session_fixture_type(self): - self.test_setup(session=SessionFixture) + self.test_setup(session=keystone.KeystoneSessionFixture) - def check_client_session(self, client, session): - if session: - if tobiko.is_fixture(session): - self.assertIsNone(client.session) - self.assertIs(session, client.session_fixture) - else: - self.assertIs(session, client.session) - self.assertIsNone(client.session_fixture) - else: - self.assertIsNone(client.session) - self.assertIsNone(client.session_fixture) + +class ClientManager(_client.OpenstackClientManager): + + def create_client(self, session): + return ClientFixture(session=session) class OpenstackClientManagerTest(openstack.OpenstackTest): @@ -104,47 +89,38 @@ class OpenstackClientManagerTest(openstack.OpenstackTest): def setUp(self): super(OpenstackClientManagerTest, self).setUp() self.patch(keystone, 'get_keystone_session', - return_value=DEFAULT_SESSION) + return_value=MockSession()) - def test_init(self, init_client=None): - manager = _client.OpenstackClientManager(init_client=init_client) - self.assertIs(init_client, manager.init_client) - - def test_init_with_init_client(self): - self.test_init(init_client=ClientFixture) + def test_init(self): + manager = ClientManager() + self.assertEqual({}, manager.clients) def test_get_client(self, session=None, shared=True): - default_init_client = mock.MagicMock(side_effect=ClientFixture) - manager = _client.OpenstackClientManager( - init_client=default_init_client) + manager = ClientManager() client1 = manager.get_client(session=session, shared=shared) client2 = manager.get_client(session=session, shared=shared) if shared: self.assertIs(client1, client2) - default_init_client.assert_called_once_with( - session=(session or DEFAULT_SESSION)) else: self.assertIsNot(client1, client2) - default_init_client.assert_has_calls( - [mock.call(session=(session or DEFAULT_SESSION))] * 2, - any_order=True) def test_get_client_with_not_shared(self): self.test_get_client(shared=False) def test_get_client_with_session(self): - self.test_get_client(session=SESSION) + self.test_get_client(session=MockSession()) def test_get_client_with_session_fixture(self): - self.test_get_client(session=SessionFixture()) + self.test_get_client(session=keystone.KeystoneSessionFixture()) def test_get_client_with_session_fixture_type(self): - self.test_get_client(session=SessionFixture) + self.test_get_client(session=keystone.KeystoneSessionFixture) def test_get_client_with_init_client(self): init_client = mock.MagicMock(return_value=CLIENT) manager = _client.OpenstackClientManager() - client = manager.get_client(session=SESSION, + session = MockSession() + client = manager.get_client(session=session, init_client=init_client) self.assertIs(CLIENT, client) - init_client.assert_called_once_with(session=SESSION) + init_client.assert_called_once_with(session=session)