diff --git a/rsd_lib/resources/v2_1/chassis/pcie_function.py b/rsd_lib/resources/v2_1/system/pcie_function.py similarity index 100% rename from rsd_lib/resources/v2_1/chassis/pcie_function.py rename to rsd_lib/resources/v2_1/system/pcie_function.py diff --git a/rsd_lib/resources/v2_1/system/system.py b/rsd_lib/resources/v2_1/system/system.py index 54dd262..2139ed9 100644 --- a/rsd_lib/resources/v2_1/system/system.py +++ b/rsd_lib/resources/v2_1/system/system.py @@ -20,6 +20,7 @@ from rsd_lib.resources.v2_1.system import ethernet_interface from rsd_lib.resources.v2_1.system import memory from rsd_lib.resources.v2_1.system import network_interface from rsd_lib.resources.v2_1.system import pcie_device +from rsd_lib.resources.v2_1.system import pcie_function from rsd_lib.resources.v2_1.system import storage_subsystem from rsd_lib import utils as rsd_lib_utils @@ -105,6 +106,21 @@ class System(system.System): self._conn, path, redfish_version=self.redfish_version ) for path in pcie_device_paths] + @property + @utils.cache_it + def pcie_functions(self): + """Property to provide reference to a list of `PCIeFunction` instances + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + pcie_function_paths = rsd_lib_utils.get_sub_resource_path_list_by( + self, 'PCIeFunctions') + return [ + pcie_function.PCIeFunction( + self._conn, path, redfish_version=self.redfish_version + ) for path in pcie_function_paths] + class SystemCollection(system.SystemCollection): diff --git a/rsd_lib/tests/unit/json_samples/v2_1/system.json b/rsd_lib/tests/unit/json_samples/v2_1/system.json index bbd2b93..e33b292 100644 --- a/rsd_lib/tests/unit/json_samples/v2_1/system.json +++ b/rsd_lib/tests/unit/json_samples/v2_1/system.json @@ -98,6 +98,14 @@ "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Device2" } ], + "PCIeFunctions": [ + { + "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1" + }, + { + "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Device2/Functions/1" + } + ], "SimpleStorage": { "@odata.id": "/redfish/v1/Systems/437XR1138R2/SimpleStorage" }, diff --git a/rsd_lib/tests/unit/resources/v2_1/chassis/test_pcie_function.py b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py similarity index 98% rename from rsd_lib/tests/unit/resources/v2_1/chassis/test_pcie_function.py rename to rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py index efeb279..553d3da 100644 --- a/rsd_lib/tests/unit/resources/v2_1/chassis/test_pcie_function.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py @@ -17,7 +17,7 @@ import json import mock import testtools -from rsd_lib.resources.v2_1.chassis import pcie_function +from rsd_lib.resources.v2_1.system import pcie_function class PCIeFunctionTestCase(testtools.TestCase): diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_system.py b/rsd_lib/tests/unit/resources/v2_1/system/test_system.py index 6def040..3e3c166 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_system.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_system.py @@ -24,6 +24,7 @@ from rsd_lib.resources.v2_1.system import ethernet_interface from rsd_lib.resources.v2_1.system import memory from rsd_lib.resources.v2_1.system import network_interface from rsd_lib.resources.v2_1.system import pcie_device +from rsd_lib.resources.v2_1.system import pcie_function from rsd_lib.resources.v2_1.system import storage_subsystem from rsd_lib.resources.v2_1.system import system @@ -323,6 +324,55 @@ class SystemTestCase(testtools.TestCase): self.assertIsInstance(pcie, pcie_device.PCIeDevice) + def test_pcie_functions(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'pcie_function.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_pcie_functions = self.system_inst.pcie_functions + # | THEN | + self.assertEqual(2, len(actual_pcie_functions)) + for pcie in actual_pcie_functions: + self.assertIsInstance(pcie, pcie_function.PCIeFunction) + self.assertEqual(2, self.conn.get.return_value.json.call_count) + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_pcie_functions, + self.system_inst.pcie_functions) + self.conn.get.return_value.json.assert_not_called() + + def test_pcie_functions_on_fresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'pcie_function.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + for pcie in self.system_inst.pcie_functions: + self.assertIsInstance(pcie, + pcie_function.PCIeFunction) + + # On refreshing the chassis instance... + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'system.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.system_inst.invalidate() + self.system_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'pcie_function.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + for pcie in self.system_inst.pcie_functions: + self.assertIsInstance(pcie, + pcie_function.PCIeFunction) + class SystemCollectionTestCase(testtools.TestCase):