diff --git a/rsd_lib/resources/v2_3/storage_service/storage_service.py b/rsd_lib/resources/v2_3/storage_service/storage_service.py index 2493aae..67f6e29 100644 --- a/rsd_lib/resources/v2_3/storage_service/storage_service.py +++ b/rsd_lib/resources/v2_3/storage_service/storage_service.py @@ -18,6 +18,7 @@ import logging from sushy import exceptions from sushy.resources import base +from rsd_lib.resources.v2_3.fabric import endpoint from rsd_lib.resources.v2_3.storage_service import drive from rsd_lib.resources.v2_3.storage_service import storage_pool from rsd_lib.resources.v2_3.storage_service import volume @@ -52,6 +53,8 @@ class StorageService(base.ResourceBase): _drives = None # ref to Drive collection + _endpoints = None # ref to Endpoint collection + def __init__(self, connector, identity, redfish_version=None): """A class representing a StorageService @@ -129,11 +132,34 @@ class StorageService(base.ResourceBase): return self._drives + def _get_endpoint_collection_path(self): + """Helper function to find the EndpointCollection path""" + endpoint_col = self.json.get('Endpoints') + if not endpoint_col: + raise exceptions.MissingAttributeError(attribute='Endpoints', + resource=self._path) + return utils.get_resource_identity(endpoint_col) + + @property + def endpoints(self): + """Property to provide reference to `EndpointCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + if self._endpoints is None: + self._endpoints = endpoint.EndpointCollection( + self._conn, self._get_endpoint_collection_path(), + redfish_version=self.redfish_version) + + return self._endpoints + def refresh(self): super(StorageService, self).refresh() self._volumes = None self._storage_pools = None self._drives = None + self._endpoints = None class StorageServiceCollection(base.ResourceCollectionBase): diff --git a/rsd_lib/tests/unit/resources/v2_3/storage_service/test_storage_service.py b/rsd_lib/tests/unit/resources/v2_3/storage_service/test_storage_service.py index b73d481..9dfef1b 100644 --- a/rsd_lib/tests/unit/resources/v2_3/storage_service/test_storage_service.py +++ b/rsd_lib/tests/unit/resources/v2_3/storage_service/test_storage_service.py @@ -19,6 +19,7 @@ import testtools from sushy import exceptions +from rsd_lib.resources.v2_3.fabric import endpoint from rsd_lib.resources.v2_3.storage_service import drive from rsd_lib.resources.v2_3.storage_service import storage_pool from rsd_lib.resources.v2_3.storage_service import storage_service @@ -230,6 +231,66 @@ class StorageServiceTestCase(testtools.TestCase): self.assertIsInstance(self.storage_service_inst.drives, drive.DriveCollection) + def test__get_endpoint_collection_path(self): + expected = '/redfish/v1/Fabrics/1/Endpoints' + result = self.storage_service_inst._get_endpoint_collection_path() + self.assertEqual(expected, result) + + def test__get_endpoint_collection_path_missing_attr(self): + self.storage_service_inst._json.pop('Endpoints') + self.assertRaisesRegex( + exceptions.MissingAttributeError, 'attribute Endpoints', + self.storage_service_inst._get_endpoint_collection_path) + + def test_endpoints(self): + # check for the underneath variable value + self.assertIsNone(self.storage_service_inst._endpoints) + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'endpoint_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_endpoints = self.storage_service_inst.endpoints + # | THEN | + self.assertIsInstance(actual_endpoints, + endpoint.EndpointCollection) + self.conn.get.return_value.json.assert_called_once_with() + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_endpoints, + self.storage_service_inst.endpoints) + self.conn.get.return_value.json.assert_not_called() + + def test_endpoints_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'endpoint_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.storage_service_inst.endpoints, + endpoint.EndpointCollection) + + # On refreshing the fabric instance... + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'fabric.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.storage_service_inst.refresh() + + # | WHEN & THEN | + self.assertIsNone(self.storage_service_inst._endpoints) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'endpoint_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.storage_service_inst.endpoints, + endpoint.EndpointCollection) + class StorageServiceCollectionTestCase(testtools.TestCase):