From 030cc09f4abb514c4ffd7417335cb88d3db55489 Mon Sep 17 00:00:00 2001 From: DennisChiuEC <108725043+DennisChiuEC@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:17:06 +0800 Subject: [PATCH] [xcvrd] Modify to support regular expression when parsing the key in media_settings.json (#471) * [xcvrd] Modify to support regular expression when parsing the key in media_settings.json * fix unit test error * add unit test for getting media settings value with regular expression * define get_media_settings() * apply the suggestion for if condition --- sonic-xcvrd/tests/test_xcvrd.py | 12 +++- .../xcvrd_utilities/media_settings_parser.py | 71 ++++++------------- 2 files changed, 34 insertions(+), 49 deletions(-) diff --git a/sonic-xcvrd/tests/test_xcvrd.py b/sonic-xcvrd/tests/test_xcvrd.py index 4e26dad60..4f6196ec5 100644 --- a/sonic-xcvrd/tests/test_xcvrd.py +++ b/sonic-xcvrd/tests/test_xcvrd.py @@ -43,6 +43,13 @@ global_media_settings = media_settings_with_comma_dict['GLOBAL_MEDIA_SETTINGS'].pop('1-32') media_settings_with_comma_dict['GLOBAL_MEDIA_SETTINGS']['1-5,6,7-20,21-32'] = global_media_settings +media_settings_with_regular_expression_dict = copy.deepcopy(media_settings_dict) +media_settings_with_regular_expression_dict['GLOBAL_MEDIA_SETTINGS']['1-32'] = {} +# Generate regular expression patterns for QSFP28-40GBASE-CR4-xxM and QSFP+-40GBASE-CR4-xxM that have the same pre-emphasis value +media_settings_with_regular_expression_dict['GLOBAL_MEDIA_SETTINGS']['1-32']['QSFP(\\+|28)-40GBASE-CR4-1M'] = global_media_settings['QSFP28-40GBASE-CR4-1M'] +media_settings_with_regular_expression_dict['GLOBAL_MEDIA_SETTINGS']['1-32']['QSFP(\\+|28)-40GBASE-CR4-2M'] = global_media_settings['QSFP28-40GBASE-CR4-2M'] +media_settings_with_regular_expression_dict['GLOBAL_MEDIA_SETTINGS']['1-32']['QSFP(\\+|28)-40GBASE-CR4-(3|4|5|7|10)M'] = global_media_settings['QSFP28-40GBASE-CR4-3M'] + with open(os.path.join(test_path, 'optics_si_settings.json'), 'r') as fn: optics_si_settings_dict = json.load(fn) port_optics_si_settings = {} @@ -765,7 +772,10 @@ def test_is_si_per_speed_supported(self): (media_settings_port_default_media_key_lane_speed_si, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), (media_settings_global_default_port_media_key_lane_speed_si, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), (media_settings_global_list_of_ranges_media_key_lane_speed_si_with_default_section, 7, {'vendor_key': 'MISSING', 'media_key': 'MISSING', 'lane_speed_key': 'MISSING'}, {'speed:400GAUI-8': {'idriver': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'pre1': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}, 'ob_m2lp': {'lane0': '0x0000000d', 'lane1': '0x0000000d', 'lane2': '0x0000000d', 'lane3': '0x0000000d'}}}), - (media_settings_empty, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {}) + (media_settings_empty, 7, {'vendor_key': 'AMPHANOL-5678', 'media_key': 'QSFP-DD-active_cable_media_interface', 'lane_speed_key': 'speed:100GAUI-2'}, {}), + (media_settings_with_regular_expression_dict, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP28-40GBASE-CR4-1M', 'lane_speed_key': 'UNKOWN'}, {'preemphasis': {'lane0': '0x16440A', 'lane1': '0x16440A', 'lane2': '0x16440A', 'lane3': '0x16440A'}}), + (media_settings_with_regular_expression_dict, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP+-40GBASE-CR4-2M', 'lane_speed_key': 'UNKOWN'}, {'preemphasis': {'lane0': '0x18420A', 'lane1': '0x18420A', 'lane2': '0x18420A', 'lane3': '0x18420A'}}), + (media_settings_with_regular_expression_dict, 7, {'vendor_key': 'UNKOWN', 'media_key': 'QSFP+-40GBASE-CR4-10M', 'lane_speed_key': 'UNKOWN'}, {'preemphasis': {'lane0': '0x1A400A', 'lane1': '0x1A400A', 'lane2': '0x1A400A', 'lane3': '0x1A400A'}}) ]) def test_get_media_settings_value(self, media_settings_dict, port, key, expected): with patch('xcvrd.xcvrd_utilities.media_settings_parser.g_dict', media_settings_dict): diff --git a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py index 9e79e6c7b..ce7805ee8 100644 --- a/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py +++ b/sonic-xcvrd/xcvrd/xcvrd_utilities/media_settings_parser.py @@ -5,6 +5,7 @@ import json import os import ast +import re from sonic_py_common import device_info, logger from swsscommon import swsscommon @@ -175,6 +176,20 @@ def get_media_settings_value(physical_port, key): media_dict = {} default_dict = {} + def get_media_settings(key, media_dict): + for dict_key in media_dict.keys(): + if (re.match(dict_key, key[VENDOR_KEY]) or \ + re.match(dict_key, key[VENDOR_KEY].split('-')[0]) # e.g: 'AMPHENOL-1234' + or re.match(dict_key, key[MEDIA_KEY]) ): # e.g: 'QSFP28-40GBASE-CR4-1M' + if is_si_per_speed_supported(media_dict[dict_key]): + if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[dict_key]: # e.g: 'speed:400GAUI-8' + return media_dict[dict_key][key[LANE_SPEED_KEY]] + else: + return {} + else: + return media_dict[dict_key] + return None + # Keys under global media settings can be a list or range or list of ranges # of physical port numbers. Below are some examples # 1-32 @@ -200,30 +215,10 @@ def get_media_settings_value(physical_port, key): # If there is a match in the global profile for a media type, # fetch those values - if key[VENDOR_KEY] in media_dict: # e.g: 'AMPHENOL-1234' - if is_si_per_speed_supported(media_dict[key[VENDOR_KEY]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY]]: # e.g: 'speed:400GAUI-8' - return media_dict[key[VENDOR_KEY]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[VENDOR_KEY]] - elif key[VENDOR_KEY].split('-')[0] in media_dict: - if is_si_per_speed_supported(media_dict[key[VENDOR_KEY].split('-')[0]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY].split('-')[0]]: - return media_dict[key[VENDOR_KEY].split('-')[0]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[VENDOR_KEY].split('-')[0]] - elif key[MEDIA_KEY] in media_dict: # e.g: 'QSFP28-40GBASE-CR4-1M' - if is_si_per_speed_supported(media_dict[key[MEDIA_KEY]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[MEDIA_KEY]]: - return media_dict[key[MEDIA_KEY]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[MEDIA_KEY]] + media_settings = get_media_settings(key, media_dict) + if media_settings is not None: + return media_settings + # Try to match 'default' key if it does not match any keys elif DEFAULT_KEY in media_dict: default_dict = media_dict[DEFAULT_KEY] @@ -242,30 +237,10 @@ def get_media_settings_value(physical_port, key): helper_logger.log_error("Error: No values for physical port '{}'".format(physical_port)) return {} - if key[VENDOR_KEY] in media_dict: - if is_si_per_speed_supported(media_dict[key[VENDOR_KEY]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY]]: - return media_dict[key[VENDOR_KEY]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[VENDOR_KEY]] - if key[VENDOR_KEY].split('-')[0] in media_dict: - if is_si_per_speed_supported(media_dict[key[VENDOR_KEY].split('-')[0]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[VENDOR_KEY].split('-')[0]]: - return media_dict[key[VENDOR_KEY].split('-')[0]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[VENDOR_KEY].split('-')[0]] - elif key[MEDIA_KEY] in media_dict: - if is_si_per_speed_supported(media_dict[key[MEDIA_KEY]]): - if key[LANE_SPEED_KEY] is not None and key[LANE_SPEED_KEY] in media_dict[key[MEDIA_KEY]]: - return media_dict[key[MEDIA_KEY]][key[LANE_SPEED_KEY]] - else: - return {} - else: - return media_dict[key[MEDIA_KEY]] + media_settings = get_media_settings(key, media_dict) + if media_settings is not None: + return media_settings + # Try to match 'default' key if it does not match any keys elif DEFAULT_KEY in media_dict: return media_dict[DEFAULT_KEY] elif len(default_dict) != 0: