diff --git a/rsd_lib/base.py b/rsd_lib/base.py index 02b4160..0618277 100644 --- a/rsd_lib/base.py +++ b/rsd_lib/base.py @@ -67,6 +67,12 @@ class StatusField(base.CompositeField): """Indicates the known state of the resource, such as if it is enabled.""" +class ReferenceableMemberField(base.ListField): + + member_id = base.Field("MemberId") + """This is the identifier for the member within the collection.""" + + class LocationField(base.CompositeField): info = base.Field("Info") @@ -76,10 +82,13 @@ class LocationField(base.CompositeField): """This represents the format of the Info property.""" -class ReferenceableMemberField(base.ListField): +class LocationCollectionField(ReferenceableMemberField): - member_id = base.Field("MemberId") - """This is the identifier for the member within the collection.""" + info = base.Field("Info") + """This indicates the location of the resource.""" + + info_format = base.Field("InfoFormat") + """This represents the format of the Info property.""" class IdentifierField(base.CompositeField): diff --git a/rsd_lib/constants.py b/rsd_lib/constants.py new file mode 100644 index 0000000..7cf13bc --- /dev/null +++ b/rsd_lib/constants.py @@ -0,0 +1,53 @@ +# 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. + +RESET_TYPE_VALUE = [ + 'On', + 'ForceOff', + 'GracefulShutdown', + 'GracefulRestart', + 'ForceRestart', + 'Nmi', + 'ForceOn', + 'PushPowerButton' +] + +BOOT_SOURCE_TARGET_VALUE = [ + 'None', + 'Pxe', + 'Floppy', + 'Cd', + 'Usb', + 'Hdd', + 'BiosSetup', + 'Utilities', + 'Diags', + 'SDCard', + 'UefiTarget', + 'UefiShell', + 'UefiHttp', + "RemoteDrive" +] + +BOOT_SOURCE_ENABLED_VALUE = { + 'Once', + 'Continuous', + 'Disabled' +} + +BOOT_SOURCE_MODE_VALUE = { + 'Legacy', + 'UEFI' +} diff --git a/rsd_lib/resources/v2_1/common/ip_addresses.py b/rsd_lib/resources/v2_1/common/ip_addresses.py index db1865a..47da348 100644 --- a/rsd_lib/resources/v2_1/common/ip_addresses.py +++ b/rsd_lib/resources/v2_1/common/ip_addresses.py @@ -33,6 +33,20 @@ class IPv6AddressCollectionField(rsd_lib_base.ReferenceableMemberField): """The current state of this address as defined in RFC 4862.""" +class IPv6StaticAddressCollectionField(rsd_lib_base.ReferenceableMemberField): + """IPv6StaticAddress field + + This object represents a single IPv6 static address to be assigned on a + network interface. + """ + + address = base.Field("Address") + """A valid IPv6 address.""" + + prefix_length = base.Field("PrefixLength") + """The Prefix Length of this IPv6 address.""" + + class IPv4AddressCollectionField(rsd_lib_base.ReferenceableMemberField): address = base.Field("Address") diff --git a/rsd_lib/resources/v2_1/ethernet_switch/vlan_network_interface.py b/rsd_lib/resources/v2_1/ethernet_switch/vlan_network_interface.py index 1b9d06c..b574a1a 100644 --- a/rsd_lib/resources/v2_1/ethernet_switch/vlan_network_interface.py +++ b/rsd_lib/resources/v2_1/ethernet_switch/vlan_network_interface.py @@ -26,6 +26,15 @@ from rsd_lib.resources.v2_1.ethernet_switch import schemas \ LOG = logging.getLogger(__name__) +class VLANField(base.CompositeField): + + vlan_enable = base.Field("VLANEnable", adapter=bool) + """This indicates if this VLAN is enabled.""" + + vlan_id = base.Field("VLANId") + """This indicates the VLAN identifier for this VLAN.""" + + class IntelRackScaleField(base.CompositeField): status = rsd_lib_base.StatusField("Status") diff --git a/rsd_lib/resources/v2_1/system/drive.py b/rsd_lib/resources/v2_1/system/drive.py new file mode 100644 index 0000000..a045049 --- /dev/null +++ b/rsd_lib/resources/v2_1/system/drive.py @@ -0,0 +1,250 @@ +# 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 exceptions +from sushy.resources import base +from sushy.resources import common +from sushy import utils + +from rsd_lib import base as rsd_lib_base +from rsd_lib.resources.v2_1.system import volume +from rsd_lib import utils as rsd_lib_utils + + +class IntelRackScaleField(base.CompositeField): + + erase_on_detach = base.Field("EraseOnDetach", adapter=bool) + """This indicates if drive should be erased when detached from PCI switch. + """ + + drive_erased = base.Field("DriveErased", adapter=bool) + """This indicates whether drive was cleared after assignment to composed + node. + """ + + firmware_version = base.Field("FirmwareVersion") + """This indicates drive firmware version.""" + + storage = base.Field( + "Storage", adapter=rsd_lib_utils.get_resource_identity + ) + """A reference to the storage controller where this drive is connected.""" + + pcie_function = base.Field( + "PCIeFunction", adapter=rsd_lib_utils.get_resource_identity + ) + """A reference to the PCIe function that provides this drive functionality. + """ + + +class LinksField(base.CompositeField): + + volumes = base.Field("Volumes", adapter=utils.get_members_identities) + """An array of references to the volumes contained in this drive. This + will reference Volumes that are either wholly or only partly contained + by this drive. + """ + + endpoints = base.Field("Endpoints", adapter=utils.get_members_identities) + """An array of references to the endpoints that connect to this drive.""" + + +class OemField(base.CompositeField): + + intel_rackscale = IntelRackScaleField("Intel_RackScale") + """Intel Rack Scale Design specific properties.""" + + +class ActionsField(base.CompositeField): + secure_erase = common.ActionField("#Drive.SecureErase") + + +class Drive(rsd_lib_base.ResourceBase): + """Drive resource class + + Drive contains properties describing a single physical disk drive for + any system, along with links to associated Volumes. + """ + + status_indicator = base.Field("StatusIndicator") + """The state of the status indicator, used to communicate status + information about this drive. + """ + + indicator_led = base.Field("IndicatorLED") + """The state of the indicator LED, used to identify the drive.""" + + model = base.Field("Model") + """This is the model number for the drive.""" + + revision = base.Field("Revision") + """The revision of this Drive""" + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + capacity_bytes = base.Field( + "CapacityBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size in bytes of this Drive""" + + failure_predicted = base.Field("FailurePredicted", adapter=bool) + """Is this drive currently predicting a failure in the near future""" + + protocol = base.Field("Protocol") + """The protocol this drive is using to communicate to the storage + controller + """ + + media_type = base.Field("MediaType") + """The type of media contained in this drive""" + + manufacturer = base.Field("Manufacturer") + """This is the manufacturer of this drive.""" + + sku = base.Field("SKU") + """This is the SKU for this drive.""" + + serial_number = base.Field("SerialNumber") + """The serial number for this drive.""" + + part_number = base.Field("PartNumber") + """The part number for this drive.""" + + asset_tag = base.Field("AssetTag") + """The user assigned asset tag for this drive.""" + + identifiers = rsd_lib_base.IdentifierCollectionField("Identifiers") + """The Durable names for the drive""" + + location = rsd_lib_base.LocationCollectionField("Location") + """The Location of the drive""" + + hotspare_type = base.Field("HotspareType") + """The type of hotspare this drive is currently serving as""" + + encryption_ability = base.Field("EncryptionAbility") + """The encryption abilities of this drive""" + + encryption_status = base.Field("EncryptionStatus") + """The status of the encryption of this drive""" + + rotation_speed_rpm = base.Field( + "RotationSpeedRPM", adapter=rsd_lib_utils.num_or_none + ) + """The rotation speed of this Drive in Revolutions per Minute (RPM)""" + + block_size_bytes = base.Field( + "BlockSizeBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size of the smallest addressible unit (Block) of this drive in bytes + """ + + capable_speed_gbs = base.Field( + "CapableSpeedGbs", adapter=rsd_lib_utils.num_or_none + ) + """The speed which this drive can communicate to a storage controller in + ideal conditions in Gigabits per second + """ + + negotiated_speed_gbs = base.Field( + "NegotiatedSpeedGbs", adapter=rsd_lib_utils.num_or_none + ) + """The speed which this drive is currently communicating to the storage + controller in Gigabits per second + """ + + predicted_media_life_left_percent = base.Field( + "PredictedMediaLifeLeftPercent", adapter=rsd_lib_utils.num_or_none + ) + """The percentage of reads and writes that are predicted to still be + available for the media + """ + + links = LinksField("Links") + """Contains references to other resources that are related to this + resource. + """ + + operations = volume.OperationsCollectionField("Operations") + """The operations currently running on the Drive.""" + + oem = OemField("Oem") + """Oem specific properties.""" + + _actions = ActionsField("Actions") + + def _get_secure_erase_action_element(self): + secure_erase_action = self._actions.secure_erase + + if not secure_erase_action: + raise exceptions.MissingActionError( + action="#Drive.SecureErase", resource=self._path + ) + return secure_erase_action + + def secure_erase(self): + """Secure erase the drive. + + :raises: MissingActionError, if no secure erase action exists. + """ + target_uri = self._get_secure_erase_action_element().target_uri + + self._conn.post(target_uri, data={}) + + def update(self, asset_tag=None, erase_on_detach=None, erased=None): + """Update drive properties + + :param asset_tag: The user assigned asset tag for this drive + :param erase_on_detach: Indicates if drive should be erased when + detached from Composed Node. + :param erased: Indicate whether drive was cleared after assignment to + composed node + :raises: InvalidParameterValueError if one param is incorrect + """ + + data = {} + + if asset_tag is not None: + data["AssetTag"] = asset_tag + + if erase_on_detach is not None or erased is not None: + data["Oem"] = {"Intel_RackScale": {}} + + if erase_on_detach is not None: + if not isinstance(erase_on_detach, bool): + raise exceptions.InvalidParameterValueError( + parameter="erase_on_detach", + value=erase_on_detach, + valid_values=[True, False], + ) + else: + data["Oem"]["Intel_RackScale"][ + "EraseOnDetach" + ] = erase_on_detach + + if erased is not None: + if not isinstance(erased, bool): + raise exceptions.InvalidParameterValueError( + parameter="erased", + value=erased, + valid_values=[True, False], + ) + else: + data["Oem"]["Intel_RackScale"]["DriveErased"] = erased + + self._conn.patch(self.path, data=data) diff --git a/rsd_lib/resources/v2_1/system/ethernet_interface.py b/rsd_lib/resources/v2_1/system/ethernet_interface.py index 1ea1705..b9f771e 100644 --- a/rsd_lib/resources/v2_1/system/ethernet_interface.py +++ b/rsd_lib/resources/v2_1/system/ethernet_interface.py @@ -16,184 +16,165 @@ from sushy.resources import base from sushy import utils -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base +from rsd_lib.resources.v2_1.common import ip_addresses from rsd_lib.resources.v2_1.ethernet_switch import vlan_network_interface from rsd_lib import utils as rsd_lib_utils -class IPv4AddressesField(base.ListField): - address = base.Field("Address") - """The IPv4Addresses address""" - - subnet_mask = base.Field("SubnetMask") - """The IPv4Addresses subnetmask""" - - address_origin = base.Field("AddressOrigin") - """The IPv4Addresses addressorigin""" - - gateway = base.Field("Gateway") - """The IPv4Addresses gateway""" - - -class IPv6AddressesField(base.ListField): - address = base.Field("Address") - """The IPv4Addresses address""" - - prefix_length = base.Field("PrefixLength", - adapter=rsd_lib_utils.num_or_none) - """The prefix length of IPv6 addresses""" - - address_origin = base.Field("AddressOrigin") - """The IPv4Addresses address origin""" - - address_state = base.Field("AddressState") - """The address state of IPv6 addresses""" - - -class IPv6StaticAddressesField(base.ListField): - address = base.Field("Address") - """The IPv6 static addresses""" - - prefix_length = base.Field("PrefixLength") - """The IPv6 prefix length""" - - -class IPv6AddressPolicyTableField(base.ListField): - prefix = base.Field("Prefix") - """The IPv6 Address Policy Table prefix""" - - precedence = base.Field("Precedence", adapter=rsd_lib_utils.num_or_none) - """The IPv6 Address Policy Table precedence""" - - label = base.Field("Label", adapter=rsd_lib_utils.num_or_none) - """The IPv6 Address Policy Table label""" - - -class IntelRackScaleField(base.CompositeField): - neighbor_port = base.Field("NeighborPort", - adapter=rsd_lib_utils.get_resource_identity) +class LinksIntelRackScaleField(base.CompositeField): + neighbor_port = base.Field( + "NeighborPort", adapter=rsd_lib_utils.get_resource_identity + ) """The neighbor port of Rack ScaleIntel""" -class OemField(base.CompositeField): - intel_rackScale = IntelRackScaleField("Intel_RackScale") +class LinksOemField(base.CompositeField): + intel_rackScale = LinksIntelRackScaleField("Intel_RackScale") """The Oem Intel_RackScale""" class LinksField(base.CompositeField): - oem = OemField("Oem") + + endpoints = base.Field("Endpoints", adapter=utils.get_members_identities) + """An array of references to the endpoints that connect to this ethernet + interface. + """ + + oem = LinksOemField("Oem") """"The oem of Links""" -class VLANField(base.CompositeField): - vlan_enable = base.Field("VLANEnable", adapter=bool) - """Whether the vlan is enable""" +class IPv6AddressPolicyEntryCollectionField( + rsd_lib_base.ReferenceableMemberField +): - vlan_id = base.Field("VLANId", adapter=rsd_lib_utils.num_or_none) - """The vlan id""" + prefix = base.Field("Prefix") + """The IPv6 Address Prefix (as defined in RFC 6724 section 2.1)""" + + precedence = base.Field("Precedence", adapter=rsd_lib_utils.num_or_none) + """The IPv6 Precedence (as defined in RFC 6724 section 2.1""" + + label = base.Field("Label", adapter=rsd_lib_utils.num_or_none) + """The IPv6 Label (as defined in RFC 6724 section 2.1)""" -class EthernetInterface(base.ResourceBase): - identity = base.Field('Id', required=True) - """The EthernetInterface identity string""" +class EthernetInterface(rsd_lib_base.ResourceBase): + """EthernetInterface resource class - name = base.Field('Name') - """The EthernetInterface identity string""" + This schema defines a simple ethernet NIC resource. + """ - description = base.Field('Description') - """The EthernetInterface description""" + uefi_device_path = base.Field("UefiDevicePath") + """The UEFI device path for this interface""" - status = rsd_lib_common.StatusField('Status') - """The EthernetInterface Status""" + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ interface_enabled = base.Field("InterfaceEnabled", adapter=bool) - """Whether the interface is enabled""" + """This indicates whether this interface is enabled.""" permanent_mac_address = base.Field("PermanentMACAddress") - """The EthernetInterface PermanentMACAddress""" + """This is the permanent MAC address assigned to this interface (port)""" mac_address = base.Field("MACAddress") - """The EthernetInterface MACAddress""" + """This is the currently configured MAC address of the (logical port) + interface. + """ speed_mbps = base.Field("SpeedMbps", adapter=rsd_lib_utils.num_or_none) - """The EthernetInterface SpeedMbps""" + """This is the current speed in Mbps of this interface.""" auto_neg = base.Field("AutoNeg", adapter=bool) - """Whether the EthernetInterface is AutoNeg""" + """This indicates if the speed and duplex are automatically negotiated and + configured on this interface. + """ full_duplex = base.Field("FullDuplex", adapter=bool) - """Whether the EthernetInterface is FullDuplex""" + """This indicates if the interface is in Full Duplex mode or not.""" mtu_size = base.Field("MTUSize", adapter=rsd_lib_utils.num_or_none) - """The EthernetInterface MTUSize""" + """This is the currently configured Maximum Transmission Unit (MTU) in + bytes on this interface. + """ host_name = base.Field("HostName") - """The EthernetInterface hostname""" + """The DNS Host Name, without any domain information""" fqdn = base.Field("FQDN") - """The EthernetInterface FQDN""" + """This is the complete, fully qualified domain name obtained by DNS for + this interface. + """ + + max_ipv6_static_addresses = base.Field( + "MaxIPv6StaticAddresses", adapter=rsd_lib_utils.num_or_none + ) + """This indicates the maximum number of Static IPv6 addresses that can be + configured on this interface. + """ + + vlan = vlan_network_interface.VLANField("VLAN") + """If this Network Interface supports more than one VLAN, this property + will not be present and the client should look for VLANs collection in + the link section of this resource. + """ + + ipv4_addresses = ip_addresses.IPv4AddressCollectionField("IPv4Addresses") + """The IPv4 addresses assigned to this interface""" + + ipv6_address_policy_table = IPv6AddressPolicyEntryCollectionField( + "IPv6AddressPolicyTable" + ) + """An array representing the RFC 6724 Address Selection Policy Table.""" + + ipv6_addresses = ip_addresses.IPv6AddressCollectionField("IPv6Addresses") + """This array of objects enumerates all of the currently assigned IPv6 + addresses on this interface. + """ + + ipv6_static_addresses = ip_addresses.IPv6StaticAddressCollectionField( + "IPv6StaticAddresses" + ) + """This array of objects represents all of the IPv6 static addresses to be + assigned on this interface. + """ ipv6_default_gateway = base.Field("IPv6DefaultGateway") - """The EthernetInterface IPv6DefaultGateway""" - - max_ipv6_static_addresses = base.Field("MaxIPv6StaticAddresses", - adapter=rsd_lib_utils.num_or_none) - """The EthernetInterface MaxIPv6StaticAddresses""" + """This is the IPv6 default gateway address that is currently in use on + this interface. + """ name_servers = base.Field("NameServers") - """The EthernetInterface nameservers""" + """This represents DNS name servers that are currently in use on this + interface. + """ - ipv4_addresses = IPv4AddressesField("IPv4Addresses") - """The EthernetInterface IPv4 addresses""" - - ipv6_addresses = IPv6AddressesField("IPv6Addresses") - """The EthernetInterface IPv4 addresses""" - - ipv6_static_addresses = IPv6StaticAddressesField("IPv6StaticAddresses") - """The EthernetInterface IPv6 Static Addresses""" - - ipv6_address_policy_table = IPv6AddressPolicyTableField( - "IPv6AddressPolicyTable") - """The EthernetInterface IPv6 Address Policy Table""" - - vlan = VLANField("VLAN") - """The EthernetInterface VLAN""" + link_status = base.Field("LinkStatus") + """The link status of this interface (port)""" links = LinksField("Links") - """The EthernetInterface links""" - - def _get_vlan_collection_path(self): - """Helper function to find the VLANCollection path""" - return utils.get_sub_resource_path_by(self, 'VLANs') + """Contains references to other resources that are related to this + resource. + """ @property @utils.cache_it def vlans(self): - """Property to provide reference to `VLANCollection` instance + """Property to provide reference to `VLanNetworkInterfaceCollection` instance - It is calculated once when it is queried for the first time. On - refresh, this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return vlan_network_interface.VLanNetworkInterfaceCollection( - self._conn, self._get_vlan_collection_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "VLANs"), + redfish_version=self.redfish_version, + ) -class EthernetInterfaceCollection(base.ResourceCollectionBase): +class EthernetInterfaceCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return EthernetInterface - - def __init__(self, connector, path, redfish_version=None): - """A class representing a EthernetInterface Collection - - :param connector: A Connector instance - :param path: The canonical path to the EthernetInterface collection - resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - - super(EthernetInterfaceCollection, self).__init__(connector, - path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/memory.py b/rsd_lib/resources/v2_1/system/memory.py index 84d2708..eedf7bd 100644 --- a/rsd_lib/resources/v2_1/system/memory.py +++ b/rsd_lib/resources/v2_1/system/memory.py @@ -15,122 +15,187 @@ from sushy.resources import base -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base from rsd_lib import utils as rsd_lib_utils +class IntelRackScaleField(base.CompositeField): + + voltage_volt = base.Field("VoltageVolt", adapter=rsd_lib_utils.num_or_none) + """This indicates current voltage of memory module""" + + +class OemField(base.CompositeField): + + intel_rackscale = IntelRackScaleField("Intel_RackScale") + """Intel Rack Scale Design specific properties.""" + + class MemoryLocationField(base.CompositeField): - socket = base.Field('Socket', required=int) - memory_controller = base.Field('MemoryController', required=int) - channel = base.Field('Channel', required=int) - slot = base.Field('Slot', required=int) + + socket = base.Field("Socket", adapter=rsd_lib_utils.num_or_none) + """Socket number in which Memory is connected""" + + memory_controller = base.Field( + "MemoryController", adapter=rsd_lib_utils.num_or_none + ) + """Memory controller number in which Memory is connected""" + + channel = base.Field("Channel", adapter=rsd_lib_utils.num_or_none) + """Channel number in which Memory is connected""" + + slot = base.Field("Slot", adapter=rsd_lib_utils.num_or_none) + """Slot number in which Memory is connected""" -class Memory(base.ResourceBase): +class RegionSetCollectionField(rsd_lib_base.ReferenceableMemberField): + """RegionSet field - name = base.Field('Name') - """The memory name""" + Memory memory region information. + """ - identity = base.Field('Id', required=True) - """The memory identity string""" + region_id = base.Field("RegionId") + """Unique region ID representing a specific region within the Memory""" - memory_type = base.Field('MemoryType') - """The type of memory""" + memory_classification = base.Field("MemoryClassification") + """Classification of memory occupied by the given memory region""" - memory_device_type = base.Field('MemoryDeviceType') - """The type of memory device""" + offset_mib = base.Field("OffsetMiB", adapter=rsd_lib_utils.num_or_none) + """Offset with in the Memory that corresponds to the starting of this + memory region in MiB + """ - base_module_type = base.Field('BaseModuleType') - """The type of base module""" + size_mib = base.Field("SizeMiB", adapter=rsd_lib_utils.num_or_none) + """Size of this memory region in MiB""" - memory_media = base.Field('MemoryMedia') - """The memory media""" - - capacity_mib = base.Field('CapacityMiB', adapter=rsd_lib_utils.num_or_none) - """The capacity of this memory in MiB""" - - data_width_bits = base.Field('DataWidthBits', - adapter=rsd_lib_utils.num_or_none) - """The data width bits of this memory.""" - - bus_width_bits = base.Field('BusWidthBits', - adapter=rsd_lib_utils.num_or_none) - """The bus width bits of this memory.""" - - manufacturer = base.Field('Manufacturer') - """The manufacturer of this memory""" - - serial_number = base.Field('SerialNumber') - """The serial number of this memory""" - - part_number = base.Field('PartNumber') - """The part number of this memory""" - - allowed_speeds_mhz = base.Field('AllowedSpeedsMHz') - """The allowed speeds of this memory in MHz""" - - firmware_revision = base.Field('FirmwareRevision') - """The revision of this memory firmware""" - - frirmware_api_version = base.Field('FirmwareApiVersion') - """The API revision of this memory firmware""" - - function_classes = base.Field('FunctionClasses') - """The function_classes of the memory""" - - vendor_id = base.Field('VendorID') - """The vendor identity""" - - device_id = base.Field('DeviceID') - """The device identity""" - - rank_count = base.Field('RankCount', - adapter=rsd_lib_utils.num_or_none) - """The rank count of this memory""" - - device_locator = base.Field('DeviceLocator') - """The device locator""" - - error_correction = base.Field('ErrorCorrection') - """The error correction""" - - operating_speed_mhz = base.Field('OperatingSpeedMhz', - adapter=rsd_lib_utils.num_or_none) - """The operating speed of this memory in MHz""" - - operating_memory_modes = base.Field('OperatingMemoryModes') - """The operating memory modes""" - - memory_location = MemoryLocationField('MemoryLocation') - """The location information of this memory""" - - status = rsd_lib_common.StatusField('Status') - """The memory status""" - - def __init__(self, connector, identity, redfish_version=None): - """A class representing a Memory - - :param connector: A Connector instance - :param identity: The identity of the memory - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(Memory, self).__init__(connector, identity, redfish_version) + passphrase_state = base.Field("PassphraseState", adapter=bool) + """State of the passphrase for this region""" -class MemoryCollection(base.ResourceCollectionBase): +class Memory(rsd_lib_base.ResourceBase): + """Memory resource class + This is the schema definition for definition of a Memory and its + configuration + """ + + memory_type = base.Field("MemoryType") + """The type of Memory""" + + memory_device_type = base.Field("MemoryDeviceType") + """Type details of the Memory""" + + base_module_type = base.Field("BaseModuleType") + """The base module type of Memory""" + + memory_media = base.Field("MemoryMedia") + """Media of this Memory""" + + capacity_mib = base.Field("CapacityMiB", adapter=rsd_lib_utils.num_or_none) + """Memory Capacity in MiB.""" + + data_width_bits = base.Field( + "DataWidthBits", adapter=rsd_lib_utils.num_or_none + ) + """Data Width in bits.""" + + bus_width_bits = base.Field( + "BusWidthBits", adapter=rsd_lib_utils.num_or_none + ) + """Bus Width in bits.""" + + manufacturer = base.Field("Manufacturer") + """The Memory manufacturer""" + + serial_number = base.Field("SerialNumber") + """The product serial number of this device""" + + part_number = base.Field("PartNumber") + """The product part number of this device""" + + allowed_speeds_mhz = base.Field("AllowedSpeedsMHz") + """Speed bins supported by this Memory""" + + firmware_revision = base.Field("FirmwareRevision") + """Revision of firmware on the Memory controller""" + + firmware_api_version = base.Field("FirmwareApiVersion") + """Version of API supported by the firmware""" + + function_classes = base.Field("FunctionClasses") + """Function Classes by the Memory""" + + vendor_id = base.Field("VendorID") + """Vendor ID""" + + device_id = base.Field("DeviceID") + """Device ID""" + + subsystem_vendor_id = base.Field("SubsystemVendorID") + """SubSystem Vendor ID""" + + subsystem_device_id = base.Field("SubsystemDeviceID") + """Subsystem Device ID""" + + max_tdp_milli_watts = base.Field("MaxTDPMilliWatts") + """Maximum TDPs in milli Watts""" + + spare_device_count = base.Field( + "SpareDeviceCount", adapter=rsd_lib_utils.num_or_none + ) + """Number of unused spare devices available in the Memory""" + + rank_count = base.Field("RankCount", adapter=rsd_lib_utils.num_or_none) + """Number of ranks available in the Memory""" + + device_locator = base.Field("DeviceLocator") + """Location of the Memory in the platform""" + + memory_location = MemoryLocationField("MemoryLocation") + """Memory connection information to sockets and memory controllers.""" + + error_correction = base.Field("ErrorCorrection") + """Error correction scheme supported for this memory""" + + operating_speed_mhz = base.Field( + "OperatingSpeedMhz", adapter=rsd_lib_utils.num_or_none + ) + """Operating speed of Memory in MHz""" + + volatile_region_size_limit_mib = base.Field( + "VolatileRegionSizeLimitMiB", adapter=rsd_lib_utils.num_or_none + ) + """Total size of volatile regions in MiB""" + + persistent_region_size_limit_mib = base.Field( + "PersistentRegionSizeLimitMiB", adapter=rsd_lib_utils.num_or_none + ) + """Total size of persistent regions in MiB""" + + regions = RegionSetCollectionField("Regions") + """Memory regions information within the Memory""" + + operating_memory_modes = base.Field("OperatingMemoryModes") + """Memory modes supported by the Memory""" + + is_spare_device_enabled = base.Field("IsSpareDeviceEnabled", adapter=bool) + """Spare device enabled status""" + + is_rank_spare_enabled = base.Field("IsRankSpareEnabled", adapter=bool) + """Rank spare enabled status""" + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + oem = OemField("Oem") + """Oem specific properties.""" + + # TODO(linyang): Add Action Field + + +class MemoryCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return Memory - - def __init__(self, connector, path, redfish_version=None): - """A class representing a MemoryCollection - - :param connector: A Connector instance - :param path: The canonical path to the Memory collection resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(MemoryCollection, self).__init__(connector, path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/network_device_function.py b/rsd_lib/resources/v2_1/system/network_device_function.py index c2a2699..c547c31 100644 --- a/rsd_lib/resources/v2_1/system/network_device_function.py +++ b/rsd_lib/resources/v2_1/system/network_device_function.py @@ -15,199 +15,146 @@ from sushy.resources import base -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base from rsd_lib import utils as rsd_lib_utils -class EthernetField(base.CompositeField): - macaddress = base.Field('MACAddress') - """This is the currently configured MAC address of the (logical port) - network device function - """ - - class iSCSIBootField(base.CompositeField): - ip_address_type = base.Field('IPAddressType') + + ip_address_type = base.Field("IPAddressType") """The type of IP address (IPv6 or IPv4) being populated in the iSCSIBoot - IP address fields + IP address fields. """ - initiator_ip_address = base.Field('InitiatorIPAddress') - """The IPv6 or IPv4 address of the iSCSI initiator""" + initiator_ip_address = base.Field("InitiatorIPAddress") + """The IPv6 or IPv4 address of the iSCSI initiator.""" - initiator_name = base.Field('InitiatorName') - """The value of this property shall be the iSCSI boot initiator name""" + initiator_name = base.Field("InitiatorName") + """The iSCSI initiator name.""" - initiator_default_gateway = base.Field('InitiatorDefaultGateway') - """The value of this property shall be the IPv6 or IPv4 iSCSI boot default - gateway + initiator_default_gateway = base.Field("InitiatorDefaultGateway") + """The IPv6 or IPv4 iSCSI boot default gateway.""" + + initiator_netmask = base.Field("InitiatorNetmask") + """The IPv6 or IPv4 netmask of the iSCSI boot initiator.""" + + target_info_via_dhcp = base.Field("TargetInfoViaDHCP", adapter=bool) + """Whether the iSCSI boot target name, LUN, IP address, and netmask should + be obtained from DHCP. """ - initiator_netmask = base.Field('InitiatorNetmask') - """The value of this property shall be the IPv6 or IPv4 netmask of the - iSCSI boot initiator - """ + primary_target_name = base.Field("PrimaryTargetName") + """The name of the iSCSI primary boot target.""" - target_info_via_dhcp = base.Field('TargetInfoViaDHCP', adapter=bool) - """The value of this property shall be a boolean indicating whether the - iSCSI boot target name, LUN, IP address, and netmask should be obtained - from DHCP - """ - - primary_target_name = base.Field('PrimaryTargetName') - """The value of this property shall be the name of the primary iSCSI boot - target (iSCSI Qualified Name, IQN) - """ - - primary_target_ip_address = base.Field('PrimaryTargetIPAddress') - """The value of this property shall be the IP address (IPv6 or IPv4) for - the primary iSCSI boot target - """ + primary_target_ip_address = base.Field("PrimaryTargetIPAddress") + """The IP address (IPv6 or IPv4) for the primary iSCSI boot target.""" primary_target_tcp_port = base.Field( - 'PrimaryTargetTCPPort', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the TCP port for the primary iSCSI - boot target - """ + "PrimaryTargetTCPPort", adapter=rsd_lib_utils.num_or_none + ) + """The TCP port for the primary iSCSI boot target.""" - primary_lun = base.Field('PrimaryLUN', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the logical unit number (LUN) for - the primary iSCSI boot target - """ + primary_lun = base.Field("PrimaryLUN", adapter=rsd_lib_utils.num_or_none) + """The logical unit number (LUN) for the primary iSCSI boot target.""" - primary_vlan_enable = base.Field('PrimaryVLANEnable', adapter=bool) - """The value of this property shall be used to indicate if PrimaryVLANId - is enabled for the primary iSCSI boot target - """ + primary_vlan_enable = base.Field("PrimaryVLANEnable", adapter=bool) + """This indicates if the primary VLAN is enabled.""" primary_vlan_id = base.Field( - 'PrimaryVLANId', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the 802.1q VLAN ID to use for iSCSI - boot from the primary target. This VLAN ID is only used if - PrimaryVLANEnable is true. + "PrimaryVLANId", adapter=rsd_lib_utils.num_or_none + ) + """The 802.1q VLAN ID to use for iSCSI boot from the primary target.""" + + primary_dns = base.Field("PrimaryDNS") + """The IPv6 or IPv4 address of the primary DNS server for the iSCSI boot + initiator. """ - primary_dns = base.Field('PrimaryDNS') - """The value of this property shall be the IPv6 or IPv4 address of the - primary DNS server for the iSCSI boot initiator - """ + secondary_target_name = base.Field("SecondaryTargetName") + """The name of the iSCSI secondary boot target.""" - secondary_target_name = base.Field('SecondaryTargetName') - """The value of this property shall be the name of the secondary iSCSI - boot target (iSCSI Qualified Name, IQN) - """ - - secondary_target_ip_address = base.Field('SecondaryTargetIPAddress') - """The value of this property shall be the IP address (IPv6 or IPv4) for - the secondary iSCSI boot target - """ + secondary_target_ip_address = base.Field("SecondaryTargetIPAddress") + """The IP address (IPv6 or IPv4) for the secondary iSCSI boot target.""" secondary_target_tcp_port = base.Field( - 'SecondaryTargetTCPPort', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the TCP port for the secondary - iSCSI boot target - """ + "SecondaryTargetTCPPort", adapter=rsd_lib_utils.num_or_none + ) + """The TCP port for the secondary iSCSI boot target.""" secondary_lun = base.Field( - 'SecondaryLUN', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the logical unit number (LUN) for - the secondary iSCSI boot target - """ + "SecondaryLUN", adapter=rsd_lib_utils.num_or_none + ) + """The logical unit number (LUN) for the secondary iSCSI boot target.""" - secondary_vlan_enable = base.Field('SecondaryVLANEnable', adapter=bool) - """The value of this property shall be used to indicate if this VLAN is - enabled for the secondary iSCSI boot target - """ + secondary_vlan_enable = base.Field("SecondaryVLANEnable", adapter=bool) + """This indicates if the secondary VLAN is enabled.""" secondary_vlan_id = base.Field( - 'SecondaryVLANId', adapter=rsd_lib_utils.num_or_none) - """The value of this property shall be the 802.1q VLAN ID to use for iSCSI - boot from the secondary target. This VLAN ID is only used if - SecondaryVLANEnable is true. + "SecondaryVLANId", adapter=rsd_lib_utils.num_or_none + ) + """The 802.1q VLAN ID to use for iSCSI boot from the secondary target.""" + + secondary_dns = base.Field("SecondaryDNS") + """The IPv6 or IPv4 address of the secondary DNS server for the iSCSI boot + initiator. """ - secondary_dns = base.Field('SecondaryDNS') - """The value of this property shall be the IPv6 or IPv4 address of the - secondary DNS server for the iSCSI boot initiator - """ - - ip_mask_dns_via_dhcp = base.Field('IPMaskDNSViaDHCP', adapter=bool) - """The value of this property shall be a boolean indicating whether the - iSCSI boot initiator uses DHCP to obtain the iniator name, IP address, - and netmask + ip_mask_dns_via_dhcp = base.Field("IPMaskDNSViaDHCP", adapter=bool) + """Whether the iSCSI boot initiator uses DHCP to obtain the iniator name, + IP address, and netmask. """ router_advertisement_enabled = base.Field( - 'RouterAdvertisementEnabled', adapter=bool) - """The value of this property shall be a boolean indicating whether IPv6 - router advertisement is enabled for the iSCSI boot target. This - setting shall only apply to IPv6 configurations. + "RouterAdvertisementEnabled", adapter=bool + ) + """Whether IPv6 router advertisement is enabled for the iSCSI boot target. """ - authentication_method = base.Field('AuthenticationMethod') - """The value of this property shall be the iSCSI boot authentication - method for this network device function + authentication_method = base.Field("AuthenticationMethod") + """The iSCSI boot authentication method for this network device function. """ - chap_username = base.Field('CHAPUsername') - """The value of this property shall be username for CHAP authentication""" + chap_username = base.Field("CHAPUsername") + """The username for CHAP authentication.""" - chap_secret = base.Field('CHAPSecret') - """The value of this property shall be the shared secret for CHAP - authentication - """ + chap_secret = base.Field("CHAPSecret") + """The shared secret for CHAP authentication.""" - mutual_chap_username = base.Field('MutualCHAPUsername') - """The value of this property shall be the CHAP Username for 2-way CHAP - authentication - """ + mutual_chap_username = base.Field("MutualCHAPUsername") + """The CHAP Username for 2-way CHAP authentication.""" - mutual_chap_secret = base.Field('MutualCHAPSecret') - """The value of this property shall be the CHAP Secret for 2-way CHAP - authentication + mutual_chap_secret = base.Field("MutualCHAPSecret") + """The CHAP Secret for 2-way CHAP authentication.""" + + +class EthernetField(base.CompositeField): + + mac_address = base.Field("MACAddress") + """This is the currently configured MAC address of the (logical port) + network device function. """ -class NetworkDeviceFunction(base.ResourceBase): +class NetworkDeviceFunction(rsd_lib_base.ResourceBase): + """NetworkDeviceFunction resource class - name = base.Field('Name') - """The NetworkDeviceFunction name""" - - identity = base.Field('Id', required=True) - """The NetworkDeviceFunction identity string""" - - description = base.Field('Description') - """The description of NetworkDeviceFunction""" - - device_enabled = base.Field('DeviceEnabled', adapter=bool) - """Whether the network device function is enabled""" - - ethernet = EthernetField('Ethernet') - """This object shall contain Ethernet capabilities for this network - device function + A Network Device Function represents a logical interface exposed by the + network adapter. """ - iscsi_boot = iSCSIBootField('iSCSIBoot') - """This object shall contain iSCSI boot capabilities, status, and - configuration values for this network device function + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. """ - status = rsd_lib_common.StatusField('Status') - """The NetworkDeviceFunction status""" + device_enabled = base.Field("DeviceEnabled", adapter=bool) + """Whether the network device function is enabled.""" - links = base.Field('Links') - """Links for this NetworkDeviceFunction""" + ethernet = EthernetField("Ethernet") + """Ethernet.""" - def __init__(self, connector, identity, redfish_version=None): - """A class representing a NetworkDeviceFunction - - :param connector: A Connector instance - :param identity: The identity of the NetworkDeviceFunction - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(NetworkDeviceFunction, self).__init__( - connector, identity, redfish_version) + iscsi_boot = iSCSIBootField("iSCSIBoot") + """iSCSI Boot.""" def update(self, ethernet=None, iscsi_boot=None): """Enable iSCSI boot of compute node @@ -218,27 +165,14 @@ class NetworkDeviceFunction(base.ResourceBase): """ data = {} if ethernet is not None: - data['Ethernet'] = ethernet + data["Ethernet"] = ethernet if iscsi_boot is not None: - data['iSCSIBoot'] = iscsi_boot + data["iSCSIBoot"] = iscsi_boot self._conn.patch(self.path, data=data) -class NetworkDeviceFunctionCollection(base.ResourceCollectionBase): - +class NetworkDeviceFunctionCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return NetworkDeviceFunction - - def __init__(self, connector, path, redfish_version=None): - """A class representing a NetworkDeviceFunctionCollection - - :param connector: A Connector instance - :param path: The canonical path to the NetworkDeviceFunction collection - resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(NetworkDeviceFunctionCollection, self).__init__( - connector, path, redfish_version) diff --git a/rsd_lib/resources/v2_1/system/network_interface.py b/rsd_lib/resources/v2_1/system/network_interface.py index 969cc81..37ae9a4 100644 --- a/rsd_lib/resources/v2_1/system/network_interface.py +++ b/rsd_lib/resources/v2_1/system/network_interface.py @@ -13,29 +13,24 @@ # 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 common as rsd_lib_common +from rsd_lib import base as rsd_lib_base from rsd_lib.resources.v2_1.system import network_device_function -class NetworkInterface(base.ResourceBase): +class NetworkInterface(rsd_lib_base.ResourceBase): + """NetworkInterface resource class - name = base.Field('Name') - """The NetworkDeviceFunction name""" + A NetworkInterface contains references linking NetworkDeviceFunction + resources and represents the functionality available to the containing + system. + """ - identity = base.Field('Id', required=True) - """The NetworkDeviceFunction identity string""" - - description = base.Field('Description') - """The description of NetworkDeviceFunction""" - - status = rsd_lib_common.StatusField('Status') - """The NetworkDeviceFunction status""" - - links = base.Field('Links') - """Links for this NetworkDeviceFunction""" + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ def __init__(self, connector, identity, redfish_version=None): """A class representing a NetworkInterface @@ -45,40 +40,26 @@ class NetworkInterface(base.ResourceBase): :param redfish_version: The version of RedFish. Used to construct the object according to schema of the given version. """ - super(NetworkInterface, self).__init__(connector, identity, - redfish_version) - - def _get_network_device_functions_path(self): - """Helper function to find the NetworkDeviceFunctions path""" - return utils.get_sub_resource_path_by(self, 'NetworkDeviceFunctions') + super(NetworkInterface, self).__init__( + connector, identity, redfish_version + ) @property @utils.cache_it def network_device_functions(self): - """Property to provide reference to `NetworkDeviceFunctionCollection` + """Property to provide reference to `NetworkDeviceFunctionCollection` instance - It is calculated once when it is queried for the first time. On - refresh, this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return network_device_function.NetworkDeviceFunctionCollection( - self._conn, self._get_network_device_functions_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "NetworkDeviceFunctions"), + redfish_version=self.redfish_version, + ) -class NetworkInterfaceCollection(base.ResourceCollectionBase): - +class NetworkInterfaceCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return NetworkInterface - - def __init__(self, connector, path, redfish_version=None): - """A class representing a NetworkInterfaceCollection - - :param connector: A Connector instance - :param path: The canonical path to the NetworkInterface collection - resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(NetworkInterfaceCollection, self).__init__(connector, path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/pcie_device.py b/rsd_lib/resources/v2_1/system/pcie_device.py index dc708f6..e18f2d6 100644 --- a/rsd_lib/resources/v2_1/system/pcie_device.py +++ b/rsd_lib/resources/v2_1/system/pcie_device.py @@ -16,85 +16,67 @@ from sushy.resources import base from sushy import utils -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base class LinksField(base.CompositeField): - chassis = base.Field('Chassis', adapter=utils.get_members_identities) - """The value of this property shall reference a resource of type Chassis - that represents the physical container associated with this resource. + + chassis = base.Field("Chassis", adapter=utils.get_members_identities) + """An array of references to the chassis in which the PCIe device is + contained """ pcie_functions = base.Field( - 'PCIeFunctions', adapter=utils.get_members_identities) - """The value of this property shall be a reference to the resources that - this device exposes and shall reference a resource of type PCIeFunction. + "PCIeFunctions", adapter=utils.get_members_identities + ) + """An array of references to PCIeFunctions exposed by this device.""" + + +class PCIeDevice(rsd_lib_base.ResourceBase): + """PCIeDevice resource class + + This is the schema definition for the PCIeDevice resource. It + represents the properties of a PCIeDevice attached to a System. """ + manufacturer = base.Field("Manufacturer") + """This is the manufacturer of this PCIe device.""" -class PCIeDevice(base.ResourceBase): - identity = base.Field('Id', required=True) - """The PCIe device identity string""" + model = base.Field("Model") + """This is the model number for the PCIe device.""" - name = base.Field('Name') - """The PCIe device name""" + sku = base.Field("SKU") + """This is the SKU for this PCIe device.""" - description = base.Field('Description') - """The PCIe device description""" + serial_number = base.Field("SerialNumber") + """The serial number for this PCIe device.""" - manufacturer = base.Field('Manufacturer') - """The PCIe device manufacturer""" + part_number = base.Field("PartNumber") + """The part number for this PCIe device.""" - model = base.Field('Model') - """The PCIe device Model""" + asset_tag = base.Field("AssetTag") + """The user assigned asset tag for this PCIe device.""" - sku = base.Field('SKU') - """The PCIe device stock-keeping unit""" + device_type = base.Field("DeviceType") + """The device type for this PCIe device.""" - serial_number = base.Field('SerialNumber') - """The PCIe device serial number""" + firmware_version = base.Field("FirmwareVersion") + """The version of firmware for this PCIe device.""" - part_number = base.Field('PartNumber') - """The PCIe device part number""" + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ - asset_tag = base.Field('AssetTag') - """The user assigned asset tag for this PCIe device""" + links = LinksField("Links") + """The links object contains the links to other resources that are related + to this resource. + """ - device_type = base.Field('DeviceType') - """The device type for this PCIe device""" - - firmware_version = base.Field('FirmwareVersion') - """The version of firmware for this PCIe device""" - - status = rsd_lib_common.StatusField('Status') - """The PCIe device status""" - - links = LinksField('Links') - """The link section of PCIe device""" - - def update(self, asset_tag=None): + def update(self, asset_tag): """Update AssetTag properties :param asset_tag: The user assigned asset tag for this PCIe device """ - - data = {'AssetTag': asset_tag} - + data = {"AssetTag": asset_tag} self._conn.patch(self.path, data=data) - - -class PCIeDeviceCollection(base.ResourceCollectionBase): - @property - def _resource_type(self): - return PCIeDevice - - def __init__(self, connector, path, redfish_version=None): - """A class representing a PCIeDeviceCollection - - :param connector: A Connector instance - :param path: The canonical path to the PCIeDevice collection resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(PCIeDeviceCollection, self).__init__(connector, path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/pcie_function.py b/rsd_lib/resources/v2_1/system/pcie_function.py index 72cbe65..bcf988b 100644 --- a/rsd_lib/resources/v2_1/system/pcie_function.py +++ b/rsd_lib/resources/v2_1/system/pcie_function.py @@ -16,77 +16,75 @@ from sushy.resources import base from sushy import utils -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base from rsd_lib import utils as rsd_lib_utils class LinksField(base.CompositeField): + ethernet_interfaces = base.Field( - 'EthernetInterfaces', adapter=utils.get_members_identities) - """The value of this property shall reference a resource of type - EthernetInterface that represents the network interfaces associated - with this resource. + "EthernetInterfaces", adapter=utils.get_members_identities + ) + """An array of references to the ethernet interfaces which the PCIe device + produces """ - drives = base.Field('Drives', adapter=utils.get_members_identities) - """The value of this property shall reference a resource of type Drive - that represents the storage drives associated with this resource. - """ + drives = base.Field("Drives", adapter=utils.get_members_identities) + """An array of references to the drives which the PCIe device produces""" storage_controllers = base.Field( - 'StorageControllers', adapter=utils.get_members_identities) - """The value of this property shall reference a resource of type - StorageController that represents the storage controllers associated - with this resource. + "StorageControllers", adapter=utils.get_members_identities + ) + """An array of references to the storage controllers which the PCIe device + produces """ pcie_device = base.Field( - 'PCIeDevice', adapter=rsd_lib_utils.get_resource_identity) - """The value of this property shall be a reference to the resource that - this function is a part of and shall reference a resource of - type PCIeDevice. + "PCIeDevice", adapter=rsd_lib_utils.get_resource_identity + ) + """A reference to the PCIeDevice on which this function resides.""" + + +class PCIeFunction(rsd_lib_base.ResourceBase): + """PCIeFunction resource class + + This is the schema definition for the PCIeFunction resource. It + represents the properties of a PCIeFunction attached to a System. """ + function_id = base.Field("FunctionId", adapter=rsd_lib_utils.num_or_none) + """The the PCIe Function identifier.""" -class PCIeFunction(base.ResourceBase): - identity = base.Field('Id', required=True) - """The PCIe function identity string""" + function_type = base.Field("FunctionType") + """The type of the PCIe Function.""" - name = base.Field('Name') - """The PCIe function name""" + device_class = base.Field("DeviceClass") + """The class for this PCIe Function.""" - description = base.Field('Description') - """The PCIe function description""" + device_id = base.Field("DeviceId") + """The Device ID of this PCIe function.""" - function_id = base.Field('FunctionId', adapter=rsd_lib_utils.num_or_none) - """The the PCIe Function identifier""" + vendor_id = base.Field("VendorId") + """The Vendor ID of this PCIe function.""" - function_type = base.Field('FunctionType') - """The type of the PCIe Function""" + class_code = base.Field("ClassCode") + """The Class Code of this PCIe function.""" - device_class = base.Field('DeviceClass') - """The class for this PCIe Function""" + revision_id = base.Field("RevisionId") + """The Revision ID of this PCIe function.""" - device_id = base.Field('DeviceId') - """The Device ID of this PCIe function""" + subsystem_id = base.Field("SubsystemId") + """The Subsystem ID of this PCIe function.""" - vendor_id = base.Field('VendorId') - """The Vendor ID of this PCIe function""" + subsystem_vendor_id = base.Field("SubsystemVendorId") + """The Subsystem Vendor ID of this PCIe function.""" - class_code = base.Field('ClassCode') - """The Class Code of this PCIe function""" + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ - revision_id = base.Field('RevisionId') - """The Revision ID of this PCIe function""" - - subsystem_id = base.Field('SubsystemId') - """The Subsystem ID of this PCIe function""" - - subsystem_vendor_id = base.Field('SubsystemVendorId') - """The Subsystem Vendor ID of this PCIe function""" - - status = rsd_lib_common.StatusField('Status') - """The PCIe function status""" - - links = LinksField('Links') - """The link section of PCIe function""" + links = LinksField("Links") + """The links object contains the links to other resources that are related + to this resource. + """ diff --git a/rsd_lib/resources/v2_1/system/processor.py b/rsd_lib/resources/v2_1/system/processor.py index 25981e6..b530be1 100644 --- a/rsd_lib/resources/v2_1/system/processor.py +++ b/rsd_lib/resources/v2_1/system/processor.py @@ -15,122 +15,98 @@ from sushy.resources import base -from rsd_lib import common as rsd_lib_common +from rsd_lib import base as rsd_lib_base from rsd_lib import utils as rsd_lib_utils -class ProcessorIdField(base.CompositeField): - - effective_family = base.Field('EffectiveFamily') - """The processor effective family""" - - effective_model = base.Field('EffectiveModel') - """The processor effective model""" - - identification_registers = base.Field('IdentificationRegisters') - """The processor identification registers""" - - microcode_info = base.Field('MicrocodeInfo') - """The processor microcode info""" - - step = base.Field('Step') - """The processor stepping""" - - vendor_id = base.Field('VendorId') - """The processor vendor id""" - - class IntelRackScaleField(base.CompositeField): brand = base.Field("Brand") - """This property shall represent the brand of processor""" + """This indicates processor brand""" capabilities = base.Field("Capabilities") - """This property shall represent array of processor capabilities - (like reported in /proc/cpuinfo flags) + """This indicates array of processor capabilities""" + + +class ProcessorIdField(base.CompositeField): + + vendor_id = base.Field("VendorId") + """The Vendor Identification for this processor""" + + identification_registers = base.Field("IdentificationRegisters") + """The contents of the Identification Registers (CPUID) for this processor """ + effective_family = base.Field("EffectiveFamily") + """The effective Family for this processor""" + + effective_model = base.Field("EffectiveModel") + """The effective Model for this processor""" + + step = base.Field("Step") + """The Step value for this processor""" + + microcode_info = base.Field("MicrocodeInfo") + """The Microcode Information for this processor""" + class OemField(base.CompositeField): intel_rackscale = IntelRackScaleField("Intel_RackScale") - """Intel Rack Scale Design extensions ("Intel_RackScale" object)""" + """Intel Rack Scale Design specific properties.""" -class Processor(base.ResourceBase): +class Processor(rsd_lib_base.ResourceBase): + """Processor resource class - identity = base.Field('Id', required=True) - """The processor identity string""" + This is the schema definition for the Processor resource. It + represents the properties of a processor attached to a System. + """ - name = base.Field('Name') - """The processor name string""" - - description = base.Field('Description') - """The processor description string""" - - socket = base.Field('Socket') + socket = base.Field("Socket") """The socket or location of the processor""" - processor_type = base.Field('ProcessorType') + processor_type = base.Field("ProcessorType") """The type of processor""" - processor_architecture = base.Field('ProcessorArchitecture') + processor_architecture = base.Field("ProcessorArchitecture") """The architecture of the processor""" - instruction_set = base.Field('InstructionSet') + instruction_set = base.Field("InstructionSet") """The instruction set of the processor""" - manufacturer = base.Field('Manufacturer') + processor_id = ProcessorIdField("ProcessorId") + """Identification information for this processor.""" + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + manufacturer = base.Field("Manufacturer") """The processor manufacturer""" - model = base.Field('Model') + model = base.Field("Model") """The product model number of this device""" max_speed_mhz = base.Field( - 'MaxSpeedMHz', adapter=rsd_lib_utils.num_or_none) - """The maximum clock speed of the processor in MHz.""" + "MaxSpeedMHz", adapter=rsd_lib_utils.num_or_none + ) + """The maximum clock speed of the processor""" - processor_id = ProcessorIdField('ProcessorId') - """The processor id""" - - status = rsd_lib_common.StatusField('Status') - """The processor status""" - - total_cores = base.Field( - 'TotalCores', adapter=rsd_lib_utils.num_or_none) + total_cores = base.Field("TotalCores", adapter=rsd_lib_utils.num_or_none) """The total number of cores contained in this processor""" total_threads = base.Field( - 'TotalThreads', adapter=rsd_lib_utils.num_or_none) + "TotalThreads", adapter=rsd_lib_utils.num_or_none + ) """The total number of execution threads supported by this processor""" oem = OemField("Oem") - """Oem extension object""" - - def __init__(self, connector, identity, redfish_version=None): - """A class representing a Processor - - :param connector: A Connector instance - :param identity: The identity of the processor - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(Processor, self).__init__(connector, identity, redfish_version) + """Oem specific properties.""" -class ProcessorCollection(base.ResourceCollectionBase): - +class ProcessorCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return Processor - - def __init__(self, connector, path, redfish_version=None): - """A class representing a ProcessorCollection - - :param connector: A Connector instance - :param path: The canonical path to the Processor collection resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(ProcessorCollection, self).__init__(connector, path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/simple_storage.py b/rsd_lib/resources/v2_1/system/simple_storage.py new file mode 100644 index 0000000..e65103a --- /dev/null +++ b/rsd_lib/resources/v2_1/system/simple_storage.py @@ -0,0 +1,67 @@ +# 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.resources import base + +from rsd_lib import base as rsd_lib_base +from rsd_lib import utils as rsd_lib_utils + + +class DeviceCollectionField(rsd_lib_base.ReferenceableMemberField): + + name = base.Field("Name") + """The name of the resource or array element.""" + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + manufacturer = base.Field("Manufacturer") + """The name of the manufacturer of this device""" + + model = base.Field("Model") + """The product model number of this device""" + + capacity_bytes = base.Field( + "CapacityBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size of the storage device.""" + + +class SimpleStorage(rsd_lib_base.ResourceBase): + """SimpleStorage resource class + + This is the schema definition for the Simple Storage resource. It + represents the properties of a storage controller and its + directly-attached devices. + """ + + uefi_device_path = base.Field("UefiDevicePath") + """The UEFI device path used to access this storage controller.""" + + devices = DeviceCollectionField("Devices") + """The storage devices associated with this resource""" + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + +class SimpleStorageCollection(rsd_lib_base.ResourceCollectionBase): + @property + def _resource_type(self): + return SimpleStorage diff --git a/rsd_lib/resources/v2_1/system/storage.py b/rsd_lib/resources/v2_1/system/storage.py new file mode 100644 index 0000000..d88f571 --- /dev/null +++ b/rsd_lib/resources/v2_1/system/storage.py @@ -0,0 +1,159 @@ +# Copyright 2018 99cloud, 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_1.common import redundancy +from rsd_lib.resources.v2_1.system import drive +from rsd_lib.resources.v2_1.system import volume +from rsd_lib import utils as rsd_lib_utils + + +class StorageControllerLinksField(base.CompositeField): + + endpoints = base.Field("Endpoints", adapter=utils.get_members_identities) + """An array of references to the endpoints that connect to this controller. + """ + + +class LinksField(base.CompositeField): + + enclosures = base.Field("Enclosures", adapter=utils.get_members_identities) + """An array of references to the chassis to which this storage subsystem + is attached + """ + + +class StorageControllerCollectionField(rsd_lib_base.ReferenceableMemberField): + """StorageController field + + This schema defines a storage controller and its respective properties. + A storage controller represents a storage device (physical or virtual) + that produces Volumes. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + speed_gbps = base.Field("SpeedGbps", adapter=rsd_lib_utils.num_or_none) + """The speed of the storage controller interface.""" + + firmware_version = base.Field("FirmwareVersion") + """The firmware version of this storage Controller""" + + manufacturer = base.Field("Manufacturer") + """This is the manufacturer of this storage controller.""" + + model = base.Field("Model") + """This is the model number for the storage controller.""" + + sku = base.Field("SKU") + """This is the SKU for this storage controller.""" + + serial_number = base.Field("SerialNumber") + """The serial number for this storage controller.""" + + part_number = base.Field("PartNumber") + """The part number for this storage controller.""" + + asset_tag = base.Field("AssetTag") + """The user assigned asset tag for this storage controller.""" + + supported_controller_protocols = base.Field("SupportedControllerProtocols") + """This represents the protocols by which this storage controller can be + communicated to. + """ + + supported_device_protocols = base.Field("SupportedDeviceProtocols") + """This represents the protocols which the storage controller can use to + communicate with attached devices. + """ + + identifiers = rsd_lib_base.IdentifierCollectionField("Identifiers") + """The Durable names for the storage controller""" + + links = StorageControllerLinksField("Links") + """Contains references to other resources that are related to this + resource. + """ + + +class Storage(rsd_lib_base.ResourceBase): + """Storage resource class + + This schema defines a storage subsystem and its respective properties. + A storage subsystem represents a set of storage controllers (physical + or virtual) and the resources such as volumes that can be accessed from + that subsystem. + """ + + links = LinksField("Links") + """Contains references to other resources that are related to this + resource. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + storage_controllers = StorageControllerCollectionField( + "StorageControllers" + ) + """The set of storage controllers represented by this resource.""" + + redundancy = redundancy.RedundancyCollectionField("Redundancy") + """Redundancy information for the storage subsystem""" + + # TODO(linyang): Add Action Field + + @property + @utils.cache_it + def drives(self): + """Property to provide a list of `Drive` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return [ + drive.Drive(self._conn, path, redfish_version=self.redfish_version) + for path in rsd_lib_utils.get_sub_resource_path_list_by( + self, "Drives" + ) + ] + + @property + @utils.cache_it + def volumes(self): + """Property to provide reference to `VolumeCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return volume.VolumeCollection( + self._conn, + utils.get_sub_resource_path_by(self, "Volumes"), + redfish_version=self.redfish_version, + ) + + +class StorageCollection(rsd_lib_base.ResourceCollectionBase): + @property + def _resource_type(self): + return Storage diff --git a/rsd_lib/resources/v2_1/system/storage_subsystem.py b/rsd_lib/resources/v2_1/system/storage_subsystem.py deleted file mode 100644 index 295d44a..0000000 --- a/rsd_lib/resources/v2_1/system/storage_subsystem.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2018 99cloud, 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 common as rsd_lib_common -from rsd_lib import utils as rsd_lib_utils - - -class IdentifiersField(base.ListField): - durable_name = base.Field('DurableName') - durable_name_format = base.Field('DurableNameFormat') - - -class StorageControllersField(base.ListField): - member_id = base.Field('MemberId') - status = rsd_lib_common.StatusField('Status') - manufacturer = base.Field('Manufacturer') - model = base.Field('Model') - sku = base.Field('SKU') - serial_number = base.Field('SerialNumber') - part_number = base.Field('PartNumber') - asset_tag = base.Field('AssetTag') - speed_gbps = base.Field('SpeedGbps', adapter=rsd_lib_utils.num_or_none) - firmware_version = base.Field('FirmwareVersion') - supported_controller_protocols = base.Field( - 'SupportedControllerProtocols') - supported_device_protocols = base.Field( - 'SupportedDeviceProtocols') - identifiers = IdentifiersField('Identifiers') - - -class StorageSubsystem(base.ResourceBase): - - name = base.Field('Name') - """The storage subsystem name""" - - identity = base.Field('Id', required=True) - """The storage subsystem identity string""" - - description = base.Field('Description') - """The storage subsystem description""" - - status = rsd_lib_common.StatusField('Status') - """The storage subsystem status""" - - storage_controllers = StorageControllersField('StorageControllers') - """The storage subsystem controllers""" - - drives = base.Field('Drives', adapter=utils.get_members_identities) - """The storage subsystem drives""" - - volumes = base.Field('Volumes', - adapter=rsd_lib_utils.get_resource_identity) - """The storage subsystem volumes""" - - def __init__(self, connector, identity, redfish_version=None): - """A class representing a Storage Subsystem - - :param connector: A Connector instance - :param identity: The identity of the storage subsystem - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(StorageSubsystem, self).__init__(connector, - identity, - redfish_version) - - -class StorageSubsystemCollection(base.ResourceCollectionBase): - - @property - def _resource_type(self): - return StorageSubsystem - - def __init__(self, connector, path, redfish_version=None): - """A class representing a StorageSubsystemCollection - - :param connector: A Connector instance - :param path: The canonical path to the storage subsystem collection - resource - :param redfish_version: The version of RedFish. Used to construct - the object according to schema of the given version. - """ - super(StorageSubsystemCollection, self).__init__(connector, - path, - redfish_version) diff --git a/rsd_lib/resources/v2_1/system/system.py b/rsd_lib/resources/v2_1/system/system.py index 11fca48..2739343 100644 --- a/rsd_lib/resources/v2_1/system/system.py +++ b/rsd_lib/resources/v2_1/system/system.py @@ -13,135 +13,516 @@ # License for the specific language governing permissions and limitations # under the License. -from sushy.resources.system import system +import logging + +from sushy import exceptions +from sushy.resources import base +from sushy.resources import common from sushy import utils +from rsd_lib import base as rsd_lib_base +from rsd_lib import constants +from rsd_lib.resources.v2_1.chassis import log_service 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 processor -from rsd_lib.resources.v2_1.system import storage_subsystem +from rsd_lib.resources.v2_1.system import simple_storage +from rsd_lib.resources.v2_1.system import storage from rsd_lib import utils as rsd_lib_utils -class System(system.System): +LOG = logging.getLogger(__name__) - def _get_processor_collection_path(self): - """Helper function to find the ProcessorCollection path""" - return utils.get_sub_resource_path_by(self, 'Processors') + +class ProcessorSummaryField(base.CompositeField): + """ProcessorSummary field + + This object describes the central processors of the system in general + detail. + """ + + count = base.Field("Count", adapter=rsd_lib_utils.num_or_none) + """The number of processors in the system.""" + + model = base.Field("Model") + """The processor model for the primary or majority of processors in this + system. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + +class LinksField(base.CompositeField): + + chassis = base.Field("Chassis", adapter=utils.get_members_identities) + """An array of references to the chassis in which this system is contained + """ + + managed_by = base.Field("ManagedBy", adapter=utils.get_members_identities) + """An array of references to the Managers responsible for this system""" + + powered_by = base.Field("PoweredBy", adapter=utils.get_members_identities) + """An array of ID[s] of resources that power this computer system. + Normally the ID will be a chassis or a specific set of powerSupplies + """ + + cooled_by = base.Field("CooledBy", adapter=utils.get_members_identities) + """An array of ID[s] of resources that cool this computer system. Normally + the ID will be a chassis or a specific set of fans. + """ + + endpoints = base.Field("Endpoints", adapter=utils.get_members_identities) + """An array of references to the endpoints that connect to this system.""" + + +class BootField(base.CompositeField): + """Boot field + + This object contains the boot information for the current resource. + """ + + boot_source_override_target = base.Field("BootSourceOverrideTarget") + """The current boot source to be used at next boot instead of the normal + boot device, if BootSourceOverrideEnabled is true. + """ + + boot_source_override_target_allowed_values = base.Field( + "BootSourceOverrideTarget@Redfish.AllowableValues" + ) + + boot_source_override_enabled = base.Field("BootSourceOverrideEnabled") + """Describes the state of the Boot Source Override feature""" + + uefi_target_boot_source_override = base.Field( + "UefiTargetBootSourceOverride" + ) + """This property is the UEFI Device Path of the device to boot from when + BootSourceOverrideSupported is UefiTarget. + """ + + boot_source_override_mode = base.Field("BootSourceOverrideMode") + """The BIOS Boot Mode (either Legacy or UEFI) to be used when + BootSourceOverrideTarget boot source is booted from. + """ + + boot_source_override_mode_allowed_values = base.Field( + "BootSourceOverrideMode@Redfish.AllowableValues" + ) + + +class MemorySummaryField(base.CompositeField): + """MemorySummary field + + This object describes the memory of the system in general detail. + """ + + total_system_memory_gib = base.Field( + "TotalSystemMemoryGiB", adapter=rsd_lib_utils.num_or_none + ) + """The total installed, operating system-accessible memory (RAM), measured + in GiB. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + +class PciDeviceCollectionField(rsd_lib_base.ReferenceableMemberField): + + vendor_id = base.Field("VendorId") + + device_id = base.Field("DeviceId") + + +class IntelRackScaleField(base.CompositeField): + + pcie_connection_id = base.Field("PCIeConnectionId") + """This property is an array of IDs of cable or cables connected to this + port. + """ + + pci_devices = PciDeviceCollectionField("PciDevices") + """This indicates array of PCI devices present in computer system""" + + discovery_state = base.Field("DiscoveryState") + """This indicates computer system discovery state""" + + processor_sockets = base.Field( + "ProcessorSockets", adapter=rsd_lib_utils.num_or_none + ) + """This indicates number of processor sockets available in system""" + + memory_sockets = base.Field( + "MemorySockets", adapter=rsd_lib_utils.num_or_none + ) + """This indicates number of memory sockets available in system""" + + +class OemField(base.CompositeField): + + intel_rackscale = IntelRackScaleField("Intel_RackScale") + """Intel Rack Scale Design specific properties.""" + + +class ActionsField(base.CompositeField): + reset = common.ResetActionField("#ComputerSystem.Reset") + + +class System(rsd_lib_base.ResourceBase): + """ComputerSystem resource class + + This schema defines a computer system and its respective properties. A + computer system represents a machine (physical or virtual) and the + local resources such as memory, cpu and other devices that can be + accessed from that machine. + """ + + system_type = base.Field("SystemType") + """The type of computer system represented by this resource.""" + + links = LinksField("Links") + """Contains references to other resources that are related to this + resource. + """ + + asset_tag = base.Field("AssetTag") + """The user definable tag that can be used to track this computer system + for inventory or other client purposes + """ + + manufacturer = base.Field("Manufacturer") + """The manufacturer or OEM of this system.""" + + model = base.Field("Model") + """The model number for this system""" + + sku = base.Field("SKU") + """The manufacturer SKU for this system""" + + serial_number = base.Field("SerialNumber") + """The serial number for this system""" + + part_number = base.Field("PartNumber") + """The part number for this system""" + + uuid = base.Field("UUID") + """The universal unique identifier (UUID) for this system""" + + host_name = base.Field("HostName") + """The DNS Host Name, without any domain information""" + + indicator_led = base.Field("IndicatorLED") + """The state of the indicator LED, used to identify the system""" + + power_state = base.Field("PowerState") + """This is the current power state of the system""" + + boot = BootField("Boot") + """Information about the boot settings for this system""" + + bios_version = base.Field("BiosVersion") + """The version of the system BIOS or primary system firmware.""" + + processor_summary = ProcessorSummaryField("ProcessorSummary") + """This object describes the central processors of the system in general + detail. + """ + + memory_summary = MemorySummaryField("MemorySummary") + """This object describes the central memory of the system in general + detail. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + hosting_roles = base.Field("HostingRoles") + """The hosing roles that this computer system supports.""" + + oem = OemField("Oem") + """Oem specific properties.""" + + _actions = ActionsField("Actions", required=True) + + def _get_reset_action_element(self): + reset_action = self._actions.reset + + if not reset_action: + raise exceptions.MissingActionError( + action="#ComputerSystem.Reset", resource=self._path + ) + return reset_action + + def get_allowed_reset_system_values(self): + """Get the allowed values for resetting the system. + + :returns: A set with the allowed values. + """ + reset_action = self._get_reset_action_element() + + if not reset_action.allowed_values: + LOG.warning( + "Could not figure out the allowed values for the " + "reset system action for System %s", + self.identity, + ) + return set(constants.RESET_TYPE_VALUE) + + return set(constants.RESET_TYPE_VALUE).intersection( + reset_action.allowed_values + ) + + def reset_system(self, value): + """Reset the system. + + :param value: The target value. + :raises: InvalidParameterValueError, if the target value is not + allowed. + """ + valid_resets = self.get_allowed_reset_system_values() + if value not in valid_resets: + raise exceptions.InvalidParameterValueError( + parameter="value", value=value, valid_values=valid_resets + ) + + target_uri = self._get_reset_action_element().target_uri + + self._conn.post(target_uri, data={"ResetType": value}) + + def get_allowed_system_boot_source_values(self): + """Get the allowed values for changing the boot source. + + :returns: A set with the allowed values. + """ + if not self.boot.boot_source_override_target_allowed_values: + LOG.warning( + "Could not figure out the allowed values for " + "configuring the boot source for System %s", + self.identity, + ) + return set(constants.BOOT_SOURCE_TARGET_VALUE) + + return set(constants.BOOT_SOURCE_TARGET_VALUE).intersection( + self.boot.boot_source_override_target_allowed_values + ) + + def get_allowed_system_boot_mode_values(self): + """Get the allowed values for the boot source mode. + + :returns: A set with the allowed values. + """ + if not self.boot.boot_source_override_mode_allowed_values: + LOG.warning( + "Could not figure out the allowed values for " + "configuring the boot mode for System %s", + self.identity, + ) + return set(constants.BOOT_SOURCE_MODE_VALUE) + + return set(constants.BOOT_SOURCE_MODE_VALUE).intersection( + self.boot.boot_source_override_mode_allowed_values + ) + + def set_system_boot_source(self, target, enabled="Once", mode=None): + """Set the boot source. + + Set the boot source to use on next reboot of the System. + + :param target: The target boot source. + :param enabled: The frequency, whether to set it for the next + reboot only (BOOT_SOURCE_ENABLED_ONCE) or persistent to all + future reboots (BOOT_SOURCE_ENABLED_CONTINUOUS) or disabled + (BOOT_SOURCE_ENABLED_DISABLED). + :param mode: The boot mode, UEFI (BOOT_SOURCE_MODE_UEFI) or + BIOS (BOOT_SOURCE_MODE_BIOS). + :raises: InvalidParameterValueError, if any information passed is + invalid. + """ + valid_targets = self.get_allowed_system_boot_source_values() + if target not in valid_targets: + raise exceptions.InvalidParameterValueError( + parameter="target", value=target, valid_values=valid_targets + ) + + if enabled not in constants.BOOT_SOURCE_ENABLED_VALUE: + raise exceptions.InvalidParameterValueError( + parameter="enabled", + value=enabled, + valid_values=constants.BOOT_SOURCE_ENABLED_VALUE, + ) + + data = { + "Boot": { + "BootSourceOverrideTarget": target, + "BootSourceOverrideEnabled": enabled, + } + } + + if mode is not None: + valid_modes = self.get_allowed_system_boot_mode_values() + if mode not in valid_modes: + raise exceptions.InvalidParameterValueError( + parameter="mode", value=mode, valid_values=valid_modes + ) + + data["Boot"]["BootSourceOverrideMode"] = mode + + self._conn.patch(self.path, data=data) + + def update(self, asset_tag): + """Update AssetTag + + :param asset_tag: The user assigned asset tag for this computer system + """ + + data = {"AssetTag": asset_tag} + + self._conn.patch(self.path, data=data) @property @utils.cache_it def processors(self): - """Property to reference `ProcessorCollection` instance + """Property to provide reference to `ProcessorCollection` instance - It is set once when the first time it is queried. On refresh, - this property is marked as stale (greedy-refresh not done). - Here the actual refresh of the sub-resource happens, if stale. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return processor.ProcessorCollection( - self._conn, self._get_processor_collection_path(), - redfish_version=self.redfish_version) - - def _get_memory_collection_path(self): - """Helper function to find the memory path""" - return utils.get_sub_resource_path_by(self, 'Memory') - - @property - @utils.cache_it - def memory(self): - """Property to provide reference to `Metrics` instance - - It is calculated once the first time it is queried. On refresh, - this property is reset. - """ - return memory.MemoryCollection( - self._conn, self._get_memory_collection_path(), - redfish_version=self.redfish_version) - - def _get_storage_subsystem_collection_path(self): - """Helper function to find the storage subsystem path""" - return utils.get_sub_resource_path_by(self, 'Storage') - - @property - @utils.cache_it - def storage_subsystem(self): - """Property to provide reference to `StorageSubsystem` instance - - It is calculated once the first time it is queried. On refresh, - this property is reset. - """ - return storage_subsystem.StorageSubsystemCollection( - self._conn, self._get_storage_subsystem_collection_path(), - redfish_version=self.redfish_version) - - def _get_ethernet_interfaces_collection_path(self): - """Helper function to find the ethernet interfaces path""" - return utils.get_sub_resource_path_by(self, 'EthernetInterfaces') + self._conn, + utils.get_sub_resource_path_by(self, "Processors"), + redfish_version=self.redfish_version, + ) @property @utils.cache_it def ethernet_interfaces(self): - """Property to provide reference to `EthernetInterfaceCollection` + """Property to provide reference to `EthernetInterfaceCollection` instance - It is calculated once the first time it is queried. On refresh, - this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return ethernet_interface.EthernetInterfaceCollection( - self._conn, self._get_ethernet_interfaces_collection_path(), - redfish_version=self.redfish_version) - - def _get_network_interfaces_collection_path(self): - """Helper function to find the network interfaces path""" - return utils.get_sub_resource_path_by(self, 'NetworkInterfaces') + self._conn, + utils.get_sub_resource_path_by(self, "EthernetInterfaces"), + redfish_version=self.redfish_version, + ) @property @utils.cache_it - def network_interfaces(self): - """Property to provide reference to `NetworkInterfaceCollection` + def simple_storage(self): + """Property to provide reference to `SimpleStorageCollection` instance - It is calculated once the first time it is queried. On refresh, - this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ - return network_interface.NetworkInterfaceCollection( - self._conn, self._get_network_interfaces_collection_path(), - redfish_version=self.redfish_version) + return simple_storage.SimpleStorageCollection( + self._conn, + utils.get_sub_resource_path_by(self, "SimpleStorage"), + redfish_version=self.redfish_version, + ) + + @property + @utils.cache_it + def log_services(self): + """Property to provide reference to `LogServiceCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return log_service.LogServiceCollection( + self._conn, + utils.get_sub_resource_path_by(self, "LogServices"), + redfish_version=self.redfish_version, + ) + + @property + @utils.cache_it + def memory(self): + """Property to provide reference to `MemoryCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return memory.MemoryCollection( + self._conn, + utils.get_sub_resource_path_by(self, "Memory"), + redfish_version=self.redfish_version, + ) + + @property + @utils.cache_it + def storage(self): + """Property to provide reference to `StorageCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return storage.StorageCollection( + self._conn, + utils.get_sub_resource_path_by(self, "Storage"), + redfish_version=self.redfish_version, + ) @property @utils.cache_it def pcie_devices(self): - """Property to provide reference to a list of `PCIeDevice` instances + """Property to provide a list of `PCIeDevice` instance - It is calculated once when it is queried for the first time. On - refresh, this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ - pcie_device_paths = rsd_lib_utils.get_sub_resource_path_list_by( - self, 'PCIeDevices') return [ pcie_device.PCIeDevice( self._conn, path, redfish_version=self.redfish_version - ) for path in pcie_device_paths] + ) + for path in rsd_lib_utils.get_sub_resource_path_list_by( + self, "PCIeDevices" + ) + ] @property @utils.cache_it def pcie_functions(self): - """Property to provide reference to a list of `PCIeFunction` instances + """Property to provide a list of `PCIeFunction` instance - It is calculated once when it is queried for the first time. On - refresh, this property is reset. + 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] + ) + for path in rsd_lib_utils.get_sub_resource_path_list_by( + self, "PCIeFunctions" + ) + ] + + @property + @utils.cache_it + def network_interfaces(self): + """Property to provide reference to `NetworkInterfaceCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return network_interface.NetworkInterfaceCollection( + self._conn, + utils.get_sub_resource_path_by(self, "NetworkInterfaces"), + redfish_version=self.redfish_version, + ) -class SystemCollection(system.SystemCollection): - +class SystemCollection(rsd_lib_base.ResourceCollectionBase): @property def _resource_type(self): return System diff --git a/rsd_lib/resources/v2_1/system/volume.py b/rsd_lib/resources/v2_1/system/volume.py new file mode 100644 index 0000000..3827a56 --- /dev/null +++ b/rsd_lib/resources/v2_1/system/volume.py @@ -0,0 +1,103 @@ +# 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.resources import base +from sushy import utils + +from rsd_lib import base as rsd_lib_base +from rsd_lib import utils as rsd_lib_utils + + +class LinksField(base.CompositeField): + + drives = base.Field("Drives", adapter=utils.get_members_identities) + """An array of references to the drives which contain this volume. This + will reference Drives that either wholly or only partly contain this + volume. + """ + + +class OperationsCollectionField(rsd_lib_base.ReferenceableMemberField): + + operation_name = base.Field("OperationName") + """The name of the operation.""" + + percentage_complete = base.Field( + "PercentageComplete", adapter=rsd_lib_utils.num_or_none + ) + """The percentage of the operation that has been completed.""" + + associated_task = base.Field( + "AssociatedTask", adapter=rsd_lib_utils.get_resource_identity + ) + """A reference to the task associated with the operation if any.""" + + +class Volume(rsd_lib_base.ResourceBase): + """Volume resource class + + Volume contains properties used to describe a volume, virtual disk, + LUN, or other logical storage entity for any system. + """ + + status = rsd_lib_base.StatusField("Status") + """This indicates the known state of the resource, such as if it is + enabled. + """ + + capacity_bytes = base.Field( + "CapacityBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size in bytes of this Volume""" + + volume_type = base.Field("VolumeType") + """The type of this volume""" + + encrypted = base.Field("Encrypted", adapter=bool) + """Is this Volume encrypted""" + + encryption_types = base.Field("EncryptionTypes") + """The types of encryption used by this Volume""" + + identifiers = rsd_lib_base.IdentifierCollectionField("Identifiers") + """The Durable names for the volume""" + + block_size_bytes = base.Field( + "BlockSizeBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size of the smallest addressible unit (Block) of this volume in + bytes + """ + + operations = OperationsCollectionField("Operations") + """The operations currently running on the Volume""" + + optimum_io_size_bytes = base.Field( + "OptimumIOSizeBytes", adapter=rsd_lib_utils.num_or_none + ) + """The size in bytes of this Volume's optimum IO size.""" + + links = LinksField("Links") + """Contains references to other resources that are related to this + resource. + """ + + # TODO(linyang): Add Action Field + + +class VolumeCollection(rsd_lib_base.ResourceCollectionBase): + @property + def _resource_type(self): + return Volume diff --git a/rsd_lib/resources/v2_2/system/system.py b/rsd_lib/resources/v2_2/system/system.py index 45de632..6697872 100644 --- a/rsd_lib/resources/v2_2/system/system.py +++ b/rsd_lib/resources/v2_2/system/system.py @@ -45,24 +45,28 @@ class System(system.System): 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. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return processor.ProcessorCollection( - self._conn, self._get_processor_collection_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "Processors"), + redfish_version=self.redfish_version, + ) @property @utils.cache_it def memory(self): - """Property to provide reference to `Memory` instance + """Property to provide reference to `MemoryCollection` instance - It is calculated once the first time it is queried. On refresh, - this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return memory.MemoryCollection( - self._conn, self._get_memory_collection_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "Memory"), + redfish_version=self.redfish_version, + ) class SystemCollection(system.SystemCollection): diff --git a/rsd_lib/resources/v2_3/system/system.py b/rsd_lib/resources/v2_3/system/system.py index 9844f57..24bd54c 100644 --- a/rsd_lib/resources/v2_3/system/system.py +++ b/rsd_lib/resources/v2_3/system/system.py @@ -24,14 +24,16 @@ class System(system.System): @property @utils.cache_it def ethernet_interfaces(self): - """Property to provide reference to `EthernetInterfaceCollection` + """Property to provide reference to `EthernetInterfaceCollection` instance - It is calculated once the first time it is queried. On refresh, - this property is reset. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return ethernet_interface.EthernetInterfaceCollection( - self._conn, self._get_ethernet_interfaces_collection_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "EthernetInterfaces"), + redfish_version=self.redfish_version, + ) class SystemCollection(system.SystemCollection): diff --git a/rsd_lib/resources/v2_4/system/system.py b/rsd_lib/resources/v2_4/system/system.py index a5b80b7..633d1a7 100644 --- a/rsd_lib/resources/v2_4/system/system.py +++ b/rsd_lib/resources/v2_4/system/system.py @@ -26,12 +26,14 @@ class System(system.System): 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. + It is calculated once when it is queried for the first time. On + refresh, this property is reset. """ return processor.ProcessorCollection( - self._conn, self._get_processor_collection_path(), - redfish_version=self.redfish_version) + self._conn, + utils.get_sub_resource_path_by(self, "Processors"), + redfish_version=self.redfish_version, + ) class SystemCollection(system.SystemCollection): diff --git a/rsd_lib/tests/unit/json_samples/v2_1/drive.json b/rsd_lib/tests/unit/json_samples/v2_1/drive.json new file mode 100644 index 0000000..6a73885 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_1/drive.json @@ -0,0 +1,69 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Chassis/Members/Drives/Members/$entity", + "@odata.id": "/redfish/v1/Chassis/Blade1/Drives/1", + "@odata.type": "#Drive.v1_1_1.Drive", + "Id": "1", + "IndicatorLED": "Lit", + "Model": "Drive Model string", + "Status": { + "State": "Enabled", + "Health": "OK" + }, + "CapacityBytes": 899527000000, + "Protocol": "SATA", + "MediaType": "SSD", + "Manufacturer": "Intel", + "SerialNumber": "72D0A037FRD27", + "PartNumber": "SG0GP8811253178M02GJA00", + "SKU": "SKU version", + "StatusIndicator": "OK", + "Revision": "revision string", + "FailurePredicted": false, + "AssetTag": null, + "CapableSpeedGbs": 6, + "NegotiatedSpeedGbs": 6, + "Location": [ + { + "Info": "4", + "InfoFormat": "Hdd index" + } + ], + "Identifiers": [ + { + "DurableName": "123e4567-e89b-12d3-a456-426655440000", + "DurableNameFormat": "UUID" + } + ], + "HotspareType": null, + "EncryptionAbility": null, + "EncryptionStatus": null, + "RotationSpeedRPM": null, + "BlockSizeBytes": null, + "PredictedMediaLifeLeftPercent": null, + "Links": { + "@odata.type": "#Drive.v1_1_0.Links", + "Volumes": [], + "Endpoints": [], + "Oem": { + } + }, + "Actions": { + "#Drive.SecureErase": { + "target": "/redfish/v1/Chassis/Blade1/Drives/1/Actions/Drive.SecureErase" + } + }, + "Oem": { + "Intel_RackScale": { + "@odata.type": "#Intel.Oem.Drive", + "EraseOnDetach": null, + "FirmwareVersion": "1.17", + "DriveErased": true, + "Storage": { + "@odata.id": "/redfish/v1/Systems/1/Storage/NVMe" + }, + "PCIeFunction": { + "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1" + } + } + } +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_1/storage_subsystem.json b/rsd_lib/tests/unit/json_samples/v2_1/storage.json similarity index 100% rename from rsd_lib/tests/unit/json_samples/v2_1/storage_subsystem.json rename to rsd_lib/tests/unit/json_samples/v2_1/storage.json diff --git a/rsd_lib/tests/unit/json_samples/v2_1/storage_subsystem_collection.json b/rsd_lib/tests/unit/json_samples/v2_1/storage_collection.json similarity index 100% rename from rsd_lib/tests/unit/json_samples/v2_1/storage_subsystem_collection.json rename to rsd_lib/tests/unit/json_samples/v2_1/storage_collection.json 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 e33b292..8abb4a3 100644 --- a/rsd_lib/tests/unit/json_samples/v2_1/system.json +++ b/rsd_lib/tests/unit/json_samples/v2_1/system.json @@ -1,17 +1,19 @@ { - "@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem", - "Id": "437XR1138R2", - "Name": "WebFrontEnd483", + "@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity", + "@odata.id": "/redfish/v1/Systems/System1", + "@odata.type": "#ComputerSystem.v1_3_0.ComputerSystem", + "Id": "System1", + "Name": "My Computer System", + "Description": "Description of server", "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", + "AssetTag": "free form asset tag", + "Manufacturer": "Manufacturer Name", + "Model": "Model Name", + "SKU": "SKU", + "SerialNumber": "2M220100SL", + "PartNumber": "Computer1", + "UUID": "00000000-0000-0000-0000-000000000000", + "HostName": null, "Status": { "State": "Enabled", "Health": "OK", @@ -20,50 +22,25 @@ "IndicatorLED": "Off", "PowerState": "On", "Boot": { + "@odata.type": "#ComputerSystem.v1_1_0.Boot", "BootSourceOverrideEnabled": "Once", "BootSourceOverrideTarget": "Pxe", "BootSourceOverrideTarget@Redfish.AllowableValues": [ "None", "Pxe", - "Cd", - "Usb", "Hdd", - "BiosSetup", - "Utilities", - "Diags", - "SDCard", - "UefiTarget" + "RemoteDrive" ], - "BootSourceOverrideMode": "UEFI", - "UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01" + "BootSourceOverrideMode": "Legacy", + "BootSourceOverrideMode@Redfish.AllowableValues": [ + "Legacy", + "UEFI" + ] }, - "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)", + "BiosVersion": "P79 v1.00 (09/20/2013)", "ProcessorSummary": { - "Count": 2, - "ProcessorFamily": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", + "Count": 8, + "Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", "Status": { "State": "Enabled", "Health": "OK", @@ -71,24 +48,25 @@ } }, "MemorySummary": { - "TotalSystemMemoryGiB": 96, + "TotalSystemMemoryGiB": 16.0, "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" + "@odata.id": "/redfish/v1/Systems/System1/Processors" }, "EthernetInterfaces": { - "@odata.id": "/redfish/v1/Systems/437XR1138R2/EthernetInterfaces" + "@odata.id": "/redfish/v1/Systems/System1/EthernetInterfaces" + }, + "SimpleStorage": {}, + "Storage": { + "@odata.id": "/redfish/v1/Systems/System1/Storage" + }, + "Memory": { + "@odata.id": "/redfish/v1/Systems/System1/Memory" }, "PCIeDevices": [ { @@ -106,50 +84,53 @@ "@odata.id": "/redfish/v1/Chassis/1/PCIeDevices/Device2/Functions/1" } ], - "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" - } - ] + "@odata.type": "#ComputerSystem.v1_2_0.Links", + "Chassis": [{ + "@odata.id": "/redfish/v1/Chassis/4" + }], + "ManagedBy": [{ + "@odata.id": "/redfish/v1/Managers/1" + }], + "Endpoints": [], + "Oem": {} }, "Actions": { "#ComputerSystem.Reset": { - "target": "/redfish/v1/Systems/437XR1138R2/Actions/ComputerSystem.Reset", + "target": "/redfish/v1/Systems/System1/Actions/ComputerSystem.Reset", "ResetType@Redfish.AllowableValues": [ "On", "ForceOff", "GracefulShutdown", - "GracefulRestart", "ForceRestart", "Nmi", - "ForceOn" + "GracefulRestart", + "ForceOn", + "PushPowerButton" ] }, "Oem": { - "#Contoso.Reset": { - "target": "/redfish/v1/Systems/437XR1138R2/Oem/Contoso/Actions/Contoso.Reset" + "#ComputerSystem.StartDeepDiscovery": { + "target": "/redfish/v1/Systems/System1/Actions/ComputerSystem.StartDeepDiscovery" } } }, - "@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." -} + "Oem": { + "Intel_RackScale": { + "@odata.type": "#Intel.Oem.ComputerSystem", + "PciDevices": [{ + "VendorId": "0x8086", + "DeviceId": "0x1234" + }], + "DiscoveryState": "Basic", + "ProcessorSockets": 8, + "MemorySockets": 8, + "PCIeConnectionId": [ + "XYZ1234567890" + ] + } + }, + "NetworkInterfaces": { + "@odata.id": "/redfish/v1/Systems/System1/NetworkInterfaces" + } +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/resources/v2_1/manager/test_ethernet_interface.py b/rsd_lib/tests/unit/resources/v2_1/manager/test_ethernet_interface.py index 263af33..7b8fea6 100644 --- a/rsd_lib/tests/unit/resources/v2_1/manager/test_ethernet_interface.py +++ b/rsd_lib/tests/unit/resources/v2_1/manager/test_ethernet_interface.py @@ -17,8 +17,6 @@ import json import mock import testtools -from sushy import exceptions - from rsd_lib.resources.v2_1.ethernet_switch import vlan_network_interface from rsd_lib.resources.v2_1.system import ethernet_interface @@ -126,19 +124,6 @@ class EthernetInterface(testtools.TestCase): neighbor_port, ) - def test__get_vlan_collection_path(self): - actual_path = self.ethernet_interface_inst._get_vlan_collection_path() - self.assertEqual( - "/redfish/v1/Managers/1/EthernetInterfaces/1/VLANs", actual_path - ) - - def test__get_vlan_collection_path_without_vlans(self): - self.ethernet_interface_inst._json.pop("VLANs") - with self.assertRaisesRegex( - exceptions.MissingAttributeError, "attribute VLANs" - ): - self.ethernet_interface_inst._get_vlan_collection_path() - def test_vlans(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_drive.py b/rsd_lib/tests/unit/resources/v2_1/system/test_drive.py new file mode 100644 index 0000000..2b6c0a9 --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_drive.py @@ -0,0 +1,170 @@ +# 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. + +import json +import mock +import testtools + +from sushy import exceptions + +from rsd_lib.resources.v2_1.system import drive + + +class DriveTestCase(testtools.TestCase): + def setUp(self): + super(DriveTestCase, self).setUp() + self.conn = mock.Mock() + with open("rsd_lib/tests/unit/json_samples/v2_1/drive.json", "r") as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.drive_inst = drive.Drive( + self.conn, + "/redfish/v1/Chassis/Blade1/Drives/1", + redfish_version="1.1.0", + ) + + def test__parse_attributes(self): + self.drive_inst._parse_attributes() + self.assertEqual("1.1.0", self.drive_inst.redfish_version) + self.assertEqual("OK", self.drive_inst.status_indicator) + self.assertEqual("Lit", self.drive_inst.indicator_led) + self.assertEqual("Drive Model string", self.drive_inst.model) + self.assertEqual("revision string", self.drive_inst.revision) + self.assertEqual("Enabled", self.drive_inst.status.state) + self.assertEqual("OK", self.drive_inst.status.health) + self.assertEqual(None, self.drive_inst.status.health_rollup) + self.assertEqual(899527000000, self.drive_inst.capacity_bytes) + self.assertEqual(False, self.drive_inst.failure_predicted) + self.assertEqual("SATA", self.drive_inst.protocol) + self.assertEqual("SSD", self.drive_inst.media_type) + self.assertEqual("Intel", self.drive_inst.manufacturer) + self.assertEqual("SKU version", self.drive_inst.sku) + self.assertEqual("72D0A037FRD27", self.drive_inst.serial_number) + self.assertEqual( + "SG0GP8811253178M02GJA00", self.drive_inst.part_number + ) + self.assertEqual(None, self.drive_inst.asset_tag) + self.assertEqual( + "123e4567-e89b-12d3-a456-426655440000", + self.drive_inst.identifiers[0].durable_name, + ) + self.assertEqual( + "UUID", self.drive_inst.identifiers[0].durable_name_format + ) + self.assertEqual("4", self.drive_inst.location[0].info) + self.assertEqual("Hdd index", self.drive_inst.location[0].info_format) + self.assertEqual(None, self.drive_inst.hotspare_type) + self.assertEqual(None, self.drive_inst.encryption_ability) + self.assertEqual(None, self.drive_inst.encryption_status) + self.assertEqual(None, self.drive_inst.rotation_speed_rpm) + self.assertEqual(None, self.drive_inst.block_size_bytes) + self.assertEqual(6, self.drive_inst.capable_speed_gbs) + self.assertEqual(6, self.drive_inst.negotiated_speed_gbs) + self.assertEqual( + None, self.drive_inst.predicted_media_life_left_percent + ) + self.assertEqual(tuple(), self.drive_inst.links.volumes) + self.assertEqual(tuple(), self.drive_inst.links.endpoints) + self.assertEqual(None, self.drive_inst.operations) + self.assertEqual( + False, self.drive_inst.oem.intel_rackscale.erase_on_detach + ) + self.assertEqual( + True, self.drive_inst.oem.intel_rackscale.drive_erased + ) + self.assertEqual( + "1.17", self.drive_inst.oem.intel_rackscale.firmware_version + ) + self.assertEqual( + "/redfish/v1/Systems/1/Storage/NVMe", + self.drive_inst.oem.intel_rackscale.storage, + ) + self.assertEqual( + "/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1", + self.drive_inst.oem.intel_rackscale.pcie_function, + ) + + def test__get_secure_erase_action_element(self): + value = self.drive_inst._get_secure_erase_action_element() + self.assertEqual( + "/redfish/v1/Chassis/Blade1/Drives/1/Actions/Drive.SecureErase", + value.target_uri, + ) + + def test_get__get_secure_erase_action_element_missing_reset_action(self): + self.drive_inst._actions.secure_erase = None + with self.assertRaisesRegex( + exceptions.MissingActionError, "action #Drive.SecureErase" + ): + self.drive_inst._get_secure_erase_action_element() + + def test_secure_erase(self): + self.drive_inst.secure_erase() + self.drive_inst._conn.post.assert_called_once_with( + "/redfish/v1/Chassis/Blade1/Drives/1/Actions/Drive.SecureErase", + data={}, + ) + + def test_update(self): + self.drive_inst.update( + asset_tag="Asset Tag", erase_on_detach=True, erased=False + ) + self.drive_inst._conn.patch.assert_called_once_with( + "/redfish/v1/Chassis/Blade1/Drives/1", + data={ + "Oem": { + "Intel_RackScale": { + "EraseOnDetach": True, + "DriveErased": False, + } + }, + "AssetTag": "Asset Tag", + }, + ) + + self.drive_inst._conn.patch.reset_mock() + self.drive_inst.update(asset_tag="Asset Tag") + self.drive_inst._conn.patch.assert_called_once_with( + "/redfish/v1/Chassis/Blade1/Drives/1", + data={"AssetTag": "Asset Tag"}, + ) + + self.drive_inst._conn.patch.reset_mock() + self.drive_inst.update(erase_on_detach=True, erased=False) + self.drive_inst._conn.patch.assert_called_once_with( + "/redfish/v1/Chassis/Blade1/Drives/1", + data={ + "Oem": { + "Intel_RackScale": { + "EraseOnDetach": True, + "DriveErased": False, + } + } + }, + ) + + def test_update_invalid_values(self): + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "erase_on_detach" value "invalid string" is ' + 'invalid', + ): + self.drive_inst.update(erase_on_detach="invalid string") + + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "erased" value "invalid string" is invalid', + ): + self.drive_inst.update(erased="invalid string") diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_ethernet_interface.py b/rsd_lib/tests/unit/resources/v2_1/system/test_ethernet_interface.py index 03325a3..f92b1b8 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_ethernet_interface.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_ethernet_interface.py @@ -21,110 +21,142 @@ from rsd_lib.resources.v2_1.system import ethernet_interface class EthernetInterfaceTestCase(testtools.TestCase): - def setUp(self): super(EthernetInterfaceTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system_ethernet_interface.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "system_ethernet_interface.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.ethernet_interface_inst = ethernet_interface.EthernetInterface( - self.conn, '/redfish/v1/Systems/System1/EthernetInterfaces/LAN1', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Systems/System1/EthernetInterfaces/LAN1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.ethernet_interface_inst._parse_attributes() - self.assertEqual('Ethernet Interface', - self.ethernet_interface_inst.name) - self.assertEqual('LAN1', self.ethernet_interface_inst.identity) - self.assertEqual('System NIC 1', - self.ethernet_interface_inst.description) - self.assertEqual('Enabled', self.ethernet_interface_inst.status.state) - self.assertEqual('OK', self.ethernet_interface_inst.status.health) - self.assertEqual('OK', - self.ethernet_interface_inst.status.health_rollup) + self.assertEqual( + "Ethernet Interface", self.ethernet_interface_inst.name + ) + self.assertEqual("LAN1", self.ethernet_interface_inst.identity) + self.assertEqual( + "System NIC 1", self.ethernet_interface_inst.description + ) + self.assertEqual("Enabled", self.ethernet_interface_inst.status.state) + self.assertEqual("OK", self.ethernet_interface_inst.status.health) + self.assertEqual( + "OK", self.ethernet_interface_inst.status.health_rollup + ) self.assertEqual(True, self.ethernet_interface_inst.interface_enabled) - self.assertEqual('AA:BB:CC:DD:EE:FF', - self.ethernet_interface_inst.permanent_mac_address) - self.assertEqual('AA:BB:CC:DD:EE:FF', - self.ethernet_interface_inst.mac_address) + self.assertEqual( + "AA:BB:CC:DD:EE:FF", + self.ethernet_interface_inst.permanent_mac_address, + ) + self.assertEqual( + "AA:BB:CC:DD:EE:FF", self.ethernet_interface_inst.mac_address + ) self.assertEqual(100, self.ethernet_interface_inst.speed_mbps) self.assertEqual(True, self.ethernet_interface_inst.auto_neg) self.assertEqual(True, self.ethernet_interface_inst.full_duplex) self.assertEqual(1500, self.ethernet_interface_inst.mtu_size) - self.assertEqual('web483', self.ethernet_interface_inst.host_name) - self.assertEqual('web483.redfishspecification.org', - self.ethernet_interface_inst.fqdn) - self.assertEqual('fe80::3ed9:2bff:fe34:600', - self.ethernet_interface_inst.ipv6_default_gateway) + self.assertEqual("web483", self.ethernet_interface_inst.host_name) self.assertEqual( - None, self.ethernet_interface_inst.max_ipv6_static_addresses) - self.assertEqual(['names.redfishspecification.org'], - self.ethernet_interface_inst.name_servers) + "web483.redfishspecification.org", + self.ethernet_interface_inst.fqdn, + ) self.assertEqual( - '192.168.0.10', - self.ethernet_interface_inst.ipv4_addresses[0].address) + "fe80::3ed9:2bff:fe34:600", + self.ethernet_interface_inst.ipv6_default_gateway, + ) self.assertEqual( - '255.255.252.0', - self.ethernet_interface_inst.ipv4_addresses[0].subnet_mask) + None, self.ethernet_interface_inst.max_ipv6_static_addresses + ) self.assertEqual( - '192.168.0.1', - self.ethernet_interface_inst.ipv4_addresses[0].gateway) + ["names.redfishspecification.org"], + self.ethernet_interface_inst.name_servers, + ) self.assertEqual( - 'fe80::1ec1:deff:fe6f:1e24', - self.ethernet_interface_inst.ipv6_addresses[0].address) + "192.168.0.10", + self.ethernet_interface_inst.ipv4_addresses[0].address, + ) self.assertEqual( - 64, self.ethernet_interface_inst.ipv6_addresses[0].prefix_length) + "255.255.252.0", + self.ethernet_interface_inst.ipv4_addresses[0].subnet_mask, + ) self.assertEqual( - 'Static', - self.ethernet_interface_inst.ipv6_addresses[0].address_origin) + "192.168.0.1", + self.ethernet_interface_inst.ipv4_addresses[0].gateway, + ) self.assertEqual( - 'Preferred', - self.ethernet_interface_inst.ipv6_addresses[0].address_state) + "fe80::1ec1:deff:fe6f:1e24", + self.ethernet_interface_inst.ipv6_addresses[0].address, + ) self.assertEqual( - [], self.ethernet_interface_inst.ipv6_static_addresses) + 64, self.ethernet_interface_inst.ipv6_addresses[0].prefix_length + ) + self.assertEqual( + "Static", + self.ethernet_interface_inst.ipv6_addresses[0].address_origin, + ) + self.assertEqual( + "Preferred", + self.ethernet_interface_inst.ipv6_addresses[0].address_state, + ) + self.assertEqual( + [], self.ethernet_interface_inst.ipv6_static_addresses + ) self.assertEqual(None, self.ethernet_interface_inst.vlan) class EthernetInterfaceCollectionTestCase(testtools.TestCase): - def setUp(self): super(EthernetInterfaceCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system_ethernet_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "system_ethernet_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.ethernet_interface_col = ethernet_interface.\ EthernetInterfaceCollection( self.conn, - '/redfish/v1/Systems/System1/EthernetInterfaces', - redfish_version='1.1.0') + "/redfish/v1/Systems/System1/EthernetInterfaces", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.ethernet_interface_col._parse_attributes() - self.assertEqual('1.1.0', self.ethernet_interface_col.redfish_version) + self.assertEqual("1.1.0", self.ethernet_interface_col.redfish_version) self.assertEqual( - ('/redfish/v1/Systems/System1/EthernetInterfaces/LAN1',), - self.ethernet_interface_col.members_identities) + ("/redfish/v1/Systems/System1/EthernetInterfaces/LAN1",), + self.ethernet_interface_col.members_identities, + ) - @mock.patch.object(ethernet_interface, 'EthernetInterface', autospec=True) + @mock.patch.object(ethernet_interface, "EthernetInterface", autospec=True) def test_get_member(self, mock_network_interface): self.ethernet_interface_col.get_member( - '/redfish/v1/Systems/System1/EthernetInterfaces/LAN1') + "/redfish/v1/Systems/System1/EthernetInterfaces/LAN1" + ) mock_network_interface.assert_called_once_with( self.ethernet_interface_col._conn, - '/redfish/v1/Systems/System1/EthernetInterfaces/LAN1', - redfish_version=self.ethernet_interface_col.redfish_version) + "/redfish/v1/Systems/System1/EthernetInterfaces/LAN1", + redfish_version=self.ethernet_interface_col.redfish_version, + ) - @mock.patch.object(ethernet_interface, 'EthernetInterface', autospec=True) + @mock.patch.object(ethernet_interface, "EthernetInterface", autospec=True) def test_get_members(self, mock_network_interface): members = self.ethernet_interface_col.get_members() calls = [ - mock.call(self.ethernet_interface_col._conn, - '/redfish/v1/Systems/System1/EthernetInterfaces/LAN1', - redfish_version=self.ethernet_interface_col. - redfish_version) + mock.call( + self.ethernet_interface_col._conn, + "/redfish/v1/Systems/System1/EthernetInterfaces/LAN1", + redfish_version=self.ethernet_interface_col.redfish_version, + ) ] mock_network_interface.assert_has_calls(calls) self.assertIsInstance(members, list) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_memory.py b/rsd_lib/tests/unit/resources/v2_1/system/test_memory.py index 942151f..c1da0ac 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_memory.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_memory.py @@ -21,92 +21,108 @@ from rsd_lib.resources.v2_1.system import memory class MemoryTestCase(testtools.TestCase): - def setUp(self): super(MemoryTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/memory.json', - 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/memory.json", "r" + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.memory_inst = memory.Memory( - self.conn, '/redfish/v1/Systems/System1/Memory/Dimm1', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Systems/System1/Memory/Dimm1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.memory_inst._parse_attributes() - self.assertEqual('1.1.0', self.memory_inst.redfish_version) - self.assertEqual('DIMM', self.memory_inst.name) - self.assertEqual('Dimm1', self.memory_inst.identity) - self.assertEqual('DRAM', self.memory_inst.memory_type) - self.assertEqual('DDR4', self.memory_inst.memory_device_type) - self.assertEqual('LRDIMM', self.memory_inst.base_module_type) - self.assertEqual(['DRAM'], self.memory_inst.memory_media) + self.assertEqual("1.1.0", self.memory_inst.redfish_version) + self.assertEqual("DIMM", self.memory_inst.name) + self.assertEqual("Dimm1", self.memory_inst.identity) + self.assertEqual("DRAM", self.memory_inst.memory_type) + self.assertEqual("DDR4", self.memory_inst.memory_device_type) + self.assertEqual("LRDIMM", self.memory_inst.base_module_type) + self.assertEqual(["DRAM"], self.memory_inst.memory_media) self.assertEqual(16384, self.memory_inst.capacity_mib) self.assertEqual(64, self.memory_inst.data_width_bits) self.assertEqual(72, self.memory_inst.bus_width_bits) - self.assertEqual('Contoso', self.memory_inst.manufacturer) - self.assertEqual('1A2B3B', self.memory_inst.serial_number) - self.assertEqual('1A2B3D', self.memory_inst.part_number) - self.assertEqual([2133, 2400, 2667], - self.memory_inst.allowed_speeds_mhz) - self.assertEqual('RevAbc', self.memory_inst.firmware_revision) - self.assertEqual('ApiAbc', self.memory_inst.frirmware_api_version) - self.assertEqual(['Volatile'], self.memory_inst.function_classes) - self.assertEqual('vendorX', self.memory_inst.vendor_id) - self.assertEqual('deviceX', self.memory_inst.device_id) + self.assertEqual("Contoso", self.memory_inst.manufacturer) + self.assertEqual("1A2B3B", self.memory_inst.serial_number) + self.assertEqual("1A2B3D", self.memory_inst.part_number) + self.assertEqual( + [2133, 2400, 2667], self.memory_inst.allowed_speeds_mhz + ) + self.assertEqual("RevAbc", self.memory_inst.firmware_revision) + self.assertEqual("ApiAbc", self.memory_inst.firmware_api_version) + self.assertEqual(["Volatile"], self.memory_inst.function_classes) + self.assertEqual("vendorX", self.memory_inst.vendor_id) + self.assertEqual("deviceX", self.memory_inst.device_id) self.assertEqual(1, self.memory_inst.rank_count) - self.assertEqual('PROC 1 DIMM 1', self.memory_inst.device_locator) - self.assertEqual('MultiBitECC', self.memory_inst.error_correction) + self.assertEqual("PROC 1 DIMM 1", self.memory_inst.device_locator) + self.assertEqual("MultiBitECC", self.memory_inst.error_correction) self.assertEqual(2400, self.memory_inst.operating_speed_mhz) - self.assertEqual(['Volatile'], self.memory_inst.operating_memory_modes) + self.assertEqual(["Volatile"], self.memory_inst.operating_memory_modes) self.assertEqual(1, self.memory_inst.memory_location.socket) self.assertEqual(1, self.memory_inst.memory_location.memory_controller) self.assertEqual(1, self.memory_inst.memory_location.channel) self.assertEqual(1, self.memory_inst.memory_location.slot) - self.assertEqual('Enabled', self.memory_inst.status.state) - self.assertEqual('OK', self.memory_inst.status.health) - self.assertEqual('OK', self.memory_inst.status.health_rollup) + self.assertEqual("Enabled", self.memory_inst.status.state) + self.assertEqual("OK", self.memory_inst.status.health) + self.assertEqual("OK", self.memory_inst.status.health_rollup) class MemoryCollectionTestCase(testtools.TestCase): - def setUp(self): super(MemoryCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'memory_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "memory_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.sys_memory_col = memory.MemoryCollection( - self.conn, '/redfish/v1/Systems/System1/Memory', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Systems/System1/Memory", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.sys_memory_col._parse_attributes() - self.assertEqual('1.1.0', self.sys_memory_col.redfish_version) - self.assertEqual(('/redfish/v1/Systems/System1/Memory/Dimm1', - '/redfish/v1/Systems/System1/Memory/Dimm2'), - self.sys_memory_col.members_identities) + self.assertEqual("1.1.0", self.sys_memory_col.redfish_version) + self.assertEqual( + ( + "/redfish/v1/Systems/System1/Memory/Dimm1", + "/redfish/v1/Systems/System1/Memory/Dimm2", + ), + self.sys_memory_col.members_identities, + ) - @mock.patch.object(memory, 'Memory', autospec=True) + @mock.patch.object(memory, "Memory", autospec=True) def test_get_member(self, mock_memory): self.sys_memory_col.get_member( - '/redfish/v1/Systems/System1/Memory/Dimm1') + "/redfish/v1/Systems/System1/Memory/Dimm1" + ) mock_memory.assert_called_once_with( self.sys_memory_col._conn, - '/redfish/v1/Systems/System1/Memory/Dimm1', - redfish_version=self.sys_memory_col.redfish_version) + "/redfish/v1/Systems/System1/Memory/Dimm1", + redfish_version=self.sys_memory_col.redfish_version, + ) - @mock.patch.object(memory, 'Memory', autospec=True) + @mock.patch.object(memory, "Memory", autospec=True) def test_get_members(self, mock_memory): members = self.sys_memory_col.get_members() calls = [ - mock.call(self.sys_memory_col._conn, - '/redfish/v1/Systems/System1/Memory/Dimm1', - redfish_version=self.sys_memory_col.redfish_version), - mock.call(self.sys_memory_col._conn, - '/redfish/v1/Systems/System1/Memory/Dimm2', - redfish_version=self.sys_memory_col.redfish_version) + mock.call( + self.sys_memory_col._conn, + "/redfish/v1/Systems/System1/Memory/Dimm1", + redfish_version=self.sys_memory_col.redfish_version, + ), + mock.call( + self.sys_memory_col._conn, + "/redfish/v1/Systems/System1/Memory/Dimm2", + redfish_version=self.sys_memory_col.redfish_version, + ), ] mock_memory.assert_has_calls(calls) self.assertIsInstance(members, list) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_network_device_function.py b/rsd_lib/tests/unit/resources/v2_1/system/test_network_device_function.py index 6aec952..404ec38 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_network_device_function.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_network_device_function.py @@ -21,202 +21,253 @@ from rsd_lib.resources.v2_1.system import network_device_function class NetworkDeviceFunctionTestCase(testtools.TestCase): - def setUp(self): super(NetworkDeviceFunctionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_device_function.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_device_function.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.network_device_function_inst = network_device_function.\ NetworkDeviceFunction( self.conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - redfish_version='1.1.0') + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.network_device_function_inst._parse_attributes() self.assertEqual( - '1.1.0', self.network_device_function_inst.redfish_version) - self.assertEqual('Network Device Function View', - self.network_device_function_inst.name) - self.assertEqual('1', self.network_device_function_inst.identity) - self.assertEqual('Network Device Function View', - self.network_device_function_inst.description) + "1.1.0", self.network_device_function_inst.redfish_version + ) self.assertEqual( - True, self.network_device_function_inst.device_enabled) + "Network Device Function View", + self.network_device_function_inst.name, + ) + self.assertEqual("1", self.network_device_function_inst.identity) self.assertEqual( - 'Enabled', self.network_device_function_inst.status.state) - self.assertEqual('OK', self.network_device_function_inst.status.health) + "Network Device Function View", + self.network_device_function_inst.description, + ) self.assertEqual( - 'OK', self.network_device_function_inst.status.health_rollup) - self.assertEqual('00:0C:29:9A:98:ED', - self.network_device_function_inst.ethernet.macaddress) - self.assertEqual({}, self.network_device_function_inst.links) + True, self.network_device_function_inst.device_enabled + ) + self.assertEqual( + "Enabled", self.network_device_function_inst.status.state + ) + self.assertEqual("OK", self.network_device_function_inst.status.health) + self.assertEqual( + "OK", self.network_device_function_inst.status.health_rollup + ) + self.assertEqual( + "00:0C:29:9A:98:ED", + self.network_device_function_inst.ethernet.mac_address, + ) # iSCSIBoot section self.assertEqual( - 'IPv4', - self.network_device_function_inst.iscsi_boot.ip_address_type) + "IPv4", + self.network_device_function_inst.iscsi_boot.ip_address_type, + ) self.assertEqual( - '10.0.10.10', - self.network_device_function_inst.iscsi_boot.initiator_ip_address) + "10.0.10.10", + self.network_device_function_inst.iscsi_boot.initiator_ip_address, + ) self.assertEqual( - 'iqn.2017-03.com.intel:workload-server', - self.network_device_function_inst.iscsi_boot.initiator_name) + "iqn.2017-03.com.intel:workload-server", + self.network_device_function_inst.iscsi_boot.initiator_name, + ) self.assertEqual( - '10.0.10.1', + "10.0.10.1", self.network_device_function_inst.iscsi_boot. - initiator_default_gateway) + initiator_default_gateway, + ) self.assertEqual( - '255.255.255.0', - self.network_device_function_inst.iscsi_boot.initiator_netmask) + "255.255.255.0", + self.network_device_function_inst.iscsi_boot.initiator_netmask, + ) self.assertEqual( False, - self.network_device_function_inst.iscsi_boot.target_info_via_dhcp) + self.network_device_function_inst.iscsi_boot.target_info_via_dhcp, + ) self.assertEqual( - 'iqn.2017-03.com.intel:image-server', - self.network_device_function_inst.iscsi_boot.primary_target_name) + "iqn.2017-03.com.intel:image-server", + self.network_device_function_inst.iscsi_boot.primary_target_name, + ) self.assertEqual( - '10.0.10.254', + "10.0.10.254", self.network_device_function_inst.iscsi_boot. - primary_target_ip_address) + primary_target_ip_address, + ) self.assertEqual( 3260, self.network_device_function_inst.iscsi_boot. - primary_target_tcp_port) + primary_target_tcp_port, + ) self.assertEqual( - 1, self.network_device_function_inst.iscsi_boot.primary_lun) + 1, self.network_device_function_inst.iscsi_boot.primary_lun + ) self.assertEqual( True, - self.network_device_function_inst.iscsi_boot.primary_vlan_enable) + self.network_device_function_inst.iscsi_boot.primary_vlan_enable, + ) self.assertEqual( - 4088, - self.network_device_function_inst.iscsi_boot.primary_vlan_id) + 4088, self.network_device_function_inst.iscsi_boot.primary_vlan_id + ) + self.assertEqual( + None, self.network_device_function_inst.iscsi_boot.primary_dns + ) self.assertEqual( None, - self.network_device_function_inst.iscsi_boot.primary_dns) - self.assertEqual( - None, - self.network_device_function_inst.iscsi_boot.secondary_target_name) + self.network_device_function_inst.iscsi_boot.secondary_target_name, + ) self.assertEqual( None, self.network_device_function_inst.iscsi_boot. - secondary_target_ip_address) + secondary_target_ip_address, + ) self.assertEqual( None, self.network_device_function_inst.iscsi_boot. - secondary_target_tcp_port) + secondary_target_tcp_port, + ) self.assertEqual( - None, - self.network_device_function_inst.iscsi_boot.secondary_lun) + None, self.network_device_function_inst.iscsi_boot.secondary_lun + ) self.assertEqual( False, - self.network_device_function_inst.iscsi_boot.secondary_vlan_enable) + self.network_device_function_inst.iscsi_boot.secondary_vlan_enable, + ) self.assertEqual( None, - self.network_device_function_inst.iscsi_boot.secondary_vlan_id) + self.network_device_function_inst.iscsi_boot.secondary_vlan_id, + ) self.assertEqual( - None, - self.network_device_function_inst.iscsi_boot.secondary_dns) + None, self.network_device_function_inst.iscsi_boot.secondary_dns + ) self.assertEqual( False, - self.network_device_function_inst.iscsi_boot.ip_mask_dns_via_dhcp) + self.network_device_function_inst.iscsi_boot.ip_mask_dns_via_dhcp, + ) self.assertEqual( False, self.network_device_function_inst.iscsi_boot. - router_advertisement_enabled) + router_advertisement_enabled, + ) self.assertEqual( - 'CHAP', - self.network_device_function_inst.iscsi_boot.authentication_method) + "CHAP", + self.network_device_function_inst.iscsi_boot.authentication_method, + ) self.assertEqual( - 'user', - self.network_device_function_inst.iscsi_boot.chap_username) + "user", self.network_device_function_inst.iscsi_boot.chap_username + ) + self.assertEqual( + None, self.network_device_function_inst.iscsi_boot.chap_secret + ) + self.assertEqual( + "mutualuser", + self.network_device_function_inst.iscsi_boot.mutual_chap_username, + ) self.assertEqual( None, - self.network_device_function_inst.iscsi_boot.chap_secret) - self.assertEqual( - 'mutualuser', - self.network_device_function_inst.iscsi_boot.mutual_chap_username) - self.assertEqual( - None, - self.network_device_function_inst.iscsi_boot.mutual_chap_secret) + self.network_device_function_inst.iscsi_boot.mutual_chap_secret, + ) def test_update(self): self.network_device_function_inst.update( - ethernet={"MACAddress": "00:0C:29:9A:98:ED"}) + ethernet={"MACAddress": "00:0C:29:9A:98:ED"} + ) self.network_device_function_inst._conn.patch.assert_called_once_with( - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - data={"Ethernet": {"MACAddress": "00:0C:29:9A:98:ED"}}) + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + data={"Ethernet": {"MACAddress": "00:0C:29:9A:98:ED"}}, + ) self.network_device_function_inst._conn.patch.reset_mock() self.network_device_function_inst.update( - iscsi_boot={"IPAddressType": "IPv4"}) + iscsi_boot={"IPAddressType": "IPv4"} + ) self.network_device_function_inst._conn.patch.assert_called_once_with( - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - data={"iSCSIBoot": {"IPAddressType": "IPv4"}}) + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + data={"iSCSIBoot": {"IPAddressType": "IPv4"}}, + ) self.network_device_function_inst._conn.patch.reset_mock() self.network_device_function_inst.update( ethernet={"MACAddress": "00:0C:29:9A:98:ED"}, - iscsi_boot={"IPAddressType": "IPv4"}) + iscsi_boot={"IPAddressType": "IPv4"}, + ) self.network_device_function_inst._conn.patch.assert_called_once_with( - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - data={"Ethernet": {"MACAddress": "00:0C:29:9A:98:ED"}, - "iSCSIBoot": {"IPAddressType": "IPv4"}}) + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + data={ + "Ethernet": {"MACAddress": "00:0C:29:9A:98:ED"}, + "iSCSIBoot": {"IPAddressType": "IPv4"}, + }, + ) class NetworkDeviceFunctionCollectionTestCase(testtools.TestCase): - def setUp(self): super(NetworkDeviceFunctionCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_device_function_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_device_function_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.network_device_function_col = network_device_function.\ NetworkDeviceFunctionCollection( self.conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions', - redfish_version='1.1.0') + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.network_device_function_col._parse_attributes() self.assertEqual( - '1.1.0', self.network_device_function_col.redfish_version) + "1.1.0", self.network_device_function_col.redfish_version + ) self.assertEqual( - ('/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1',), - self.network_device_function_col.members_identities) + ( + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + ), + self.network_device_function_col.members_identities, + ) @mock.patch.object( - network_device_function, 'NetworkDeviceFunction', - autospec=True) + network_device_function, "NetworkDeviceFunction", autospec=True + ) def test_get_member(self, mock_network_device_function): self.network_device_function_col.get_member( - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1') + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1" + ) mock_network_device_function.assert_called_once_with( self.network_device_function_col._conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - redfish_version=self.network_device_function_col.redfish_version) + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + redfish_version=self.network_device_function_col.redfish_version, + ) @mock.patch.object( - network_device_function, 'NetworkDeviceFunction', - autospec=True) + network_device_function, "NetworkDeviceFunction", autospec=True + ) def test_get_members(self, mock_network_device_function): members = self.network_device_function_col.get_members() mock_network_device_function.assert_called_once_with( self.network_device_function_col._conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1/' - 'NetworkDeviceFunctions/1', - redfish_version=self.network_device_function_col.redfish_version) + "/redfish/v1/Systems/System1/NetworkInterfaces/1/" + "NetworkDeviceFunctions/1", + redfish_version=self.network_device_function_col.redfish_version, + ) self.assertIsInstance(members, list) self.assertEqual(1, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_network_interface.py b/rsd_lib/tests/unit/resources/v2_1/system/test_network_interface.py index da7a47d..d0c623e 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_network_interface.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_network_interface.py @@ -22,126 +22,147 @@ from rsd_lib.resources.v2_1.system import network_interface class NetworkInterface(testtools.TestCase): - def setUp(self): super(NetworkInterface, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_interface.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "network_interface.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.network_interface_inst = network_interface.NetworkInterface( - self.conn, '/redfish/v1/Systems/System1/NetworkInterfaces/1/', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Systems/System1/NetworkInterfaces/1/", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.network_interface_inst._parse_attributes() - self.assertEqual('1.1.0', self.network_interface_inst.redfish_version) - self.assertEqual('Network Device View', - self.network_interface_inst.name) - self.assertEqual('1', self.network_interface_inst.identity) - self.assertEqual('Network Device View', - self.network_interface_inst.description) - self.assertEqual('Enabled', self.network_interface_inst.status.state) - self.assertEqual('OK', self.network_interface_inst.status.health) + self.assertEqual("1.1.0", self.network_interface_inst.redfish_version) self.assertEqual( - 'OK', self.network_interface_inst.status.health_rollup) - self.assertEqual({}, self.network_interface_inst.links) - - def test__get_network_device_functions_path(self): - expected = '/redfish/v1/Systems/System1/NetworkInterfaces/1/'\ - 'NetworkDeviceFunctions' - result = self.network_interface_inst.\ - _get_network_device_functions_path() - self.assertEqual(expected, result) + "Network Device View", self.network_interface_inst.name + ) + self.assertEqual("1", self.network_interface_inst.identity) + self.assertEqual( + "Network Device View", self.network_interface_inst.description + ) + self.assertEqual("Enabled", self.network_interface_inst.status.state) + self.assertEqual("OK", self.network_interface_inst.status.health) + self.assertEqual( + "OK", self.network_interface_inst.status.health_rollup + ) def test_network_device_functions(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_device_function_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_device_function_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN | - actual_network_device_functions = self.network_interface_inst.\ - network_device_functions + actual_network_device_functions = ( + self.network_interface_inst.network_device_functions + ) # | THEN | self.assertIsInstance( actual_network_device_functions, - network_device_function.NetworkDeviceFunctionCollection) + network_device_function.NetworkDeviceFunctionCollection, + ) 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_network_device_functions, - self.network_interface_inst.network_device_functions) + self.assertIs( + actual_network_device_functions, + self.network_interface_inst.network_device_functions, + ) self.conn.get.return_value.json.assert_not_called() def test_network_device_functions_on_refresh(self): # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_device_function_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_device_function_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN & THEN | self.assertIsInstance( self.network_interface_inst.network_device_functions, - network_device_function.NetworkDeviceFunctionCollection) + network_device_function.NetworkDeviceFunctionCollection, + ) # On refreshing the network_interface instance... - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_interface.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "network_interface.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.network_interface_inst.invalidate() self.network_interface_inst.refresh(force=False) # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_device_function_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_device_function_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN & THEN | self.assertIsInstance( self.network_interface_inst.network_device_functions, - network_device_function.NetworkDeviceFunctionCollection) + network_device_function.NetworkDeviceFunctionCollection, + ) class NetworkInterfaceCollectionTestCase(testtools.TestCase): - def setUp(self): super(NetworkInterfaceCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.network_interface_col = network_interface.\ NetworkInterfaceCollection( self.conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1', - redfish_version='1.1.0') + "/redfish/v1/Systems/System1/NetworkInterfaces/1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.network_interface_col._parse_attributes() + self.assertEqual("1.1.0", self.network_interface_col.redfish_version) self.assertEqual( - '1.1.0', self.network_interface_col.redfish_version) - self.assertEqual( - ('/redfish/v1/Systems/System1/NetworkInterfaces/1',), - self.network_interface_col.members_identities) + ("/redfish/v1/Systems/System1/NetworkInterfaces/1",), + self.network_interface_col.members_identities, + ) - @mock.patch.object(network_interface, 'NetworkInterface', autospec=True) + @mock.patch.object(network_interface, "NetworkInterface", autospec=True) def test_get_member(self, mock_network_interface): self.network_interface_col.get_member( - '/redfish/v1/Systems/System1/NetworkInterfaces/1') + "/redfish/v1/Systems/System1/NetworkInterfaces/1" + ) mock_network_interface.assert_called_once_with( self.network_interface_col._conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1', - redfish_version=self.network_interface_col.redfish_version) + "/redfish/v1/Systems/System1/NetworkInterfaces/1", + redfish_version=self.network_interface_col.redfish_version, + ) - @mock.patch.object(network_interface, 'NetworkInterface', autospec=True) + @mock.patch.object(network_interface, "NetworkInterface", autospec=True) def test_get_members(self, mock_network_interface): members = self.network_interface_col.get_members() mock_network_interface.assert_called_once_with( self.network_interface_col._conn, - '/redfish/v1/Systems/System1/NetworkInterfaces/1', - redfish_version=self.network_interface_col.redfish_version) + "/redfish/v1/Systems/System1/NetworkInterfaces/1", + redfish_version=self.network_interface_col.redfish_version, + ) self.assertIsInstance(members, list) self.assertEqual(1, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_device.py b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_device.py index 54206d0..7c3c178 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_device.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_device.py @@ -21,47 +21,53 @@ from rsd_lib.resources.v2_1.system import pcie_device class PCIeDeviceTestCase(testtools.TestCase): - def setUp(self): super(PCIeDeviceTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'pcie_device.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "pcie_device.json", "r" + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.pcie_device_inst = pcie_device.PCIeDevice( - self.conn, '/redfish/v1/Chassis/1/PCIeDevices/Device1', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Chassis/1/PCIeDevices/Device1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.pcie_device_inst._parse_attributes() - self.assertEqual('Device1', self.pcie_device_inst.identity) - self.assertEqual('NVMe SSD Drive', self.pcie_device_inst.name) - self.assertEqual('Simple NVMe Drive', - self.pcie_device_inst.description) + self.assertEqual("Device1", self.pcie_device_inst.identity) + self.assertEqual("NVMe SSD Drive", self.pcie_device_inst.name) self.assertEqual( - 'Enabled', self.pcie_device_inst.status.state) - self.assertEqual('OK', self.pcie_device_inst.status.health) + "Simple NVMe Drive", self.pcie_device_inst.description + ) + self.assertEqual("Enabled", self.pcie_device_inst.status.state) + self.assertEqual("OK", self.pcie_device_inst.status.health) + self.assertEqual("OK", self.pcie_device_inst.status.health_rollup) + self.assertEqual("Intel", self.pcie_device_inst.manufacturer) + self.assertEqual("Model Name", self.pcie_device_inst.model) + self.assertEqual("sku string", self.pcie_device_inst.sku) + self.assertEqual("SN123456", self.pcie_device_inst.serial_number) self.assertEqual( - 'OK', self.pcie_device_inst.status.health_rollup) - self.assertEqual('Intel', self.pcie_device_inst.manufacturer) - self.assertEqual('Model Name', self.pcie_device_inst.model) - self.assertEqual('sku string', self.pcie_device_inst.sku) - self.assertEqual('SN123456', self.pcie_device_inst.serial_number) + "partnumber string", self.pcie_device_inst.part_number + ) self.assertEqual( - 'partnumber string', self.pcie_device_inst.part_number) + "free form asset tag", self.pcie_device_inst.asset_tag + ) + self.assertEqual("SingleFunction", self.pcie_device_inst.device_type) + self.assertEqual("XYZ1234", self.pcie_device_inst.firmware_version) self.assertEqual( - 'free form asset tag', self.pcie_device_inst.asset_tag) - self.assertEqual('SingleFunction', self.pcie_device_inst.device_type) - self.assertEqual('XYZ1234', self.pcie_device_inst.firmware_version) + ("/redfish/v1/Chassis/1",), self.pcie_device_inst.links.chassis + ) self.assertEqual( - ('/redfish/v1/Chassis/1',), self.pcie_device_inst.links.chassis) - self.assertEqual( - ('/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1',), - self.pcie_device_inst.links.pcie_functions) + ("/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1",), + self.pcie_device_inst.links.pcie_functions, + ) def test_update(self): - self.pcie_device_inst.update(asset_tag='Rack#1') + self.pcie_device_inst.update(asset_tag="Rack#1") self.pcie_device_inst._conn.patch.assert_called_once_with( - '/redfish/v1/Chassis/1/PCIeDevices/Device1', - data={"AssetTag": "Rack#1"}) + "/redfish/v1/Chassis/1/PCIeDevices/Device1", + data={"AssetTag": "Rack#1"}, + ) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py index 553d3da..72562dd 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_pcie_function.py @@ -21,46 +21,50 @@ from rsd_lib.resources.v2_1.system import pcie_function class PCIeFunctionTestCase(testtools.TestCase): - def setUp(self): super(PCIeFunctionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'pcie_function.json', 'r') as f: + 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()) self.pcie_function_inst = pcie_function.PCIeFunction( - self.conn, '/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1', - redfish_version='1.1.0') + self.conn, + "/redfish/v1/Chassis/1/PCIeDevices/Device1/Functions/1", + redfish_version="1.1.0", + ) def test__parse_attributes(self): self.pcie_function_inst._parse_attributes() - self.assertEqual('1', self.pcie_function_inst.identity) - self.assertEqual('SSD', self.pcie_function_inst.name) - self.assertEqual('SSD Drive', - self.pcie_function_inst.description) - self.assertEqual( - 'Enabled', self.pcie_function_inst.status.state) - self.assertEqual('OK', self.pcie_function_inst.status.health) - self.assertEqual( - 'OK', self.pcie_function_inst.status.health_rollup) + self.assertEqual("1", self.pcie_function_inst.identity) + self.assertEqual("SSD", self.pcie_function_inst.name) + self.assertEqual("SSD Drive", self.pcie_function_inst.description) + self.assertEqual("Enabled", self.pcie_function_inst.status.state) + self.assertEqual("OK", self.pcie_function_inst.status.health) + self.assertEqual("OK", self.pcie_function_inst.status.health_rollup) self.assertEqual(1, self.pcie_function_inst.function_id) - self.assertEqual('Physical', self.pcie_function_inst.function_type) + self.assertEqual("Physical", self.pcie_function_inst.function_type) self.assertEqual( - 'MassStorageController', self.pcie_function_inst.device_class) - self.assertEqual('0xABCD', self.pcie_function_inst.device_id) - self.assertEqual('0x8086', self.pcie_function_inst.vendor_id) - self.assertEqual('0x10802', self.pcie_function_inst.class_code) - self.assertEqual('0x00', self.pcie_function_inst.revision_id) - self.assertEqual('0xABCD', self.pcie_function_inst.subsystem_id) - self.assertEqual('0xABCD', self.pcie_function_inst.subsystem_vendor_id) + "MassStorageController", self.pcie_function_inst.device_class + ) + self.assertEqual("0xABCD", self.pcie_function_inst.device_id) + self.assertEqual("0x8086", self.pcie_function_inst.vendor_id) + self.assertEqual("0x10802", self.pcie_function_inst.class_code) + self.assertEqual("0x00", self.pcie_function_inst.revision_id) + self.assertEqual("0xABCD", self.pcie_function_inst.subsystem_id) + self.assertEqual("0xABCD", self.pcie_function_inst.subsystem_vendor_id) self.assertEqual( - None, self.pcie_function_inst.links.ethernet_interfaces) + None, self.pcie_function_inst.links.ethernet_interfaces + ) self.assertEqual( - ('/redfish/v1/Chassis/PCIeSwitch1/Drives/Disk.Bay.1',), - self.pcie_function_inst.links.drives) + ("/redfish/v1/Chassis/PCIeSwitch1/Drives/Disk.Bay.1",), + self.pcie_function_inst.links.drives, + ) self.assertEqual( - None, self.pcie_function_inst.links.storage_controllers) + None, self.pcie_function_inst.links.storage_controllers + ) self.assertEqual( - '/redfish/v1/Chassis/1/PCIeDevices/Device1', - self.pcie_function_inst.links.pcie_device) + "/redfish/v1/Chassis/1/PCIeDevices/Device1", + self.pcie_function_inst.links.pcie_device, + ) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_processor.py b/rsd_lib/tests/unit/resources/v2_1/system/test_processor.py index 4190235..b83ce3f 100644 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_processor.py +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_processor.py @@ -21,93 +21,118 @@ from rsd_lib.resources.v2_1.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_1/processor.json', 'r') as f: + "rsd_lib/tests/unit/json_samples/v2_1/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.0.2') + self.conn, + "/redfish/v1/Systems/System1/Processors/CPU1", + redfish_version="1.0.2", + ) def test__parse_attributes(self): self.processor_inst._parse_attributes() - self.assertEqual('CPU1', self.processor_inst.identity) - self.assertEqual('Processor', self.processor_inst.name) + 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("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) + "0x42", self.processor_inst.processor_id.effective_family + ) self.assertEqual( - '0x61', self.processor_inst.processor_id.effective_model) + "0x61", self.processor_inst.processor_id.effective_model + ) self.assertEqual( - '0x34AC34DC8901274A', - self.processor_inst.processor_id.identification_registers) + "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) + "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) + "GenuineIntel", self.processor_inst.processor_id.vendor_id + ) + self.assertEqual("OK", self.processor_inst.status.health) self.assertEqual(None, self.processor_inst.status.health_rollup) - self.assertEqual('Enabled', self.processor_inst.status.state) + 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("E5", self.processor_inst.oem.intel_rackscale.brand) self.assertEqual( - ['sse', 'sse2', 'sse3'], - self.processor_inst.oem.intel_rackscale.capabilities) + ["sse", "sse2", "sse3"], + self.processor_inst.oem.intel_rackscale.capabilities, + ) class ProcessorCollectionTestCase(testtools.TestCase): - def setUp(self): super(ProcessorCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'processor_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "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') + 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/CPU2'), - self.processor_col.members_identities) + self.assertEqual("1.1.0", self.processor_col.redfish_version) + self.assertEqual( + ( + "/redfish/v1/Systems/System1/Processors/CPU1", + "/redfish/v1/Systems/System1/Processors/CPU2", + ), + self.processor_col.members_identities, + ) - @mock.patch.object(processor, 'Processor', autospec=True) + @mock.patch.object(processor, "Processor", autospec=True) def test_get_member(self, mock_processor): self.processor_col.get_member( - '/redfish/v1/Systems/System1/Processors/CPU1') + "/redfish/v1/Systems/System1/Processors/CPU1" + ) mock_processor.assert_called_once_with( self.processor_col._conn, - '/redfish/v1/Systems/System1/Processors/CPU1', - redfish_version=self.processor_col.redfish_version) + "/redfish/v1/Systems/System1/Processors/CPU1", + redfish_version=self.processor_col.redfish_version, + ) - @mock.patch.object(processor, 'Processor', autospec=True) + @mock.patch.object(processor, "Processor", autospec=True) def test_get_members(self, mock_processor): 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/CPU2', - redfish_version=self.processor_col.redfish_version) + 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/CPU2", + redfish_version=self.processor_col.redfish_version, + ), ] mock_processor.assert_has_calls(calls) self.assertIsInstance(members, list) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_storage.py b/rsd_lib/tests/unit/resources/v2_1/system/test_storage.py new file mode 100644 index 0000000..cc2ca20 --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_1/system/test_storage.py @@ -0,0 +1,200 @@ +# Copyright 2018 99cloud, 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_1.system import drive +from rsd_lib.resources.v2_1.system import storage + + +class StorageSubsystemTestCase(testtools.TestCase): + def setUp(self): + super(StorageSubsystemTestCase, self).setUp() + self.conn = mock.Mock() + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "storage.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.storage_inst = storage.Storage( + self.conn, + "/redfish/v1/Systems/1/Storage/SATA", + redfish_version="1.1.0", + ) + + def test__parse_attributes(self): + self.storage_inst._parse_attributes() + self.assertEqual("SATA Storage System", self.storage_inst.name) + self.assertEqual("1", self.storage_inst.identity) + self.assertEqual("System SATA", self.storage_inst.description) + self.assertEqual("Enabled", self.storage_inst.status.state) + self.assertEqual("OK", self.storage_inst.status.health) + self.assertEqual("OK", self.storage_inst.status.health_rollup) + self.assertEqual( + "0", self.storage_inst.storage_controllers[0].member_id + ) + self.assertEqual( + "Enabled", self.storage_inst.storage_controllers[0].status.state + ) + self.assertEqual( + "OK", self.storage_inst.storage_controllers[0].status.health + ) + self.assertEqual( + "ManufacturerName", + self.storage_inst.storage_controllers[0].manufacturer, + ) + self.assertEqual( + "ProductModelName", self.storage_inst.storage_controllers[0].model + ) + self.assertEqual("", self.storage_inst.storage_controllers[0].sku) + self.assertEqual( + "2M220100SL", + self.storage_inst.storage_controllers[0].serial_number, + ) + self.assertEqual( + "", self.storage_inst.storage_controllers[0].part_number + ) + self.assertEqual( + "CustomerWritableThingy", + self.storage_inst.storage_controllers[0].asset_tag, + ) + self.assertEqual( + 6, self.storage_inst.storage_controllers[0].speed_gbps + ) + self.assertEqual( + None, self.storage_inst.storage_controllers[0].firmware_version + ) + self.assertEqual( + "PCIe", + self.storage_inst.storage_controllers[ + 0 + ].supported_controller_protocols[0], + ) + self.assertEqual( + "SATA", + self.storage_inst.storage_controllers[ + 0 + ].supported_device_protocols[0], + ) + self.assertEqual( + "123e4567-e89b-12d3-a456-426655440000", + self.storage_inst.storage_controllers[0] + .identifiers[0] + .durable_name, + ) + self.assertEqual( + "UUID", + self.storage_inst.storage_controllers[0] + .identifiers[0] + .durable_name_format, + ) + + def test_drives(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open("rsd_lib/tests/unit/json_samples/v2_1/drive.json", "r") as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_drives = self.storage_inst.drives + # | THEN | + self.assertIsInstance(actual_drives, list) + self.assertEqual(1, len(actual_drives)) + self.assertIsInstance(actual_drives[0], drive.Drive) + 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_drives, self.storage_inst.drives) + self.conn.get.return_value.json.assert_not_called() + + def test_drives_on_refresh(self): + # | GIVEN | + with open("rsd_lib/tests/unit/json_samples/v2_1/drive.json", "r") as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + actual_drives = self.storage_inst.drives + self.assertIsInstance(actual_drives, list) + self.assertEqual(1, len(actual_drives)) + self.assertIsInstance(actual_drives[0], drive.Drive) + + # On refreshing the system instance... + with open( + "rsd_lib/tests/unit/json_samples/v2_1/storage.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.storage_inst.invalidate() + self.storage_inst.refresh(force=True) + + # | GIVEN | + with open("rsd_lib/tests/unit/json_samples/v2_1/drive.json", "r") as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.storage_inst.drives, list) + self.assertEqual(1, len(self.storage_inst.drives)) + self.assertIsInstance(self.storage_inst.drives[0], drive.Drive) + + +class StorageSubsystemCollectionTestCase(testtools.TestCase): + def setUp(self): + super(StorageSubsystemCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" "storage_collection.json", + "r", + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.storage_subsystem_col = storage.StorageCollection( + self.conn, + "/redfish/v1/Systems/1/Storage", + redfish_version="1.1.0", + ) + + def test__parse_attributes(self): + self.storage_subsystem_col._parse_attributes() + self.assertEqual("1.1.0", self.storage_subsystem_col.redfish_version) + self.assertEqual( + ("/redfish/v1/Systems/1/Storage/SATA",), + self.storage_subsystem_col.members_identities, + ) + + @mock.patch.object(storage, "Storage", autospec=True) + def test_get_member(self, mock_storage_subsystem): + self.storage_subsystem_col.get_member( + "/redfish/v1/Systems/1/Storage/SATA" + ) + mock_storage_subsystem.assert_called_once_with( + self.storage_subsystem_col._conn, + "/redfish/v1/Systems/1/Storage/SATA", + redfish_version=self.storage_subsystem_col.redfish_version, + ) + + @mock.patch.object(storage, "Storage", autospec=True) + def test_get_members(self, mock_storage_subsystem): + members = self.storage_subsystem_col.get_members() + calls = [ + mock.call( + self.storage_subsystem_col._conn, + "/redfish/v1/Systems/1/Storage/SATA", + redfish_version=self.storage_subsystem_col.redfish_version, + ) + ] + mock_storage_subsystem.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_1/system/test_storage_subsystem.py b/rsd_lib/tests/unit/resources/v2_1/system/test_storage_subsystem.py deleted file mode 100644 index a1206ec..0000000 --- a/rsd_lib/tests/unit/resources/v2_1/system/test_storage_subsystem.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright 2018 99cloud, 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_1.system import storage_subsystem - - -class StorageSubsystemTestCase(testtools.TestCase): - - def setUp(self): - super(StorageSubsystemTestCase, self).setUp() - self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'storage_subsystem.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - - self.storage_subsystem_inst = storage_subsystem.StorageSubsystem( - self.conn, '/redfish/v1/Systems/1/Storage/SATA', - redfish_version='1.1.0') - - def test__parse_attributes(self): - self.storage_subsystem_inst._parse_attributes() - self.assertEqual('SATA Storage System', - self.storage_subsystem_inst.name) - self.assertEqual('1', self.storage_subsystem_inst.identity) - self.assertEqual('System SATA', - self.storage_subsystem_inst.description) - self.assertEqual('Enabled', - self.storage_subsystem_inst.status.state) - self.assertEqual('OK', - self.storage_subsystem_inst.status.health) - self.assertEqual('OK', - self.storage_subsystem_inst.status.health_rollup) - self.assertEqual( - '0', - self.storage_subsystem_inst.storage_controllers[0].member_id) - self.assertEqual( - 'Enabled', - self.storage_subsystem_inst.storage_controllers[0].status.state) - self.assertEqual( - 'OK', - self.storage_subsystem_inst.storage_controllers[0].status.health) - self.assertEqual( - 'ManufacturerName', - self.storage_subsystem_inst.storage_controllers[0].manufacturer) - self.assertEqual( - 'ProductModelName', - self.storage_subsystem_inst.storage_controllers[0].model) - self.assertEqual( - '', - self.storage_subsystem_inst.storage_controllers[0].sku) - self.assertEqual( - '2M220100SL', - self.storage_subsystem_inst.storage_controllers[0].serial_number) - self.assertEqual( - '', - self.storage_subsystem_inst.storage_controllers[0].part_number) - self.assertEqual( - 'CustomerWritableThingy', - self.storage_subsystem_inst.storage_controllers[0].asset_tag) - self.assertEqual( - 6, - self.storage_subsystem_inst.storage_controllers[0].speed_gbps) - self.assertEqual( - None, - self.storage_subsystem_inst.storage_controllers[0]. - firmware_version) - self.assertEqual( - 'PCIe', - self.storage_subsystem_inst.storage_controllers[0]. - supported_controller_protocols[0]) - self.assertEqual( - 'SATA', - self.storage_subsystem_inst.storage_controllers[0]. - supported_device_protocols[0]) - self.assertEqual( - '123e4567-e89b-12d3-a456-426655440000', - self.storage_subsystem_inst.storage_controllers[0].identifiers[0]. - durable_name) - self.assertEqual( - 'UUID', - self.storage_subsystem_inst.storage_controllers[0].identifiers[0]. - durable_name_format) - self.assertEqual(('/redfish/v1/Chassis/Blade1/Drives/Disk1',), - self.storage_subsystem_inst.drives) - self.assertEqual('/redfish/v1/Systems/1/Storage/SATA/Volumes', - self.storage_subsystem_inst.volumes) - - -class StorageSubsystemCollectionTestCase(testtools.TestCase): - - def setUp(self): - super(StorageSubsystemCollectionTestCase, self).setUp() - self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'storage_subsystem_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - self.storage_subsystem_col = storage_subsystem.\ - StorageSubsystemCollection( - self.conn, '/redfish/v1/Systems/1/Storage', - redfish_version='1.1.0') - - def test__parse_attributes(self): - self.storage_subsystem_col._parse_attributes() - self.assertEqual('1.1.0', self.storage_subsystem_col.redfish_version) - self.assertEqual(('/redfish/v1/Systems/1/Storage/SATA',), - self.storage_subsystem_col.members_identities) - - @mock.patch.object(storage_subsystem, 'StorageSubsystem', autospec=True) - def test_get_member(self, mock_storage_subsystem): - self.storage_subsystem_col.get_member( - '/redfish/v1/Systems/1/Storage/SATA') - mock_storage_subsystem.assert_called_once_with( - self.storage_subsystem_col._conn, - '/redfish/v1/Systems/1/Storage/SATA', - redfish_version=self.storage_subsystem_col.redfish_version) - - @mock.patch.object(storage_subsystem, 'StorageSubsystem', autospec=True) - def test_get_members(self, mock_storage_subsystem): - members = self.storage_subsystem_col.get_members() - calls = [ - mock.call(self.storage_subsystem_col._conn, - '/redfish/v1/Systems/1/Storage/SATA', - redfish_version=self.storage_subsystem_col. - redfish_version) - ] - mock_storage_subsystem.assert_has_calls(calls) - self.assertIsInstance(members, list) - self.assertEqual(1, len(members)) 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 50f129e..0d7837a 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 @@ -18,325 +18,571 @@ import mock import testtools from sushy import exceptions -from sushy.resources.system import system as sushy_system +from rsd_lib import constants 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 processor -from rsd_lib.resources.v2_1.system import storage_subsystem +from rsd_lib.resources.v2_1.system import storage from rsd_lib.resources.v2_1.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_1/system.json', - 'r') as f: + 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 = system.System( - self.conn, '/redfish/v1/Systems/437XR1138R2', - redfish_version='1.1.0') + self.conn, "/redfish/v1/Systems/System1", redfish_version="1.1.0" + ) - def test_class_inherit(self): - self.assertIsInstance(self.system_inst, system.System) - self.assertIsInstance(self.system_inst, sushy_system.System) + def test__parse_attributes(self): + self.system_inst._parse_attributes() + self.assertEqual("1.1.0", self.system_inst.redfish_version) + self.assertEqual("System1", self.system_inst.identity) + self.assertEqual("My Computer System", self.system_inst.name) + self.assertEqual("Description of server", self.system_inst.description) + self.assertEqual("Physical", self.system_inst.system_type) + self.assertEqual( + ("/redfish/v1/Chassis/4",), self.system_inst.links.chassis + ) + self.assertEqual( + ("/redfish/v1/Managers/1",), self.system_inst.links.managed_by + ) + self.assertEqual(None, self.system_inst.links.powered_by) + self.assertEqual(None, self.system_inst.links.cooled_by) + self.assertEqual(tuple(), self.system_inst.links.endpoints) + self.assertEqual("free form asset tag", self.system_inst.asset_tag) + self.assertEqual("Manufacturer Name", self.system_inst.manufacturer) + self.assertEqual("Model Name", self.system_inst.model) + self.assertEqual("SKU", self.system_inst.sku) + self.assertEqual("2M220100SL", self.system_inst.serial_number) + self.assertEqual("Computer1", self.system_inst.part_number) + self.assertEqual( + "00000000-0000-0000-0000-000000000000", self.system_inst.uuid + ) + self.assertEqual(None, self.system_inst.host_name) + self.assertEqual("Off", self.system_inst.indicator_led) + self.assertEqual("On", self.system_inst.power_state) + self.assertEqual( + "Pxe", self.system_inst.boot.boot_source_override_target + ) + self.assertEqual( + ["None", "Pxe", "Hdd", "RemoteDrive"], + self.system_inst.boot.boot_source_override_target_allowed_values, + ) + self.assertEqual( + "Once", self.system_inst.boot.boot_source_override_enabled + ) + self.assertEqual( + None, self.system_inst.boot.uefi_target_boot_source_override + ) + self.assertEqual( + "Legacy", self.system_inst.boot.boot_source_override_mode + ) + self.assertEqual( + ["Legacy", "UEFI"], + self.system_inst.boot.boot_source_override_mode_allowed_values, + ) + self.assertEqual( + "P79 v1.00 (09/20/2013)", self.system_inst.bios_version + ) + self.assertEqual(8, self.system_inst.processor_summary.count) + self.assertEqual( + "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", + self.system_inst.processor_summary.model, + ) + self.assertEqual( + "Enabled", self.system_inst.processor_summary.status.state + ) + self.assertEqual( + "OK", self.system_inst.processor_summary.status.health + ) + self.assertEqual( + "OK", self.system_inst.processor_summary.status.health_rollup + ) + self.assertEqual( + 16, self.system_inst.memory_summary.total_system_memory_gib + ) + self.assertEqual( + "Enabled", self.system_inst.memory_summary.status.state + ) + self.assertEqual("OK", self.system_inst.memory_summary.status.health) + self.assertEqual( + "OK", self.system_inst.memory_summary.status.health_rollup + ) + self.assertEqual("Enabled", self.system_inst.status.state) + self.assertEqual("OK", self.system_inst.status.health) + self.assertEqual("OK", self.system_inst.status.health_rollup) + self.assertEqual(None, self.system_inst.hosting_roles) + self.assertEqual( + ["XYZ1234567890"], + self.system_inst.oem.intel_rackscale.pcie_connection_id, + ) + self.assertEqual( + "0x8086", + self.system_inst.oem.intel_rackscale.pci_devices[0].vendor_id, + ) + self.assertEqual( + "0x1234", + self.system_inst.oem.intel_rackscale.pci_devices[0].device_id, + ) + self.assertEqual( + "Basic", self.system_inst.oem.intel_rackscale.discovery_state + ) + self.assertEqual( + 8, self.system_inst.oem.intel_rackscale.processor_sockets + ) + self.assertEqual( + 8, self.system_inst.oem.intel_rackscale.memory_sockets + ) - def test__get_processor_collection_path(self): - self.assertEqual('/redfish/v1/Systems/437XR1138R2/Processors', - self.system_inst._get_processor_collection_path()) + def test_get__reset_action_element(self): + value = self.system_inst._get_reset_action_element() + self.assertEqual( + "/redfish/v1/Systems/System1/Actions/ComputerSystem.Reset", + value.target_uri, + ) + self.assertEqual( + [ + "On", + "ForceOff", + "GracefulShutdown", + "ForceRestart", + "Nmi", + "GracefulRestart", + "ForceOn", + "PushPowerButton", + ], + value.allowed_values, + ) - def test__get_processor_collection_path_missing_attr(self): - self.system_inst._json.pop('Processors') + def test_get__reset_action_element_missing_reset_action(self): + self.system_inst._actions.reset = None with self.assertRaisesRegex( - exceptions.MissingAttributeError, 'attribute Processors'): - self.system_inst._get_processor_collection_path() + exceptions.MissingActionError, "action #ComputerSystem.Reset" + ): + self.system_inst._get_reset_action_element() + + def test_get_allowed_reset_system_values(self): + values = self.system_inst.get_allowed_reset_system_values() + expected = set( + [ + "On", + "ForceOff", + "GracefulShutdown", + "GracefulRestart", + "ForceRestart", + "Nmi", + "ForceOn", + "PushPowerButton", + ] + ) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + + @mock.patch.object(system.LOG, "warning", autospec=True) + def test_get_allowed_reset_system_values_no_values_specified( + self, mock_log + ): + self.system_inst._actions.reset.allowed_values = {} + values = self.system_inst.get_allowed_reset_system_values() + # Assert it returns all values if it can't get the specific ones + expected = set(constants.RESET_TYPE_VALUE) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + self.assertEqual(1, mock_log.call_count) + + def test_reset_system(self): + self.system_inst.reset_system("ForceOff") + self.system_inst._conn.post.assert_called_once_with( + "/redfish/v1/Systems/System1/Actions/ComputerSystem.Reset", + data={"ResetType": "ForceOff"}, + ) + + def test_reset_system_invalid_value(self): + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "value" value "invalid-value" is invalid', + ): + self.system_inst.reset_system("invalid-value") + + def test_get_allowed_system_boot_source_values(self): + values = self.system_inst.get_allowed_system_boot_source_values() + expected = set(["None", "Pxe", "Hdd", "RemoteDrive"]) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + + @mock.patch.object(system.LOG, "warning", autospec=True) + def test_get_allowed_system_boot_source_values_no_values_specified( + self, mock_log + ): + self.system_inst.boot.boot_source_override_target_allowed_values = None + values = self.system_inst.get_allowed_system_boot_source_values() + # Assert it returns all values if it can't get the specific ones + expected = set(constants.BOOT_SOURCE_TARGET_VALUE) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + self.assertEqual(1, mock_log.call_count) + + def test_get_allowed_system_boot_mode_values(self): + values = self.system_inst.get_allowed_system_boot_mode_values() + expected = set(["Legacy", "UEFI"]) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + + @mock.patch.object(system.LOG, "warning", autospec=True) + def test_get_allowed_system_boot_mode_values_no_values_specified( + self, mock_log + ): + self.system_inst.boot.boot_source_override_mode_allowed_values = None + values = self.system_inst.get_allowed_system_boot_mode_values() + # Assert it returns all values if it can't get the specific ones + expected = set(constants.BOOT_SOURCE_MODE_VALUE) + self.assertEqual(expected, values) + self.assertIsInstance(values, set) + self.assertEqual(1, mock_log.call_count) + + def test_set_system_boot_source(self): + self.system_inst.set_system_boot_source( + target="Pxe", enabled="Continuous", mode="UEFI" + ) + self.system_inst._conn.patch.assert_called_once_with( + "/redfish/v1/Systems/System1", + data={ + "Boot": { + "BootSourceOverrideEnabled": "Continuous", + "BootSourceOverrideTarget": "Pxe", + "BootSourceOverrideMode": "UEFI", + } + }, + ) + + def test_set_system_boot_source_no_mode_specified(self): + self.system_inst.set_system_boot_source(target="Hdd") + self.system_inst._conn.patch.assert_called_once_with( + "/redfish/v1/Systems/System1", + data={ + "Boot": { + "BootSourceOverrideEnabled": "Once", + "BootSourceOverrideTarget": "Hdd", + } + }, + ) + + def test_set_system_boot_source_invalid_target(self): + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "target" value "invalid-target" is invalid', + ): + self.system_inst.set_system_boot_source("invalid-target") + + def test_set_system_boot_source_invalid_enabled(self): + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "enabled" value "invalid-enabled" is invalid', + ): + self.system_inst.set_system_boot_source( + "Hdd", enabled="invalid-enabled" + ) + + def test_set_system_boot_source_invalid_mode(self): + with self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + 'The parameter "mode" value "invalid-mode" is invalid', + ): + self.system_inst.set_system_boot_source("Hdd", mode="invalid-mode") def test_processors(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'processor_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/processor_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN | actual_processor_col = self.system_inst.processors # | THEN | - self.assertIsInstance(actual_processor_col, - processor.ProcessorCollection) + 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.system_inst.processors) + self.assertIs(actual_processor_col, self.system_inst.processors) self.conn.get.return_value.json.assert_not_called() - def test_processor_on_refresh(self): + def test_processors_on_refresh(self): # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'processor_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/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) + self.assertIsInstance( + self.system_inst.processors, processor.ProcessorCollection + ) # On refreshing the system instance... - with open('rsd_lib/tests/unit/json_samples/v2_1/system.json', - 'r') as f: + 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/' - 'processor_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/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) - - def test__get_memory_collection_path(self): - self.assertEqual('/redfish/v1/Systems/437XR1138R2/Memory', - self.system_inst._get_memory_collection_path()) - - def test__get_memory_collection_path_missing_attr(self): - self.system_inst._json.pop('Memory') - with self.assertRaisesRegex( - exceptions.MissingAttributeError, 'attribute Memory'): - self.system_inst._get_memory_collection_path() - - def test_memory(self): - # | GIVEN | - self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'memory_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN | - actual_memory_col = self.system_inst.memory - # | THEN | - self.assertIsInstance(actual_memory_col, - memory.MemoryCollection) - 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_memory_col, - self.system_inst.memory) - self.conn.get.return_value.json.assert_not_called() - - def test_memory_on_refresh(self): - # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'memory_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN & THEN | - self.assertIsInstance(self.system_inst.memory, - memory.MemoryCollection) - - # On refreshing the system 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/' - 'memory_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN & THEN | - self.assertIsInstance(self.system_inst.memory, - memory.MemoryCollection) - - def test__get_storage_collection_path(self): - self.assertEqual( - '/redfish/v1/Systems/437XR1138R2/Storage', - self.system_inst._get_storage_subsystem_collection_path()) - - def test__get_storage_collection_path_missing_attr(self): - self.system_inst._json.pop('Storage') - with self.assertRaisesRegex( - exceptions.MissingAttributeError, 'attribute Storage'): - self.system_inst._get_storage_subsystem_collection_path() - - def test_storage_subsystem(self): - # | GIVEN | - self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'storage_subsystem_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN | - actual_storage_subsystem_col = self.system_inst.storage_subsystem - # | THEN | - self.assertIsInstance(actual_storage_subsystem_col, - storage_subsystem.StorageSubsystemCollection) - 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_storage_subsystem_col, - self.system_inst.storage_subsystem) - self.conn.get.return_value.json.assert_not_called() - - def test_storage_subsystem_on_refresh(self): - # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'storage_subsystem_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN & THEN | - self.assertIsInstance(self.system_inst.storage_subsystem, - storage_subsystem.StorageSubsystemCollection) - - # on refreshing the system 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/' - 'storage_subsystem_collection.json', 'r') as f: - self.conn.get.return_value.json.return_value = json.loads(f.read()) - # | WHEN & THEN | - self.assertIsInstance(self.system_inst.storage_subsystem, - storage_subsystem.StorageSubsystemCollection) - - def test__get_ethernet_interfaces_collection_path(self): - self.assertEqual( - '/redfish/v1/Systems/437XR1138R2/EthernetInterfaces', - self.system_inst._get_ethernet_interfaces_collection_path()) - - def test__get_ethernet_interfaces_collection_path_missing_attr(self): - self.system_inst._json.pop('EthernetInterfaces') - with self.assertRaisesRegex( - exceptions.MissingAttributeError, - 'attribute EthernetInterfaces'): - self.system_inst._get_ethernet_interfaces_collection_path() + self.assertIsInstance( + self.system_inst.processors, processor.ProcessorCollection + ) def test_ethernet_interfaces(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system_ethernet_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "system_ethernet_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN | actual_ethernet_interface_col = self.system_inst.ethernet_interfaces # | THEN | - self.assertIsInstance(actual_ethernet_interface_col, - ethernet_interface.EthernetInterfaceCollection) + self.assertIsInstance( + actual_ethernet_interface_col, + ethernet_interface.EthernetInterfaceCollection, + ) 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_ethernet_interface_col, - self.system_inst.ethernet_interfaces) + self.assertIs( + actual_ethernet_interface_col, self.system_inst.ethernet_interfaces + ) self.conn.get.return_value.json.assert_not_called() def test_ethernet_interfaces_on_refresh(self): # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system_ethernet_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "system_ethernet_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN & THEN | - self.assertIsInstance(self.system_inst.ethernet_interfaces, - ethernet_interface.EthernetInterfaceCollection) + self.assertIsInstance( + self.system_inst.ethernet_interfaces, + ethernet_interface.EthernetInterfaceCollection, + ) # on refreshing the system instance... - with open('rsd_lib/tests/unit/json_samples/v2_1/system.json', - 'r') as f: + 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/' - 'system_ethernet_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "system_ethernet_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.son.return_value = json.loads(f.read()) # | WHEN & THEN | - self.assertIsInstance(self.system_inst.ethernet_interfaces, - ethernet_interface.EthernetInterfaceCollection) + self.assertIsInstance( + self.system_inst.ethernet_interfaces, + ethernet_interface.EthernetInterfaceCollection, + ) - def test__get_network_interfaces_collection_path(self): - self.assertEqual( - '/redfish/v1/Systems/437XR1138R2/NetworkInterfaces', - self.system_inst._get_network_interfaces_collection_path()) - - def test__get_network_interfaces_collection_path_missing_attr(self): - self.system_inst._json.pop('NetworkInterfaces') - with self.assertRaisesRegex( - exceptions.MissingAttributeError, - 'attribute NetworkInterfaces'): - self.system_inst._get_network_interfaces_collection_path() - - def test_network_interfaces(self): + def test_memory(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/memory_collection.json", "r" + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN | - actual_network_interface_col = self.system_inst.network_interfaces + actual_memory_col = self.system_inst.memory # | THEN | - self.assertIsInstance(actual_network_interface_col, - network_interface.NetworkInterfaceCollection) + self.assertIsInstance(actual_memory_col, memory.MemoryCollection) 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_network_interface_col, - self.system_inst.network_interfaces) + self.assertIs(actual_memory_col, self.system_inst.memory) self.conn.get.return_value.json.assert_not_called() - def test_network_interfaces_on_refresh(self): + def test_memory_on_refresh(self): # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'network_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/memory_collection.json", "r" + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN & THEN | - self.assertIsInstance(self.system_inst.network_interfaces, - network_interface.NetworkInterfaceCollection) + self.assertIsInstance(self.system_inst.memory, memory.MemoryCollection) - # on refreshing the system instance... - with open('rsd_lib/tests/unit/json_samples/v2_1/system.json', - 'r') as f: + # On refreshing the system 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/' - 'network_interface_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/memory_collection.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.system_inst.memory, memory.MemoryCollection) + + def test_storage(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open( + "rsd_lib/tests/unit/json_samples/v2_1/storage_collection.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_storage_col = self.system_inst.storage + # | THEN | + self.assertIsInstance(actual_storage_col, storage.StorageCollection) + 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_storage_col, self.system_inst.storage) + self.conn.get.return_value.json.assert_not_called() + + def test_storage_on_refresh(self): + # | GIVEN | + with open( + "rsd_lib/tests/unit/json_samples/v2_1/storage_collection.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.system_inst.storage, storage.StorageCollection + ) + + # on refreshing the system 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/storage_collection.json", "r" + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.system_inst.storage, storage.StorageCollection + ) + + def test_network_interfaces(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_interface_collection.json", + "r", + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_network_interface_col = self.system_inst.network_interfaces + # | THEN | + self.assertIsInstance( + actual_network_interface_col, + network_interface.NetworkInterfaceCollection, + ) + 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_network_interface_col, self.system_inst.network_interfaces + ) + self.conn.get.return_value.json.assert_not_called() + + def test_network_interfaces_on_refresh(self): + # | GIVEN | + with open( + "rsd_lib/tests/unit/json_samples/v2_1/" + "network_interface_collection.json", + "r", + ) as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.system_inst.network_interfaces, + network_interface.NetworkInterfaceCollection, + ) + + # on refreshing the system 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/" + "network_interface_collection.json", + "r", + ) as f: self.conn.get.return_value.son.return_value = json.loads(f.read()) # | WHEN & THEN | - self.assertIsInstance(self.system_inst.network_interfaces, - network_interface.NetworkInterfaceCollection) + self.assertIsInstance( + self.system_inst.network_interfaces, + network_interface.NetworkInterfaceCollection, + ) def test_pcie_devices(self): # | GIVEN | self.conn.get.return_value.json.reset_mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'pcie_device.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/pcie_device.json", "r" + ) as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) # | WHEN | actual_pcie_devices = self.system_inst.pcie_devices @@ -350,42 +596,43 @@ class SystemTestCase(testtools.TestCase): self.conn.get.return_value.json.reset_mock() # | WHEN & THEN | # tests for same object on invoking subsequently - self.assertIs(actual_pcie_devices, - self.system_inst.pcie_devices) + self.assertIs(actual_pcie_devices, self.system_inst.pcie_devices) self.conn.get.return_value.json.assert_not_called() def test_pcie_devices_on_fresh(self): # | GIVEN | - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'pcie_device.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/pcie_device.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_devices: - self.assertIsInstance(pcie, - pcie_device.PCIeDevice) + self.assertIsInstance(pcie, pcie_device.PCIeDevice) # On refreshing the chassis instance... - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system.json', 'r') as f: + 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_device.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/pcie_device.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_devices: - self.assertIsInstance(pcie, - pcie_device.PCIeDevice) + 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: + 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 @@ -399,76 +646,81 @@ class SystemTestCase(testtools.TestCase): 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.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: + 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) + 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: + 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: + 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) + self.assertIsInstance(pcie, pcie_function.PCIeFunction) class SystemCollectionTestCase(testtools.TestCase): - def setUp(self): super(SystemCollectionTestCase, self).setUp() self.conn = mock.Mock() - with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'system_collection.json', 'r') as f: + with open( + "rsd_lib/tests/unit/json_samples/v2_1/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') + 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) + 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) + @mock.patch.object(system, "System", autospec=True) def test_get_member(self, mock_system): - self.system_col.get_member( - '/redfish/v1/Systems/System1') + 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) + "/redfish/v1/Systems/System1", + redfish_version=self.system_col.redfish_version, + ) - @mock.patch.object(system, 'System', autospec=True) + @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.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) diff --git a/rsd_lib/tests/unit/resources/v2_2/system/test_memory.py b/rsd_lib/tests/unit/resources/v2_2/system/test_memory.py index fca7290..1afeb33 100644 --- a/rsd_lib/tests/unit/resources/v2_2/system/test_memory.py +++ b/rsd_lib/tests/unit/resources/v2_2/system/test_memory.py @@ -54,7 +54,7 @@ class MemoryTestCase(testtools.TestCase): self.assertEqual([2133, 2400, 2667], self.memory_inst.allowed_speeds_mhz) self.assertEqual('RevAbc', self.memory_inst.firmware_revision) - self.assertEqual('ApiAbc', self.memory_inst.frirmware_api_version) + self.assertEqual('ApiAbc', self.memory_inst.firmware_api_version) self.assertEqual(['Volatile'], self.memory_inst.function_classes) self.assertEqual('vendorX', self.memory_inst.vendor_id) self.assertEqual('deviceX', self.memory_inst.device_id) diff --git a/rsd_lib/tests/unit/resources/v2_2/system/test_system.py b/rsd_lib/tests/unit/resources/v2_2/system/test_system.py index 19fb2c2..d701f7e 100644 --- a/rsd_lib/tests/unit/resources/v2_2/system/test_system.py +++ b/rsd_lib/tests/unit/resources/v2_2/system/test_system.py @@ -18,7 +18,6 @@ import mock import testtools from sushy import exceptions -from sushy.resources.system import system as sushy_system from rsd_lib.resources.v2_1.system import system as v2_1_system from rsd_lib.resources.v2_2.system import memory @@ -43,7 +42,6 @@ class SystemTestCase(testtools.TestCase): def test_class_inherit(self): self.assertIsInstance(self.system_inst, system.System) self.assertIsInstance(self.system_inst, v2_1_system.System) - self.assertIsInstance(self.system_inst, sushy_system.System) def test__get_metrics_path(self): self.assertEqual('/redfish/v1/Systems/System2/Metrics', diff --git a/rsd_lib/tests/unit/resources/v2_3/system/test_ethernet_interface.py b/rsd_lib/tests/unit/resources/v2_3/system/test_ethernet_interface.py index 7469763..6aa9a58 100644 --- a/rsd_lib/tests/unit/resources/v2_3/system/test_ethernet_interface.py +++ b/rsd_lib/tests/unit/resources/v2_3/system/test_ethernet_interface.py @@ -17,8 +17,6 @@ import json import mock import testtools -from sushy import exceptions - from rsd_lib.resources.v2_3.system import ethernet_interface @@ -111,11 +109,6 @@ class EthernetInterface(testtools.TestCase): self.assertEqual( None, self.ethernet_interface_inst.links.endpoints) - def test__get_vlan_collection_path_without_vlans(self): - with self.assertRaisesRegex( - exceptions.MissingAttributeError, 'attribute VLANs'): - self.ethernet_interface_inst._get_vlan_collection_path() - class EthernetInterfaceCollectionTestCase(testtools.TestCase): def setUp(self): diff --git a/rsd_lib/tests/unit/resources/v2_3/system/test_system.py b/rsd_lib/tests/unit/resources/v2_3/system/test_system.py index bd82bdc..4daff41 100644 --- a/rsd_lib/tests/unit/resources/v2_3/system/test_system.py +++ b/rsd_lib/tests/unit/resources/v2_3/system/test_system.py @@ -17,9 +17,6 @@ import json import mock import testtools -from sushy import exceptions -from sushy.resources.system import system as sushy_system - from rsd_lib.resources.v2_2.system import system as v2_2_system from rsd_lib.resources.v2_3.system import ethernet_interface from rsd_lib.resources.v2_3.system import system @@ -41,18 +38,6 @@ class SystemTestCase(testtools.TestCase): def test_class_inherit(self): self.assertIsInstance(self.system_inst, system.System) self.assertIsInstance(self.system_inst, v2_2_system.System) - self.assertIsInstance(self.system_inst, sushy_system.System) - - def test__get_ethernet_interfaces_collection_path(self): - self.assertEqual( - '/redfish/v1/Systems/437XR1138R2/EthernetInterfaces', - self.system_inst._get_ethernet_interfaces_collection_path()) - - def test__get_ethernet_interfaces_collection_path_missing_attr(self): - self.system_inst._json.pop('EthernetInterfaces') - with self.assertRaisesRegex( - exceptions.MissingAttributeError, 'attribute EthernetInterfaces'): - self.system_inst._get_ethernet_interfaces_collection_path() def test_ethernet_interfaces(self): # | GIVEN |