diff --git a/rsd_lib/resources/v2_1/ethernet_switch/ethernet_switch.py b/rsd_lib/resources/v2_1/ethernet_switch/ethernet_switch.py index 8aad16c..c63fa01 100644 --- a/rsd_lib/resources/v2_1/ethernet_switch/ethernet_switch.py +++ b/rsd_lib/resources/v2_1/ethernet_switch/ethernet_switch.py @@ -15,9 +15,11 @@ import logging +from sushy import exceptions from sushy.resources import base from sushy import utils +from rsd_lib.resources.v2_1.ethernet_switch import port from rsd_lib import utils as rsd_lib_utils LOG = logging.getLogger(__name__) @@ -58,8 +60,8 @@ class EthernetSwitch(base.ResourceBase): model = base.Field('Model') """The ethernet switch model""" - manufacturing_data = base.Field('ManufacturingData') - """The ethernet switch manufacturing data""" + manufacturing_date = base.Field('ManufacturingDate') + """The ethernet switch manufacturing date""" seria_number = base.Field('SerialNumber') """The ethernet switch serial number""" @@ -83,8 +85,7 @@ class EthernetSwitch(base.ResourceBase): adapter=rsd_lib_utils.get_resource_identity) """The ethernet switch ACLs""" - ports = base.Field('Ports', default=(), - adapter=rsd_lib_utils.get_resource_identity) + _ports = None # ref to PortCollection instance """The ethernet switch ports""" links = LinksField('Links') @@ -102,6 +103,33 @@ class EthernetSwitch(base.ResourceBase): identity, redfish_version) + def _get_port_collection_path(self): + """Helper functionto find the PortCollection path""" + port_col = self.json.get('Ports') + if not port_col: + raise exceptions.MissingAttributeError(attribute='Ports', + resource=self._path) + return rsd_lib_utils.get_resource_identity(port_col) + + @property + def ports(self): + """Property to provide reference to `PortCollection` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + if self._ports is None: + self._ports = port.PortCollection( + self._conn, self._get_port_collection_path(), + redfish_version=self.redfish_version + ) + + return self._ports + + def refresh(self): + super(EthernetSwitch, self).refresh() + self._ports = None + class EthernetSwitchCollection(base.ResourceCollectionBase): diff --git a/rsd_lib/resources/v2_1/ethernet_switch/port.py b/rsd_lib/resources/v2_1/ethernet_switch/port.py new file mode 100644 index 0000000..059a980 --- /dev/null +++ b/rsd_lib/resources/v2_1/ethernet_switch/port.py @@ -0,0 +1,179 @@ +# 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 logging + +from sushy.resources import base +from sushy import utils + +from rsd_lib import utils as rsd_lib_utils + +LOG = logging.getLogger(__name__) + + +class StatusField(base.CompositeField): + state = base.Field('State') + """The port state""" + + health = base.Field('Health') + """The port health""" + + health_rollup = base.Field('HealthRollup') + """The port health rollup""" + + +class NeighborInfoField(base.CompositeField): + switch_id = base.Field('SwitchId') + port_id = base.Field('PortId') + cable_id = base.Field('CableId') + + +class IPv4AddressesField(base.ListField): + address = base.Field('Address') + """The port ipv4 address""" + + subnet_mask = base.Field('SubnetMask') + """The port ipv4 address subnet mask""" + + address_origin = base.Field('AddressOrigin') + """The port ipv4 address origin""" + + gateway = base.Field('Gateway') + """The port ipv4 address gateway""" + + +class IPv6AddressesField(base.ListField): + address = base.Field('Address') + """The port ipv6 address""" + + prefix_length = base.Field('PrefixLength', adapter=int) + """The port ipv6 address prefix length""" + + address_origin = base.Field('AddressOrigin') + """The port ipv6 address origin""" + + address_state = base.Field('AddressState') + """The port ipv6 address gateway""" + + +class LinksField(base.CompositeField): + primary_vlan = base.Field('PrimaryVLAN', + adapter=rsd_lib_utils.get_resource_identity) + switch = base.Field('Switch', adapter=rsd_lib_utils.get_resource_identity) + member_of_port = base.Field('MemberOfPort', + adapter=rsd_lib_utils.get_resource_identity) + port_members = base.Field('PortMembers', adapter=list) + active_acls = base.Field('ActiveACLs', + adapter=utils.get_members_identities) + + +class Port(base.ResourceBase): + + identity = base.Field('Id', required=True) + """The port identity string""" + + name = base.Field('Name') + """The port name""" + + description = base.Field('Description') + """The port description""" + + port_id = base.Field('PortId') + """The port id""" + + status = StatusField('Status') + """The port status""" + + link_type = base.Field('LinkType') + """The port link type""" + + operational_state = base.Field('OperationalState') + """The port operational state""" + + administrative_state = base.Field('AdministrativeState') + """The port administrative state""" + + link_speed_mbps = base.Field('LinkSpeedMbps', adapter=int) + """The port link speed(mbps)""" + + neighbor_info = NeighborInfoField('NeighborInfo') + """The port neighbor info""" + + neighbor_mac = base.Field('NeighborMAC') + """The port neighbor mac""" + + frame_size = base.Field('FrameSize', adapter=int) + """The port frame size""" + + autosense = base.Field('Autosense', adapter=bool) + """The boolean indicate the autosense is enabled or not""" + + full_duplex = base.Field('FullDuplex', adapter=bool) + """The boolean indicate the full duplex is enabled or not""" + + mac_address = base.Field('MACAddress') + """The port mac address""" + + ipv4_addresses = IPv4AddressesField('IPv4Addresses') + """The port ipv4 link info""" + + ipv6_addresses = IPv6AddressesField('IPv6Addresses') + """The port ipv6 link info""" + + port_class = base.Field('PortClass') + """The port class""" + + port_mode = base.Field('PortMode') + """The port mode""" + + port_type = base.Field('PortType') + """The port type""" + + vlans = base.Field('VLANs', adapter=rsd_lib_utils.get_resource_identity) + """The port vlans""" + + static_macs = base.Field('StaticMACs', + adapter=rsd_lib_utils.get_resource_identity) + """The port static macs""" + + links = LinksField('Links') + """The port links""" + + def __init__(self, connector, identity, redfish_version=None): + """A class representing an Port + + :param connector: A Connector instance + :param identity: The identity of the Port resource + :param redfish_version: The version of RedFish. Used to construct + the object according to schema of the given version. + """ + super(Port, self).__init__(connector, identity, redfish_version) + + +class PortCollection(base.ResourceCollectionBase): + + @property + def _resource_type(self): + return Port + + def __init__(self, connector, path, redfish_version=None): + """A class representing an Port + + :param connector: A Connector instance + :param path: The canonical path to the Port collection resource + :param redfish_version: The version of RedFish. Used to construct + the object according to schema of the given version. + """ + super(PortCollection, self).__init__(connector, path, redfish_version) diff --git a/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port.json b/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port.json new file mode 100644 index 0000000..5a0f7ee --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port.json @@ -0,0 +1,79 @@ +{ + "@odata.context": "/redfish/v1/$metadata#EthernetSwitches/Members/1/Ports/Members/1/$entity", + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1", + "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort", + "Id": "Port1", + "Name": "Switch Port", + "Description": "description-as-string", + "PortId": "sw0p10", + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollup": "OK" + }, + "LinkType": "Ethernet", + "OperationalState": "Up", + "AdministrativeState": "Up", + "LinkSpeedMbps": 10000, + "NeighborInfo": { + "SwitchId": "sw2", + "PortId": "11", + "CableId": "CustomerWritableThing" + }, + "NeighborMAC": "00:11:22:33:44:55", + "FrameSize": 1520, + "Autosense": true, + "FullDuplex": true, + "MACAddress": "2c:60:0c:72:e6:33", + "IPv4Addresses": [ + { + "Address": "192.168.0.10", + "SubnetMask": "255.255.252.0", + "AddressOrigin": "Static", + "Gateway": "192.168.0.1" + } + ], + "IPv6Addresses": [ + { + "Address": "fe80::1ec1:deff:fe6f:1e24", + "PrefixLength": 64, + "AddressOrigin": "Static", + "AddressState": "Preferred" + } + ], + "PortClass": "Logical", + "PortMode": "LinkAggregationStatic", + "PortType": "Upstream", + "Oem": {}, + "VLANs": { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs" + }, + "StaticMACs": { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs" + }, + "Links": { + "PrimaryVLAN": { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs/VLAN1" + }, + "Switch": { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1" + }, + "MemberOfPort": { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/LAG1" + }, + "PortMembers": [], + "ActiveACLs": [ + { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/ACLs/ACL1" + } + ], + "Oem": { + "Intel_RackScale": { + "@odata.type": "#Intel.Oem.EthernetSwitchPort", + "NeighborInterface": { + "@odata.id": "/redfish/v1/Systems/1/EthernetInterfaces/3" + } + } + } + } +} diff --git a/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port_collection.json b/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port_collection.json new file mode 100644 index 0000000..d8cbfc4 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port_collection.json @@ -0,0 +1,13 @@ +{ + "@odata.context": "/redfish/v1/$metadata#EthernetSwitches/Members/1/Ports", + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports", + "@odata.type": "#SwitchPortsCollection.SwitchPortsCollection", + "Name": "Ethernet Switch Port Collection", + "Description": "Switch Port Collection", + "Members@odata.count": 1, + "Members": [ + { + "@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1" + } + ] +} diff --git a/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/__init__.py b/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_ethernet_switch.py b/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_ethernet_switch.py index 44f33eb..2f44034 100644 --- a/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_ethernet_switch.py +++ b/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_ethernet_switch.py @@ -1,3 +1,6 @@ +# Copyright 2017 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 @@ -13,16 +16,17 @@ import json import mock - -from sushy.tests.unit import base +from sushy import exceptions +import testtools from rsd_lib.resources.v2_1.ethernet_switch import ethernet_switch +from rsd_lib.resources.v2_1.ethernet_switch import port -class TestEthernetSwtich(base.TestCase): +class EthernetSwtichTestCase(testtools.TestCase): def setUp(self): - super(TestEthernetSwtich, self).setUp() + super(EthernetSwtichTestCase, self).setUp() self.conn = mock.Mock() with open('rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch.json', @@ -34,7 +38,7 @@ class TestEthernetSwtich(base.TestCase): '/redfish/v1/EthernetSwitches/Switch1', redfish_version='1.0.2') - def test_parse_attributes(self): + def test__parse_attributes(self): self.ethernet_switch_inst._parse_attributes() self.assertEqual('1.0.2', self.ethernet_switch_inst.redfish_version) self.assertEqual('Switch1', self.ethernet_switch_inst.identity) @@ -44,7 +48,7 @@ class TestEthernetSwtich(base.TestCase): self.assertEqual('Quanta', self.ethernet_switch_inst.manufacturer) self.assertEqual('ly8_rangley', self.ethernet_switch_inst.model) self.assertEqual('02/21/2015 00:00:00', - self.ethernet_switch_inst.manufacturing_data) + self.ethernet_switch_inst.manufacturing_date) self.assertEqual('2M220100SL', self.ethernet_switch_inst.seria_number) self.assertEqual('1LY8UZZ0007', self.ethernet_switch_inst.part_number) self.assertEqual('ONIE', self.ethernet_switch_inst.firmware_name) @@ -54,22 +58,81 @@ class TestEthernetSwtich(base.TestCase): self.assertEqual('OK', self.ethernet_switch_inst.status.health) self.assertEqual('/redfish/v1/EthernetSwitches/Switch1/ACLs', self.ethernet_switch_inst.acls) - self.assertEqual('/redfish/v1/EthernetSwitches/Switch1/Ports', - self.ethernet_switch_inst.ports) + self.assertIsNone(self.ethernet_switch_inst._ports) self.assertEqual('/redfish/v1/Chassis/FabricModule1', self.ethernet_switch_inst.links.chassis) - self.assertEqual(('/redfish/v1/EthernetSwitches/Switch1/Ports',), + self.assertEqual(('/redfish/v1/Managers/Manager1',), self.ethernet_switch_inst.links.managed_by) + def test__get_port_collection_path(self): + expected = '/redfish/v1/EthernetSwitches/Switch1/Ports' + result = self.ethernet_switch_inst._get_port_collection_path() + self.assertEqual(expected, result) -class TestEthernetSwitchCollection(base.TestCase): + def test__get_port_collection_path_missing_attr(self): + self.ethernet_switch_inst._json.pop('Ports') + self.assertRaisesRegex( + exceptions.MissingAttributeError, 'attribute Ports', + self.ethernet_switch_inst._get_port_collection_path) + + def test_ports(self): + # check for the underpath variable value + self.assertIsNone(self.ethernet_switch_inst._ports) + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'ethernet_switch_port_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_ports = self.ethernet_switch_inst.ports + # | THEN | + self.assertIsInstance(actual_ports, + port.PortCollection) + 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_ports, + self.ethernet_switch_inst.ports) + self.conn.get.return_value.json.assert_not_called() + + def test_ports_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'ethernet_switch_port_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.ethernet_switch_inst.ports, + port.PortCollection) + + # On refreshing the port instance... + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'ethernet_switch.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.ethernet_switch_inst.refresh() + + # | WHEN & THEN | + self.assertIsNone(self.ethernet_switch_inst._ports) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_1/' + 'ethernet_switch_port_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.ethernet_switch_inst.ports, + port.PortCollection) + + +class EthernetSwitchCollectionTestCase(testtools.TestCase): def setUp(self): - super(TestEthernetSwitchCollection, self).setUp() + super(EthernetSwitchCollectionTestCase, self).setUp() self.conn = mock.Mock() with open('rsd_lib/tests/unit/json_samples/v2_1/' - 'manager_collection.json', 'r') as f: + 'ethernet_switch_collection.json', 'r') as f: self.conn.get.return_value.json.return_value = json.loads(f.read()) self.ethernet_switch_col = ethernet_switch.EthernetSwitchCollection( @@ -77,17 +140,18 @@ class TestEthernetSwitchCollection(base.TestCase): 'redfish/v1/EthernetSwitches', redfish_version='1.0.2') - def test_parse_attributes(self): + def test__parse_attributes(self): self.ethernet_switch_col._parse_attributes() self.assertEqual('1.0.2', self.ethernet_switch_col.redfish_version) self.assertEqual('Ethernet Switches Collection', self.ethernet_switch_col.name) - self.assertIn(('/redfish/v1/EthernetSwitches/Switch1',), - self.ethernet_switch_col.members_identities) + self.assertEqual(('/redfish/v1/EthernetSwitches/Switch1',), + self.ethernet_switch_col.members_identities) @mock.patch.object(ethernet_switch, 'EthernetSwitch', autospec=True) def test_get_member(self, mock_ethernet_switch): - self.manager_col.get_member('/redfish/v1/EthernetSwitches/Switch1') + self.ethernet_switch_col.get_member( + '/redfish/v1/EthernetSwitches/Switch1') mock_ethernet_switch.assert_called_once_with( self.ethernet_switch_col._conn, @@ -99,5 +163,5 @@ class TestEthernetSwitchCollection(base.TestCase): def test_get_members(self, mock_ethernet_switch): members = self.ethernet_switch_col.get_members() self.assertEqual(mock_ethernet_switch.call_count, 1) - self.assertInstance(members, list) + self.assertIsInstance(members, list) self.assertEqual(1, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_port.py b/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_port.py new file mode 100644 index 0000000..0bcd184 --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_1/ethernet_switch/test_port.py @@ -0,0 +1,143 @@ +# 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.ethernet_switch import port + + +class PortTestCase(testtools.TestCase): + + def setUp(self): + super(PortTestCase, self).setUp() + self.conn = mock.Mock() + with open( + 'rsd_lib/tests/unit/json_samples/v2_1/ethernet_switch_port.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.port_inst = port.Port( + self.conn, '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1', + redfish_version='1.0.2' + ) + + def test__parse_attributes(self): + self.port_inst._parse_attributes() + self.assertEqual('1.0.2', self.port_inst.redfish_version) + self.assertEqual('Port1', self.port_inst.identity) + self.assertEqual('Switch Port', self.port_inst.name) + self.assertEqual('description-as-string', self.port_inst.description) + self.assertEqual('sw0p10', self.port_inst.port_id) + self.assertEqual('Enabled', self.port_inst.status.state) + self.assertEqual('OK', self.port_inst.status.health) + self.assertEqual('OK', self.port_inst.status.health_rollup) + self.assertEqual('Ethernet', self.port_inst.link_type) + self.assertEqual('Up', self.port_inst.operational_state) + self.assertEqual('Up', self.port_inst.administrative_state) + self.assertEqual(10000, self.port_inst.link_speed_mbps) + self.assertEqual('sw2', self.port_inst.neighbor_info.switch_id) + self.assertEqual('11', self.port_inst.neighbor_info.port_id) + self.assertEqual('CustomerWritableThing', + self.port_inst.neighbor_info.cable_id) + self.assertEqual('00:11:22:33:44:55', + self.port_inst.neighbor_mac) + self.assertEqual(1520, self.port_inst.frame_size) + self.assertEqual(True, self.port_inst.autosense) + self.assertEqual(True, self.port_inst.full_duplex) + self.assertEqual('2c:60:0c:72:e6:33', self.port_inst.mac_address) + self.assertEqual('192.168.0.10', + self.port_inst.ipv4_addresses[0].address) + self.assertEqual('255.255.252.0', + self.port_inst.ipv4_addresses[0].subnet_mask) + self.assertEqual('Static', + self.port_inst.ipv4_addresses[0].address_origin) + self.assertEqual('192.168.0.1', + self.port_inst.ipv4_addresses[0].gateway) + self.assertEqual('fe80::1ec1:deff:fe6f:1e24', + self.port_inst.ipv6_addresses[0].address) + self.assertEqual(64, self.port_inst.ipv6_addresses[0].prefix_length) + self.assertEqual('Static', + self.port_inst.ipv6_addresses[0].address_origin) + self.assertEqual('Preferred', + self.port_inst.ipv6_addresses[0].address_state) + self.assertEqual('Logical', self.port_inst.port_class) + self.assertEqual('LinkAggregationStatic', self.port_inst.port_mode) + self.assertEqual('Upstream', self.port_inst.port_type) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs', + self.port_inst.vlans) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs', + self.port_inst.static_macs) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs/VLAN1', + self.port_inst.links.primary_vlan) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1', + self.port_inst.links.switch) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1/Ports/LAG1', + self.port_inst.links.member_of_port) + self.assertEqual([], self.port_inst.links.port_members) + self.assertEqual( + '/redfish/v1/EthernetSwitches/Switch1/ACLs/ACL1', + self.port_inst.links.active_acls[0]) + + +class PortCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(PortCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open( + 'rsd_lib/tests/unit/json_samples/v2_1/' + 'ethernet_switch_port_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.port_col = port.PortCollection( + self.conn, '/redfish/v1/EthernetSwitch/Ports', + redfish_version='1.0.2') + + def test__parse_attributes(self): + self.port_col._parse_attributes() + self.assertEqual('1.0.2', self.port_col.redfish_version) + self.assertEqual( + 'Ethernet Switch Port Collection', + self.port_col.name) + self.assertEqual( + ('/redfish/v1/EthernetSwitches/Switch1/Ports/Port1'), + self.port_col.members_identities) + + @mock.patch.object(port, 'Port', autospec=True) + def test_get_member(self, mock_port): + self.port_col.get_member( + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1' + ) + mock_port.assert_called_once_with( + self.port_col._conn, + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1', + redfish_version=self.port_col.redfish_version) + + @mock.patch.object(port, 'Port', autospec=True) + def test_get_members(self, mock_port): + members = self.port_col.get_members() + mock_port.assert_called_with( + self.port_col.__conn, + '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1', + redfish_version=self.port_col.redfish_version) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members))