From ee05f57ff2216734e835a22558cccf0c26fb79e7 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Wed, 31 May 2023 13:31:16 +0800 Subject: [PATCH 1/2] Fix issue: show interfaces transceiver eeprom -d should display same entry for CMIS cable --- scripts/sfpshow | 6 +- sfputil/main.py | 6 +- tests/mock_tables/state_db.json | 105 +++++++++++++++++++++ tests/sfp_test.py | 75 +++++++++++++++ tests/sfputil_test.py | 156 +++++++++++++++++++++++++++----- 5 files changed, 318 insertions(+), 30 deletions(-) diff --git a/scripts/sfpshow b/scripts/sfpshow index 5ed1390123..81add13296 100755 --- a/scripts/sfpshow +++ b/scripts/sfpshow @@ -345,9 +345,9 @@ class SFPShow(object): channel_threshold_align = 18 module_threshold_align = 15 - if sfp_type.startswith('QSFP'): + if sfp_type.startswith('QSFP') or sfp_type.startswith('OSFP'): # Channel Monitor - if sfp_type.startswith('QSFP-DD'): + if sfp_type.startswith('QSFP-DD') or sfp_type.startswith('OSFP'): output_dom += (indent + 'ChannelMonitorValues:\n') sorted_key_table = natsorted(QSFP_DD_DOM_CHANNEL_MONITOR_MAP) output_channel = self.format_dict_value_to_string( @@ -365,7 +365,7 @@ class SFPShow(object): output_dom += output_channel # Channel Threshold - if sfp_type.startswith('QSFP-DD'): + if sfp_type.startswith('QSFP-DD') or sfp_type.startswith('OSFP'): dom_map = SFP_DOM_CHANNEL_THRESHOLD_MAP else: dom_map = QSFP_DOM_CHANNEL_THRESHOLD_MAP diff --git a/sfputil/main.py b/sfputil/main.py index 3af370d5b4..c19f8bdfda 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -372,9 +372,9 @@ def convert_dom_to_output_string(sfp_type, dom_info_dict): channel_threshold_align = 18 module_threshold_align = 15 - if sfp_type.startswith('QSFP'): + if sfp_type.startswith('QSFP') or sfp_type.startswith('OSFP'): # Channel Monitor - if sfp_type.startswith('QSFP-DD'): + if sfp_type.startswith('QSFP-DD') or sfp_type.startswith('OSFP'): output_dom += (indent + 'ChannelMonitorValues:\n') sorted_key_table = natsorted(QSFP_DD_DOM_CHANNEL_MONITOR_MAP) output_channel = format_dict_value_to_string( @@ -392,7 +392,7 @@ def convert_dom_to_output_string(sfp_type, dom_info_dict): output_dom += output_channel # Channel Threshold - if sfp_type.startswith('QSFP-DD'): + if sfp_type.startswith('QSFP-DD') or sfp_type.startswith('OSFP'): dom_map = SFP_DOM_CHANNEL_THRESHOLD_MAP else: dom_map = QSFP_DOM_CHANNEL_THRESHOLD_MAP diff --git a/tests/mock_tables/state_db.json b/tests/mock_tables/state_db.json index 1e7b506c28..f98de518b8 100644 --- a/tests/mock_tables/state_db.json +++ b/tests/mock_tables/state_db.json @@ -691,6 +691,111 @@ "supported_max_laser_freq" : "196100", "supported_min_laser_freq" : "191300" }, + "TRANSCEIVER_INFO|Ethernet72": { + "active_apsel_hostlane4": "N/A", + "active_firmware": "0.0", + "is_replaceable": "True", + "application_advertisement": "{1: {'host_electrical_interface_id': 'IB NDR', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}, 2: {'host_electrical_interface_id': 'IB SDR (Arch.Spec.Vol.2)', 'module_media_interface_id': 'Copper cable', 'media_lane_count': 4, 'host_lane_count': 4, 'host_lane_assignment_options': 17}}", + "host_electrical_interface": "N/A", + "active_apsel_hostlane2": "N/A", + "supported_min_tx_power": "N/A", + "supported_max_tx_power": "N/A", + "host_lane_assignment_option": "17", + "specification_compliance": "passive_copper_media_interface", + "ext_identifier": "Power Class 1 (0.25W Max)", + "active_apsel_hostlane8": "N/A", + "manufacturer": "vendor1 ", + "cmis_rev": "5.0", + "cable_type": "Length Cable Assembly(m)", + "supported_min_laser_freq": "N/A", + "serial": "serial1 ", + "active_apsel_hostlane7": "N/A", + "inactive_firmware": "N/A", + "active_apsel_hostlane1": "N/A", + "type": "OSFP 8X Pluggable Transceiver", + "cable_length": "1.0", + "active_apsel_hostlane5": "N/A", + "media_lane_assignment_option": "N/A", + "vendor_rev": "A3", + "active_apsel_hostlane6": "N/A", + "encoding": "N/A", + "dom_capability": "N/A", + "media_interface_technology": "Copper cable unequalized", + "nominal_bit_rate": "0", + "hardware_rev": "0.0", + "media_lane_count": "0", + "host_lane_count": "4", + "vendor_oui": "some-oui", + "connector": "No separable connector", + "supported_max_laser_freq": "N/A", + "media_interface_code": "Copper cable", + "active_apsel_hostlane3": "N/A", + "ext_rateselect_compliance": "N/A", + "model": "some-model ", + "vendor_date": "2022-05-28 " + }, + "TRANSCEIVER_DOM_SENSOR|Ethernet72": { + "rx_los": "N/A", + "tx_fault": "N/A", + "tx_disabled_channel": "N/A", + "temperature": "40.5", + "voltage": "3.331", + "tx1disable": "N/A", + "tx1bias": "6.5", + "rx1power": "0.5", + "tx1power": "0.6", + "tx2disable": "N/A", + "tx2bias": "6.5", + "rx2power": "0.3", + "tx2power": "0.4", + "tx3disable": "N/A", + "tx3bias": "6.6", + "rx3power": "0.1", + "tx3power": "0.2", + "tx4disable": "N/A", + "tx4bias": "6.7", + "rx4power": "0.7", + "tx4power": "0.8", + "tx5disable": "N/A", + "tx5bias": "6.4", + "rx5power": "0.8", + "tx5power": "0.9", + "tx6disable": "N/A", + "tx6bias": "6.3", + "rx6power": "0.2", + "tx6power": "0.1", + "tx7disable": "N/A", + "tx7bias": "6.2", + "rx7power": "0.2", + "tx7power": "0.5", + "tx8disable": "N/A", + "tx8bias": "6.1", + "rx8power": "0.3", + "tx8power": "0.4", + "laser_temperature": "N/A" + }, + "TRANSCEIVER_DOM_THRESHOLD|Ethernet72": { + "temphighalarm": "N/A", + "temphighwarning": "N/A", + "templowalarm": "N/A", + "templowwarning": "N/A", + "vcchighalarm": "N/A", + "vcchighwarning": "N/A", + "vcclowalarm": "N/A", + "vcclowwarning": "N/A", + "rxpowerhighalarm": "N/A", + "rxpowerhighwarning": "N/A", + "rxpowerlowalarm": "N/A", + "rxpowerlowwarning": "N/A", + "txpowerhighalarm": "N/A", + "txpowerhighwarning": "N/A", + "txpowerlowalarm": "N/A", + "txpowerlowwarning": "N/A", + "txbiashighalarm": "N/A", + "txbiashighwarning": "N/A", + "txbiaslowalarm": "N/A", + "txbiaslowwarning": "N/A" + }, "TRANSCEIVER_STATUS|Ethernet0": { "status": "67", "error": "Blocking Error|High temperature" diff --git a/tests/sfp_test.py b/tests/sfp_test.py index f509c04748..c24ec49e20 100644 --- a/tests/sfp_test.py +++ b/tests/sfp_test.py @@ -133,6 +133,75 @@ VccLowWarning : 3.1304Volts """ +test_osfp_eeprom_with_dom_output = """\ +Ethernet72: SFP EEPROM detected + Active Firmware: 0.0 + Active application selected code assigned to host lane 1: N/A + Active application selected code assigned to host lane 2: N/A + Active application selected code assigned to host lane 3: N/A + Active application selected code assigned to host lane 4: N/A + Active application selected code assigned to host lane 5: N/A + Active application selected code assigned to host lane 6: N/A + Active application selected code assigned to host lane 7: N/A + Active application selected code assigned to host lane 8: N/A + Application Advertisement: IB NDR - Host Assign (0x11) - Copper cable - Media Assign (Unknown) + IB SDR (Arch.Spec.Vol.2) - Host Assign (0x11) - Copper cable - Media Assign (Unknown) + CMIS Rev: 5.0 + Connector: No separable connector + Encoding: N/A + Extended Identifier: Power Class 1 (0.25W Max) + Extended RateSelect Compliance: N/A + Host Lane Count: 4 + Identifier: OSFP 8X Pluggable Transceiver + Inactive Firmware: N/A + Length Cable Assembly(m): 1.0 + Media Interface Technology: Copper cable unequalized + Media Lane Count: 0 + Module Hardware Rev: 0.0 + Nominal Bit Rate(100Mbs): 0 + Specification compliance: passive_copper_media_interface + Supported Max Laser Frequency: N/A + Supported Max TX Power: N/A + Supported Min Laser Frequency: N/A + Supported Min TX Power: N/A + Vendor Date Code(YYYY-MM-DD Lot): 2022-05-28 + Vendor Name: vendor1 + Vendor OUI: some-oui + Vendor PN: some-model + Vendor Rev: A3 + Vendor SN: serial1 + ChannelMonitorValues: + RX1Power: 0.5dBm + RX2Power: 0.3dBm + RX3Power: 0.1dBm + RX4Power: 0.7dBm + RX5Power: 0.8dBm + RX6Power: 0.2dBm + RX7Power: 0.2dBm + RX8Power: 0.3dBm + TX1Bias: 6.5mA + TX1Power: 0.6dBm + TX2Bias: 6.5mA + TX2Power: 0.4dBm + TX3Bias: 6.6mA + TX3Power: 0.2dBm + TX4Bias: 6.7mA + TX4Power: 0.8dBm + TX5Bias: 6.4mA + TX5Power: 0.9dBm + TX6Bias: 6.3mA + TX6Power: 0.1dBm + TX7Bias: 6.2mA + TX7Power: 0.5dBm + TX8Bias: 6.1mA + TX8Power: 0.4dBm + ChannelThresholdValues: + ModuleMonitorValues: + Temperature: 40.5C + Vcc: 3.331Volts + ModuleThresholdValues: +""" + test_sfp_eeprom_output = """\ Ethernet0: SFP EEPROM detected Application Advertisement: N/A @@ -826,6 +895,12 @@ def test_qsfp_dd_eeprom_with_dom(self): result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet8", "-d"]) assert result.exit_code == 0 assert result.output == test_qsfp_dd_eeprom_with_dom_output + + def test_osfp_eeprom_with_dom(self): + runner = CliRunner() + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet72 -d"]) + assert result.exit_code == 0 + assert result.output == test_osfp_eeprom_with_dom_output def test_sfp_eeprom(self): runner = CliRunner() diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index c57a5dc613..f50acdc441 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -221,27 +221,26 @@ def test_convert_sfp_info_to_output_string(self, sfp_info_dict, expected_output) output = sfputil.convert_sfp_info_to_output_string(sfp_info_dict) assert output == expected_output - def test_convert_dom_to_output_string(self): - sfp_type = 'QSFP28 or later' - - dom_info_dict = { - 'temperature': '41.7539C', - 'voltage': '3.2577Volts', - 'rx1power': '-1.6622dBm', - 'rx2power': '-1.7901dBm', - 'rx3power': '-1.6973dBm', - 'rx4power': '-2.0915dBm', - 'tx1bias': '35.8400mA', - 'tx2bias': '37.5780mA', - 'tx3bias': '35.8400mA', - 'tx4bias': '35.8400mA', - 'tx1power': 'N/A', - 'tx2power': 'N/A', - 'tx3power': 'N/A', - 'tx4power': 'N/A' - } - - expected_output = '''\ + @pytest.mark.parametrize("sfp_type, dom_info_dict, expected_output", [ + ( + 'QSFP28 or later', + { + 'temperature': '41.7539C', + 'voltage': '3.2577Volts', + 'rx1power': '-1.6622dBm', + 'rx2power': '-1.7901dBm', + 'rx3power': '-1.6973dBm', + 'rx4power': '-2.0915dBm', + 'tx1bias': '35.8400mA', + 'tx2bias': '37.5780mA', + 'tx3bias': '35.8400mA', + 'tx4bias': '35.8400mA', + 'tx1power': 'N/A', + 'tx2power': 'N/A', + 'tx3power': 'N/A', + 'tx4power': 'N/A' + }, + '''\ ChannelMonitorValues: RX1Power: -1.6622dBm RX2Power: -1.7901dBm @@ -257,12 +256,121 @@ def test_convert_dom_to_output_string(self): Vcc: 3.2577Volts ModuleThresholdValues: ''' - + ), + ( + 'QSFP-DD Double Density 8X Pluggable Transceiver', + { + 'temperature': '41.7539C', + 'voltage': '3.2577Volts', + 'rx1power': '-1.6622dBm', + 'rx2power': '-1.7901dBm', + 'rx3power': '-1.6973dBm', + 'rx4power': '-2.0915dBm', + 'rx5power': '-1.6622dBm', + 'rx6power': '-1.7901dBm', + 'rx7power': '-1.6973dBm', + 'rx8power': '-2.0915dBm', + 'tx1bias': '35.8400mA', + 'tx2bias': '37.5780mA', + 'tx3bias': '35.8400mA', + 'tx4bias': '35.8400mA', + 'tx5bias': '35.8400mA', + 'tx6bias': '37.5780mA', + 'tx7bias': '35.8400mA', + 'tx8bias': '35.8400mA', + 'tx1power': 'N/A', + 'tx2power': 'N/A', + 'tx3power': 'N/A', + 'tx4power': 'N/A', + 'tx5power': 'N/A', + 'tx6power': 'N/A', + 'tx7power': 'N/A', + 'tx8power': 'N/A' + }, + '''\ + ChannelMonitorValues: + RX1Power: -1.6622dBm + RX2Power: -1.7901dBm + RX3Power: -1.6973dBm + RX4Power: -2.0915dBm + RX5Power: -1.6622dBm + RX6Power: -1.7901dBm + RX7Power: -1.6973dBm + RX8Power: -2.0915dBm + TX1Bias: 35.8400mA + TX2Bias: 37.5780mA + TX3Bias: 35.8400mA + TX4Bias: 35.8400mA + TX5Bias: 35.8400mA + TX6Bias: 37.5780mA + TX7Bias: 35.8400mA + TX8Bias: 35.8400mA + ChannelThresholdValues: + ModuleMonitorValues: + Temperature: 41.7539C + Vcc: 3.2577Volts + ModuleThresholdValues: +''' + ), + ( + 'OSFP 8X Pluggable Transceiver', + { + 'temperature': '41.7539C', + 'voltage': '3.2577Volts', + 'rx1power': '-1.6622dBm', + 'rx2power': '-1.7901dBm', + 'rx3power': '-1.6973dBm', + 'rx4power': '-2.0915dBm', + 'rx5power': '-1.6622dBm', + 'rx6power': '-1.7901dBm', + 'rx7power': '-1.6973dBm', + 'rx8power': '-2.0915dBm', + 'tx1bias': '35.8400mA', + 'tx2bias': '37.5780mA', + 'tx3bias': '35.8400mA', + 'tx4bias': '35.8400mA', + 'tx5bias': '35.8400mA', + 'tx6bias': '37.5780mA', + 'tx7bias': '35.8400mA', + 'tx8bias': '35.8400mA', + 'tx1power': 'N/A', + 'tx2power': 'N/A', + 'tx3power': 'N/A', + 'tx4power': 'N/A', + 'tx5power': 'N/A', + 'tx6power': 'N/A', + 'tx7power': 'N/A', + 'tx8power': 'N/A' + }, + '''\ + ChannelMonitorValues: + RX1Power: -1.6622dBm + RX2Power: -1.7901dBm + RX3Power: -1.6973dBm + RX4Power: -2.0915dBm + RX5Power: -1.6622dBm + RX6Power: -1.7901dBm + RX7Power: -1.6973dBm + RX8Power: -2.0915dBm + TX1Bias: 35.8400mA + TX2Bias: 37.5780mA + TX3Bias: 35.8400mA + TX4Bias: 35.8400mA + TX5Bias: 35.8400mA + TX6Bias: 37.5780mA + TX7Bias: 35.8400mA + TX8Bias: 35.8400mA + ChannelThresholdValues: + ModuleMonitorValues: + Temperature: 41.7539C + Vcc: 3.2577Volts + ModuleThresholdValues: +''' + )]) + def test_convert_dom_to_output_string(self, sfp_type, dom_info_dict, expected_output): output = sfputil.convert_dom_to_output_string(sfp_type, dom_info_dict) assert output == expected_output - # TODO: Add tests for other SFP types - def test_get_physical_port_name(self): output = sfputil.get_physical_port_name(0, 0, False) assert output == '0' From 21fa8d2307c5c6f36599cc2b3b1a86f9275f6245 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Thu, 8 Jun 2023 15:10:40 +0800 Subject: [PATCH 2/2] Fix unit test issue --- tests/sfp_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sfp_test.py b/tests/sfp_test.py index c24ec49e20..37a025a35c 100644 --- a/tests/sfp_test.py +++ b/tests/sfp_test.py @@ -898,7 +898,7 @@ def test_qsfp_dd_eeprom_with_dom(self): def test_osfp_eeprom_with_dom(self): runner = CliRunner() - result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet72 -d"]) + result = runner.invoke(show.cli.commands["interfaces"].commands["transceiver"].commands["eeprom"], ["Ethernet72", "-d"]) assert result.exit_code == 0 assert result.output == test_osfp_eeprom_with_dom_output