Update OpenStack clients to improve 'lazyness'

Change-Id: If32e99f20c628e0c8c8ab201fc92fa58ebaf4587
This commit is contained in:
Federico Ressi 2019-06-17 08:20:39 +02:00
parent 5996055ab6
commit 8a7b39d050
9 changed files with 137 additions and 83 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -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)