diff --git a/sonic_platform_base/sonic_sfp/bcmshell.py b/sonic_platform_base/sonic_sfp/bcmshell.py index 244dfa6721b3..99e8082f31b3 100644 --- a/sonic_platform_base/sonic_sfp/bcmshell.py +++ b/sonic_platform_base/sonic_sfp/bcmshell.py @@ -227,7 +227,7 @@ def getreg(self, reg, fields=False): # t = self.re_oneline.sub('', t) t = t.split('\n') - if t[-1] is '': + if t[-1] == '': t.pop() # get the results into a dict (module) of lists (array) of values/fields @@ -253,10 +253,10 @@ def __parse_reg__(text, fields=False): # now optimize the return # for I in iter(d): - if len(d[I]) is 1: + if len(d[I]) == 1: d[I] = d[I][0] - if len(d) is 1: + if len(d) == 1: return d.values()[0] else: return d @@ -319,7 +319,7 @@ def gettable(self, table, fields=False, start=None, entries=None): t = self.re_table_header.sub('', t) t = self.re_table_trailer.sub('', t) t = t.split('\n') - if t[-1] is '': + if t[-1] == '': t.pop() # parse the contents diff --git a/sonic_platform_base/sonic_sfp/sfputilhelper.py b/sonic_platform_base/sonic_sfp/sfputilhelper.py index f847a43708c2..7504729c7001 100644 --- a/sonic_platform_base/sonic_sfp/sfputilhelper.py +++ b/sonic_platform_base/sonic_sfp/sfputilhelper.py @@ -13,7 +13,7 @@ from natsort import natsorted from portconfig import get_port_config - from sonic_py_common import device_info + from sonic_py_common import device_info, multi_asic from sonic_py_common.interface import backplane_prefix, inband_prefix, recirc_prefix except ImportError as e: @@ -22,6 +22,7 @@ # Global Variable PLATFORM_JSON = 'platform.json' PORT_CONFIG_INI = 'port_config.ini' +ASIC_NAME_PREFIX = 'asic' class SfpUtilHelper(object): # List to specify filter for sfp_ports @@ -52,7 +53,12 @@ def read_porttab_mappings(self, porttabfile, asic_inst=0): fp_port_index = 1 (platform, hwsku) = device_info.get_platform_and_hwsku() - ports, _, _ = get_port_config(hwsku, platform) + + asic_name = None + if multi_asic.is_multi_asic(): + asic_name = ASIC_NAME_PREFIX + str(asic_inst) + + ports, _, _ = get_port_config(hwsku, platform, asic_name=asic_name) if not ports: ports, _, _ = get_port_config(hwsku, platform, porttabfile) @@ -65,9 +71,9 @@ def read_porttab_mappings(self, porttabfile, asic_inst=0): logical_list.append(intf) # Ignore if this is an internal backplane interface and Inband interface - logical = [name for name in logical + logical = [name for name in logical_list if not name.startswith((backplane_prefix(), inband_prefix(), recirc_prefix()))] - logical = natsorted(logical_list, key=lambda y: y.lower()) + logical = natsorted(logical, key=lambda y: y.lower()) logical_to_physical, physical_to_logical = OrderedDict(), OrderedDict() for intf_name in logical: @@ -83,24 +89,25 @@ def read_porttab_mappings(self, porttabfile, asic_inst=0): # Mapping of logical port names available on a system to ASIC instance self.logical_to_asic[intf_name] = asic_inst - self.logical = logical - self.logical_to_physical = logical_to_physical - self.physical_to_logical = physical_to_logical + self.logical.extend(logical) + self.logical = list(set(self.logical)) + self.logical_to_physical.update(logical_to_physical) + self.physical_to_logical.update(physical_to_logical) return None def read_all_porttab_mappings(self, platform_dir, num_asic_inst): - # In multi asic scenario, get all the port_config files for different asics - for inst in range(num_asic_inst): - port_map_dir = os.path.join(platform_dir, str(inst)) - port_map_file = os.path.join(port_map_dir, PORT_CONFIG_INI) - if os.path.exists(port_map_file): - self.read_porttab_mappings(port_map_file, inst) - else: - port_json_file = os.path.join(port_map_dir, PLATFORM_JSON) - if os.path.exists(port_json_file): - self.read_porttab_mappings(port_json_file, inst) + # In multi asic scenario, get all the port_config files for different asic + for inst in range(num_asic_inst): + port_map_dir = os.path.join(platform_dir, str(inst)) + port_map_file = os.path.join(port_map_dir, PORT_CONFIG_INI) + if os.path.exists(port_map_file): + self.read_porttab_mappings(port_map_file, inst) + else: + port_json_file = os.path.join(platform_dir, PLATFORM_JSON) + if os.path.exists(port_json_file): + self.read_porttab_mappings(port_json_file, inst) def get_physical_to_logical(self, port_num): """Returns list of logical ports for the given physical port""" diff --git a/tests/0/port_config.ini b/tests/0/port_config.ini new file mode 100644 index 000000000000..4fb083de5033 --- /dev/null +++ b/tests/0/port_config.ini @@ -0,0 +1,7 @@ +# name lanes alias index +Ethernet0 29,30,31,32 fortyGigE0/0 1 +Ethernet4 25,26,27,28 fortyGigE0/4 2 +Ethernet8 37,38,39,40 fortyGigE0/8 3 +Ethernet12 33,34,35,36 fortyGigE0/12 4 +Ethernet16 41,42,43,44 fortyGigE0/16 5 +Ethernet20 45,46,47,48 fortyGigE0/20 6 diff --git a/tests/1/port_config.ini b/tests/1/port_config.ini new file mode 100644 index 000000000000..01f15465931b --- /dev/null +++ b/tests/1/port_config.ini @@ -0,0 +1,8 @@ +# name lanes alias index +Ethernet24 5,6,7,8 fortyGigE0/24 7 +Ethernet28 1,2,3,4 fortyGigE0/28 8 +Ethernet32 9,10,11,12 fortyGigE0/32 9 +Ethernet36 13,14,15,16 fortyGigE0/36 10 +Ethernet40 21,22,23,24 fortyGigE0/40 11 +Ethernet44 17,18,19,20 fortyGigE0/44 12 +Ethernet48 49,50,51,52 fortyGigE0/48 13 diff --git a/tests/platform_json/hwsku.json b/tests/platform_json/hwsku.json new file mode 100644 index 000000000000..58bb6f1deff9 --- /dev/null +++ b/tests/platform_json/hwsku.json @@ -0,0 +1,46 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet4": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet12": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet16": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet20": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet24": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet28": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet32": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet36": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet40": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet44": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet48": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + }, + "Ethernet52": { + "default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]" + } + } +} diff --git a/tests/platform_json/platform.json b/tests/platform_json/platform.json new file mode 100644 index 000000000000..8f436859a821 --- /dev/null +++ b/tests/platform_json/platform.json @@ -0,0 +1,117 @@ +{ + "chassis": { + "name": "", + "components": [], + "fans": [], + "fan_drawers": [], + "psus": [], + "thermals": [], + "sfps": [] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "29,30,31,32", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp1"], + "2x100G[50G,25G,10G,1G]": ["etp1a", "etp1b"] + } + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp2"], + "2x100G[50G,25G,10G,1G]": ["etp2a", "etp2b"] + } + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "37,38,39,40", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp3"], + "2x100G[50G,25G,10G,1G]": ["etp3a", "etp3b"] + } + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "33,34,35,36", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp4"], + "2x100G[50G,25G,10G,1G]": ["etp4a", "etp4b"] + } + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp5"], + "2x100G[50G,25G,10G,1G]": ["etp5a", "etp5b"] + } + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "44,46,47,48", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp6"], + "2x100G[50G,25G,10G,1G]": ["etp6a", "etp6b"] + } + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "5,6,7,8", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp7"], + "2x100G[50G,25G,10G,1G]": ["etp7a", "etp7b"] + } + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "1,2,3,4", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp8"], + "2x100G[50G,25G,10G,1G]": ["etp8a", "etp8b"] + } + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "9,10,11,12", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp9"], + "2x100G[50G,25G,10G,1G]": ["etp9a", "etp9b"] + } + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "13,14,15,16", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp10"], + "2x100G[50G,25G,10G,1G]": ["etp10a", "etp10b"] + } + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp11"], + "2x100G[50G,25G,10G,1G]": ["etp11a", "etp11b"] + } + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "17,18,19,20", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp12"], + "2x100G[50G,25G,10G,1G]": ["etp12a", "etp12b"] + } + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "49,50,51,51", + "breakout_modes": { + "1x200G[100G,50G,40G,25G,10G,1G]": ["etp13"], + "2x100G[50G,25G,10G,1G]": ["etp13a", "etp13b"] + } + } + } +} diff --git a/tests/port_config.ini b/tests/port_config.ini index ed03fa85cbbd..923cab7cf73c 100644 --- a/tests/port_config.ini +++ b/tests/port_config.ini @@ -1,14 +1,14 @@ -# name lanes alias -Ethernet0 29,30,31,32 fortyGigE0/0 -Ethernet4 25,26,27,28 fortyGigE0/4 -Ethernet8 37,38,39,40 fortyGigE0/8 -Ethernet12 33,34,35,36 fortyGigE0/12 -Ethernet16 41,42,43,44 fortyGigE0/16 -Ethernet20 45,46,47,48 fortyGigE0/20 -Ethernet24 5,6,7,8 fortyGigE0/24 -Ethernet28 1,2,3,4 fortyGigE0/28 -Ethernet32 9,10,11,12 fortyGigE0/32 -Ethernet36 13,14,15,16 fortyGigE0/36 -Ethernet40 21,22,23,24 fortyGigE0/40 -Ethernet44 17,18,19,20 fortyGigE0/44 -Ethernet48 49,50,51,52 fortyGigE0/48 +# name lanes alias index +Ethernet0 29,30,31,32 fortyGigE0/0 1 +Ethernet4 25,26,27,28 fortyGigE0/4 2 +Ethernet8 37,38,39,40 fortyGigE0/8 3 +Ethernet12 33,34,35,36 fortyGigE0/12 4 +Ethernet16 41,42,43,44 fortyGigE0/16 5 +Ethernet20 45,46,47,48 fortyGigE0/20 6 +Ethernet24 5,6,7,8 fortyGigE0/24 7 +Ethernet28 1,2,3,4 fortyGigE0/28 8 +Ethernet32 9,10,11,12 fortyGigE0/32 9 +Ethernet36 13,14,15,16 fortyGigE0/36 10 +Ethernet40 21,22,23,24 fortyGigE0/40 11 +Ethernet44 17,18,19,20 fortyGigE0/44 12 +Ethernet48 49,50,51,52 fortyGigE0/48 13 diff --git a/tests/sfputilhelper_test.py b/tests/sfputilhelper_test.py index 49342e5613a3..e812809127ed 100644 --- a/tests/sfputilhelper_test.py +++ b/tests/sfputilhelper_test.py @@ -4,36 +4,75 @@ import pytest from sonic_platform_base.sonic_sfp import sfputilhelper +from unittest import mock +PORT_LIST = [ + "Ethernet0", + "Ethernet4", + "Ethernet8", + "Ethernet12", + "Ethernet16", + "Ethernet20", + "Ethernet24", + "Ethernet28", + "Ethernet32", + "Ethernet36", + "Ethernet40", + "Ethernet44", + "Ethernet48" +] + +LOGICAL_TO_PHYSICAL ={ + 'Ethernet0': [1], + 'Ethernet4': [2], + 'Ethernet8': [3], + 'Ethernet12': [4], + 'Ethernet16': [5], + 'Ethernet20': [6], + 'Ethernet24': [7], + 'Ethernet28': [8], + 'Ethernet32': [9], + 'Ethernet36': [10], + 'Ethernet40': [11], + 'Ethernet44': [12], + 'Ethernet48': [13] +} + +PHYSICAL_TO_LOGICAL = { + 1: ['Ethernet0'], + 2: ['Ethernet4'], + 3: ['Ethernet8'], + 4: ['Ethernet12'], + 5: ['Ethernet16'], + 6: ['Ethernet20'], + 7: ['Ethernet24'], + 8: ['Ethernet28'], + 9: ['Ethernet32'], + 10: ['Ethernet36'], + 11: ['Ethernet40'], + 12: ['Ethernet44'], + 13: ['Ethernet48'] +} + +test_dir = os.path.dirname(os.path.realpath(__file__)) +hwsku_json_file = os.path.join(test_dir, 'platform_json', 'hwsku.json') @pytest.fixture(scope="class") def setup_class(request): # Configure the setup - test_dir = os.path.dirname(os.path.realpath(__file__)) request.cls.port_config_file = os.path.join(test_dir, 'port_config.ini') + request.cls.platform_dir = os.path.dirname(os.path.realpath(__file__)) + request.cls.platform_json_dir = os.path.join(test_dir, 'platform_json') @pytest.mark.usefixtures("setup_class") class TestSfpUtilHelper(object): port_config_file = None + platform_dir = None + platform_json_dir = None def test_read_port_mappings(self): - PORT_LIST = [ - "Ethernet0", - "Ethernet4", - "Ethernet8", - "Ethernet12", - "Ethernet16", - "Ethernet20", - "Ethernet24", - "Ethernet28", - "Ethernet32", - "Ethernet36", - "Ethernet40", - "Ethernet44", - "Ethernet48" - ] sfputil_helper = sfputilhelper.SfpUtilHelper() sfputil_helper.read_porttab_mappings(self.port_config_file, 0) @@ -43,3 +82,36 @@ def test_read_port_mappings(self): for logical_port_name in logical_port_list: assert logical_port_name in PORT_LIST + + + @mock.patch('portconfig.get_hwsku_file_name', mock.MagicMock(return_value=hwsku_json_file)) + def test_read_all_port_mappings(self): + + sfputil_helper = sfputilhelper.SfpUtilHelper() + sfputil_helper.logical = [] + sfputil_helper.logical_to_physical = {} + sfputil_helper.physical_to_logica = {} + sfputil_helper.read_all_porttab_mappings(self.platform_dir, 2) + logical_port_list = sfputil_helper.logical + + assert len(logical_port_list) == len(PORT_LIST) + for logical_port_name in logical_port_list: + assert logical_port_name in PORT_LIST + assert sfputil_helper.logical_to_physical == LOGICAL_TO_PHYSICAL + assert sfputil_helper.physical_to_logical == PHYSICAL_TO_LOGICAL + + # test platform.json case + + sfputil_helper.logical = [] + sfputil_helper.logical_to_physical = {} + sfputil_helper.physical_to_logica = {} + sfputil_helper.read_all_porttab_mappings(self.platform_json_dir, 2) + logical_port_list = sfputil_helper.logical + + assert len(logical_port_list) == len(PORT_LIST) + + for logical_port_name in logical_port_list: + assert logical_port_name in PORT_LIST + + assert sfputil_helper.logical_to_physical == LOGICAL_TO_PHYSICAL + assert sfputil_helper.physical_to_logical == PHYSICAL_TO_LOGICAL