diff --git a/rsd_lib/resources/v2_4/__init__.py b/rsd_lib/resources/v2_4/__init__.py index ff2ccbb..08295a6 100644 --- a/rsd_lib/resources/v2_4/__init__.py +++ b/rsd_lib/resources/v2_4/__init__.py @@ -18,6 +18,7 @@ from sushy.resources import base from rsd_lib.resources import v2_3 from rsd_lib.resources.v2_4.node import node from rsd_lib.resources.v2_4.storage_service import storage_service +from rsd_lib.resources.v2_4.system import system class RSDLibV2_4(v2_3.RSDLibV2_3): @@ -26,6 +27,25 @@ class RSDLibV2_4(v2_3.RSDLibV2_3): ['Oem', 'Intel_RackScale', 'TelemetryService', '@odata.id']) """EthernetSwitchCollecton path""" + def get_system(self, identity): + """Given the identity return a System object + + :param identity: The identity of the System resource + :returns: The System object + """ + return system.System(self._conn, identity, + redfish_version=self.redfish_version) + + def get_system_collection(self): + """Get the SystemCollection object + + :raises: MissingAttributeError, if the collection attribute is + not found + :returns: a SystemCollection object + """ + return system.SystemCollection(self._conn, self._systems_path, + redfish_version=self.redfish_version) + def get_storage_service_collection(self): """Get the StorageServiceCollection object diff --git a/rsd_lib/resources/v2_4/system/__init__.py b/rsd_lib/resources/v2_4/system/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rsd_lib/resources/v2_4/system/processor.py b/rsd_lib/resources/v2_4/system/processor.py new file mode 100644 index 0000000..8ac0b41 --- /dev/null +++ b/rsd_lib/resources/v2_4/system/processor.py @@ -0,0 +1,193 @@ +# Copyright 2018 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sushy.resources import base +from sushy import utils + +from rsd_lib import base as rsd_lib_base +from rsd_lib.resources.v2_2.system import processor +from rsd_lib import utils as rsd_lib_utils + + +class OnPackageMemoryField(base.ListField): + + memory_type = base.Field('Type') + """Type of memory""" + + capacity_mb = base.Field('CapacityMB', adapter=rsd_lib_utils.num_or_none) + """Memory capacity""" + + speed_mhz = base.Field('SpeedMHz', adapter=rsd_lib_utils.num_or_none) + """Memory speed""" + + +class ReconfigurationSlotsDetailsField(base.ListField): + + slot_id = base.Field('SlotId') + """Reconfiguration slot identity""" + + uuid = base.Field('UUID') + """Reconfiguration slot uuid""" + + programmable_from_host = base.Field('ProgrammableFromHost', adapter=bool) + """Indict whether programmable from host""" + + +class FpgaField(base.CompositeField): + + fpga_type = base.Field('Type') + """Type of FPGA""" + + model = base.Field('Model') + """Model of FPGA""" + + fw_id = base.Field('FwId') + """Firmware identity of FPGA""" + + fw_manufacturer = base.Field('FwManufacturer') + """Firmware manufacturer of FPGA""" + + fw_version = base.Field('FwVersion') + """Firmware version of FPGA""" + + host_interface = base.Field('HostInterface') + """Host interface of FPGA""" + + external_interfaces = base.Field('ExternalInterfaces') + """External interfaces of FPGA""" + + sideband_interface = base.Field('SidebandInterface') + """Sideband interface of FPGA""" + + pcie_virtual_functions = base.Field( + 'PCIeVirtualFunctions', adapter=rsd_lib_utils.num_or_none) + """PCIe Virtual functions of FPGA""" + + programmable_from_host = base.Field('ProgrammableFromHost', adapter=bool) + """Indict whether programmable from host""" + + reconfiguration_slots = base.Field( + 'ReconfigurationSlots', adapter=rsd_lib_utils.num_or_none) + """Number of supported reconfiguration slots""" + + reconfiguration_slots_details = ReconfigurationSlotsDetailsField( + 'ReconfigurationSlotsDetails') + """Details of supported reconfiguration slots""" + + # TODO(linyang): might need to return instance instead of URI + acceleration_functions = base.Field( + 'AccelerationFunctions', adapter=rsd_lib_utils.get_resource_identity) + """The reference to a resource of type AccelerationFunctions""" + + +class IntelRackScaleField(processor.IntelRackScaleField): + + on_package_memory = OnPackageMemoryField('OnPackageMemory') + """An array of references to the endpoints that connect to this processor + """ + + thermal_design_power_watt = base.Field( + 'ThermalDesignPowerWatt', adapter=rsd_lib_utils.num_or_none) + """Thermal Design Power (TDP) of this processor""" + + metrics = base.Field( + 'Metrics', adapter=rsd_lib_utils.get_resource_identity) + """A reference to the Metrics associated with this Processor""" + + extended_identification_registers = rsd_lib_base.DynamicField( + 'ExtendedIdentificationRegisters') + """Extended contents of the Identification Registers (CPUID) for this + processor + """ + + fpga = FpgaField('FPGA') + """FPGA specific properties for FPGA ProcessorType""" + + # TODO(linyang): might need to return instance instead of URI + pcie_function = base.Field( + 'PCIeFunction', adapter=rsd_lib_utils.get_resource_identity) + """The reference to a resource of type PCIeFunction""" + + +class OemField(base.CompositeField): + + intel_rackscale = IntelRackScaleField('Intel_RackScale') + """Intel Rack Scale Design extensions ('Intel_RackScale' object)""" + + +class LinksIntelRackScaleField(base.CompositeField): + + connected_port = base.Field( + 'ConnectedPort', adapter=rsd_lib_utils.get_resource_identity) + """The reference to a resource of type ConnectedPort""" + + endpoints = base.Field('Endpoints', adapter=utils.get_members_identities) + """The reference to a list of type Endpoints""" + + connected_processors = base.Field( + 'ConnectedProcessors', adapter=utils.get_members_identities) + """The reference to a list of type ConnectedProcessors""" + + +class LinksOemField(base.CompositeField): + + intel_rackscale = LinksIntelRackScaleField('Intel_RackScale') + """The Intel Rack Scale specific reference links""" + + +class LinksField(base.CompositeField): + + chassis = base.Field( + 'Chassis', adapter=rsd_lib_utils.get_resource_identity) + """The reference to a resource of type Chassis that represent the physical + container associated with this processor + """ + + oem = LinksOemField('Oem') + """The Oem specific reference links""" + + +class Processor(processor.Processor): + + links = LinksField('Links') + """Contain references to resources that are related to, but not contained + by (subordinate to), this processor + """ + + oem = OemField('Oem') + """Oem extension object""" + + def _get_sub_processors_path(self): + """Helper function to find the System process metrics path""" + return utils.get_sub_resource_path_by(self, 'SubProcessors') + + @property + @utils.cache_it + def sub_processors(self): + """Property to provide reference to `ProcessorCollection` instance + + It is calculated once the first time it is queried. On refresh, + this property is reset. + """ + return ProcessorCollection( + self._conn, self._get_sub_processors_path(), + redfish_version=self.redfish_version) + + +class ProcessorCollection(processor.ProcessorCollection): + + @property + def _resource_type(self): + return Processor diff --git a/rsd_lib/resources/v2_4/system/system.py b/rsd_lib/resources/v2_4/system/system.py new file mode 100644 index 0000000..a5b80b7 --- /dev/null +++ b/rsd_lib/resources/v2_4/system/system.py @@ -0,0 +1,41 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sushy import utils + +from rsd_lib.resources.v2_3.system import system +from rsd_lib.resources.v2_4.system import processor + + +class System(system.System): + + @property + @utils.cache_it + def processors(self): + """Property to provide reference to `ProcessorCollection` instance + + It is calculated once when the first time it is queried. On refresh, + this property gets reset. + """ + return processor.ProcessorCollection( + self._conn, self._get_processor_collection_path(), + redfish_version=self.redfish_version) + + +class SystemCollection(system.SystemCollection): + + @property + def _resource_type(self): + return System diff --git a/rsd_lib/tests/unit/json_samples/v2_4/processor.json b/rsd_lib/tests/unit/json_samples/v2_4/processor.json new file mode 100644 index 0000000..f6f6df6 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_4/processor.json @@ -0,0 +1,128 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Processor.Processor", + "@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1", + "@odata.type": "#Processor.v1_0_0.Processor", + "Name": "Processor", + "Id": "CPU1", + "Socket": "CPU 1", + "ProcessorType": "CPU", + "ProcessorArchitecture": "x86", + "InstructionSet": "x86-64", + "Manufacturer": "Intel(R) Corporation", + "Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", + "ProcessorId": { + "VendorId": "GenuineIntel", + "IdentificationRegisters": "0x34AC34DC8901274A", + "EffectiveFamily": "0x42", + "EffectiveModel": "0x61", + "Step": "0x1", + "MicrocodeInfo": "0x429943" + }, + "MaxSpeedMHz": 3700, + "TotalCores": 8, + "TotalThreads": 16, + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollup": "OK" + }, + "SubProcessors": { + "@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1/SubProcessors" + }, + "Links": { + "Chassis": { + "@odata.id": "/redfish/v1/Chassis/Chassis1" + }, + "Oem": { + "Intel_RackScale": { + "@odata.type": "#Intel.Oem.ProcessorLinks", + "Endpoints": [ + { + "@odata.id": "/redfish/v1/Fabrics/FPGAoF/Endpoints/1" + } + ], + "ConnectedProcessors": [ + { + "@odata.id": "/redfish/v1/Systems/System1/Processors/1" + } + ], + "ConnectedPort": { + "@odata.id": "/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down1" + } + } + } + }, + "Oem": { + "Intel_RackScale": { + "@odata.type": "http://rsa.intel.com/Schema#RSA.Processor", + "Brand": "E5", + "Capabilities": [ + "sse", + "sse2", + "sse3" + ], + "PCIeFunction": { + "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Devices/1/Functions/1" + }, + "OnPackageMemory": [ + { + "Type": "L2Cache", + "CapacityMB": 2, + "SpeedMHz": null + }, + { + "Type": "L3Cache", + "CapacityMB": 20, + "SpeedMHz": null + } + ], + "ThermalDesignPowerWatt": 160, + "Metrics": { + "@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1/Metrics" + }, + "FPGA": { + "Type": "Discrete", + "Model": "Stratix10", + "FwId": "0x6400002fc614bb9", + "FwManufacturer": "Intel(R) Corporation", + "FwVersion": "Blue v.1.00.86", + "HostInterface": "8xPCIe-4", + "ExternalInterfaces": [ + "4x10G" + ], + "SidebandInterface": "I2C", + "PCIeVirtualFunctions": 1, + "ProgrammableFromHost": true, + "ReconfigurationSlots": 1, + "ReconfigurationSlotsDetails": [ + { + "SlotId": "AFU0", + "UUID": "00000000-0000-0000-0000-000000000000", + "ProgrammableFromHost": true + } + ], + "AccelerationFunctions": { + "@odata.id": "/redfish/v1/Systems/System1/Processors/FPGA1/Functions" + } + }, + "ExtendedIdentificationRegisters": { + "EAX_00h": "0x0429943FFFFFFFFF", + "EAX_01h": "0x0429943FFFFFFFFF", + "EAX_02h": "0x0429943FFFFFFFFF", + "EAX_03h": "0x0429943FFFFFFFFF", + "EAX_04h": "0x0429943FFFFFFFFF", + "EAX_05h": "0x0429943FFFFFFFFF", + "EAX_07h": "0x0429943FFFFFFFFF", + "EAX_80000000h": "0x0429943FFFFFFFFF", + "EAX_80000001h": "0x0429943FFFFFFFFF", + "EAX_80000002h": "0x0429943FFFFFFFFF", + "EAX_80000003h": "0x0429943FFFFFFFFF", + "EAX_80000004h": "0x0429943FFFFFFFFF", + "EAX_80000005h": "0x0429943FFFFFFFFF", + "EAX_80000006h": "0x0429943FFFFFFFFF", + "EAX_80000007h": "0x0429943FFFFFFFFF", + "EAX_80000008h": "0x0429943FFFFFFFFF" + } + } + } +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_4/processor_collection.json b/rsd_lib/tests/unit/json_samples/v2_4/processor_collection.json new file mode 100644 index 0000000..122bf02 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_4/processor_collection.json @@ -0,0 +1,16 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/Processors/#entity", + "@odata.id": "/redfish/v1/Systems/System1/Processors", + "@odata.type": "#ProcessorCollection.ProcessorCollection", + "Name": "Processors Collection", + "Description": "description-as-string", + "Members@odata.count": 1, + "Members": [ + { + "@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1" + }, + { + "@odata.id": "/redfish/v1/Systems/System1/Processors/FPGA1" + } + ] +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_4/system.json b/rsd_lib/tests/unit/json_samples/v2_4/system.json new file mode 100644 index 0000000..ba05543 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_4/system.json @@ -0,0 +1,139 @@ +{ + "@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem", + "Id": "437XR1138R2", + "Name": "WebFrontEnd483", + "SystemType": "Physical", + "AssetTag": "Chicago-45Z-2381", + "Manufacturer": "Contoso", + "Model": "3500RX", + "SKU": "8675309", + "SerialNumber": "437XR1138R2", + "PartNumber": "224071-J23", + "Description": "Web Front End node", + "UUID": "38947555-7742-3448-3784-823347823834", + "HostName": "web483", + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollup": "OK" + }, + "IndicatorLED": "Off", + "PowerState": "On", + "Boot": { + "BootSourceOverrideEnabled": "Once", + "BootSourceOverrideTarget": "Pxe", + "BootSourceOverrideTarget@Redfish.AllowableValues": [ + "None", + "Pxe", + "Cd", + "Usb", + "Hdd", + "BiosSetup", + "Utilities", + "Diags", + "SDCard", + "UefiTarget" + ], + "BootSourceOverrideMode": "UEFI", + "UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01" + }, + "TrustedModules": [ + { + "FirmwareVersion": "1.13b", + "InterfaceType": "TPM1_2", + "Status": { + "State": "Enabled", + "Health": "OK" + } + } + ], + "Oem": { + "Contoso": { + "@odata.type": "http://Contoso.com/Schema#Contoso.ComputerSystem", + "ProductionLocation": { + "FacilityName": "PacWest Production Facility", + "Country": "USA" + } + }, + "Chipwise": { + "@odata.type": "http://Chipwise.com/Schema#Chipwise.ComputerSystem", + "Style": "Executive" + } + }, + "BiosVersion": "P79 v1.33 (02/28/2015)", + "ProcessorSummary": { + "Count": 2, + "ProcessorFamily": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollup": "OK" + } + }, + "MemorySummary": { + "TotalSystemMemoryGiB": 96, + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollup": "OK" + } + }, + "Bios": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/BIOS" + }, + "Processors": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Processors" + }, + "Memory": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Memory" + }, + "EthernetInterfaces": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/EthernetInterfaces" + }, + "SimpleStorage": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/SimpleStorage" + }, + "Storage": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage" + }, + "LogServices": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/LogServices" + }, + "NetworkInterfaces": { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/NetworkInterfaces" + }, + "Links": { + "Chassis": [ + { + "@odata.id": "/redfish/v1/Chassis/1U" + } + ], + "ManagedBy": [ + { + "@odata.id": "/redfish/v1/Managers/BMC" + } + ] + }, + "Actions": { + "#ComputerSystem.Reset": { + "target": "/redfish/v1/Systems/437XR1138R2/Actions/ComputerSystem.Reset", + "ResetType@Redfish.AllowableValues": [ + "On", + "ForceOff", + "GracefulShutdown", + "GracefulRestart", + "ForceRestart", + "Nmi", + "ForceOn" + ] + }, + "Oem": { + "#Contoso.Reset": { + "target": "/redfish/v1/Systems/437XR1138R2/Oem/Contoso/Actions/Contoso.Reset" + } + } + }, + "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem", + "@odata.id": "/redfish/v1/Systems/437XR1138R2", + "@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright." +} diff --git a/rsd_lib/tests/unit/json_samples/v2_4/system_collection.json b/rsd_lib/tests/unit/json_samples/v2_4/system_collection.json new file mode 100644 index 0000000..d465f12 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_4/system_collection.json @@ -0,0 +1,15 @@ +{ + "@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection", + "@odata.id": "/redfish/v1/Systems", + "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection", + "Name": "Computer System Collection", + "Members@odata.count": 2, + "Members": [ + { + "@odata.id": "/redfish/v1/Systems/System1" + }, + { + "@odata.id": "/redfish/v1/Systems/System2" + } + ] +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/resources/v2_2/system/test_processor.py b/rsd_lib/tests/unit/resources/v2_2/system/test_processor.py index 91c4f9c..4ac88c7 100644 --- a/rsd_lib/tests/unit/resources/v2_2/system/test_processor.py +++ b/rsd_lib/tests/unit/resources/v2_2/system/test_processor.py @@ -248,7 +248,7 @@ class ProcessorCollectionTestCase(testtools.TestCase): 'processor_collection.json', 'r') as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.processor_col = processor.ProcessorCollection( - self.conn, '/redfish/v1/Systems', + self.conn, '/redfish/v1/Systems/System1/Processors', redfish_version='1.1.0') def test__parse_attributes(self): diff --git a/rsd_lib/tests/unit/resources/v2_4/system/__init__.py b/rsd_lib/tests/unit/resources/v2_4/system/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rsd_lib/tests/unit/resources/v2_4/system/test_processor.py b/rsd_lib/tests/unit/resources/v2_4/system/test_processor.py new file mode 100644 index 0000000..9c6867a --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_4/system/test_processor.py @@ -0,0 +1,332 @@ +# Copyright 2018 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import mock +import testtools + +from sushy import exceptions + +from rsd_lib.resources.v2_4.system import processor + + +class ProcessorTestCase(testtools.TestCase): + + def setUp(self): + super(ProcessorTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/processor.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.processor_inst = processor.Processor( + self.conn, '/redfish/v1/Systems/System1/Processors/CPU1', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.processor_inst._parse_attributes() + self.assertEqual('1.1.0', self.processor_inst.redfish_version) + self.assertEqual('CPU1', self.processor_inst.identity) + self.assertEqual('Processor', self.processor_inst.name) + self.assertEqual(None, self.processor_inst.description) + self.assertEqual('CPU 1', self.processor_inst.socket) + self.assertEqual('CPU', self.processor_inst.processor_type) + self.assertEqual('x86', self.processor_inst.processor_architecture) + self.assertEqual('x86-64', self.processor_inst.instruction_set) + self.assertEqual('Intel(R) Corporation', + self.processor_inst.manufacturer) + self.assertEqual('Multi-Core Intel(R) Xeon(R) processor 7xxx Series', + self.processor_inst.model) + self.assertEqual(3700, self.processor_inst.max_speed_mhz) + self.assertEqual( + '0x42', self.processor_inst.processor_id.effective_family) + self.assertEqual( + '0x61', self.processor_inst.processor_id.effective_model) + self.assertEqual( + '0x34AC34DC8901274A', + self.processor_inst.processor_id.identification_registers) + self.assertEqual( + '0x429943', self.processor_inst.processor_id.microcode_info) + self.assertEqual('0x1', self.processor_inst.processor_id.step) + self.assertEqual( + 'GenuineIntel', self.processor_inst.processor_id.vendor_id) + self.assertEqual('OK', self.processor_inst.status.health) + self.assertEqual('OK', self.processor_inst.status.health_rollup) + self.assertEqual('Enabled', self.processor_inst.status.state) + self.assertEqual(8, self.processor_inst.total_cores) + self.assertEqual(16, self.processor_inst.total_threads) + self.assertEqual('E5', self.processor_inst.oem.intel_rackscale.brand) + self.assertEqual( + ['sse', 'sse2', 'sse3'], + self.processor_inst.oem.intel_rackscale.capabilities) + self.assertEqual( + 'L2Cache', + self.processor_inst.oem.intel_rackscale.on_package_memory[0]. + memory_type) + self.assertEqual( + 2, + self.processor_inst.oem.intel_rackscale.on_package_memory[0]. + capacity_mb) + self.assertEqual( + None, + self.processor_inst.oem.intel_rackscale.on_package_memory[0]. + speed_mhz) + self.assertEqual( + 'L3Cache', + self.processor_inst.oem.intel_rackscale.on_package_memory[1]. + memory_type) + self.assertEqual( + 20, + self.processor_inst.oem.intel_rackscale.on_package_memory[1]. + capacity_mb) + self.assertEqual( + None, + self.processor_inst.oem.intel_rackscale.on_package_memory[1]. + speed_mhz) + self.assertEqual( + 160, + self.processor_inst.oem.intel_rackscale.thermal_design_power_watt) + self.assertEqual( + '/redfish/v1/Systems/System1/Processors/CPU1/Metrics', + self.processor_inst.oem.intel_rackscale.metrics) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_00h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_01h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_02h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_03h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_04h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_05h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_07h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000000h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000001h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000002h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000003h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000004h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000005h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000006h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000007h) + self.assertEqual( + "0x0429943FFFFFFFFF", + self.processor_inst.oem.intel_rackscale. + extended_identification_registers.eax_80000008h) + self.assertEqual( + "/redfish/v1/Chassis/1/PCIeDevices/Devices/1/Functions/1", + self.processor_inst.oem.intel_rackscale.pcie_function) + + self.assertEqual( + 'Discrete', self.processor_inst.oem.intel_rackscale.fpga.fpga_type) + self.assertEqual( + 'Stratix10', self.processor_inst.oem.intel_rackscale.fpga.model) + self.assertEqual( + '0x6400002fc614bb9', + self.processor_inst.oem.intel_rackscale.fpga.fw_id) + self.assertEqual( + 'Intel(R) Corporation', + self.processor_inst.oem.intel_rackscale.fpga.fw_manufacturer) + self.assertEqual( + "Blue v.1.00.86", + self.processor_inst.oem.intel_rackscale.fpga.fw_version) + self.assertEqual( + "8xPCIe-4", + self.processor_inst.oem.intel_rackscale.fpga.host_interface) + self.assertEqual( + ["4x10G"], + self.processor_inst.oem.intel_rackscale.fpga.external_interfaces) + self.assertEqual( + "I2C", + self.processor_inst.oem.intel_rackscale.fpga.sideband_interface) + self.assertEqual( + 1, + self.processor_inst.oem.intel_rackscale.fpga. + pcie_virtual_functions) + self.assertEqual( + True, + self.processor_inst.oem.intel_rackscale.fpga. + programmable_from_host) + self.assertEqual( + 1, + self.processor_inst.oem.intel_rackscale.fpga.reconfiguration_slots) + self.assertEqual( + "/redfish/v1/Systems/System1/Processors/FPGA1/Functions", + self.processor_inst.oem.intel_rackscale.fpga. + acceleration_functions) + self.assertEqual( + "AFU0", + self.processor_inst.oem.intel_rackscale.fpga. + reconfiguration_slots_details[0].slot_id) + self.assertEqual( + "00000000-0000-0000-0000-000000000000", + self.processor_inst.oem.intel_rackscale.fpga. + reconfiguration_slots_details[0].uuid) + self.assertEqual( + True, + self.processor_inst.oem.intel_rackscale.fpga. + reconfiguration_slots_details[0].programmable_from_host) + self.assertEqual( + '/redfish/v1/Chassis/Chassis1', self.processor_inst.links.chassis) + self.assertEqual( + '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down1', + self.processor_inst.links.oem.intel_rackscale.connected_port) + self.assertEqual( + ('/redfish/v1/Fabrics/FPGAoF/Endpoints/1',), + self.processor_inst.links.oem.intel_rackscale.endpoints) + self.assertEqual( + ('/redfish/v1/Systems/System1/Processors/1',), + self.processor_inst.links.oem.intel_rackscale.connected_processors) + + def test__get_sub_processors_path(self): + self.assertEqual( + '/redfish/v1/Systems/System1/Processors/CPU1/SubProcessors', + self.processor_inst._get_sub_processors_path()) + + def test__get_sub_processors_path_missing_attr(self): + self.processor_inst._json.pop('SubProcessors') + with self.assertRaisesRegex(exceptions.MissingAttributeError, + 'attribute SubProcessors'): + self.processor_inst._get_sub_processors_path() + + def test_sub_processors(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_processor_col = self.processor_inst.sub_processors + # | THEN | + self.assertIsInstance(actual_processor_col, + processor.ProcessorCollection) + 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_processor_col, + self.processor_inst.sub_processors) + self.conn.get.return_value.json.assert_not_called() + + def test_sub_processors_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.processor_inst.sub_processors, + processor.ProcessorCollection) + + # On refreshing the processor instance... + with open('rsd_lib/tests/unit/json_samples/v2_4/processor.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.processor_inst.invalidate() + self.processor_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.processor_inst.sub_processors, + processor.ProcessorCollection) + + +class ProcessorCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(ProcessorCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.processor_col = processor.ProcessorCollection( + self.conn, '/redfish/v1/Systems/System1/Processors', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.processor_col._parse_attributes() + self.assertEqual('1.1.0', self.processor_col.redfish_version) + self.assertEqual(('/redfish/v1/Systems/System1/Processors/CPU1', + '/redfish/v1/Systems/System1/Processors/FPGA1'), + self.processor_col.members_identities) + + @mock.patch.object(processor, 'Processor', autospec=True) + def test_get_member(self, mock_system): + self.processor_col.get_member( + '/redfish/v1/Systems/System1/Processors/CPU1') + mock_system.assert_called_once_with( + self.processor_col._conn, + '/redfish/v1/Systems/System1/Processors/CPU1', + redfish_version=self.processor_col.redfish_version) + + @mock.patch.object(processor, 'Processor', autospec=True) + def test_get_members(self, mock_system): + members = self.processor_col.get_members() + calls = [ + mock.call(self.processor_col._conn, + '/redfish/v1/Systems/System1/Processors/CPU1', + redfish_version=self.processor_col.redfish_version), + mock.call(self.processor_col._conn, + '/redfish/v1/Systems/System1/Processors/FPGA1', + redfish_version=self.processor_col.redfish_version) + ] + mock_system.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(2, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_4/system/test_system.py b/rsd_lib/tests/unit/resources/v2_4/system/test_system.py new file mode 100644 index 0000000..c4a597e --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_4/system/test_system.py @@ -0,0 +1,125 @@ +# Copyright 2018 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import mock +import testtools + +from rsd_lib.resources.v2_4.system import processor +from rsd_lib.resources.v2_4.system import system + + +class SystemTestCase(testtools.TestCase): + + def setUp(self): + super(SystemTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/system.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.system_inst = system.System( + self.conn, '/redfish/v1/Systems/System1', + redfish_version='1.0.2') + + def test_processors(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_processors = self.system_inst.processors + # | THEN | + self.assertIsInstance(actual_processors, + processor.ProcessorCollection) + 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_processors, + self.system_inst.processors) + self.conn.get.return_value.json.assert_not_called() + + def test_processors_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.system_inst.processors, + processor.ProcessorCollection) + + # On refreshing the system instance... + with open('rsd_lib/tests/unit/json_samples/v2_4/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_4/' + 'processor_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.system_inst.processors, + processor.ProcessorCollection) + + +class SystemCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(SystemCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_4/' + 'system_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.system_col = system.SystemCollection( + self.conn, '/redfish/v1/Systems', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.system_col._parse_attributes() + self.assertEqual('1.1.0', self.system_col.redfish_version) + self.assertEqual(('/redfish/v1/Systems/System1', + '/redfish/v1/Systems/System2'), + self.system_col.members_identities) + + @mock.patch.object(system, 'System', autospec=True) + def test_get_member(self, mock_system): + self.system_col.get_member( + '/redfish/v1/Systems/System1') + mock_system.assert_called_once_with( + self.system_col._conn, + '/redfish/v1/Systems/System1', + redfish_version=self.system_col.redfish_version) + + @mock.patch.object(system, 'System', autospec=True) + def test_get_members(self, mock_system): + members = self.system_col.get_members() + calls = [ + mock.call(self.system_col._conn, + '/redfish/v1/Systems/System1', + redfish_version=self.system_col.redfish_version), + mock.call(self.system_col._conn, + '/redfish/v1/Systems/System2', + redfish_version=self.system_col.redfish_version) + ] + mock_system.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(2, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py b/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py index 265daa1..1825473 100644 --- a/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py +++ b/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py @@ -28,11 +28,11 @@ from rsd_lib.resources.v2_3.ethernet_switch import ethernet_switch \ as v2_3_ethernet_switch from rsd_lib.resources.v2_3.fabric import fabric as v2_3_fabric from rsd_lib.resources.v2_3.manager import manager as v2_3_manager -from rsd_lib.resources.v2_3.system import system as v2_3_system from rsd_lib.resources import v2_4 from rsd_lib.resources.v2_4.node import node as v2_4_node from rsd_lib.resources.v2_4.storage_service import storage_service \ as v2_4_storage_service +from rsd_lib.resources.v2_4.system import system as v2_4_system class RSDLibV2_3TestCase(testtools.TestCase): @@ -68,14 +68,14 @@ class RSDLibV2_3TestCase(testtools.TestCase): self.assertEqual("/redfish/v1/EventService", self.rsd._event_service_path) - @mock.patch.object(v2_3_system, 'SystemCollection', autospec=True) + @mock.patch.object(v2_4_system, 'SystemCollection', autospec=True) def test_get_system_collection(self, mock_system_collection): self.rsd.get_system_collection() mock_system_collection.assert_called_once_with( self.rsd._conn, '/redfish/v1/Systems', redfish_version=self.rsd.redfish_version) - @mock.patch.object(v2_3_system, 'System', autospec=True) + @mock.patch.object(v2_4_system, 'System', autospec=True) def test_get_system(self, mock_system): self.rsd.get_system('fake-system-id') mock_system.assert_called_once_with(