Merge "Add support for additional network resources."
This commit is contained in:
@@ -16,11 +16,14 @@
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.system.network import device_function
|
||||
from sushy.resources.system.network import port
|
||||
from sushy import utils
|
||||
|
||||
|
||||
class NetworkAdapter(base.ResourceBase):
|
||||
description = base.Field('Description')
|
||||
"""Human-readable description of the BIOS resource"""
|
||||
"""Human-readable description of the resource"""
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""The network adapter identity string"""
|
||||
@@ -43,6 +46,45 @@ class NetworkAdapter(base.ResourceBase):
|
||||
status = common.StatusField("Status")
|
||||
"""The status"""
|
||||
|
||||
@property
|
||||
@utils.cache_it
|
||||
def network_device_functions(self):
|
||||
"""Property to reference `NetworkDeviceFunctionCollection` 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.
|
||||
"""
|
||||
|
||||
return device_function.NetworkDeviceFunctionCollection(
|
||||
self._conn,
|
||||
path=utils.get_sub_resource_path_by(
|
||||
self,
|
||||
"NetworkDeviceFunctions"
|
||||
),
|
||||
redfish_version=self.redfish_version,
|
||||
registries=self.registries,
|
||||
root=self.root
|
||||
)
|
||||
|
||||
@property
|
||||
@utils.cache_it
|
||||
def network_ports(self):
|
||||
"""Property to reference `NetworkPortCollection` 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.
|
||||
"""
|
||||
|
||||
return port.NetworkPortCollection(
|
||||
self._conn,
|
||||
path=utils.get_sub_resource_path_by(self, "NetworkPorts"),
|
||||
redfish_version=self.redfish_version,
|
||||
registries=self.registries,
|
||||
root=self.root
|
||||
)
|
||||
|
||||
|
||||
class NetworkAdapterCollection(base.ResourceCollectionBase):
|
||||
|
||||
|
||||
89
sushy/resources/system/network/constants.py
Normal file
89
sushy/resources/system/network/constants.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2021 Anexia Internetdienstleistungs GmbH
|
||||
# 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.
|
||||
|
||||
# AuthenticationMethod Types
|
||||
|
||||
AUTHENTICATION_METHOD_CHAP = 'iSCSI Challenge Handshake'\
|
||||
'Authentication Protocol'
|
||||
"""
|
||||
iSCSI Challenge Handshake Authentication Protocol (CHAP)
|
||||
authentication is used.
|
||||
"""
|
||||
|
||||
AUTHENTICATION_METHOD_MUTUAL_CHAP = 'iSCSI Mutual Challenge Handshake'\
|
||||
'Authentication Protocol'
|
||||
"""
|
||||
iSCSI Mutual Challenge Handshake Authentication Protocol (CHAP)
|
||||
authentication is used.
|
||||
"""
|
||||
|
||||
AUTHENTICATION_METHOD_NONE = 'none'
|
||||
"""No iSCSI authentication is used."""
|
||||
|
||||
# BootMode Types
|
||||
|
||||
BOOT_MODE_DISABLED = 'disabled'
|
||||
"""Do not indicate to UEFI/BIOS that this device is bootable."""
|
||||
|
||||
BOOT_MODE_PXE = 'pxe'
|
||||
"""Boot this device by PXE"""
|
||||
|
||||
# IP Address Types
|
||||
|
||||
IP_ADDRESS_TYPE_IPV4 = 'IPv4'
|
||||
"""IPv4 addressing is used for all IP-fields in this object."""
|
||||
|
||||
IP_ADDRESS_TYPE_IPV6 = 'IPv6'
|
||||
"""IPv6 addressing is used for all IP-fields in this object."""
|
||||
|
||||
# FlowControl Types
|
||||
|
||||
FLOW_CONTROL_NONE = 'none'
|
||||
"""No IEEE 802.3x flow control is enabled on this port."""
|
||||
|
||||
FLOW_CONTROL_RX = 'rx'
|
||||
"""IEEE 802.3x flow control may be initiated by the link partner."""
|
||||
|
||||
FLOW_CONTROL_TX = 'tx'
|
||||
"""IEEE 802.3x flow control may be initiated by this station."""
|
||||
|
||||
FLOW_CONTROL_TX_RX = 'tx/rx'
|
||||
"""
|
||||
IEEE 802.3x flow control may be initiated
|
||||
by this station or the link partner.
|
||||
"""
|
||||
|
||||
# NetworkDeviceTechnology Types
|
||||
|
||||
NETWORK_DEVICE_TECHNOLOGY_DISABLED = 'disabled'
|
||||
"""Neither enumerated nor visible to the operating system."""
|
||||
|
||||
NETWORK_DEVICE_TECHNOLOGY_ETHERNET = 'ethernet'
|
||||
"""Appears to the operating system as an Ethernet device."""
|
||||
|
||||
NETWORK_DEVICE_TECHNOLOGY_FIBRE_CHANNEL = 'fibre channel'
|
||||
"""Appears to the operating system as a Fibre Channel device."""
|
||||
|
||||
NETWORK_DEVICE_TECHNOLOGY_FCOE = 'fibre channel over ethernet'
|
||||
"""Appears to the operating system as an FCoE device."""
|
||||
|
||||
NETWORK_DEVICE_TECHNOLOGY_ISCSI = 'Internet SCSI'
|
||||
"""Appears to the operating system as an iSCSI device."""
|
||||
|
||||
# LinkStatus Types
|
||||
|
||||
LINK_STATUS_DOWN = 'down'
|
||||
"""The port is enabled but link is down."""
|
||||
|
||||
LINK_STATUS_UP = 'up'
|
||||
"""The port is enabled and link is good (up)."""
|
||||
188
sushy/resources/system/network/device_function.py
Normal file
188
sushy/resources/system/network/device_function.py
Normal file
@@ -0,0 +1,188 @@
|
||||
# Copyright (c) 2021 Anexia Internetdienstleistungs GmbH
|
||||
# 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.
|
||||
|
||||
# This is referred from Redfish standard schema.
|
||||
# https://redfish.dmtf.org/schemas/v1/NetworkDeviceFunction.v1_3_3.json
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.system.network import mappings as net_maps
|
||||
from sushy.resources.system.network import port
|
||||
from sushy import utils
|
||||
|
||||
|
||||
class BootTargetsField(base.ListField):
|
||||
lun_id = base.Field("LUNID")
|
||||
"""The logical unit number (LUN) ID from which to boot on the device"""
|
||||
|
||||
priority = base.Field("BootPriority", adapter=utils.int_or_none)
|
||||
"""The relative priority for this entry in the boot targets array."""
|
||||
|
||||
wwpn = base.Field("WWPN")
|
||||
"""The World Wide Port Name (WWPN) from which to boot."""
|
||||
|
||||
|
||||
class VLANField(base.CompositeField):
|
||||
vlan_enabled = base.Field("VLANEnable", adapter=utils.bool_or_none)
|
||||
vlan_id = base.Field("VLANId", adapter=utils.int_or_none)
|
||||
|
||||
|
||||
class ISCSIBootField(base.CompositeField):
|
||||
authentication_method = base.MappedField(
|
||||
'AuthenticationMethod', net_maps.AUTHENTICATION_METHOD_TYPE_MAP)
|
||||
"""The configured capability of this network device function."""
|
||||
|
||||
initiator_default_gateway = base.Field('InitiatorDefaultGateway')
|
||||
"""The IPv6 or IPv4 iSCSI boot default gateway."""
|
||||
|
||||
initiator_ip_address = base.Field('InitiatorIPAddress')
|
||||
"""The IPv6 or IPv4 address of the iSCSI initiator."""
|
||||
|
||||
initiator_netmask = base.Field('InitiatorNetmask')
|
||||
"""The IPv6 or IPv4 netmask of the iSCSI boot initiator."""
|
||||
|
||||
ip_address_type = base.MappedField(
|
||||
'IPAddressType', net_maps.IP_ADDRESS_TYPE_MAP)
|
||||
"""The type of IP address being populated IP address fields."""
|
||||
|
||||
primary_dns = base.Field('PrimaryDNS')
|
||||
"""The IPv6 or IPv4 address of the primary DNS server."""
|
||||
|
||||
primary_lun = base.Field('PrimaryLUN', adapter=utils.int_or_none)
|
||||
"""The logical unit number (LUN) for the primary iSCSI boot target."""
|
||||
|
||||
primary_target_ip_address = base.Field('PrimaryTargetIPAddress')
|
||||
"""The IPv4 or IPv6 address for the primary iSCSI boot target."""
|
||||
|
||||
primary_target_tcp_port = base.Field('PrimaryTargetTCPPort')
|
||||
"""The TCP port for the primary iSCSI boot target."""
|
||||
|
||||
primary_vlan_enabled = base.Field(
|
||||
'PrimaryVLANEnable',
|
||||
adapter=utils.bool_or_none
|
||||
)
|
||||
"""An indication of whether the primary VLAN is enabled."""
|
||||
|
||||
primary_vlan_id = base.Field("PrimaryVLANId", adapter=utils.int_or_none)
|
||||
"""The 802.1q VLAN ID to use for iSCSI boot from the primary target."""
|
||||
|
||||
secondary_dns = base.Field('SecondaryDNS')
|
||||
"""The IPv6 or IPv4 address of the secondary DNS server."""
|
||||
|
||||
secondary_lun = base.Field('SecondaryLUN', adapter=utils.int_or_none)
|
||||
"""The logical unit number (LUN) for the secondary iSCSI boot target."""
|
||||
|
||||
secondary_target_ip_address = base.Field('SecondaryTargetIPAddress')
|
||||
"""The IPv4 or IPv6 address for the secondary iSCSI boot target."""
|
||||
|
||||
secondary_target_tcp_port = base.Field('SecondaryTargetTCPPort')
|
||||
"""The TCP port for the secondary iSCSI boot target."""
|
||||
|
||||
secondary_vlan_enabled = base.Field(
|
||||
'SecondaryVLANEnable', adapter=utils.bool_or_none)
|
||||
"""An indication of whether the secondary VLAN is enabled."""
|
||||
|
||||
secondary_vlan_id = base.Field(
|
||||
"SecondaryVLANId",
|
||||
adapter=utils.int_or_none
|
||||
)
|
||||
"""The 802.1q VLAN ID to use for iSCSI boot from the secondary target."""
|
||||
|
||||
|
||||
class EthernetField(base.CompositeField):
|
||||
mac_address = base.Field("MACAddress")
|
||||
"""The currently configured MAC address of the resource"""
|
||||
|
||||
mtu_size = base.Field("MTUSize", adapter=utils.int_or_none)
|
||||
"""The Maximum Transmission Unit (MTU) configured for this resource"""
|
||||
|
||||
permanent_mac_address = base.Field("PermanentMACAddress")
|
||||
"""The permanent MAC address assigned to this resource"""
|
||||
|
||||
vlan = VLANField("VLAN")
|
||||
"""The VLAN for this interface"""
|
||||
|
||||
|
||||
class FibreChannelField(base.CompositeField):
|
||||
boot_targets = BootTargetsField("BootTargets")
|
||||
"""An array of Fibre Channel boot targets configured for this resource."""
|
||||
|
||||
|
||||
class NetworkDeviceFunction(base.ResourceBase):
|
||||
capabilities = base.MappedListField(
|
||||
'NetDevFuncCapabilities', net_maps.NETWORK_TECHNOLOGY_TYPE_MAP)
|
||||
"""An array of capabilities for this network device function."""
|
||||
|
||||
type = base.MappedField(
|
||||
'NetDevFuncType', net_maps.NETWORK_TECHNOLOGY_TYPE_MAP)
|
||||
"""The configured capability of this network device function."""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""The network device function description"""
|
||||
|
||||
ethernet = EthernetField("Ethernet")
|
||||
"""The Ethernet capabilities, status, and configuration values."""
|
||||
|
||||
fibre_channel = FibreChannelField("FibreChannel")
|
||||
"""The Fibre Channel capabilities, status, and configuration values."""
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""Identifier for the network device function"""
|
||||
|
||||
iscsi_boot = ISCSIBootField('iSCSIBoot')
|
||||
"""
|
||||
The iSCSI boot capabilities, status, and configuration
|
||||
for a network device function.
|
||||
"""
|
||||
|
||||
max_virtual_functions = base.Field(
|
||||
'MaxVirtualFunctions',
|
||||
adapter=utils.int_or_none
|
||||
)
|
||||
"""
|
||||
The number of virtual functions that are available
|
||||
for this network device function.
|
||||
"""
|
||||
|
||||
name = base.Field('Name', required=True)
|
||||
"""The network device function name"""
|
||||
|
||||
status = common.StatusField('Status')
|
||||
"""The status of the resource"""
|
||||
|
||||
@property
|
||||
@utils.cache_it
|
||||
def assignable_physical_ports(self):
|
||||
"""An array of physical ports to which this resource may be assigned.
|
||||
|
||||
Network ports to which this network device function may be assigned.
|
||||
|
||||
:raises: MissingAttributeError if '@odata.id' field is missing.
|
||||
:returns: A list of `NetworkPort` instances
|
||||
"""
|
||||
paths = utils.get_sub_resource_path_by(
|
||||
self, "AssignablePhysicalPorts", is_collection=True)
|
||||
|
||||
return [port.NetworkPort(self._conn, path,
|
||||
redfish_version=self.redfish_version,
|
||||
registries=self.registries,
|
||||
root=self.root
|
||||
)
|
||||
for path in paths]
|
||||
|
||||
|
||||
class NetworkDeviceFunctionCollection(base.ResourceCollectionBase):
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return NetworkDeviceFunction
|
||||
53
sushy/resources/system/network/mappings.py
Normal file
53
sushy/resources/system/network/mappings.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2021 Anexia Internetdienstleistungs GmbH
|
||||
# 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.system.network import constants as net_cons
|
||||
|
||||
AUTHENTICATION_METHOD_TYPE_MAP = {
|
||||
'CHAP': net_cons.AUTHENTICATION_METHOD_CHAP,
|
||||
'MutualCHAP': net_cons.AUTHENTICATION_METHOD_MUTUAL_CHAP,
|
||||
'None': net_cons.AUTHENTICATION_METHOD_NONE
|
||||
}
|
||||
|
||||
BOOT_MODE_TYPE_MAP = {
|
||||
'Disabled': net_cons.BOOT_MODE_DISABLED,
|
||||
'FibreChannel': net_cons.NETWORK_DEVICE_TECHNOLOGY_FIBRE_CHANNEL,
|
||||
'FibreChannelOverEthernet': net_cons.NETWORK_DEVICE_TECHNOLOGY_FCOE,
|
||||
'PXE': net_cons.BOOT_MODE_PXE,
|
||||
'iSCSI': net_cons.NETWORK_DEVICE_TECHNOLOGY_ISCSI
|
||||
}
|
||||
|
||||
IP_ADDRESS_TYPE_MAP = {
|
||||
'IPv4': net_cons.IP_ADDRESS_TYPE_IPV4,
|
||||
'IPv6': net_cons.IP_ADDRESS_TYPE_IPV6,
|
||||
}
|
||||
|
||||
LINK_STATUS_TYPE_MAP = {
|
||||
'Up': net_cons.LINK_STATUS_UP,
|
||||
'Down': net_cons.LINK_STATUS_DOWN,
|
||||
}
|
||||
|
||||
FLOW_CONTROL_TYPE_MAP = {
|
||||
'None': net_cons.FLOW_CONTROL_NONE,
|
||||
'TX': net_cons.FLOW_CONTROL_TX,
|
||||
'RX': net_cons.FLOW_CONTROL_RX,
|
||||
'TX_RX': net_cons.FLOW_CONTROL_TX_RX,
|
||||
}
|
||||
|
||||
NETWORK_TECHNOLOGY_TYPE_MAP = {
|
||||
'Disabled': net_cons.NETWORK_DEVICE_TECHNOLOGY_DISABLED,
|
||||
'Ethernet': net_cons.NETWORK_DEVICE_TECHNOLOGY_ETHERNET,
|
||||
'FibreChannel': net_cons.NETWORK_DEVICE_TECHNOLOGY_FIBRE_CHANNEL,
|
||||
'iSCSI': net_cons.NETWORK_DEVICE_TECHNOLOGY_ISCSI,
|
||||
'FibreChannelOverEthernet': net_cons.NETWORK_DEVICE_TECHNOLOGY_FCOE
|
||||
}
|
||||
71
sushy/resources/system/network/port.py
Normal file
71
sushy/resources/system/network/port.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright (c) 2021 Anexia Internetdienstleistungs GmbH
|
||||
# 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.
|
||||
|
||||
# This is referred from Redfish standard schema.
|
||||
# https://redfish.dmtf.org/schemas/v1/NetworkPort.v1_2_1.json
|
||||
|
||||
from sushy.resources import base
|
||||
from sushy.resources import common
|
||||
from sushy.resources.system.network import mappings as net_maps
|
||||
|
||||
|
||||
class NetworkPortCollection(base.ResourceCollectionBase):
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return NetworkPort
|
||||
|
||||
|
||||
class NetworkPort(base.ResourceBase):
|
||||
associated_network_addresses = base.Field(
|
||||
"AssociatedNetworkAddresses", adapter=list
|
||||
)
|
||||
"""The array of configured network addresses that are associated."""
|
||||
|
||||
current_link_speed_mbps = base.Field(
|
||||
"CurrentLinkSpeedMbps", adapter=int
|
||||
)
|
||||
"""The network port current link speed."""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""The network port description"""
|
||||
|
||||
flow_control_configuration = base.MappedField(
|
||||
'FlowControlConfiguration',
|
||||
net_maps.FLOW_CONTROL_TYPE_MAP
|
||||
)
|
||||
"""The locally configured 802.3x flow control setting."""
|
||||
|
||||
flow_control_status = base.MappedField('FlowControlStatus',
|
||||
net_maps.FLOW_CONTROL_TYPE_MAP)
|
||||
"""The 802.3x flow control behavior negotiated with the link partner"""
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""The network port identity"""
|
||||
|
||||
link_status = base.MappedField(
|
||||
'LinkStatus',
|
||||
net_maps.LINK_STATUS_TYPE_MAP
|
||||
)
|
||||
"""The link status of the network port."""
|
||||
|
||||
name = base.Field(
|
||||
"Name", required=True
|
||||
)
|
||||
"""The network port name"""
|
||||
|
||||
physical_port_number = base.Field("PhysicalPortNumber", adapter=int)
|
||||
"""The physical port number label for this port."""
|
||||
|
||||
status = common.StatusField('Status')
|
||||
"""The network port status"""
|
||||
83
sushy/tests/unit/json_samples/network_device_function.json
Normal file
83
sushy/tests/unit/json_samples/network_device_function.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"@Redfish.Settings": {
|
||||
"@odata.context": "/redfish/v1/$metadata#Settings.Settings",
|
||||
"@odata.type": "#Settings.v1_3_0.Settings",
|
||||
"SettingsObject": {
|
||||
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1/Settings"
|
||||
},
|
||||
"SupportedApplyTimes": [
|
||||
"OnReset",
|
||||
"AtMaintenanceWindowStart",
|
||||
"InMaintenanceWindowOnReset"
|
||||
]
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#NetworkDeviceFunction.NetworkDeviceFunction",
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1",
|
||||
"@odata.type": "#NetworkDeviceFunction.v1_3_3.NetworkDeviceFunction",
|
||||
"AssignablePhysicalPorts": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2"
|
||||
}
|
||||
],
|
||||
"AssignablePhysicalPorts@odata.count": 1,
|
||||
"Description": "NetworkDeviceFunction",
|
||||
"Ethernet": {
|
||||
"MACAddress": "01:01:01:01:01:D1",
|
||||
"MTUSize": 1234,
|
||||
"PermanentMACAddress": "01:01:01:01:01:D1",
|
||||
"VLAN": {
|
||||
"VLANEnable": true,
|
||||
"VLANId": 1
|
||||
}
|
||||
},
|
||||
"FibreChannel": {
|
||||
"BootTargets": [
|
||||
{
|
||||
"LUNID": "1234",
|
||||
"WWPN": "ABCEDFG"
|
||||
}
|
||||
],
|
||||
"BootTargets@odata.count": 1
|
||||
},
|
||||
"Id": "NIC.Integrated.1-2-1",
|
||||
"Links": {
|
||||
"PhysicalPortAssignment": {
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2"
|
||||
},
|
||||
"Oem": {}
|
||||
},
|
||||
"MaxVirtualFunctions": 127,
|
||||
"Name": "NetworkDeviceFunction",
|
||||
"NetDevFuncCapabilities": [
|
||||
"Disabled",
|
||||
"Ethernet",
|
||||
"iSCSI"
|
||||
],
|
||||
"NetDevFuncCapabilities@odata.count": 3,
|
||||
"NetDevFuncType": "Ethernet",
|
||||
"Oem": {},
|
||||
"PhysicalPortAssignment": {
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2"
|
||||
},
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"iSCSIBoot": {
|
||||
"AuthenticationMethod": "None",
|
||||
"IPAddressType": "IPv4",
|
||||
"InitiatorDefaultGateway": "0.0.0.0",
|
||||
"InitiatorIPAddress": "0.0.0.0",
|
||||
"InitiatorNetmask": "0.0.0.0",
|
||||
"PrimaryDNS": "0.0.0.0",
|
||||
"PrimaryLUN": 0,
|
||||
"PrimaryTargetIPAddress": "0.0.0.0",
|
||||
"PrimaryTargetTCPPort": 3260,
|
||||
"SecondaryTargetIPAddress": "127.0.0.1",
|
||||
"SecondaryTargetTCPPort": 123,
|
||||
"SecondaryVLANEnable": false,
|
||||
"SecondaryVLANId": 1,
|
||||
"TargetInfoViaDHCP": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#NetworkDeviceFunctionCollection.NetworkDeviceFunctionCollection",
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions",
|
||||
"@odata.type": "#NetworkDeviceFunctionCollection.NetworkDeviceFunctionCollection",
|
||||
"Description": "Collection Of Network Device Function entities",
|
||||
"Members": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1"
|
||||
},
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1"
|
||||
}
|
||||
],
|
||||
"Members@odata.count": 2,
|
||||
"Name": "Network Device Function Collection"
|
||||
}
|
||||
55
sushy/tests/unit/json_samples/network_port.json
Normal file
55
sushy/tests/unit/json_samples/network_port.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#NetworkPort.NetworkPort",
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1",
|
||||
"@odata.type": "#NetworkPort.v1_2_3.NetworkPort",
|
||||
"ActiveLinkTechnology": "Ethernet",
|
||||
"AssociatedNetworkAddresses": [
|
||||
"01:02:03:04:05:06"
|
||||
],
|
||||
"CurrentLinkSpeedMbps": 10000,
|
||||
"Description": "Network Port View",
|
||||
"FlowControlConfiguration": "None",
|
||||
"FlowControlStatus": "None",
|
||||
"Id": "NIC.Integrated.1-1",
|
||||
"LinkStatus": "Up",
|
||||
"Name": "Network Port View",
|
||||
"NetDevFuncMaxBWAlloc": [
|
||||
{
|
||||
"MaxBWAllocPercent": 100,
|
||||
"NetworkDeviceFunction": {
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"NetDevFuncMaxBWAlloc@odata.count": 1,
|
||||
"NetDevFuncMinBWAlloc": [
|
||||
{
|
||||
"MinBWAllocPercent": 100,
|
||||
"NetworkDeviceFunction": {
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"NetDevFuncMinBWAlloc@odata.count": 1,
|
||||
"Oem": {},
|
||||
"PhysicalPortNumber": "1",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"SupportedEthernetCapabilities": [
|
||||
"WakeOnLAN"
|
||||
],
|
||||
"SupportedEthernetCapabilities@odata.count": 1,
|
||||
"SupportedLinkCapabilities": [
|
||||
{
|
||||
"AutoSpeedNegotiation": true,
|
||||
"LinkNetworkTechnology": "Ethernet",
|
||||
"LinkSpeedMbps": 10000
|
||||
}
|
||||
],
|
||||
"SupportedLinkCapabilities@odata.count": 1,
|
||||
"VendorId": "15b3",
|
||||
"WakeOnLANEnabled": false
|
||||
}
|
||||
16
sushy/tests/unit/json_samples/network_port_collection.json
Normal file
16
sushy/tests/unit/json_samples/network_port_collection.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#NetworkPortCollection.NetworkPortCollection",
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts",
|
||||
"@odata.type": "#NetworkPortCollection.NetworkPortCollection",
|
||||
"Description": "Collection Of Network Port entities",
|
||||
"Members": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1"
|
||||
},
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2"
|
||||
}
|
||||
],
|
||||
"Members@odata.count": 2,
|
||||
"Name": "Network Port Collection"
|
||||
}
|
||||
@@ -16,6 +16,8 @@ from unittest import mock
|
||||
|
||||
from sushy.resources import constants as res_cons
|
||||
from sushy.resources.system.network import adapter
|
||||
from sushy.resources.system.network import device_function
|
||||
from sushy.resources.system.network import port
|
||||
from sushy.tests.unit import base
|
||||
|
||||
|
||||
@@ -48,6 +50,93 @@ class NetworkAdapterTestCase(base.TestCase):
|
||||
self.assertEqual(res_cons.HEALTH_OK, self.adapter.status.health)
|
||||
self.assertEqual(res_cons.HEALTH_OK, self.adapter.status.health_rollup)
|
||||
|
||||
def test_network_ports(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('sushy/tests/unit/'
|
||||
'json_samples/network_port_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
actual_network_ports = self.adapter.network_ports
|
||||
self.assertIsInstance(actual_network_ports,
|
||||
port.NetworkPortCollection)
|
||||
self.conn.get.return_value.json.assert_called_once_with()
|
||||
|
||||
def test_network_ports_cached(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('sushy/tests/unit/'
|
||||
'json_samples/network_port_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
actual_ports = self.adapter.network_ports
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
self.assertIs(actual_ports,
|
||||
self.adapter.network_ports)
|
||||
self.conn.get.return_value.json.assert_not_called()
|
||||
|
||||
def test_network_ports_refresh(self):
|
||||
with open('sushy/tests/unit/'
|
||||
'json_samples/network_port_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
ports = self.adapter.network_ports
|
||||
self.assertIsInstance(ports, port.NetworkPortCollection)
|
||||
|
||||
with open('sushy/tests/unit/'
|
||||
'json_samples/network_adapter.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
|
||||
self.adapter.invalidate()
|
||||
self.adapter.refresh(force=False)
|
||||
|
||||
self.assertTrue(ports._is_stale)
|
||||
|
||||
with open('sushy/tests/unit/'
|
||||
'json_samples/network_port_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
self.assertIsInstance(self.adapter.network_ports,
|
||||
port.NetworkPortCollection)
|
||||
|
||||
def test_network_device_functions(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
actual_functions = self.adapter.network_device_functions
|
||||
self.assertIsInstance(actual_functions,
|
||||
device_function.NetworkDeviceFunctionCollection)
|
||||
self.conn.get.return_value.json.assert_called_once_with()
|
||||
|
||||
def test_network_device_functions_cached(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
actual_functions = self.adapter.network_device_functions
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
self.assertIs(actual_functions,
|
||||
self.adapter.network_device_functions)
|
||||
self.conn.get.return_value.json.assert_not_called()
|
||||
|
||||
def test_network_device_functions_refresh(self):
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
functions = self.adapter.network_device_functions
|
||||
self.assertIsInstance(functions,
|
||||
device_function.NetworkDeviceFunctionCollection)
|
||||
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_adapter.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
|
||||
self.adapter.invalidate()
|
||||
self.adapter.refresh(force=False)
|
||||
|
||||
self.assertTrue(functions._is_stale)
|
||||
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function_collection.json') as f:
|
||||
self.conn.get.return_value.json.return_value = json.load(f)
|
||||
self.assertIsInstance(self.adapter.network_device_functions,
|
||||
device_function.NetworkDeviceFunctionCollection)
|
||||
|
||||
|
||||
class NetworkAdapterCollectionTestCase(base.TestCase):
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
# 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
|
||||
from unittest import mock
|
||||
|
||||
from sushy.resources import constants as res_cons
|
||||
from sushy.resources.system.network import constants as net_cons
|
||||
from sushy.resources.system.network import device_function
|
||||
from sushy.tests.unit import base
|
||||
|
||||
|
||||
class NetworkDeviceFunctionTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkDeviceFunctionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function.json') as f:
|
||||
self.json_doc = json.load(f)
|
||||
|
||||
self.conn.get.return_value.json.return_value = self.json_doc
|
||||
|
||||
self.function = device_function.NetworkDeviceFunction(
|
||||
self.conn,
|
||||
'/redfish/v1/Chassis/Blade1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.function._parse_attributes(self.json_doc)
|
||||
self.assertEqual('1.0.2', self.function.redfish_version)
|
||||
self.assertEqual('NIC.Integrated.1-2-1', self.function.identity)
|
||||
self.assertEqual('NetworkDeviceFunction', self.function.name)
|
||||
self.assertEqual('NetworkDeviceFunction', self.function.description)
|
||||
self.assertEqual(res_cons.STATE_ENABLED, self.function.status.state)
|
||||
self.assertEqual(res_cons.HEALTH_OK,
|
||||
self.function.status.health)
|
||||
self.assertEqual(res_cons.HEALTH_OK,
|
||||
self.function.status.health_rollup)
|
||||
self.assertEqual(self.function.type,
|
||||
net_cons.NETWORK_DEVICE_TECHNOLOGY_ETHERNET)
|
||||
self.assertEqual([
|
||||
net_cons.NETWORK_DEVICE_TECHNOLOGY_DISABLED,
|
||||
net_cons.NETWORK_DEVICE_TECHNOLOGY_ETHERNET,
|
||||
net_cons.NETWORK_DEVICE_TECHNOLOGY_ISCSI,
|
||||
], self.function.capabilities)
|
||||
self.assertEqual(1,
|
||||
len(self.function.fibre_channel.boot_targets))
|
||||
self.assertEqual('ABCEDFG',
|
||||
self.function.fibre_channel.boot_targets[0].wwpn)
|
||||
self.assertEqual('1234',
|
||||
self.function.fibre_channel.boot_targets[0].lun_id)
|
||||
self.assertIsNone(
|
||||
self.function.fibre_channel.boot_targets[0].priority
|
||||
)
|
||||
self.assertEqual(127, self.function.max_virtual_functions)
|
||||
self.assertEqual('01:01:01:01:01:D1',
|
||||
self.function.ethernet.mac_address)
|
||||
self.assertEqual('01:01:01:01:01:D1',
|
||||
self.function.ethernet.permanent_mac_address)
|
||||
self.assertEqual(1234,
|
||||
self.function.ethernet.mtu_size)
|
||||
self.assertEqual(1,
|
||||
self.function.ethernet.vlan.vlan_id)
|
||||
self.assertTrue(self.function.ethernet.vlan.vlan_enabled)
|
||||
self.assertEqual(net_cons.AUTHENTICATION_METHOD_NONE,
|
||||
self.function.iscsi_boot.authentication_method)
|
||||
self.assertEqual(net_cons.IP_ADDRESS_TYPE_IPV4,
|
||||
self.function.iscsi_boot.ip_address_type)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.initiator_ip_address)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.initiator_default_gateway)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.initiator_netmask)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.primary_dns)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.primary_dns)
|
||||
self.assertEqual(0, self.function.iscsi_boot.primary_lun)
|
||||
self.assertEqual('0.0.0.0',
|
||||
self.function.iscsi_boot.primary_target_ip_address)
|
||||
self.assertEqual(3260,
|
||||
self.function.iscsi_boot.primary_target_tcp_port)
|
||||
self.assertFalse(self.function.iscsi_boot.secondary_vlan_enabled)
|
||||
self.assertEqual(1,
|
||||
self.function.iscsi_boot.secondary_vlan_id)
|
||||
self.assertEqual(123,
|
||||
self.function.iscsi_boot.secondary_target_tcp_port)
|
||||
|
||||
|
||||
class NetworkDeviceFunctionCollectionTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkDeviceFunctionCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_device_function_collection.json') as f:
|
||||
self.json_doc = json.load(f)
|
||||
|
||||
self.conn.get.return_value.json.return_value = self.json_doc
|
||||
|
||||
self.function_col = device_function.NetworkDeviceFunctionCollection(
|
||||
self.conn, '/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.function_col._parse_attributes(self.json_doc)
|
||||
self.assertEqual((
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1',
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1'
|
||||
),
|
||||
self.function_col.members_identities)
|
||||
|
||||
@mock.patch.object(device_function, 'NetworkDeviceFunction', autospec=True)
|
||||
def test_get_member(self, device_function_mock):
|
||||
self.function_col.get_member(
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1',
|
||||
)
|
||||
device_function_mock.assert_called_once_with(
|
||||
self.function_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1',
|
||||
redfish_version=self.function_col.redfish_version,
|
||||
registries=None,
|
||||
root=self.function_col.root)
|
||||
|
||||
@mock.patch.object(device_function, 'NetworkDeviceFunction', autospec=True)
|
||||
def test_get_members(self, device_function_mock):
|
||||
members = self.function_col.get_members()
|
||||
device_function_mock.assert_has_calls([
|
||||
mock.call(
|
||||
self.function_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-1-1',
|
||||
redfish_version=self.function_col.redfish_version,
|
||||
registries=None,
|
||||
root=self.function_col.root
|
||||
),
|
||||
mock.call(
|
||||
self.function_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkDeviceFunctions/NIC.Integrated.1-2-1',
|
||||
redfish_version=self.function_col.redfish_version,
|
||||
registries=None,
|
||||
root=self.function_col.root
|
||||
),
|
||||
])
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(2, len(members))
|
||||
115
sushy/tests/unit/resources/system/network/test_port.py
Normal file
115
sushy/tests/unit/resources/system/network/test_port.py
Normal file
@@ -0,0 +1,115 @@
|
||||
# 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
|
||||
from unittest import mock
|
||||
|
||||
from sushy.resources import constants as res_cons
|
||||
from sushy.resources.system.network import constants as net_cons
|
||||
from sushy.resources.system.network import port
|
||||
from sushy.tests.unit import base
|
||||
|
||||
|
||||
class NetworkPortTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkPortTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/network_port.json') as f:
|
||||
self.json_doc = json.load(f)
|
||||
|
||||
self.conn.get.return_value.json.return_value = self.json_doc
|
||||
|
||||
self.port = port.NetworkPort(
|
||||
self.conn, '/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'/NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.port._parse_attributes(self.json_doc)
|
||||
self.assertEqual('1.0.2', self.port.redfish_version)
|
||||
self.assertEqual('NIC.Integrated.1-1', self.port.identity)
|
||||
self.assertEqual('Network Port View', self.port.name)
|
||||
self.assertEqual('Network Port View', self.port.description)
|
||||
self.assertEqual(res_cons.STATE_ENABLED, self.port.status.state)
|
||||
self.assertEqual(res_cons.HEALTH_OK, self.port.status.health)
|
||||
self.assertEqual(res_cons.HEALTH_OK, self.port.status.health_rollup)
|
||||
self.assertEqual(['01:02:03:04:05:06'],
|
||||
self.port.associated_network_addresses)
|
||||
self.assertEqual(10000, self.port.current_link_speed_mbps)
|
||||
self.assertEqual(net_cons.FLOW_CONTROL_NONE,
|
||||
self.port.flow_control_configuration)
|
||||
self.assertEqual(net_cons.FLOW_CONTROL_NONE,
|
||||
self.port.flow_control_status)
|
||||
self.assertEqual(net_cons.LINK_STATUS_UP, self.port.link_status)
|
||||
|
||||
|
||||
class NetworkPortCollectionTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkPortCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'network_port_collection.json') as f:
|
||||
self.json_doc = json.load(f)
|
||||
|
||||
self.conn.get.return_value.json.return_value = self.json_doc
|
||||
|
||||
self.port_col = port.NetworkPortCollection(
|
||||
self.conn, '/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.port_col._parse_attributes(self.json_doc)
|
||||
self.assertEqual((
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1',
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2'
|
||||
),
|
||||
self.port_col.members_identities)
|
||||
|
||||
@mock.patch.object(port, 'NetworkPort', autospec=True)
|
||||
def test_get_member(self, NetworkPort_mock):
|
||||
self.port_col.get_member(
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1'
|
||||
)
|
||||
NetworkPort_mock.assert_called_once_with(
|
||||
self.port_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1',
|
||||
redfish_version=self.port_col.redfish_version, registries=None,
|
||||
root=self.port_col.root)
|
||||
|
||||
@mock.patch.object(port, 'NetworkPort', autospec=True)
|
||||
def test_get_members(self, NetworkPort_mock):
|
||||
members = self.port_col.get_members()
|
||||
NetworkPort_mock.assert_has_calls([
|
||||
mock.call(
|
||||
self.port_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-1',
|
||||
redfish_version=self.port_col.redfish_version, registries=None,
|
||||
root=self.port_col.root
|
||||
),
|
||||
mock.call(
|
||||
self.port_col._conn,
|
||||
'/redfish/v1/Chassis/System.Embedded.1/NetworkAdapters/'
|
||||
'NIC.Integrated.1/NetworkPorts/NIC.Integrated.1-2',
|
||||
redfish_version=self.port_col.redfish_version, registries=None,
|
||||
root=self.port_col.root
|
||||
),
|
||||
])
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(2, len(members))
|
||||
Reference in New Issue
Block a user