add ethernet switch port static mac field for rsd 2.1;

fix bug for network interface test

Change-Id: I5675374ad3b68b5167ba7c594bb3f8641d6c561a
This commit is contained in:
ya.wang 2018-08-08 09:52:02 +08:00
parent 09085c01b0
commit 9c721a1ffa
8 changed files with 280 additions and 15 deletions

View File

@ -121,8 +121,7 @@ class EthernetSwitch(base.ResourceBase):
if self._ports is None: if self._ports is None:
self._ports = port.PortCollection( self._ports = port.PortCollection(
self._conn, self._get_port_collection_path(), self._conn, self._get_port_collection_path(),
redfish_version=self.redfish_version redfish_version=self.redfish_version)
)
return self._ports return self._ports

View File

@ -15,9 +15,11 @@
import logging import logging
from sushy import exceptions
from sushy.resources import base from sushy.resources import base
from sushy import utils from sushy import utils
from rsd_lib.resources.v2_1.ethernet_switch import static_mac
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -144,8 +146,7 @@ class Port(base.ResourceBase):
vlans = base.Field('VLANs', adapter=rsd_lib_utils.get_resource_identity) vlans = base.Field('VLANs', adapter=rsd_lib_utils.get_resource_identity)
"""The port vlans""" """The port vlans"""
static_macs = base.Field('StaticMACs', _static_macs = None # ref to StaticMACCollection instance
adapter=rsd_lib_utils.get_resource_identity)
"""The port static macs""" """The port static macs"""
links = LinksField('Links') links = LinksField('Links')
@ -161,6 +162,32 @@ class Port(base.ResourceBase):
""" """
super(Port, self).__init__(connector, identity, redfish_version) super(Port, self).__init__(connector, identity, redfish_version)
def _get_static_mac_collection_path(self):
"""Helper function to find the StaticMACCollection path"""
static_mac_col = self.json.get('StaticMACs')
if not static_mac_col:
raise exceptions.MissingAttributeError(attribute='StaticMAC',
resource=self._path)
return rsd_lib_utils.get_resource_identity(static_mac_col)
@property
def static_macs(self):
"""Property to provide reference to `StaticMACollection` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
if self._static_macs is None:
self._static_macs = static_mac.StaticMACCollection(
self._conn, self._get_static_mac_collection_path(),
redfish_version=self.redfish_version)
return self._static_macs
def refresh(self):
super(Port, self).refresh()
self._static_macs = None
class PortCollection(base.ResourceCollectionBase): class PortCollection(base.ResourceCollectionBase):

View File

@ -0,0 +1,68 @@
# 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 rsd_lib import utils as rsd_lib_utils
class StaticMAC(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The static mac identity string"""
name = base.Field('Name')
"""The static mac name"""
description = base.Field('Description')
"""The static mac description"""
mac_address = base.Field('MACAddress')
"""The static mac address"""
vlan_id = base.Field('VLANId', adapter=rsd_lib_utils.int_or_none)
"""The static mac vlan id"""
oem = base.Field('Oem')
"""The static mac oem info"""
def __init__(self, connector, identity, redfish_version=None):
"""A class representing an StaticMAC
:param connector: A Connector instance
:param identity: The identity of the StaticMAC resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(StaticMAC, self).__init__(connector, identity, redfish_version)
class StaticMACCollection(base.ResourceCollectionBase):
@property
def _resource_type(self):
return StaticMAC
def __init__(self, connector, path, redfish_version=None):
"""A class representing an StaticMAC
:param connector: A Connector instance
:param identity: The identity of the StaticMAC Collection resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(StaticMACCollection, self).__init__(connector,
path,
redfish_version)

View File

@ -0,0 +1,11 @@
{
"@odata.context": "/redfish/v1/$metadata#EthernetSwitches/Members/Switch1/Ports/Members/StaticMACs/Members/$entity",
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs/1",
"@odata.type": "#StaticMAC.v1_0_0.StaticMAC",
"Id": "1",
"Name": "StaticMAC",
"Description": "description-as-string",
"MACAddress": "00:11:22:33:44:55",
"VLANId": 112,
"Oem": {}
}

View File

@ -0,0 +1,13 @@
{
"@odata.context": "/redfish/v1/$metadata#EthernetSwitches/Members/Switch1/Ports/Members/StaticMACs",
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs",
"@odata.type": "#StaticMACCollection.StaticMACCollection",
"Name": "Static MAC Collection",
"Description": "description-as-string",
"Members@odata.count": 1,
"Members": [
{
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs/1"
}
]
}

View File

@ -16,9 +16,11 @@
import json import json
import mock import mock
from sushy import exceptions
import testtools import testtools
from rsd_lib.resources.v2_1.ethernet_switch import port from rsd_lib.resources.v2_1.ethernet_switch import port
from rsd_lib.resources.v2_1.ethernet_switch import static_mac
class PortTestCase(testtools.TestCase): class PortTestCase(testtools.TestCase):
@ -81,9 +83,7 @@ class PortTestCase(testtools.TestCase):
self.assertEqual( self.assertEqual(
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs', '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs',
self.port_inst.vlans) self.port_inst.vlans)
self.assertEqual( self.assertIsNone(self.port_inst._static_macs)
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs',
self.port_inst.static_macs)
self.assertEqual( self.assertEqual(
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs/VLAN1', '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs/VLAN1',
self.port_inst.links.primary_vlan) self.port_inst.links.primary_vlan)
@ -98,6 +98,64 @@ class PortTestCase(testtools.TestCase):
'/redfish/v1/EthernetSwitches/Switch1/ACLs/ACL1', '/redfish/v1/EthernetSwitches/Switch1/ACLs/ACL1',
self.port_inst.links.active_acls[0]) self.port_inst.links.active_acls[0])
def test__get_static_mac_collection_path(self):
self.assertEqual(
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs',
self.port_inst._get_static_mac_collection_path())
def test__get_static_mac_collection_path_missing_attr(self):
self.port_inst._json.pop('StaticMACs')
self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute StaticMAC',
self.port_inst._get_static_mac_collection_path)
def test_static_mac(self):
# checkou for the underpath variable value
self.assertIsNone(self.port_inst._static_macs)
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'ethernet_switch_port_static_mac_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
actual_static_macs = self.port_inst.static_macs
# | THEN |
self.assertIsInstance(actual_static_macs,
static_mac.StaticMACCollection)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN |
self.assertIs(actual_static_macs, self.port_inst.static_macs)
self.conn.get.return_value.json.assert_not_called()
def test_static_mac_on_refresh(self):
# | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'ethernet_switch_port_static_mac_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.port_inst.static_macs,
static_mac.StaticMACCollection)
# On refreshing...
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.refresh()
# | WHEN & THEN |
self.assertIsNone(self.port_inst._static_macs)
# | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'ethernet_switch_port_static_mac_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.port_inst.static_macs,
static_mac.StaticMACCollection)
class PortCollectionTestCase(testtools.TestCase): class PortCollectionTestCase(testtools.TestCase):

View File

@ -0,0 +1,91 @@
# 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 static_mac
class StaticMACTestCase(testtools.TestCase):
def setUp(self):
super(StaticMACTestCase, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'ethernet_switch_port_static_mac.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.static_mac_inst = static_mac.StaticMAC(
self.conn,
'/redfish/v1/EthernetSwitches/Switch1/Ports/StaticMACs/1',
redfish_version='1.0.2')
def test__parse_attributes(self):
self.static_mac_inst._parse_attributes()
self.assertEqual('1.0.2', self.static_mac_inst.redfish_version)
self.assertEqual('1', self.static_mac_inst.identity)
self.assertEqual('StaticMAC', self.static_mac_inst.name)
self.assertEqual('description-as-string',
self.static_mac_inst.description)
self.assertEqual('00:11:22:33:44:55', self.static_mac_inst.mac_address)
self.assertEqual(112, self.static_mac_inst.vlan_id)
self.assertEqual({}, self.static_mac_inst.oem)
class StaticMACCollectionTestCase(testtools.TestCase):
def setUp(self):
super(StaticMACCollectionTestCase, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/'
'ethernet_switch_port_static_mac_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.static_mac_col = static_mac.StaticMACCollection(
self.conn,
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs',
redfish_version='1.1.0')
def test__parse_attributes(self):
self.static_mac_col._parse_attributes()
self.assertEqual('1.1.0', self.static_mac_col.redfish_version)
self.assertEqual(
('/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs/1',),
self.static_mac_col.members_identities)
@mock.patch.object(static_mac, 'StaticMAC', autospec=True)
def test_get_member(self, mock_static_mac):
self.static_mac_col.get_member(
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs/1')
mock_static_mac.assert_called_once_with(
self.static_mac_col._conn,
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs/1',
redfish_version=self.static_mac_col.redfish_version)
@mock.patch.object(static_mac, 'StaticMAC', autopspec=True)
def test_get_members(self, mock_static_mac):
members = self.static_mac_col.get_members()
calls = [
mock.call(self.static_mac_col._conn,
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/'
'StaticMACs/1',
redfish_version=self.static_mac_col.redfish_version)
]
mock_static_mac.assert_has_calls(calls)
self.assertIsInstance(members, list)
self.assertEqual(1, len(members))

View File

@ -92,12 +92,11 @@ class NetworkInterfaceCollectionTestCase(testtools.TestCase):
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open('rsd_lib/tests/unit/json_samples/v2_1/'
'system_network_interface_collection.json', 'r') as f: 'system_network_interface_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.network_interface_col = network_interface.\ self.network_interface_col = network_interface.\
NetworkInterfaceCollection( NetworkInterfaceCollection(
self.conn, self.conn,
'/redfish/v1/Systems/System1/EthernetInterfaces', '/redfish/v1/Systems/System1/EthernetInterfaces',
redfish_version='1.1.0' redfish_version='1.1.0')
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.network_interface_col._parse_attributes() self.network_interface_col._parse_attributes()
@ -113,8 +112,7 @@ class NetworkInterfaceCollectionTestCase(testtools.TestCase):
mock_network_interface.assert_called_once_with( mock_network_interface.assert_called_once_with(
self.network_interface_col._conn, self.network_interface_col._conn,
'/redfish/v1/Systems/System1/EthernetInterfaces/LAN1', '/redfish/v1/Systems/System1/EthernetInterfaces/LAN1',
redfish_version=self.network_interface_col.redfish_version 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): def test_get_members(self, mock_network_interface):