From 2aa89c21515d5a77ce221782befabea5e5a5c84e Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Fri, 8 Sep 2023 14:52:17 +0800 Subject: [PATCH 01/15] Collect module EEPROM data in dump --- scripts/generate_dump | 7 ++++--- sfputil/main.py | 31 +++++++++++++++++++++++++++++-- tests/sfputil_test.py | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/scripts/generate_dump b/scripts/generate_dump index dd98302a27..8f6ef34704 100755 --- a/scripts/generate_dump +++ b/scripts/generate_dump @@ -1126,7 +1126,7 @@ collect_mellanox_dfw_dumps() { local sdk_dump_path=`cat /usr/share/sonic/device/${platform}/${hwsku}/sai.profile|grep "SAI_DUMP_STORE_PATH"|cut -d = -f2` if [[ ! -d $sdk_dump_path ]]; then - # This would mean the SAI_DUMP_STORE_PATH is not mounted on the host and is only accessible though the container + # This would mean the SAI_DUMP_STORE_PATH is not mounted on the host and is only accessible though the container # This is a bad design and not recommended But there is nothing which restricts against it and thus the special handling if [[ "$( docker container inspect -f '{{.State.Running}}' syncd )" == "true" ]]; then $RM $V -rf /tmp/dfw-sdk-dumps @@ -1382,7 +1382,7 @@ collect_barefoot() { for file in $(find /tmp/bf_logs -type f); do save_file "${file}" log true done -} +} ############################################################################### # Collect Cisco-8000 specific information @@ -1728,6 +1728,7 @@ main() { save_cmd "show interface transceiver presence" "interface.xcvrs.presence" & save_cmd "show interface transceiver eeprom --dom" "interface.xcvrs.eeprom" & save_cmd "show ip interface -d all" "ip.interface" & + save_cmd "sfputil show eeprom-hexdump-all" "interface.xcvrs.eeprom.raw" & wait save_cmd "lldpctl" "lldpctl" & @@ -1851,7 +1852,7 @@ main() { save_to_tar - save_sai_failure_dump + save_sai_failure_dump if [[ "$asic" = "mellanox" ]]; then collect_mellanox_dfw_dumps diff --git a/sfputil/main.py b/sfputil/main.py index 51d5af4895..cbc6d24a33 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -821,6 +821,33 @@ def hexdump(indent, data, mem_address): return result + +# 'eeprom-hexdump-all' subcommand +@show.command() +def eeprom_hexdump_all(): + """Display EEPROM hexdump of SFP transceiver(s) for all modules""" + lines = [] + + for index, sfp in enumerate(platform_chassis.get_all_sfps()): + try: + presence = sfp.get_presence() + if not presence: + lines.append(f'\nModule {index + 1} not present') + else: + lines.append(f'\nEEPROM hexdump for module {index + 1}') + eeprom_data = sfp.dump_eeprom() + if eeprom_data is None: + lines.append(' N/A\n') + else: + lines.append(eeprom_data) + except NotImplementedError: + lines.append(f'\nModule {index + 1} not supported') + except Exception as e: + lines.append(f'\nModule {index + 1} get EEPROM failed: {e}') + + click.echo('\n'.join(lines)) + + # 'presence' subcommand @show.command() @click.option('-p', '--port', metavar='', help="Display SFP presence for port only") @@ -1253,10 +1280,10 @@ def is_fw_switch_done(port_name): status = -1 # Abnormal status. elif (ImageARunning == 1) and (ImageACommitted == 0): # ImageA is running, but not committed. click.echo("FW images switch successful : ImageA is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. elif (ImageBRunning == 1) and (ImageBCommitted == 0): # ImageB is running, but not committed. click.echo("FW images switch successful : ImageB is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. else: # No image is running, or running and committed image is same. click.echo("FW info error : Failed to switch into uncommitted image!") status = -1 # Failure for Switching images. diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index f8917d9c44..115b7630f1 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -256,7 +256,7 @@ def test_convert_sfp_info_to_output_string(self, sfp_info_dict, expected_output) Vcc: 3.2577Volts ModuleThresholdValues: ''' - ), + ), ( 'QSFP-DD Double Density 8X Pluggable Transceiver', { @@ -780,6 +780,37 @@ def side_effect(offset, num_bytes): assert result.exit_code == 0 assert result.output == expected_output + @patch('sfputil.main.platform_chassis') + def test_eeprom_hexdump_all(self, mock_chassis): + sfp_list = [MagicMock() for x in range(5)] + sfp_list[0].get_presence = MagicMock(return_value=False) + sfp_list[1].get_presence = MagicMock(side_effect=NotImplementedError) + sfp_list[2].get_presence = MagicMock(side_effect=RuntimeError('error')) + sfp_list[3].get_presence = MagicMock(return_value=True) + sfp_list[3].dump_eeprom = MagicMock(return_value=None) + sfp_list[4].get_presence = MagicMock(return_value=True) + sfp_list[4].dump_eeprom = MagicMock(return_value=' Hello') + mock_chassis.get_all_sfps.return_value = sfp_list + runner = CliRunner() + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump-all']) + assert result.exit_code == 0 + expected_output = """ +Module 1 not present + +Module 2 not supported + +Module 3 get EEPROM failed: error + +EEPROM hexdump for module 4 + N/A + + +EEPROM hexdump for module 5 + Hello +""" + print(result.output) + assert result.output == expected_output + @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) From 3d041bd0378b250738645b0288de96f50eb3db5e Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Wed, 18 Oct 2023 12:03:06 +0300 Subject: [PATCH 02/15] Fix review comment --- scripts/generate_dump | 2 +- sfputil/main.py | 202 ++++++++++++++++++++++++++++++++---------- tests/sfputil_test.py | 163 +++++++++++++++++++++++++++++++++- 3 files changed, 313 insertions(+), 54 deletions(-) diff --git a/scripts/generate_dump b/scripts/generate_dump index 8f6ef34704..979dd30d45 100755 --- a/scripts/generate_dump +++ b/scripts/generate_dump @@ -1728,7 +1728,7 @@ main() { save_cmd "show interface transceiver presence" "interface.xcvrs.presence" & save_cmd "show interface transceiver eeprom --dom" "interface.xcvrs.eeprom" & save_cmd "show ip interface -d all" "ip.interface" & - save_cmd "sfputil show eeprom-hexdump-all" "interface.xcvrs.eeprom.raw" & + save_cmd "sfputil show eeprom-hexdump" "interface.xcvrs.eeprom.raw" & wait save_cmd "lldpctl" "lldpctl" & diff --git a/sfputil/main.py b/sfputil/main.py index cbc6d24a33..785d0cc3ca 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -50,6 +50,7 @@ PAGE_OFFSET = 128 SFF8472_A0_SIZE = 256 +EEPROM_DUMP_INDENT = ' ' * 8 # TODO: We should share these maps and the formatting functions between sfputil and sfpshow QSFP_DD_DATA_MAP = { @@ -680,12 +681,17 @@ def eeprom(port, dump_dom, namespace): # 'eeprom-hexdump' subcommand @show.command() -@click.option('-p', '--port', metavar='', required=True, help="Display SFP EEPROM hexdump for port ") +@click.option('-p', '--port', metavar='', help="Display SFP EEPROM hexdump for port ") @click.option('-n', '--page', metavar='', help="Display SFP EEEPROM hexdump for ") def eeprom_hexdump(port, page): - """Display EEPROM hexdump of SFP transceiver(s) for a given port name and page number""" - output = "" + """Display EEPROM hexdump of SFP transceiver(s)""" + if port: + dump_eeprom_for_single_port(port, page) + else: + dump_eeprom_for_all_ports(page) + +def dump_eeprom_for_single_port(port, page): if platform_sfputil.is_logical_port(port) == 0: click.echo("Error: invalid port {}".format(port)) print_all_valid_port_values() @@ -729,6 +735,120 @@ def eeprom_hexdump(port, page): click.echo(output) + +def dump_eeprom_for_all_ports(page): + lines = [] + + for index, sfp in enumerate(platform_chassis.get_all_sfps()): + try: + presence = sfp.get_presence() + if not presence: + lines.append(f'\nModule {index + 1} not present') + else: + lines.append(f'\nEEPROM hexdump for module {index + 1}') + eeprom_data = dump_sfp_eeprom(sfp, page) + if eeprom_data is None: + lines.append(f'{EEPROM_DUMP_INDENT}N/A\n') + else: + lines.append(eeprom_data) + except NotImplementedError: + lines.append(f'\nModule {index + 1} not supported') + except Exception as e: + lines.append(f'\nModule {index + 1} get EEPROM failed: {e}') + + click.echo('\n'.join(lines)) + + +def dump_sfp_eeprom(sfp, page): + api = sfp.get_xcvr_api() + if api is None: + return f'{EEPROM_DUMP_INDENT}N/A\n' + + from sonic_platform_base.sonic_xcvr.api.public import sff8636, sff8436, cmis, sff8472 + from sonic_platform_base.sonic_xcvr.fields import consts + if isinstance(api, cmis.CmisApi): + if api.is_flat_memory(): + valid_pages = [0] + else: + valid_pages = [0, 1, 2, 16, 17] + if api.is_coherent_module(): + valid_pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) + cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) + if cdb_support != 0: + valid_pages.append(0x9f) + return dump_eeprom_pages(sfp, page, valid_pages) + elif isinstance(api, sff8636.Sff8636Api) or isinstance(api, sff8436.Sff8436Api): + if api.is_flat_memory(): + valid_pages = [0] + else: + valid_pages = [0, 1, 2, 3] + return dump_eeprom_pages(sfp, page, valid_pages) + elif isinstance(api, sff8472.Sff8472Api): + is_active_cable = api.xcvr_eeprom.read(consts.SFP_CABLE_TECH_FIELD) == 'Active Cable' + if is_active_cable: + valid_pages = [0, 1, 2] + else: + valid_pages = [0] + return dump_eeprom_pages_sff8472(sfp, page, valid_pages, api.is_flat_memory()) + + +def dump_eeprom_pages(sfp, page, valid_pages): + if page and int(page) not in valid_pages: + return f'{EEPROM_DUMP_INDENT}Page not supported\n' + pages = valid_pages if page is None else [int(page)] + lines = [] + first = True + for page in pages: + if first: + first = False + else: + lines.append('') + if page == 0: + lines.append(f'{EEPROM_DUMP_INDENT}Lower page 0h') + lines.append(dump_eeprom_single_page(sfp, 0, PAGE_SIZE, 0)) + lines.append(f'\n{EEPROM_DUMP_INDENT}Upper page 0h') + lines.append(dump_eeprom_single_page(sfp, PAGE_OFFSET, PAGE_SIZE, PAGE_OFFSET)) + else: + lines.append(f'{EEPROM_DUMP_INDENT}Page {page:x}h') + lines.append(dump_eeprom_single_page(sfp, 256 + (page - 1) * PAGE_SIZE, PAGE_SIZE, PAGE_OFFSET)) + return '\n'.join(lines) + + +def dump_eeprom_pages_sff8472(sfp, page, valid_pages, is_flat_memory): + if page and int(page) not in valid_pages: + return f'{EEPROM_DUMP_INDENT}Page not supported\n' + pages = valid_pages if page is None else [int(page)] + lines = [] + first = True + for page in pages: + if first: + first = False + else: + lines.append('') + if page == 0: + if not is_flat_memory: + lines.append(f'{EEPROM_DUMP_INDENT}A0h dump') + lines.append(dump_eeprom_single_page(sfp, 0, SFF8472_A0_SIZE, 0)) + else: + lines.append(f'{EEPROM_DUMP_INDENT}A0h dump') + lines.append(dump_eeprom_single_page(sfp, 0, PAGE_SIZE, 0)) + elif page == 1: + lines.append(f'{EEPROM_DUMP_INDENT}A2h dump (lower 128 bytes)') + lines.append(dump_eeprom_single_page(sfp, SFF8472_A0_SIZE, PAGE_SIZE, 0)) + elif page == 2: + lines.append(f'{EEPROM_DUMP_INDENT}A2h dump (upper 128 bytes)') + lines.append(dump_eeprom_single_page(sfp, SFF8472_A0_SIZE + PAGE_SIZE, PAGE_SIZE, 0)) + return '\n'.join(lines) + + +def dump_eeprom_single_page(sfp, overall_offset, size, page_offset): + page_data = sfp.read_eeprom(overall_offset, size) + if page_data: + return hexdump(EEPROM_DUMP_INDENT, page_data, page_offset, start_newline=False) + else: + return f'{EEPROM_DUMP_INDENT}Failed to read EEPROM' + + def eeprom_hexdump_sff8472(port, physical_port, page): try: output = "" @@ -765,6 +885,7 @@ def eeprom_hexdump_sff8472(port, physical_port, page): return output + def eeprom_hexdump_sff8636(port, physical_port, page): try: output = "" @@ -793,59 +914,42 @@ def eeprom_hexdump_sff8636(port, physical_port, page): return output + def convert_byte_to_valid_ascii_char(byte): if byte < 32 or 126 < byte: return '.' else: return chr(byte) -def hexdump(indent, data, mem_address): - ascii_string = '' - result = '' - for byte in data: - ascii_string = ascii_string + convert_byte_to_valid_ascii_char(byte) - byte_string = "{:02x}".format(byte) - if mem_address % 16 == 0: - mem_address_string = "{:08x}".format(mem_address) - result += '\n{}{} '.format(indent, mem_address_string) - result += '{} '.format(byte_string) - elif mem_address % 16 == 15: - result += '{} '.format(byte_string) - result += '|{}|'.format(ascii_string) - ascii_string = "" - elif mem_address % 16 == 8: - result += ' {} '.format(byte_string) - else: - result += '{} '.format(byte_string) - mem_address += 1 - - return result - -# 'eeprom-hexdump-all' subcommand -@show.command() -def eeprom_hexdump_all(): - """Display EEPROM hexdump of SFP transceiver(s) for all modules""" - lines = [] - - for index, sfp in enumerate(platform_chassis.get_all_sfps()): - try: - presence = sfp.get_presence() - if not presence: - lines.append(f'\nModule {index + 1} not present') - else: - lines.append(f'\nEEPROM hexdump for module {index + 1}') - eeprom_data = sfp.dump_eeprom() - if eeprom_data is None: - lines.append(' N/A\n') - else: - lines.append(eeprom_data) - except NotImplementedError: - lines.append(f'\nModule {index + 1} not supported') - except Exception as e: - lines.append(f'\nModule {index + 1} get EEPROM failed: {e}') - - click.echo('\n'.join(lines)) +def hexdump(indent, data, mem_address, start_newline=True): + size = len(data) + offset = 0 + lines = [''] if start_newline else [] + while size > 0: + offset_str = "{}{:08x}".format(indent, mem_address) + if size >= 16: + first_half = ' '.join("{:02x}".format(x) for x in data[offset:offset + 8]) + second_half = ' '.join("{:02x}".format(x) for x in data[offset + 8:offset + 16]) + ascii_str = ''.join(convert_byte_to_valid_ascii_char(x) for x in data[offset:offset + 16]) + lines.append(f'{offset_str} {first_half} {second_half} |{ascii_str}|') + elif size > 8: + first_half = ' '.join("{:02x}".format(x) for x in data[offset:offset + 8]) + second_half = ' '.join("{:02x}".format(x) for x in data[offset + 8:offset + size]) + padding = ' ' * (16 - size) + ascii_str = ''.join(convert_byte_to_valid_ascii_char(x) for x in data[offset:offset + size]) + lines.append(f'{offset_str} {first_half} {second_half}{padding} |{ascii_str}|') + break + else: + hex_part = ' '.join("{:02x}".format(x) for x in data[offset:offset + size]) + padding = ' ' * (16 - size) + ascii_str = ''.join(convert_byte_to_valid_ascii_char(x) for x in data[offset:offset + size]) + lines.append(f'{offset_str} {hex_part} {padding} |{ascii_str}|') + break + size -= 16 + offset += 16 + mem_address += 16 + return '\n'.join(lines) # 'presence' subcommand diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index 115b7630f1..6937adc41d 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -781,18 +781,18 @@ def side_effect(offset, num_bytes): assert result.output == expected_output @patch('sfputil.main.platform_chassis') - def test_eeprom_hexdump_all(self, mock_chassis): + @patch('sfputil.main.dump_sfp_eeprom') + def test_eeprom_hexdump_all(self, mock_dump_eeprom, mock_chassis): sfp_list = [MagicMock() for x in range(5)] + mock_dump_eeprom.side_effect = [None, ' Hello'] sfp_list[0].get_presence = MagicMock(return_value=False) sfp_list[1].get_presence = MagicMock(side_effect=NotImplementedError) sfp_list[2].get_presence = MagicMock(side_effect=RuntimeError('error')) sfp_list[3].get_presence = MagicMock(return_value=True) - sfp_list[3].dump_eeprom = MagicMock(return_value=None) sfp_list[4].get_presence = MagicMock(return_value=True) - sfp_list[4].dump_eeprom = MagicMock(return_value=' Hello') mock_chassis.get_all_sfps.return_value = sfp_list runner = CliRunner() - result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump-all']) + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump']) assert result.exit_code == 0 expected_output = """ Module 1 not present @@ -811,6 +811,161 @@ def test_eeprom_hexdump_all(self, mock_chassis): print(result.output) assert result.output == expected_output + @patch('sfputil.main.isinstance') + def test_dump_sfp_eeprom(self, mock_is_instance): + mock_sfp = MagicMock() + mock_sfp.get_xcvr_api = MagicMock(return_value=None) + output = sfputil.dump_sfp_eeprom(mock_sfp, None) + assert 'N/A' in output + + mock_api = MagicMock() + mock_api.is_flat_memory = MagicMock(return_value=False) + mock_api.is_coherent_module = MagicMock(return_value=True) + mock_api.xcvr_eeprom = MagicMock() + mock_api.xcvr_eeprom.read = MagicMock(return_value=1) + mock_sfp.get_xcvr_api.return_value = mock_api + mock_is_instance.return_value = True + + output = sfputil.dump_sfp_eeprom(mock_sfp, -1) + assert 'Page not supported' in output + + expected_output_page0 = """ Lower page 0h + 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................| + + Upper page 0h + 00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000090 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 000000a0 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 000000b0 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 000000c0 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 000000d0 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 000000e0 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 000000f0 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000100 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000110 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 00000120 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 00000130 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 00000140 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 00000150 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 00000160 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 00000170 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" + mock_sfp.read_eeprom = MagicMock(return_value=bytearray([x for x in range(256)])) + output = sfputil.dump_sfp_eeprom(mock_sfp, 0) + assert output == expected_output_page0 + expected_output_page1 = """ Page 1h + 00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000090 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 000000a0 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 000000b0 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 000000c0 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 000000d0 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 000000e0 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 000000f0 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000100 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000110 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 00000120 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 00000130 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 00000140 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 00000150 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 00000160 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 00000170 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" + output = sfputil.dump_sfp_eeprom(mock_sfp, 1) + assert output == expected_output_page1 + + mock_is_instance.side_effect = [False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, 0) + assert output == expected_output_page0 + + mock_api.xcvr_eeprom.read = MagicMock(return_value='Active Cable') + mock_is_instance.side_effect = [False, False, False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, -1) + assert 'Page not supported' in output + mock_is_instance.side_effect = [False, False, False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, 0) + expected_output_a0h = """ A0h dump + 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" + assert output == expected_output_a0h + mock_is_instance.side_effect = [False, False, False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, 1) + expected_output_a2h_lower = """ A2h dump (lower 128 bytes) + 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" + assert output == expected_output_a2h_lower + mock_is_instance.side_effect = [False, False, False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, 2) + expected_output_a2h_upper = """ A2h dump (upper 128 bytes) + 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| + 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| + 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| + 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| + 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| + 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| + 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| + 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| + 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| + 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| + 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| + 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| + 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| + 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| + 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| + 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" + assert output == expected_output_a2h_upper + mock_api.is_flat_memory.return_value = True + mock_is_instance.side_effect = [False, False, False, True] + output = sfputil.dump_sfp_eeprom(mock_sfp, 0) + assert output == expected_output_a0h + + mock_is_instance.side_effect = None + mock_is_instance.return_value = True + mock_sfp.read_eeprom.return_value = None + output = sfputil.dump_sfp_eeprom(mock_sfp, 0) + assert 'Failed to read EEPROM' in output + @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) From be6ae28acd0f6f66a99b81b86c23733ca2806074 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Thu, 19 Oct 2023 06:25:05 +0300 Subject: [PATCH 03/15] Improve validation and update command reference --- doc/Command-Reference.md | 129 +++++++++++++++++++++++++++++++++------ sfputil/main.py | 67 ++++++++++++-------- tests/sfputil_test.py | 30 +++++++-- 3 files changed, 175 insertions(+), 51 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 429fe39bbf..1458e82bf1 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -200,6 +200,8 @@ * [MACsec config command](#macsec-config-command) * [MACsec show command](#macsec-show-command) * [MACsec clear command](#macsec-clear-command) +* [SFP Utilities Commands](#sfp-utilities-commands) + * [SFP Utilities show commands](#sfp-utilities-show-commands) * [Static DNS Commands](#static-dns-commands) * [Static DNS config command](#static-dns-config-command) * [Static DNS show command](#static-dns-show-command) @@ -553,7 +555,7 @@ This command displays the current date and time configured on the system ``` **config clock date** - + This command will set the date-time of the systetm, given strings with date-time format - Usage: @@ -571,7 +573,7 @@ This command will set the date-time of the systetm, given strings with date-time ``` **config clock timezone** - + This command will set the timezone of the systetm, given a string of a valid timezone. - Usage: @@ -581,13 +583,13 @@ This command will set the timezone of the systetm, given a string of a valid tim - Parameters: - _timezone_: valid timezone to be configured - - + + - Example: ``` admin@sonic:~$ config clock timezone Africa/Accra - + **show clock timezones** This command Will display list of all valid timezones to be configured. @@ -2564,7 +2566,7 @@ Once enabled, BGP will not advertise routes which aren't yet offloaded. admin@sonic:~$ sudo config suppress-fib-pending enabled ``` ``` - admin@sonic:~$ sudo config suppress-fib-pending disabled + admin@sonic:~$ sudo config suppress-fib-pending disabled ``` Go Back To [Beginning of the document](#) or [Beginning of this section](#bgp) @@ -4670,11 +4672,11 @@ This command displays switchport modes status of the interfaces - Example (show interface switchport status of all interfaces): ``` admin@sonic:~$ show interfaces switchport status - Interface Mode - ----------- -------- - Ethernet0 access - Ethernet4 trunk - Ethernet8 routed + Interface Mode + ----------- -------- + Ethernet0 access + Ethernet4 trunk + Ethernet8 routed ``` @@ -4690,17 +4692,17 @@ This command displays switchport modes configuration of the interfaces - Example (show interface switchport config of all interfaces): ``` admin@sonic:~$ show interfaces switchport config - Interface Mode Untagged Tagged - ----------- -------- -------- ------- - Ethernet0 access 2 - Ethernet4 trunk 3 4,5,6 - Ethernet8 routed + Interface Mode Untagged Tagged + ----------- -------- -------- ------- + Ethernet0 access 2 + Ethernet4 trunk 3 4,5,6 + Ethernet8 routed ``` For details please refer [Switchport Mode HLD](https://github.com/sonic-net/SONiC/pull/912/files#diff-03597c34684d527192f76a6e975792fcfc83f54e20dde63f159399232d148397) to know more about this command. - + **show interfaces transceiver** This command is already explained [here](#Transceivers) @@ -6732,7 +6734,7 @@ in order to detemine whether the health of the cable is Ok the following are checked - the vendor name is correct able to be read - the FW is correctly loaded for SerDes by reading the appropriate register val -- the Counters for UART are displaying healthy status +- the Counters for UART are displaying healthy status i.e Error Counters , retry Counters for UART or internal xfer protocols are below a threshold @@ -6788,7 +6790,7 @@ the result will be displayed like this, each item in the dictionary shows the he { "uart_stat1": "2", "uart_stat2": "1", - + } ``` @@ -12748,6 +12750,95 @@ Clear MACsec counters which is to reset all MACsec counters to ZERO. Go Back To [Beginning of the document](#) or [Beginning of this section](#macsec-commands) +# SFP Utilities Commands + +This sub-section explains the list of commands available for SFP utilities feature. + +## SFP Utilities show commands + +- Show SFP EEPROM hex dump + +``` +admin@sonic:~$ sfputil show eeprom-hexdump --help +Usage: sfputil show eeprom-hexdump [OPTIONS] + + Display EEPROM hexdump of SFP transceiver(s) + +Options: + -p, --port Display SFP EEPROM hexdump for port + -n, --page Display SFP EEEPROM hexdump for + + --help Show this message and exit. +``` + +``` +admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 +EEPROM hexdump for port Ethernet0 page 0h + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + +admin@sonic:~$ sfputil show eeprom-hexdump +EEPROM hexdump for module 1 + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + +EEPROM hexdump for module 2 + Lower page 0h + 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| + 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| + 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| + 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| + 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + + Upper page 0h + 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| + 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| + 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| + 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| + 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| + 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | + 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| +... +``` + # Static DNS Commands This sub-section explains the list of the configuration options available for static DNS feature. diff --git a/sfputil/main.py b/sfputil/main.py index 785d0cc3ca..b2aac97b72 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -39,6 +39,7 @@ ERROR_PORT_CONFIG_LOAD = 4 ERROR_NOT_IMPLEMENTED = 5 ERROR_INVALID_PORT = 6 +ERROR_INVALID_PAGE = 7 SMBUS_BLOCK_WRITE_SIZE = 32 # Default host password as per CMIS spec: # http://www.qsfp-dd.com/wp-content/uploads/2021/05/CMIS5p0.pdf @@ -739,6 +740,17 @@ def dump_eeprom_for_single_port(port, page): def dump_eeprom_for_all_ports(page): lines = [] + if page is not None: + try: + page = int(page) + # Only do simple validation to a given page, user is responsible to make sure the page existence + if page < 0 or page > 255: + click.echo(f"Invalid page {page}") + sys.exit(ERROR_INVALID_PAGE) + except ValueError: + click.echo(f"Page {page} is not a valid number") + sys.exit(ERROR_INVALID_PAGE) + for index, sfp in enumerate(platform_chassis.get_all_sfps()): try: presence = sfp.get_presence() @@ -767,35 +779,41 @@ def dump_sfp_eeprom(sfp, page): from sonic_platform_base.sonic_xcvr.api.public import sff8636, sff8436, cmis, sff8472 from sonic_platform_base.sonic_xcvr.fields import consts if isinstance(api, cmis.CmisApi): - if api.is_flat_memory(): - valid_pages = [0] + if page is None: + if api.is_flat_memory(): + pages = [0] + else: + pages = [0, 1, 2, 16, 17] + if api.is_coherent_module(): + pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) + cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) + if cdb_support != 0: + pages.append(0x9f) else: - valid_pages = [0, 1, 2, 16, 17] - if api.is_coherent_module(): - valid_pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) - cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) - if cdb_support != 0: - valid_pages.append(0x9f) - return dump_eeprom_pages(sfp, page, valid_pages) + pages = [page] + return dump_eeprom_pages(sfp, pages) elif isinstance(api, sff8636.Sff8636Api) or isinstance(api, sff8436.Sff8436Api): - if api.is_flat_memory(): - valid_pages = [0] + if page is None: + if api.is_flat_memory(): + pages = [0] + else: + pages = [0, 1, 2, 3] else: - valid_pages = [0, 1, 2, 3] - return dump_eeprom_pages(sfp, page, valid_pages) + pages = [page] + return dump_eeprom_pages(sfp, pages) elif isinstance(api, sff8472.Sff8472Api): - is_active_cable = api.xcvr_eeprom.read(consts.SFP_CABLE_TECH_FIELD) == 'Active Cable' - if is_active_cable: - valid_pages = [0, 1, 2] + if page is None: + is_active_cable = api.xcvr_eeprom.read(consts.SFP_CABLE_TECH_FIELD) == 'Active Cable' + if is_active_cable: + pages = [0, 1, 2] + else: + pages = [0] else: - valid_pages = [0] - return dump_eeprom_pages_sff8472(sfp, page, valid_pages, api.is_flat_memory()) + pages = [page] + return dump_eeprom_pages_sff8472(sfp, pages, api.is_flat_memory()) -def dump_eeprom_pages(sfp, page, valid_pages): - if page and int(page) not in valid_pages: - return f'{EEPROM_DUMP_INDENT}Page not supported\n' - pages = valid_pages if page is None else [int(page)] +def dump_eeprom_pages(sfp, pages): lines = [] first = True for page in pages: @@ -814,10 +832,7 @@ def dump_eeprom_pages(sfp, page, valid_pages): return '\n'.join(lines) -def dump_eeprom_pages_sff8472(sfp, page, valid_pages, is_flat_memory): - if page and int(page) not in valid_pages: - return f'{EEPROM_DUMP_INDENT}Page not supported\n' - pages = valid_pages if page is None else [int(page)] +def dump_eeprom_pages_sff8472(sfp, pages, is_flat_memory): lines = [] first = True for page in pages: diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index 6937adc41d..16e76326f7 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -811,6 +811,17 @@ def test_eeprom_hexdump_all(self, mock_dump_eeprom, mock_chassis): print(result.output) assert result.output == expected_output + def test_test_eeprom_hexdump_all_invalid_page(self): + runner = CliRunner() + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '-1']) + assert result.exit_code != 0 + + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '256']) + assert result.exit_code != 0 + + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', 'invalid_number']) + assert result.exit_code != 0 + @patch('sfputil.main.isinstance') def test_dump_sfp_eeprom(self, mock_is_instance): mock_sfp = MagicMock() @@ -826,9 +837,6 @@ def test_dump_sfp_eeprom(self, mock_is_instance): mock_sfp.get_xcvr_api.return_value = mock_api mock_is_instance.return_value = True - output = sfputil.dump_sfp_eeprom(mock_sfp, -1) - assert 'Page not supported' in output - expected_output_page0 = """ Lower page 0h 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| @@ -867,6 +875,7 @@ def test_dump_sfp_eeprom(self, mock_is_instance): mock_sfp.read_eeprom = MagicMock(return_value=bytearray([x for x in range(256)])) output = sfputil.dump_sfp_eeprom(mock_sfp, 0) assert output == expected_output_page0 + expected_output_page1 = """ Page 1h 00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| 00000090 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| @@ -886,16 +895,17 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 00000170 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" output = sfputil.dump_sfp_eeprom(mock_sfp, 1) assert output == expected_output_page1 + sfputil.dump_sfp_eeprom(mock_sfp, None) mock_is_instance.side_effect = [False, True] output = sfputil.dump_sfp_eeprom(mock_sfp, 0) assert output == expected_output_page0 + mock_is_instance.side_effect = [False, True] + sfputil.dump_sfp_eeprom(mock_sfp, None) + mock_api.xcvr_eeprom.read = MagicMock(return_value='Active Cable') mock_is_instance.side_effect = [False, False, False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, -1) - assert 'Page not supported' in output - mock_is_instance.side_effect = [False, False, False, True] output = sfputil.dump_sfp_eeprom(mock_sfp, 0) expected_output_a0h = """ A0h dump 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| @@ -915,6 +925,7 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" assert output == expected_output_a0h + mock_is_instance.side_effect = [False, False, False, True] output = sfputil.dump_sfp_eeprom(mock_sfp, 1) expected_output_a2h_lower = """ A2h dump (lower 128 bytes) @@ -935,6 +946,7 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" assert output == expected_output_a2h_lower + mock_is_instance.side_effect = [False, False, False, True] output = sfputil.dump_sfp_eeprom(mock_sfp, 2) expected_output_a2h_upper = """ A2h dump (upper 128 bytes) @@ -955,10 +967,16 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" assert output == expected_output_a2h_upper + + mock_is_instance.side_effect = [False, False, False, True] + sfputil.dump_sfp_eeprom(mock_sfp, None) + mock_api.is_flat_memory.return_value = True mock_is_instance.side_effect = [False, False, False, True] output = sfputil.dump_sfp_eeprom(mock_sfp, 0) assert output == expected_output_a0h + mock_is_instance.side_effect = [False, False, False, True] + sfputil.dump_sfp_eeprom(mock_sfp, None) mock_is_instance.side_effect = None mock_is_instance.return_value = True From 44cf459d7b99294a009516e997db499702c7d657 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Thu, 19 Oct 2023 06:40:00 +0300 Subject: [PATCH 04/15] Update command ref --- doc/Command-Reference.md | 204 +++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 107 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 1458e82bf1..b9a4468dfd 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -201,7 +201,7 @@ * [MACsec show command](#macsec-show-command) * [MACsec clear command](#macsec-clear-command) * [SFP Utilities Commands](#sfp-utilities-commands) - * [SFP Utilities show commands](#sfp-utilities-show-commands) + * [SFP Utilities show commands](#sfp-utilities-show-commands) * [Static DNS Commands](#static-dns-commands) * [Static DNS config command](#static-dns-config-command) * [Static DNS show command](#static-dns-show-command) @@ -555,7 +555,7 @@ This command displays the current date and time configured on the system ``` **config clock date** - + This command will set the date-time of the systetm, given strings with date-time format - Usage: @@ -573,7 +573,7 @@ This command will set the date-time of the systetm, given strings with date-time ``` **config clock timezone** - + This command will set the timezone of the systetm, given a string of a valid timezone. - Usage: @@ -583,13 +583,13 @@ This command will set the timezone of the systetm, given a string of a valid tim - Parameters: - _timezone_: valid timezone to be configured - - + + - Example: ``` admin@sonic:~$ config clock timezone Africa/Accra - + **show clock timezones** This command Will display list of all valid timezones to be configured. @@ -2566,7 +2566,7 @@ Once enabled, BGP will not advertise routes which aren't yet offloaded. admin@sonic:~$ sudo config suppress-fib-pending enabled ``` ``` - admin@sonic:~$ sudo config suppress-fib-pending disabled + admin@sonic:~$ sudo config suppress-fib-pending disabled ``` Go Back To [Beginning of the document](#) or [Beginning of this section](#bgp) @@ -4672,11 +4672,11 @@ This command displays switchport modes status of the interfaces - Example (show interface switchport status of all interfaces): ``` admin@sonic:~$ show interfaces switchport status - Interface Mode - ----------- -------- - Ethernet0 access - Ethernet4 trunk - Ethernet8 routed + Interface Mode + ----------- -------- + Ethernet0 access + Ethernet4 trunk + Ethernet8 routed ``` @@ -4692,17 +4692,17 @@ This command displays switchport modes configuration of the interfaces - Example (show interface switchport config of all interfaces): ``` admin@sonic:~$ show interfaces switchport config - Interface Mode Untagged Tagged - ----------- -------- -------- ------- - Ethernet0 access 2 - Ethernet4 trunk 3 4,5,6 - Ethernet8 routed + Interface Mode Untagged Tagged + ----------- -------- -------- ------- + Ethernet0 access 2 + Ethernet4 trunk 3 4,5,6 + Ethernet8 routed ``` For details please refer [Switchport Mode HLD](https://github.com/sonic-net/SONiC/pull/912/files#diff-03597c34684d527192f76a6e975792fcfc83f54e20dde63f159399232d148397) to know more about this command. - + **show interfaces transceiver** This command is already explained [here](#Transceivers) @@ -6734,7 +6734,7 @@ in order to detemine whether the health of the cable is Ok the following are checked - the vendor name is correct able to be read - the FW is correctly loaded for SerDes by reading the appropriate register val -- the Counters for UART are displaying healthy status +- the Counters for UART are displaying healthy status i.e Error Counters , retry Counters for UART or internal xfer protocols are below a threshold @@ -6790,7 +6790,7 @@ the result will be displayed like this, each item in the dictionary shows the he { "uart_stat1": "2", "uart_stat2": "1", - + } ``` @@ -12751,93 +12751,83 @@ Clear MACsec counters which is to reset all MACsec counters to ZERO. Go Back To [Beginning of the document](#) or [Beginning of this section](#macsec-commands) # SFP Utilities Commands - -This sub-section explains the list of commands available for SFP utilities feature. - -## SFP Utilities show commands - -- Show SFP EEPROM hex dump - -``` -admin@sonic:~$ sfputil show eeprom-hexdump --help -Usage: sfputil show eeprom-hexdump [OPTIONS] - - Display EEPROM hexdump of SFP transceiver(s) - -Options: - -p, --port Display SFP EEPROM hexdump for port - -n, --page Display SFP EEEPROM hexdump for - - --help Show this message and exit. -``` - -``` -admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 -EEPROM hexdump for port Ethernet0 page 0h - Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - - Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| - 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| - -admin@sonic:~$ sfputil show eeprom-hexdump -EEPROM hexdump for module 1 - Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - - Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| - 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| - -EEPROM hexdump for module 2 - Lower page 0h - 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| - 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| - 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| - 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| - 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - - Upper page 0h - 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| - 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| - 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| - 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| - 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| - 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | - 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| -... -``` + This sub-section explains the list of commands available for SFP utilities feature. + ## SFP Utilities show commands + - Show SFP EEPROM hex dump + ``` + admin@sonic:~$ sfputil show eeprom-hexdump --help + Usage: sfputil show eeprom-hexdump [OPTIONS] + Display EEPROM hexdump of SFP transceiver(s) + Options: + -p, --port Display SFP EEPROM hexdump for port + -n, --page Display SFP EEEPROM hexdump for + + --help Show this message and exit. + ``` + ``` + admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 + EEPROM hexdump for port Ethernet0 page 0h + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + admin@sonic:~$ sfputil show eeprom-hexdump + EEPROM hexdump for module 1 + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + EEPROM hexdump for module 2 + Lower page 0h + 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| + 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| + 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| + 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| + 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| + 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| + 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| + 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| + 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| + 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | + 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| + ... + ``` + + Go Back To [Beginning of the document](#) or [Beginning of this section](#sfp-utilities-commands) # Static DNS Commands From 0e3ce9b4ebbe433ce0bfae5927c7183bf6f9d932 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Thu, 19 Oct 2023 07:30:36 +0300 Subject: [PATCH 05/15] Fix format --- doc/Command-Reference.md | 158 ++++++++++++++++++++------------------- scripts/generate_dump | 6 +- sfputil/main.py | 8 +- tests/sfputil_test.py | 2 +- 4 files changed, 89 insertions(+), 85 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index b9a4468dfd..310b276b05 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -201,7 +201,7 @@ * [MACsec show command](#macsec-show-command) * [MACsec clear command](#macsec-clear-command) * [SFP Utilities Commands](#sfp-utilities-commands) - * [SFP Utilities show commands](#sfp-utilities-show-commands) + * [SFP Utilities show commands](#sfp-utilities-show-commands) * [Static DNS Commands](#static-dns-commands) * [Static DNS config command](#static-dns-config-command) * [Static DNS show command](#static-dns-show-command) @@ -12752,82 +12752,86 @@ Go Back To [Beginning of the document](#) or [Beginning of this section](#macsec # SFP Utilities Commands This sub-section explains the list of commands available for SFP utilities feature. - ## SFP Utilities show commands - - Show SFP EEPROM hex dump - ``` - admin@sonic:~$ sfputil show eeprom-hexdump --help - Usage: sfputil show eeprom-hexdump [OPTIONS] - Display EEPROM hexdump of SFP transceiver(s) - Options: - -p, --port Display SFP EEPROM hexdump for port - -n, --page Display SFP EEEPROM hexdump for - - --help Show this message and exit. - ``` - ``` - admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 - EEPROM hexdump for port Ethernet0 page 0h - Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| - 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| - admin@sonic:~$ sfputil show eeprom-hexdump - EEPROM hexdump for module 1 - Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| - 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| - EEPROM hexdump for module 2 - Lower page 0h - 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| - 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| - 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| - 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| - 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| - 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - Upper page 0h - 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| - 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| - 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| - 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| - 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| - 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | - 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| - ... - ``` - - Go Back To [Beginning of the document](#) or [Beginning of this section](#sfp-utilities-commands) + +## SFP Utilities show commands + +- Show SFP EEPROM hex dump + +``` +admin@sonic:~$ sfputil show eeprom-hexdump --help +Usage: sfputil show eeprom-hexdump [OPTIONS] + Display EEPROM hexdump of SFP transceiver(s) +Options: + -p, --port Display SFP EEPROM hexdump for port + -n, --page Display SFP EEEPROM hexdump for + + --help Show this message and exit. +``` + +``` +admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 +EEPROM hexdump for port Ethernet0 page 0h + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| +admin@sonic:~$ sfputil show eeprom-hexdump +EEPROM hexdump for module 1 + Lower page 0h + 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| + 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| + 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| + 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| + 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| + 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| + 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| +EEPROM hexdump for module 2 + Lower page 0h + 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| + 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| + 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| + 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| + 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h + 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| + 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| + 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| + 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| + 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| + 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | + 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| +... +``` + +Go Back To [Beginning of the document](#) or [Beginning of this section](#sfp-utilities-commands) # Static DNS Commands diff --git a/scripts/generate_dump b/scripts/generate_dump index 979dd30d45..7a3d001cbe 100755 --- a/scripts/generate_dump +++ b/scripts/generate_dump @@ -1126,7 +1126,7 @@ collect_mellanox_dfw_dumps() { local sdk_dump_path=`cat /usr/share/sonic/device/${platform}/${hwsku}/sai.profile|grep "SAI_DUMP_STORE_PATH"|cut -d = -f2` if [[ ! -d $sdk_dump_path ]]; then - # This would mean the SAI_DUMP_STORE_PATH is not mounted on the host and is only accessible though the container + # This would mean the SAI_DUMP_STORE_PATH is not mounted on the host and is only accessible though the container # This is a bad design and not recommended But there is nothing which restricts against it and thus the special handling if [[ "$( docker container inspect -f '{{.State.Running}}' syncd )" == "true" ]]; then $RM $V -rf /tmp/dfw-sdk-dumps @@ -1382,7 +1382,7 @@ collect_barefoot() { for file in $(find /tmp/bf_logs -type f); do save_file "${file}" log true done -} +} ############################################################################### # Collect Cisco-8000 specific information @@ -1852,7 +1852,7 @@ main() { save_to_tar - save_sai_failure_dump + save_sai_failure_dump if [[ "$asic" = "mellanox" ]]; then collect_mellanox_dfw_dumps diff --git a/sfputil/main.py b/sfputil/main.py index b2aac97b72..fd73460f3b 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -51,6 +51,7 @@ PAGE_OFFSET = 128 SFF8472_A0_SIZE = 256 + EEPROM_DUMP_INDENT = ' ' * 8 # TODO: We should share these maps and the formatting functions between sfputil and sfpshow @@ -680,6 +681,7 @@ def eeprom(port, dump_dom, namespace): click.echo(output) + # 'eeprom-hexdump' subcommand @show.command() @click.option('-p', '--port', metavar='', help="Display SFP EEPROM hexdump for port ") @@ -900,7 +902,6 @@ def eeprom_hexdump_sff8472(port, physical_port, page): return output - def eeprom_hexdump_sff8636(port, physical_port, page): try: output = "" @@ -929,7 +930,6 @@ def eeprom_hexdump_sff8636(port, physical_port, page): return output - def convert_byte_to_valid_ascii_char(byte): if byte < 32 or 126 < byte: return '.' @@ -1399,10 +1399,10 @@ def is_fw_switch_done(port_name): status = -1 # Abnormal status. elif (ImageARunning == 1) and (ImageACommitted == 0): # ImageA is running, but not committed. click.echo("FW images switch successful : ImageA is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. elif (ImageBRunning == 1) and (ImageBCommitted == 0): # ImageB is running, but not committed. click.echo("FW images switch successful : ImageB is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. else: # No image is running, or running and committed image is same. click.echo("FW info error : Failed to switch into uncommitted image!") status = -1 # Failure for Switching images. diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index 16e76326f7..f1faeefe58 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -256,7 +256,7 @@ def test_convert_sfp_info_to_output_string(self, sfp_info_dict, expected_output) Vcc: 3.2577Volts ModuleThresholdValues: ''' - ), + ), ( 'QSFP-DD Double Density 8X Pluggable Transceiver', { From 6f9b83d29b5acf456391e6c9865f9fae3f959ff9 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Thu, 9 Nov 2023 08:37:25 +0200 Subject: [PATCH 06/15] Use is_copper API instead of reading EEPROM --- sfputil/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index fd73460f3b..16bd167bd9 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -805,8 +805,7 @@ def dump_sfp_eeprom(sfp, page): return dump_eeprom_pages(sfp, pages) elif isinstance(api, sff8472.Sff8472Api): if page is None: - is_active_cable = api.xcvr_eeprom.read(consts.SFP_CABLE_TECH_FIELD) == 'Active Cable' - if is_active_cable: + if not api.is_copper(): pages = [0, 1, 2] else: pages = [0] From 2f97d7e8bf059885ee4e01366bb59878797918bf Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Mon, 20 Nov 2023 09:24:22 +0200 Subject: [PATCH 07/15] Fix review comments --- doc/Command-Reference.md | 85 +++++---- sfputil/main.py | 395 +++++++++++++++++++-------------------- tests/sfputil_test.py | 222 ++++++---------------- 3 files changed, 293 insertions(+), 409 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 310b276b05..bb0285af32 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -12772,62 +12772,67 @@ Options: admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 0 EEPROM hexdump for port Ethernet0 page 0h Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000000 18 30 80 03 00 00 00 00 00 00 00 00 00 00 00 00 |.0..............| + 00000010 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 03 1d 01 88 01 1c 01 44 11 1b 01 |............D...| + 00000060 22 55 1a 01 44 11 18 01 11 ff 17 01 44 11 16 01 |"U..D.......D...| + 00000070 11 ff 01 01 11 ff 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| - 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + 00000080 18 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 20 20 20 |.Mellanox | + 00000090 20 00 02 c9 4d 43 50 31 36 36 30 2d 57 30 30 41 | ...MCP1660-W00A| + 000000a0 45 33 30 20 41 32 4d 54 32 30 31 39 56 53 30 34 |E30 A2MT2019VS04| + 000000b0 37 39 35 20 20 20 32 30 30 35 30 37 20 20 00 00 |795 200507 ..| + 000000c0 00 00 00 00 00 00 00 00 00 01 05 23 04 05 07 15 |...........#....| + 000000d0 00 00 00 02 0a 00 00 00 00 00 00 00 00 00 77 00 |..............w.| + 000000e0 33 30 33 33 30 4b 34 33 34 31 30 44 00 00 00 00 |30330K43410D....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + admin@sonic:~$ sfputil show eeprom-hexdump -EEPROM hexdump for module 1 +EEPROM hexdump for port Ethernet0 Lower page 0h - 00000000 11 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000000 11 08 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000060 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 00 |................| - 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 01 08 00 |................| + 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h - 00000080 11 00 23 88 00 00 00 00 00 00 00 00 ff 00 00 00 |..#.............| - 00000090 00 00 03 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 30 30 2d | ....MCP1600-| - 000000b0 43 30 30 33 20 20 20 20 41 32 06 08 0a 10 00 2e |C003 A2......| - 000000c0 0b 00 00 00 4d 54 31 36 32 33 56 53 30 30 37 37 |....MT1623VS0077| - 000000d0 39 20 20 20 31 36 30 36 30 34 20 20 00 00 67 60 |9 160604 ..g`| - 000000e0 31 32 38 38 36 32 31 35 56 43 42 56 00 00 00 00 |12886215VCBV....| + 00000080 11 00 23 88 00 00 04 00 00 00 00 08 ff 00 00 00 |..#.............| + 00000090 00 00 01 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 35 30 2d | ....MCP1650-| + 000000b0 56 30 30 31 45 33 30 20 41 32 02 03 05 07 46 c5 |V001E30 A2....F.| + 000000c0 40 00 00 00 4d 54 32 30 31 30 56 53 30 38 33 32 |@...MT2010VS0832| + 000000d0 39 20 20 20 32 30 30 33 30 32 20 20 00 00 6a 84 |9 200302 ..j.| + 000000e0 31 39 32 32 39 33 31 43 41 31 43 54 00 1e 00 00 |1922931CA1CT....| 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| -EEPROM hexdump for module 2 + +EEPROM hexdump for port Ethernet8 Lower page 0h - 00000000 11 07 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000010 00 00 00 00 00 00 2b d6 00 00 82 22 00 00 00 00 |......+...."....| - 00000020 00 00 1c 00 1a ea 1a d0 19 64 0d 2f 0d 2f 0d 2f |.........d./././| - 00000030 0d 2f 23 0c 24 c3 28 18 27 72 00 00 00 00 00 00 |./#.$.(.'r......| + 00000000 18 30 80 03 00 00 00 00 00 00 00 00 00 00 00 00 |.0..............| + 00000010 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| - 00000060 00 00 ff 00 ff ff ff ff ff 00 00 00 00 00 08 00 |................| - 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 03 1d 01 88 01 1c 01 44 11 1b 01 |............D...| + 00000060 22 55 1a 01 44 11 18 01 11 ff 17 01 44 11 16 01 |"U..D.......D...| + 00000070 11 ff 01 01 11 ff 00 00 00 00 00 00 00 00 00 00 |................| + Upper page 0h - 00000080 11 8c 23 80 00 00 00 00 00 00 00 05 ff 00 00 00 |..#.............| - 00000090 00 00 03 00 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | - 000000a0 20 20 20 20 00 00 02 c9 4d 46 41 31 41 30 30 2d | ....MFA1A00-| - 000000b0 43 30 30 33 20 20 20 20 42 32 42 68 0b b8 46 a2 |C003 B2Bh..F.| - 000000c0 01 07 f5 9e 4d 54 31 39 30 37 46 54 30 38 30 38 |....MT1907FT0808| - 000000d0 32 20 20 20 31 39 30 32 31 35 00 00 0c 10 67 be |2 190215....g.| - 000000e0 39 30 32 46 4d 41 32 30 32 4a 36 34 31 31 20 20 |902FMA202J6411 | - 000000f0 00 00 00 00 00 00 00 00 00 00 01 00 0e 00 00 00 |................| + 00000080 18 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 20 20 20 |.Mellanox | + 00000090 20 00 02 c9 4d 43 50 31 36 36 30 2d 57 30 30 41 | ...MCP1660-W00A| + 000000a0 45 33 30 20 41 32 4d 54 32 30 31 39 56 53 30 34 |E30 A2MT2019VS04| + 000000b0 37 39 35 20 20 20 32 30 30 35 30 37 20 20 00 00 |795 200507 ..| + 000000c0 00 00 00 00 00 00 00 00 00 01 05 23 04 05 07 15 |...........#....| + 000000d0 00 00 00 02 0a 00 00 00 00 00 00 00 00 00 77 00 |..............w.| + 000000e0 33 30 33 33 30 4b 34 33 34 31 30 44 00 00 00 00 |30330K43410D....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ... ``` diff --git a/sfputil/main.py b/sfputil/main.py index 16bd167bd9..e7d24410ca 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -689,245 +689,236 @@ def eeprom(port, dump_dom, namespace): def eeprom_hexdump(port, page): """Display EEPROM hexdump of SFP transceiver(s)""" if port: - dump_eeprom_for_single_port(port, page) + if page is None: + page = 0 + else: + page = validate_eeprom_page(page) + return_code, output = eeprom_hexdump_single_port(port, page) + click.echo(output) + sys.exit(return_code) else: - dump_eeprom_for_all_ports(page) - - -def dump_eeprom_for_single_port(port, page): - if platform_sfputil.is_logical_port(port) == 0: - click.echo("Error: invalid port {}".format(port)) - print_all_valid_port_values() - sys.exit(ERROR_INVALID_PORT) - - if page is None: - page = '0' + if page is not None: + page = validate_eeprom_page(page) + logical_port_list = natsorted(platform_sfputil.logical) + lines = [] + for logical_port_name in logical_port_list: + return_code, output = eeprom_hexdump_single_port(logical_port_name, page) + if return_code != 0: + lines.append(f'EEPROM hexdump for port {logical_port_name}') + lines.append(f'{EEPROM_DUMP_INDENT}{output}\n') + continue + lines.append(output) + click.echo('\n'.join(lines)) - logical_port_name = port - physical_port = logical_port_to_physical_port_index(logical_port_name) - if is_port_type_rj45(logical_port_name): - click.echo("{}: SFP EEPROM Hexdump is not applicable for RJ45 port".format(port)) - sys.exit(ERROR_INVALID_PORT) +def validate_eeprom_page(page): + """ + Validate input page module EEPROM + Args: + page: str page input by user + Returns: + int page + """ try: - presence = platform_chassis.get_sfp(physical_port).get_presence() - except NotImplementedError: - click.echo("Sfp.get_presence() is currently not implemented for this platform") + page = int(page) + except ValueError: + click.echo('Please enter a numeric page number') sys.exit(ERROR_NOT_IMPLEMENTED) + if page < 0 or page > 255: + click.echo(f'Invalid page {page}') + sys.exit(ERROR_INVALID_PAGE) + return page - if not presence: - click.echo("SFP EEPROM not detected") - sys.exit(ERROR_NOT_IMPLEMENTED) - else: - try: - id = platform_chassis.get_sfp(physical_port).read_eeprom(0, 1) - if id is None: - click.echo("Error: Failed to read EEPROM for offset 0!") - sys.exit(ERROR_NOT_IMPLEMENTED) - except NotImplementedError: - click.echo("Sfp.read_eeprom() is currently not implemented for this platform") - sys.exit(ERROR_NOT_IMPLEMENTED) - if id[0] == 0x3: - output = eeprom_hexdump_sff8472(port, physical_port, page) - else: - output = eeprom_hexdump_sff8636(port, physical_port, page) +def eeprom_hexdump_single_port(logical_port_name, page): + """ + Dump EEPROM for a single logical port in hex format. + Args: + logical_port_name: logical port name + page: page to be dumped - output += '\n' + Returns: + tuple(0, dump string) if success else tuple(error_code, error_message) + """ + if platform_sfputil.is_logical_port(logical_port_name) == 0: + print_all_valid_port_values() + return ERROR_INVALID_PORT, f'Error: invalid port {logical_port_name}' - click.echo(output) + if is_port_type_rj45(logical_port_name): + return ERROR_INVALID_PORT, f'{logical_port_name}: SFP EEPROM Hexdump is not applicable for RJ45 port' + physical_port = logical_port_to_physical_port_index(logical_port_name) + try: + sfp = platform_chassis.get_sfp(physical_port) + presence = sfp.get_presence() + except NotImplementedError: + return ERROR_NOT_IMPLEMENTED, 'Sfp.get_presence() is currently not implemented for this platform' -def dump_eeprom_for_all_ports(page): - lines = [] + if not presence: + return ERROR_NOT_IMPLEMENTED, 'SFP EEPROM not detected' - if page is not None: - try: - page = int(page) - # Only do simple validation to a given page, user is responsible to make sure the page existence - if page < 0 or page > 255: - click.echo(f"Invalid page {page}") - sys.exit(ERROR_INVALID_PAGE) - except ValueError: - click.echo(f"Page {page} is not a valid number") - sys.exit(ERROR_INVALID_PAGE) - - for index, sfp in enumerate(platform_chassis.get_all_sfps()): - try: - presence = sfp.get_presence() - if not presence: - lines.append(f'\nModule {index + 1} not present') - else: - lines.append(f'\nEEPROM hexdump for module {index + 1}') - eeprom_data = dump_sfp_eeprom(sfp, page) - if eeprom_data is None: - lines.append(f'{EEPROM_DUMP_INDENT}N/A\n') + try: + api = sfp.get_xcvr_api() + if not api: + return ERROR_NOT_IMPLEMENTED, 'Error: Failed to read EEPROM for offset 0!' + + from sonic_platform_base.sonic_xcvr.api.public import sff8636, sff8436, cmis, sff8472 + from sonic_platform_base.sonic_xcvr.fields import consts + if isinstance(api, cmis.CmisApi): + if page is None: # print all possible pages + if api.is_flat_memory(): + pages = [0] else: - lines.append(eeprom_data) - except NotImplementedError: - lines.append(f'\nModule {index + 1} not supported') - except Exception as e: - lines.append(f'\nModule {index + 1} get EEPROM failed: {e}') - - click.echo('\n'.join(lines)) - - -def dump_sfp_eeprom(sfp, page): - api = sfp.get_xcvr_api() - if api is None: - return f'{EEPROM_DUMP_INDENT}N/A\n' - - from sonic_platform_base.sonic_xcvr.api.public import sff8636, sff8436, cmis, sff8472 - from sonic_platform_base.sonic_xcvr.fields import consts - if isinstance(api, cmis.CmisApi): - if page is None: - if api.is_flat_memory(): - pages = [0] + pages = [0, 1, 2, 16, 17] + if api.is_coherent_module(): + pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) + cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) + if cdb_support != 0: + pages.append(0x9f) else: - pages = [0, 1, 2, 16, 17] - if api.is_coherent_module(): - pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) - cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) - if cdb_support != 0: - pages.append(0x9f) - else: - pages = [page] - return dump_eeprom_pages(sfp, pages) - elif isinstance(api, sff8636.Sff8636Api) or isinstance(api, sff8436.Sff8436Api): - if page is None: - if api.is_flat_memory(): pages = [0] - else: - pages = [0, 1, 2, 3] - else: - pages = [page] - return dump_eeprom_pages(sfp, pages) - elif isinstance(api, sff8472.Sff8472Api): - if page is None: - if not api.is_copper(): - pages = [0, 1, 2] + if page not in pages: + pages.append(page) + return eeprom_hexdump_pages_general(logical_port_name, pages, page) + elif isinstance(api, sff8636.Sff8636Api) or isinstance(api, sff8436.Sff8436Api): + if page is None: + if api.is_flat_memory(): + pages = [0] + else: + pages = [0, 1, 2, 3] else: pages = [0] + if page not in pages: + pages.append(page) + return eeprom_hexdump_pages_general(logical_port_name, pages, page) + elif isinstance(api, sff8472.Sff8472Api): + if page is None: + if not api.is_copper(): + pages = [0, 1, 2] + else: + pages = [0] + else: + pages = [0, 1, 2] if not api.is_copper() else [0] + if page not in pages: + pages.append(page) + return eeprom_hexdump_pages_sff8472(logical_port_name, pages, page) else: - pages = [page] - return dump_eeprom_pages_sff8472(sfp, pages, api.is_flat_memory()) + return ERROR_NOT_IMPLEMENTED, 'Cable type is not supported' + except NotImplementedError: + return ERROR_NOT_IMPLEMENTED, 'Sfp.read_eeprom() is currently not implemented for this platform' -def dump_eeprom_pages(sfp, pages): - lines = [] - first = True +def eeprom_hexdump_pages_general(logical_port_name, pages, target_page): + """ + Dump module EEPROM for given pages in hex format. This function is designed for cable type other than SFF8472. + Args: + logical_port_name: logical port name + pages: a list of pages to be dumped. The list always include a default page list and the target_page input by + user + target_page: user input page number, optional. target_page is only for display purpose + + Returns: + tuple(0, dump string) if success else tuple(error_code, error_message) + """ + if target_page is not None: + lines = [f'EEPROM hexdump for port {logical_port_name} page {target_page}h'] + else: + lines = [f'EEPROM hexdump for port {logical_port_name}'] + physical_port = logical_port_to_physical_port_index(logical_port_name) for page in pages: - if first: - first = False - else: - lines.append('') if page == 0: lines.append(f'{EEPROM_DUMP_INDENT}Lower page 0h') - lines.append(dump_eeprom_single_page(sfp, 0, PAGE_SIZE, 0)) + return_code, output = eeprom_dump_general(physical_port, page, 0, PAGE_SIZE, 0) + if return_code != 0: + return return_code, output + lines.append(output) + lines.append(f'\n{EEPROM_DUMP_INDENT}Upper page 0h') - lines.append(dump_eeprom_single_page(sfp, PAGE_OFFSET, PAGE_SIZE, PAGE_OFFSET)) + return_code, output = eeprom_dump_general(physical_port, page, PAGE_OFFSET, PAGE_SIZE, PAGE_OFFSET) + if return_code != 0: + return return_code, output + lines.append(output) else: - lines.append(f'{EEPROM_DUMP_INDENT}Page {page:x}h') - lines.append(dump_eeprom_single_page(sfp, 256 + (page - 1) * PAGE_SIZE, PAGE_SIZE, PAGE_OFFSET)) - return '\n'.join(lines) + lines.append(f'\n{EEPROM_DUMP_INDENT}Upper page {page:x}h') + return_code, output = eeprom_dump_general(physical_port, page, page * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE, PAGE_OFFSET) + if return_code != 0: + return return_code, output + lines.append(output) + lines.append('') # add a new line + return 0, '\n'.join(lines) -def dump_eeprom_pages_sff8472(sfp, pages, is_flat_memory): - lines = [] - first = True + +def eeprom_hexdump_pages_sff8472(logical_port_name, pages, target_page): + """ + Dump module EEPROM for given pages in hex format. This function is designed for SFF8472 only. + Args: + logical_port_name: logical port name + pages: a list of pages to be dumped. The list always include a default page list and the target_page input by + user + target_page: user input page number, optional. target_page is only for display purpose + + Returns: + tuple(0, dump string) if success else tuple(error_code, error_message) + """ + if target_page is not None: + lines = [f'EEPROM hexdump for port {logical_port_name} page {target_page}h'] + else: + lines = [f'EEPROM hexdump for port {logical_port_name}'] + physical_port = logical_port_to_physical_port_index(logical_port_name) + api = platform_chassis.get_sfp(physical_port).get_xcvr_api() + is_flat_memory = api.is_flat_memory() for page in pages: - if first: - first = False - else: - lines.append('') if page == 0: + lines.append(f'{EEPROM_DUMP_INDENT}A0h dump') if not is_flat_memory: - lines.append(f'{EEPROM_DUMP_INDENT}A0h dump') - lines.append(dump_eeprom_single_page(sfp, 0, SFF8472_A0_SIZE, 0)) + return_code, output = eeprom_dump_general(physical_port, page, 0, SFF8472_A0_SIZE, 0) else: - lines.append(f'{EEPROM_DUMP_INDENT}A0h dump') - lines.append(dump_eeprom_single_page(sfp, 0, PAGE_SIZE, 0)) + return_code, output = eeprom_dump_general(physical_port, page, 0, PAGE_SIZE, 0) + if return_code != 0: + return return_code, 'Error: Failed to read EEPROM for A0h!' + lines.append(output) elif page == 1: - lines.append(f'{EEPROM_DUMP_INDENT}A2h dump (lower 128 bytes)') - lines.append(dump_eeprom_single_page(sfp, SFF8472_A0_SIZE, PAGE_SIZE, 0)) - elif page == 2: - lines.append(f'{EEPROM_DUMP_INDENT}A2h dump (upper 128 bytes)') - lines.append(dump_eeprom_single_page(sfp, SFF8472_A0_SIZE + PAGE_SIZE, PAGE_SIZE, 0)) - return '\n'.join(lines) - - -def dump_eeprom_single_page(sfp, overall_offset, size, page_offset): - page_data = sfp.read_eeprom(overall_offset, size) - if page_data: - return hexdump(EEPROM_DUMP_INDENT, page_data, page_offset, start_newline=False) - else: - return f'{EEPROM_DUMP_INDENT}Failed to read EEPROM' - - -def eeprom_hexdump_sff8472(port, physical_port, page): - try: - output = "" - indent = ' ' * 8 - output += 'EEPROM hexdump for port {} page {}h'.format(port, page) - output += '\n{}A0h dump'.format(indent) - page_dump = platform_chassis.get_sfp(physical_port).read_eeprom(0, SFF8472_A0_SIZE) - if page_dump is None: - click.echo("Error: Failed to read EEPROM for A0h!") - sys.exit(ERROR_NOT_IMPLEMENTED) - - output += hexdump(indent, page_dump, 0) - page_dump = platform_chassis.get_sfp(physical_port).read_eeprom(SFF8472_A0_SIZE, PAGE_SIZE) - if page_dump is None: - click.echo("Error: Failed to read EEPROM for A2h!") - sys.exit(ERROR_NOT_IMPLEMENTED) + lines.append(f'\n{EEPROM_DUMP_INDENT}A2h dump (lower 128 bytes)') + return_code, output = eeprom_dump_general(physical_port, page, SFF8472_A0_SIZE, PAGE_SIZE, 0) + if return_code != 0: + return ERROR_NOT_IMPLEMENTED, 'Error: Failed to read EEPROM for A2h!' + lines.append(output) else: - output += '\n\n{}A2h dump (lower 128 bytes)'.format(indent) - output += hexdump(indent, page_dump, 0) + lines.append(f'\n{EEPROM_DUMP_INDENT}A2h dump (upper 128 bytes) page {page - 2:x}h') + return_code, output = eeprom_dump_general(physical_port, page, SFF8472_A0_SIZE + PAGE_OFFSET + page * PAGE_SIZE, PAGE_SIZE, PAGE_SIZE) + if return_code != 0: + return ERROR_NOT_IMPLEMENTED, 'Error: Failed to read EEPROM for A2h upper page!' + lines.append(output) - page_dump = platform_chassis.get_sfp(physical_port).read_eeprom(SFF8472_A0_SIZE + PAGE_OFFSET + (int(page, base=16) * PAGE_SIZE), PAGE_SIZE) - if page_dump is None: - click.echo("Error: Failed to read EEPROM for A2h upper page!") - sys.exit(ERROR_NOT_IMPLEMENTED) - else: - output += '\n\n{}A2h dump (upper 128 bytes) page {}h'.format(indent, page) - output += hexdump(indent, page_dump, PAGE_OFFSET) - except NotImplementedError: - click.echo("Sfp.read_eeprom() is currently not implemented for this platform") - sys.exit(ERROR_NOT_IMPLEMENTED) - except ValueError: - click.echo("Please enter a numeric page number") - sys.exit(ERROR_NOT_IMPLEMENTED) + lines.append('') # add a new line + return 0, '\n'.join(lines) - return output -def eeprom_hexdump_sff8636(port, physical_port, page): - try: - output = "" - indent = ' ' * 8 - output += 'EEPROM hexdump for port {} page {}h'.format(port, page) - output += '\n{}Lower page 0h'.format(indent) - page_dump = platform_chassis.get_sfp(physical_port).read_eeprom(0, PAGE_SIZE) - if page_dump is None: - click.echo("Error: Failed to read EEPROM for page 0!") - sys.exit(ERROR_NOT_IMPLEMENTED) +def eeprom_dump_general(physical_port, page, overall_offset, size, page_offset, no_format=False): + """ + Dump module EEPROM. + Args: + physical_port: physical port index + page: module EEPROM page number + overall_offset: overall offset in flat memory + size: size of bytes to be dumped + page_offset: offset within a page, only for print purpose + no_format: False if dump with hex format else dump with flat hex string. Default False. - output += hexdump(indent, page_dump, 0) - page_dump = platform_chassis.get_sfp(physical_port).read_eeprom(int(page, base=16) * PAGE_SIZE + PAGE_OFFSET, PAGE_SIZE) - if page_dump is None: - click.echo("Error: Failed to read EEPROM!") - sys.exit(ERROR_NOT_IMPLEMENTED) - else: - output += '\n\n{}Upper page {}h'.format(indent, page) - output += hexdump(indent, page_dump, PAGE_OFFSET) - except NotImplementedError: - click.echo("Sfp.read_eeprom() is currently not implemented for this platform") - sys.exit(ERROR_NOT_IMPLEMENTED) - except ValueError: - click.echo("Please enter a numeric page number") - sys.exit(ERROR_NOT_IMPLEMENTED) + Returns: + tuple(0, dump string) if success else tuple(error_code, error_message) + """ + sfp = platform_chassis.get_sfp(physical_port) + page_dump = sfp.read_eeprom(overall_offset, size) + if page_dump is None: + return ERROR_NOT_IMPLEMENTED, f'Error: Failed to read EEPROM for page {page:x}h, overall_offset {overall_offset}, page_offset {page_offset}, size {size}!' + if not no_format: + return 0, hexdump(EEPROM_DUMP_INDENT, page_dump, page_offset, start_newline=False) + else: + return 0, ''.join('{:02x}'.format(x) for x in page_dump) - return output def convert_byte_to_valid_ascii_char(byte): if byte < 32 or 126 < byte: @@ -1398,10 +1389,10 @@ def is_fw_switch_done(port_name): status = -1 # Abnormal status. elif (ImageARunning == 1) and (ImageACommitted == 0): # ImageA is running, but not committed. click.echo("FW images switch successful : ImageA is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. elif (ImageBRunning == 1) and (ImageBCommitted == 0): # ImageB is running, but not committed. click.echo("FW images switch successful : ImageB is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. else: # No image is running, or running and committed image is same. click.echo("FW info error : Failed to switch into uncommitted image!") status = -1 # Failure for Switching images. diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index f1faeefe58..6c4112d026 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -256,7 +256,7 @@ def test_convert_sfp_info_to_output_string(self, sfp_info_dict, expected_output) Vcc: 3.2577Volts ModuleThresholdValues: ''' - ), + ), ( 'QSFP-DD Double Density 8X Pluggable Transceiver', { @@ -650,7 +650,7 @@ def test_show_eeprom_hexdump_read_eeprom_failure(self, mock_chassis): mock_sfp = MagicMock() mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) mock_sfp.get_presence.return_value = True - mock_sfp.read_eeprom = MagicMock(return_value=None) + mock_sfp.get_xcvr_api = MagicMock(return_value=None) runner = CliRunner() result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ["-p", "Ethernet16"]) assert result.exit_code == ERROR_NOT_IMPLEMENTED @@ -661,6 +661,7 @@ def test_show_eeprom_hexdump_read_eeprom_failure(self, mock_chassis): @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) + @patch('sfputil.main.isinstance', MagicMock(return_value=True)) def test_show_eeprom_hexdump_read_eeprom_not_implemented(self, mock_chassis): mock_sfp = MagicMock() mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) @@ -676,6 +677,7 @@ def test_show_eeprom_hexdump_read_eeprom_not_implemented(self, mock_chassis): @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) + @patch('sfputil.main.isinstance', MagicMock(return_value=True)) def test_show_eeprom_hexdump_sff8636_page(self, mock_chassis): lower_page_bytearray = bytearray([13, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) upper_page0_bytearray = bytearray([13, 0, 35, 8, 0, 0, 0, 65, 128, 128, 245, 0, 0, 0, 0, 0, 0, 0, 1, 160, 77, 111, 108, 101, 120, 32, 73, 110, 99, 46, 32, 32, 32, 32, 32, 32, 7, 0, 9, 58, 49, 49, 49, 48, 52, 48, 49, 48, 53, 52, 32, 32, 32, 32, 32, 32, 32, 32, 3, 4, 0, 0, 70, 196, 0, 0, 0, 0, 54, 49, 49, 48, 51, 48, 57, 50, 57, 32, 32, 32, 32, 32, 32, 32, 49, 54, 48, 52, 49, 57, 32, 32, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) @@ -719,6 +721,7 @@ def side_effect(offset, num_bytes): @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) + @patch('sfputil.main.isinstance', MagicMock(side_effect=[False, False, False, True])) def test_show_eeprom_hexdump_sff8472_page(self, mock_chassis): a0h_bytearray = bytearray([3, 4, 7, 16, 0, 0, 0, 0, 0, 0, 0, 6, 103, 0, 0, 0, 8, 3, 0, 30, 70, 73, 78, 73, 83, 65, 82, 32, 67, 79, 82, 80, 46, 32, 32, 32, 0, 0, 144, 101, 70, 84, 76, 88, 56, 53, 55, 49, 68, 51, 66, 67, 76, 32, 32, 32, 65, 32, 32, 32, 3, 82, 0, 72, 0, 26, 0, 0, 65, 85, 74, 48, 82, 67, 74, 32, 32, 32, 32, 32, 32, 32, 32, 32, 49, 53, 49, 48, 50, 57, 32, 32, 104, 240, 3, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) a2h_lower_bytearray = bytearray([78, 0, 243, 0, 73, 0, 248, 0, 144, 136, 113, 72, 140, 160, 117, 48, 25, 200, 7, 208, 24, 156, 9, 196, 39, 16, 9, 208, 31, 7, 12, 90, 39, 16, 0, 100, 31, 7, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 27, 20, 2, 129, 177, 13, 90, 23, 165, 21, 135, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 1]) @@ -775,69 +778,56 @@ def side_effect(offset, num_bytes): mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) mock_sfp.get_presence.return_value = True mock_sfp.read_eeprom = MagicMock(side_effect=side_effect) + mock_api = MagicMock() + mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api) + mock_api.is_copper = MagicMock(return_value=False) runner = CliRunner() result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ["-p", "Ethernet256", "-n", "0"]) assert result.exit_code == 0 assert result.output == expected_output @patch('sfputil.main.platform_chassis') - @patch('sfputil.main.dump_sfp_eeprom') - def test_eeprom_hexdump_all(self, mock_dump_eeprom, mock_chassis): - sfp_list = [MagicMock() for x in range(5)] - mock_dump_eeprom.side_effect = [None, ' Hello'] - sfp_list[0].get_presence = MagicMock(return_value=False) - sfp_list[1].get_presence = MagicMock(side_effect=NotImplementedError) - sfp_list[2].get_presence = MagicMock(side_effect=RuntimeError('error')) - sfp_list[3].get_presence = MagicMock(return_value=True) - sfp_list[4].get_presence = MagicMock(return_value=True) - mock_chassis.get_all_sfps.return_value = sfp_list + @patch('sfputil.main.platform_sfputil') + @patch('sfputil.main.isinstance', MagicMock(side_effect=[True, False, False, False, True])) + def test_eeprom_hexdump_all_falure(self, mock_sfputil, mock_chassis): + mock_sfputil.logical = ['Ethernet4', 'Ethernet0'] + mock_sfp = MagicMock() + mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) + mock_sfp.get_presence.return_value = True + mock_sfp.read_eeprom = MagicMock(return_value=None) + runner = CliRunner() result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump']) assert result.exit_code == 0 - expected_output = """ -Module 1 not present + expected_output = """EEPROM hexdump for port Ethernet0 + Error: Failed to read EEPROM for page 0h, overall_offset 0, page_offset 0, size 128! -Module 2 not supported +EEPROM hexdump for port Ethernet4 + Error: Failed to read EEPROM for A0h! -Module 3 get EEPROM failed: error - -EEPROM hexdump for module 4 - N/A - - -EEPROM hexdump for module 5 - Hello """ - print(result.output) assert result.output == expected_output - def test_test_eeprom_hexdump_all_invalid_page(self): - runner = CliRunner() - result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '-1']) - assert result.exit_code != 0 - - result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '256']) - assert result.exit_code != 0 + @patch('sfputil.main.platform_chassis') + @patch('sfputil.main.platform_sfputil') + @patch('sfputil.main.isinstance', MagicMock(side_effect=[True, False, False, False, True])) + def test_eeprom_hexdump_all_falure(self, mock_sfputil, mock_chassis): + mock_sfputil.logical = ['Ethernet4', 'Ethernet0'] + mock_sfp = MagicMock() + mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) + mock_sfp.get_presence.return_value = True + mock_sfp.read_eeprom = MagicMock(return_value=None) - result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', 'invalid_number']) - assert result.exit_code != 0 + def mock_read_eeprom(offset, num_bytes): + return bytearray([x for x in range(num_bytes)]) - @patch('sfputil.main.isinstance') - def test_dump_sfp_eeprom(self, mock_is_instance): - mock_sfp = MagicMock() - mock_sfp.get_xcvr_api = MagicMock(return_value=None) - output = sfputil.dump_sfp_eeprom(mock_sfp, None) - assert 'N/A' in output + mock_sfp.read_eeprom.side_effect = mock_read_eeprom - mock_api = MagicMock() - mock_api.is_flat_memory = MagicMock(return_value=False) - mock_api.is_coherent_module = MagicMock(return_value=True) - mock_api.xcvr_eeprom = MagicMock() - mock_api.xcvr_eeprom.read = MagicMock(return_value=1) - mock_sfp.get_xcvr_api.return_value = mock_api - mock_is_instance.return_value = True - - expected_output_page0 = """ Lower page 0h + runner = CliRunner() + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump']) + assert result.exit_code == 0 + expected_output = """EEPROM hexdump for port Ethernet0 + Lower page 0h 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| @@ -846,14 +836,6 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................| Upper page 0h 00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| @@ -864,92 +846,9 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 000000d0 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| 000000e0 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| 000000f0 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000100 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000110 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 00000120 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 00000130 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 00000140 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 00000150 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 00000160 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 00000170 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" - mock_sfp.read_eeprom = MagicMock(return_value=bytearray([x for x in range(256)])) - output = sfputil.dump_sfp_eeprom(mock_sfp, 0) - assert output == expected_output_page0 - - expected_output_page1 = """ Page 1h - 00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| - 00000090 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| - 000000a0 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| - 000000b0 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| - 000000c0 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| - 000000d0 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| - 000000e0 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| - 000000f0 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000100 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000110 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 00000120 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 00000130 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 00000140 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 00000150 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 00000160 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 00000170 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" - output = sfputil.dump_sfp_eeprom(mock_sfp, 1) - assert output == expected_output_page1 - sfputil.dump_sfp_eeprom(mock_sfp, None) - - mock_is_instance.side_effect = [False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, 0) - assert output == expected_output_page0 - - mock_is_instance.side_effect = [False, True] - sfputil.dump_sfp_eeprom(mock_sfp, None) - - mock_api.xcvr_eeprom.read = MagicMock(return_value='Active Cable') - mock_is_instance.side_effect = [False, False, False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, 0) - expected_output_a0h = """ A0h dump - 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| - 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| - 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| - 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| - 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| - 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| - 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| - 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" - assert output == expected_output_a0h - - mock_is_instance.side_effect = [False, False, False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, 1) - expected_output_a2h_lower = """ A2h dump (lower 128 bytes) - 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| - 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| - 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| - 00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| - 00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| - 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| - 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| - 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" - assert output == expected_output_a2h_lower - - mock_is_instance.side_effect = [False, False, False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, 2) - expected_output_a2h_upper = """ A2h dump (upper 128 bytes) + +EEPROM hexdump for port Ethernet4 + A0h dump 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| 00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| @@ -958,31 +857,20 @@ def test_dump_sfp_eeprom(self, mock_is_instance): 00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| 00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| 00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| - 00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| - 00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| - 000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| - 000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| - 000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| - 000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| - 000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| - 000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................|""" - assert output == expected_output_a2h_upper - - mock_is_instance.side_effect = [False, False, False, True] - sfputil.dump_sfp_eeprom(mock_sfp, None) - - mock_api.is_flat_memory.return_value = True - mock_is_instance.side_effect = [False, False, False, True] - output = sfputil.dump_sfp_eeprom(mock_sfp, 0) - assert output == expected_output_a0h - mock_is_instance.side_effect = [False, False, False, True] - sfputil.dump_sfp_eeprom(mock_sfp, None) - - mock_is_instance.side_effect = None - mock_is_instance.return_value = True - mock_sfp.read_eeprom.return_value = None - output = sfputil.dump_sfp_eeprom(mock_sfp, 0) - assert 'Failed to read EEPROM' in output + +""" + assert expected_output == result.output + + def test_test_eeprom_hexdump_all_invalid_page(self): + runner = CliRunner() + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '-1']) + assert result.exit_code != 0 + + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', '256']) + assert result.exit_code != 0 + + result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', 'invalid_number']) + assert result.exit_code != 0 @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) From 913ff3a70c147c41a84f30d63d21a4203d9d3be7 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Tue, 21 Nov 2023 05:23:53 +0200 Subject: [PATCH 08/15] Increase coverage --- tests/sfputil_test.py | 56 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index 6c4112d026..0173accfcd 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -811,7 +811,7 @@ def test_eeprom_hexdump_all_falure(self, mock_sfputil, mock_chassis): @patch('sfputil.main.platform_chassis') @patch('sfputil.main.platform_sfputil') @patch('sfputil.main.isinstance', MagicMock(side_effect=[True, False, False, False, True])) - def test_eeprom_hexdump_all_falure(self, mock_sfputil, mock_chassis): + def test_eeprom_hexdump_all(self, mock_sfputil, mock_chassis): mock_sfputil.logical = ['Ethernet4', 'Ethernet0'] mock_sfp = MagicMock() mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) @@ -872,6 +872,60 @@ def test_test_eeprom_hexdump_all_invalid_page(self): result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ['--page', 'invalid_number']) assert result.exit_code != 0 + @patch('sfputil.main.platform_chassis') + @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) + @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) + @patch('sfputil.main.eeprom_hexdump_pages_general') + @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) + @patch('sfputil.main.isinstance') + def test_eeprom_hexdump_single_port(self, mock_isinstance, mock_dump, mock_chassis): + mock_isinstance.return_value = True + mock_sfp = MagicMock() + mock_chassis.get_sfp = MagicMock(return_value=mock_sfp) + mock_sfp.get_presence.return_value = True + mock_api = MagicMock() + mock_sfp.get_xcvr_api.return_value = mock_api + sfputil.eeprom_hexdump_single_port('Ethernet0', 0) + mock_dump.assert_called_with('Ethernet0', [0], 0) + + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', 1) + mock_dump.assert_called_with('Ethernet0', [0, 1], 1) + + mock_api.is_flat_memory.return_value = False + mock_api.is_coherent_module.return_value = False + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', None) + mock_dump.assert_called_with('Ethernet0', [0, 1, 2, 16, 17, 159], None) + + mock_api.is_coherent_module.return_value = True + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', None) + mock_dump.assert_called_with('Ethernet0', [0, 1, 2, 16, 17, 48, 49, 50, 51, 52, 53, 56, 57, 58, 59, 159], None) + + mock_api.is_flat_memory.return_value = True + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', None) + mock_dump.assert_called_with('Ethernet0', [0], None) + + mock_isinstance.side_effect = [False, True] + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', None) + mock_dump.assert_called_with('Ethernet0', [0], None) + + mock_api.is_flat_memory.return_value = False + mock_isinstance.side_effect = [False, True] + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', None) + mock_dump.assert_called_with('Ethernet0', [0, 1, 2, 3], None) + + mock_isinstance.side_effect = [False, True] + mock_dump.reset_mock() + sfputil.eeprom_hexdump_single_port('Ethernet0', 3) + mock_dump.assert_called_with('Ethernet0', [0, 3], 3) + + + @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) From fce71e4c1455983b451d49042bff0bd603567cbe Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Fri, 8 Dec 2023 04:07:23 +0200 Subject: [PATCH 09/15] Fix review comment --- sfputil/main.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index e7d24410ca..4db7ee4957 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -51,6 +51,10 @@ PAGE_OFFSET = 128 SFF8472_A0_SIZE = 256 +SFF8636_MODULE_PAGES = [0, 1, 2, 3] +SFF8472_MODULE_PAGES = [0, 1, 2] +CMIS_MODULE_PAGES = [0, 1, 2, 16, 17] +CMIS_COHERENT_MODULE_PAGES = [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b] EEPROM_DUMP_INDENT = ' ' * 8 @@ -770,9 +774,9 @@ def eeprom_hexdump_single_port(logical_port_name, page): if api.is_flat_memory(): pages = [0] else: - pages = [0, 1, 2, 16, 17] + pages = CMIS_MODULE_PAGES if api.is_coherent_module(): - pages.extend([0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, 0x3b]) + pages.extend(CMIS_COHERENT_MODULE_PAGES) cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) if cdb_support != 0: pages.append(0x9f) @@ -786,7 +790,7 @@ def eeprom_hexdump_single_port(logical_port_name, page): if api.is_flat_memory(): pages = [0] else: - pages = [0, 1, 2, 3] + pages = SFF8636_MODULE_PAGES else: pages = [0] if page not in pages: @@ -795,11 +799,11 @@ def eeprom_hexdump_single_port(logical_port_name, page): elif isinstance(api, sff8472.Sff8472Api): if page is None: if not api.is_copper(): - pages = [0, 1, 2] + pages = SFF8472_MODULE_PAGES else: pages = [0] else: - pages = [0, 1, 2] if not api.is_copper() else [0] + pages = SFF8472_MODULE_PAGES if not api.is_copper() else [0] if page not in pages: pages.append(page) return eeprom_hexdump_pages_sff8472(logical_port_name, pages, page) @@ -896,13 +900,13 @@ def eeprom_hexdump_pages_sff8472(logical_port_name, pages, target_page): return 0, '\n'.join(lines) -def eeprom_dump_general(physical_port, page, overall_offset, size, page_offset, no_format=False): +def eeprom_dump_general(physical_port, page, flat_offset, size, page_offset, no_format=False): """ Dump module EEPROM. Args: physical_port: physical port index page: module EEPROM page number - overall_offset: overall offset in flat memory + flat_offset: overall offset in flat memory size: size of bytes to be dumped page_offset: offset within a page, only for print purpose no_format: False if dump with hex format else dump with flat hex string. Default False. @@ -911,9 +915,9 @@ def eeprom_dump_general(physical_port, page, overall_offset, size, page_offset, tuple(0, dump string) if success else tuple(error_code, error_message) """ sfp = platform_chassis.get_sfp(physical_port) - page_dump = sfp.read_eeprom(overall_offset, size) + page_dump = sfp.read_eeprom(flat_offset, size) if page_dump is None: - return ERROR_NOT_IMPLEMENTED, f'Error: Failed to read EEPROM for page {page:x}h, overall_offset {overall_offset}, page_offset {page_offset}, size {size}!' + return ERROR_NOT_IMPLEMENTED, f'Error: Failed to read EEPROM for page {page:x}h, flat_offset {flat_offset}, page_offset {page_offset}, size {size}!' if not no_format: return 0, hexdump(EEPROM_DUMP_INDENT, page_dump, page_offset, start_newline=False) else: From d29e9aa327649b61322710de7b17bc2d83bf1c55 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Fri, 8 Dec 2023 05:58:26 +0200 Subject: [PATCH 10/15] Fix ut --- sfputil/main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index 4db7ee4957..35dcbb716e 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -5,6 +5,7 @@ # Command-line utility for interacting with SFP transceivers within SONiC # +import copy import os import sys import natsort @@ -774,7 +775,7 @@ def eeprom_hexdump_single_port(logical_port_name, page): if api.is_flat_memory(): pages = [0] else: - pages = CMIS_MODULE_PAGES + pages = copy.deepcopy(CMIS_MODULE_PAGES) if api.is_coherent_module(): pages.extend(CMIS_COHERENT_MODULE_PAGES) cdb_support = api.xcvr_eeprom.read(consts.CDB_SUPPORT) @@ -790,7 +791,7 @@ def eeprom_hexdump_single_port(logical_port_name, page): if api.is_flat_memory(): pages = [0] else: - pages = SFF8636_MODULE_PAGES + pages = copy.deepcopy(SFF8636_MODULE_PAGES) else: pages = [0] if page not in pages: @@ -799,11 +800,11 @@ def eeprom_hexdump_single_port(logical_port_name, page): elif isinstance(api, sff8472.Sff8472Api): if page is None: if not api.is_copper(): - pages = SFF8472_MODULE_PAGES + pages = copy.deepcopy(SFF8472_MODULE_PAGES) else: pages = [0] else: - pages = SFF8472_MODULE_PAGES if not api.is_copper() else [0] + pages = copy.deepcopy(SFF8472_MODULE_PAGES) if not api.is_copper() else [0] if page not in pages: pages.append(page) return eeprom_hexdump_pages_sff8472(logical_port_name, pages, page) From e9c3472149a9c30d2d1ecd6b5dc215e437876a8c Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:29:24 +0800 Subject: [PATCH 11/15] Update Command-Reference.md --- doc/Command-Reference.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 26771b05fa..a581e5ff06 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -12999,8 +12999,6 @@ EEPROM hexdump for port Ethernet8 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ``` -This sub-section explains the list of commands available for SFP utilities feature. - # SFP Utilities read command - Read SFP EEPROM data From 25266d8a3bdfb3292c87cf220da6ad0fc395a374 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Sat, 9 Dec 2023 14:52:22 +0200 Subject: [PATCH 12/15] Fix UT --- sfputil/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index cf0f43512b..de0d9f83b5 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -933,7 +933,7 @@ def eeprom_dump_general(physical_port, page, flat_offset, size, page_offset, no_ -def eeprom_dump_general(physical_port, page, overall_offset, size, page_offset, no_format=False): +def eeprom_dump_general(physical_port, page, flat_offset, size, page_offset, no_format=False): """ Dump module EEPROM for given pages in hex format. Args: @@ -945,9 +945,9 @@ def eeprom_dump_general(physical_port, page, overall_offset, size, page_offset, tuple(0, dump string) if success else tuple(error_code, error_message) """ sfp = platform_chassis.get_sfp(physical_port) - page_dump = sfp.read_eeprom(overall_offset, size) + page_dump = sfp.read_eeprom(flat_offset, size) if page_dump is None: - return ERROR_NOT_IMPLEMENTED, f'Error: Failed to read EEPROM for page {page:x}h, overall_offset {overall_offset}, page_offset {page_offset}, size {size}!' + return ERROR_NOT_IMPLEMENTED, f'Error: Failed to read EEPROM for page {page:x}h, flat_offset {flat_offset}, page_offset {page_offset}, size {size}!' if not no_format: return 0, hexdump(EEPROM_DUMP_INDENT, page_dump, page_offset, start_newline=False) else: From f966e52bc3fa6495870425094b750d5aa7dc8369 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Wed, 13 Dec 2023 11:02:38 +0200 Subject: [PATCH 13/15] Remove unindented changes --- sfputil/main.py | 4 ++-- tests/sfputil_test.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index de0d9f83b5..39f18bc5f1 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -1423,10 +1423,10 @@ def is_fw_switch_done(port_name): status = -1 # Abnormal status. elif (ImageARunning == 1) and (ImageACommitted == 0): # ImageA is running, but not committed. click.echo("FW images switch successful : ImageA is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. elif (ImageBRunning == 1) and (ImageBCommitted == 0): # ImageB is running, but not committed. click.echo("FW images switch successful : ImageB is running") - status = 1 # run_firmware is done. + status = 1 # run_firmware is done. else: # No image is running, or running and committed image is same. click.echo("FW info error : Failed to switch into uncommitted image!") status = -1 # Failure for Switching images. diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index f764ebd881..908ea72646 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -256,7 +256,7 @@ def test_convert_sfp_info_to_output_string(self, sfp_info_dict, expected_output) Vcc: 3.2577Volts ModuleThresholdValues: ''' - ), + ), ( 'QSFP-DD Double Density 8X Pluggable Transceiver', { From 9ca52d0fb55e6749af99a79046ff42ce0ae2b03a Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sat, 16 Dec 2023 08:38:18 +0800 Subject: [PATCH 14/15] Update Command-Reference.md --- doc/Command-Reference.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index a581e5ff06..6aea452560 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -12955,6 +12955,28 @@ EEPROM hexdump for port Ethernet0 page 0h 000000e0 33 30 33 33 30 4b 34 33 34 31 30 44 00 00 00 00 |30330K43410D....| 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +admin@sonic:~$ sfputil show eeprom-hexdump --port Ethernet0 --page 1 +EEPROM hexdump for port Ethernet0 page 1h + Lower page 0h + 00000000 11 08 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 01 08 00 |................| + 00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + + Upper page 1h + 00000080 11 00 23 88 00 00 04 00 00 00 00 08 ff 00 00 00 |..#.............| + 00000090 00 00 01 a0 4d 65 6c 6c 61 6e 6f 78 20 20 20 20 |....Mellanox | + 000000a0 20 20 20 20 00 00 02 c9 4d 43 50 31 36 35 30 2d | ....MCP1650-| + 000000b0 56 30 30 31 45 33 30 20 41 32 02 03 05 07 46 c5 |V001E30 A2....F.| + 000000c0 40 00 00 00 4d 54 32 30 31 30 56 53 30 38 33 32 |@...MT2010VS0832| + 000000d0 39 20 20 20 32 30 30 33 30 32 20 20 00 00 6a 84 |9 200302 ..j.| + 000000e0 31 39 32 32 39 33 31 43 41 31 43 54 00 1e 00 00 |1922931CA1CT....| + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 |.............0..| + admin@sonic:~$ sfputil show eeprom-hexdump EEPROM hexdump for port Ethernet0 Lower page 0h From 60416a0fd9014bcfbdc3dbc306eeefd4b9afa137 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox Date: Wed, 20 Dec 2023 06:11:50 +0200 Subject: [PATCH 15/15] Fix review comment --- sfputil/main.py | 6 +----- tests/sfputil_test.py | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index 39f18bc5f1..cde36f9f9a 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -697,20 +697,16 @@ def eeprom(port, dump_dom, namespace): # 'eeprom-hexdump' subcommand @show.command() @click.option('-p', '--port', metavar='', help="Display SFP EEPROM hexdump for port ") -@click.option('-n', '--page', metavar='', help="Display SFP EEEPROM hexdump for ") +@click.option('-n', '--page', metavar='', type=click.IntRange(0, MAX_EEPROM_PAGE), help="Display SFP EEEPROM hexdump for ") def eeprom_hexdump(port, page): """Display EEPROM hexdump of SFP transceiver(s)""" if port: if page is None: page = 0 - else: - page = validate_eeprom_page(page) return_code, output = eeprom_hexdump_single_port(port, page) click.echo(output) sys.exit(return_code) else: - if page is not None: - page = validate_eeprom_page(page) logical_port_list = natsorted(platform_sfputil.logical) lines = [] for logical_port_name in logical_port_list: diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index 908ea72646..63814f31c5 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -594,14 +594,14 @@ def test_show_eeprom_RJ45(self, mock_chassis): def test_show_eeprom_hexdump_invalid_port(self, mock_chassis): runner = CliRunner() result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ["-p", "Ethernet"]) - assert result.exit_code == ERROR_INVALID_PORT + assert result.exit_code != 0 @patch('sfputil.main.platform_chassis') @patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1))) def test_show_eeprom_hexdump_invalid_page(self, mock_chassis): runner = CliRunner() result = runner.invoke(sfputil.cli.commands['show'].commands['eeprom-hexdump'], ["-p", "Ethernet1", "-n", "INVALID"]) - assert result.exit_code == ERROR_NOT_IMPLEMENTED + assert result.exit_code != 0 @patch('sfputil.main.platform_chassis') @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))