Fix OEM extension loading for different servers
Remove caching and re-using loaded extension objects
as it loaded the same instance for different servers
making it impossible to use it for more than 1
server.
The caching of extension managers is still in place,
consumer of loaded extension object can manage and
reuse the instance as needed.
Change-Id: I7834b49455258f4c3e5690708b23c67d6a361158
Story: 2007669
Task: 39767
(cherry picked from commit 359f2ec2c1
)
This commit is contained in:
parent
c1a7d06f63
commit
0241cd9a43
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes Sushy OEM extension loading when using multiple servers that
|
||||
caused loaded extensions to point to server for which the extension
|
||||
was loaded first.
|
|
@ -85,26 +85,6 @@ def _get_extension_manager_of_resource(resource_name):
|
|||
return _global_extn_mgrs_by_resource[resource_name]
|
||||
|
||||
|
||||
@utils.synchronized
|
||||
def _get_resource_vendor_extension_obj(extension, resource, vendor):
|
||||
"""Get the object returned by extension's plugin() method.
|
||||
|
||||
:param extension: stevedore Extension
|
||||
:param resource: The Sushy resource instance
|
||||
:param vendor: This is the OEM vendor string which is the vendor-specific
|
||||
extensibility identifier. Examples are: 'Contoso', 'Hpe'. As a matter
|
||||
of fact the lowercase of this string will be the plugin entry point
|
||||
name.
|
||||
:returns: The object returned by ``plugin(*args, **kwds)`` of extension.
|
||||
"""
|
||||
if extension.obj is None:
|
||||
oem_resource = extension.plugin()
|
||||
extension.obj = resource.clone_resource(
|
||||
oem_resource).set_parent_resource(resource, vendor)
|
||||
|
||||
return extension.obj
|
||||
|
||||
|
||||
def get_resource_extension_by_vendor(
|
||||
resource_name, vendor, resource):
|
||||
"""Helper method to get Resource specific OEM extension object for vendor
|
||||
|
@ -131,7 +111,6 @@ def get_resource_extension_by_vendor(
|
|||
raise exceptions.OEMExtensionNotFoundError(
|
||||
resource=resource_name, name=vendor.lower())
|
||||
|
||||
if resource_vendor_extn.obj is None:
|
||||
return _get_resource_vendor_extension_obj(
|
||||
resource_vendor_extn, resource, vendor)
|
||||
return resource_vendor_extn.obj
|
||||
oem_resource = resource_vendor_extn.plugin()
|
||||
return resource.clone_resource(
|
||||
oem_resource).set_parent_resource(resource, vendor)
|
||||
|
|
|
@ -114,32 +114,6 @@ class ResourceOEMCommonMethodsTestCase(base.TestCase):
|
|||
self.assertTrue(extension in (self.contoso_extn,
|
||||
self.faux_extn))
|
||||
|
||||
def test__get_resource_vendor_extension_obj_lazy_plugin_invoke(self):
|
||||
resource_instance_mock = mock.Mock()
|
||||
extension_mock = mock.MagicMock()
|
||||
extension_mock.obj = None
|
||||
|
||||
mock_oem_resource = extension_mock.plugin.return_value
|
||||
|
||||
result = oem_common._get_resource_vendor_extension_obj(
|
||||
extension_mock, resource_instance_mock, 'fish-n-chips')
|
||||
|
||||
mock_clone_resource = resource_instance_mock.clone_resource
|
||||
mock_clone_resource.assert_called_once_with(mock_oem_resource)
|
||||
mock_ext = mock_clone_resource.return_value
|
||||
mock_ext.set_parent_resource.assert_called_once_with(
|
||||
resource_instance_mock, 'fish-n-chips')
|
||||
mock_ext = mock_ext.set_parent_resource.return_value
|
||||
self.assertEqual(result, mock_ext)
|
||||
|
||||
extension_mock.reset_mock()
|
||||
|
||||
# extension_mock.obj is not None anymore
|
||||
oem_common._get_resource_vendor_extension_obj(
|
||||
extension_mock, resource_instance_mock, 'fish-n-chips')
|
||||
|
||||
self.assertFalse(extension_mock.plugin.called)
|
||||
|
||||
@mock.patch.object(stevedore, 'ExtensionManager', autospec=True)
|
||||
def test_get_resource_extension_by_vendor(self, ExtensionManager_mock):
|
||||
oem_resource_mock = mock.Mock()
|
||||
|
@ -192,3 +166,30 @@ class ResourceOEMCommonMethodsTestCase(base.TestCase):
|
|||
'by name "faux"',
|
||||
oem_common.get_resource_extension_by_vendor,
|
||||
'sushy.resources.system.oems', 'Faux', resource_instance_mock)
|
||||
|
||||
@mock.patch.object(stevedore, 'ExtensionManager', autospec=True)
|
||||
def test_get_resource_extension_by_vendor_different_resources(
|
||||
self, ExtensionManager_mock):
|
||||
oem_resource_mock = mock.Mock()
|
||||
oem_resource_mock.set_parent_resource = lambda *x: oem_resource_mock
|
||||
resource_instance_mock = mock.Mock()
|
||||
resource_instance_mock.clone_resource = lambda *x: oem_resource_mock
|
||||
oem_resource_mock2 = mock.Mock()
|
||||
oem_resource_mock2.set_parent_resource = lambda *x: oem_resource_mock2
|
||||
resource_instance_mock2 = mock.Mock()
|
||||
resource_instance_mock2.clone_resource = lambda *x: oem_resource_mock2
|
||||
ExtensionManager_mock.side_effect = [self.fake_ext_mgr]
|
||||
|
||||
result = oem_common.get_resource_extension_by_vendor(
|
||||
'system', 'Faux', resource_instance_mock)
|
||||
self.assertEqual(result, oem_resource_mock)
|
||||
ExtensionManager_mock.assert_called_once_with(
|
||||
'sushy.resources.system.oems', propagate_map_exceptions=True,
|
||||
on_load_failure_callback=oem_common._raise)
|
||||
ExtensionManager_mock.reset_mock()
|
||||
|
||||
result2 = oem_common.get_resource_extension_by_vendor(
|
||||
'system', 'Faux', resource_instance_mock2)
|
||||
self.assertEqual(result2, oem_resource_mock2)
|
||||
ExtensionManager_mock.assert_not_called()
|
||||
ExtensionManager_mock.reset_mock()
|
||||
|
|
Loading…
Reference in New Issue