From a80931bf8d82a0407cf8455eddea54a0e37e96d4 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Wed, 4 Sep 2024 07:27:15 +0000 Subject: [PATCH 01/12] [show][interface][counters] Add proposal and changes for fec-histogram for show int counters fec-histogram subcommand Signed-off-by: Vaibhav Dahiya --- doc/Command-Reference.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index cdc3f5644d..2584469b4f 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -4806,6 +4806,7 @@ Optional argument "-p" specify a period (in seconds) with which to gather counte show interfaces counters errors show interfaces counters rates show interfaces counters rif [-p|--period ] [-i ] + show interfaces counters fec-histogram [-i ] ``` - Example: @@ -4923,6 +4924,41 @@ Optionally, you can specify a period (in seconds) with which to gather counters admin@sonic:~$ sonic-clear rifcounters ``` +The "fec-histogram" subcommand is used to display the fec histogram for the port. + +When data is transmitted, it's broken down into units called codewords. FEC algorithms add extra data to each codeword that can be used to detect and correct errors in transmission. +In a FEC histogram, "bins" represent ranges of errors or specific categories of errors. For instance, Bin0 might represent codewords with no errors, while Bin1 could represent codewords with a single bit error, and so on. The histogram shows how many codewords fell into each bin. A high number in the higher bins might indicate a problem with the transmission link, such as signal degradation. + +- Example: + ``` + admin@str-s6000-acs-11:/usr/bin$ show interface counters fec-histogram -i + + Symbol Errors Per Codeword Codewords + -------------------------- --------- + BIN_FEC_CODEWORD_S0 4075208478588 + BIN_FEC_CODEWORD_S1 7 + BIN_FEC_CODEWORD_S2 0 + BIN_FEC_CODEWORD_S3 0 + BIN_FEC_CODEWORD_S4 0 + BIN_FEC_CODEWORD_S5 0 + BIN_FEC_CODEWORD_S6 0 + BIN_FEC_CODEWORD_S7 0 + BIN_FEC_CODEWORD_S8 0 + BIN_FEC_CODEWORD_S9 0 + BIN_FEC_CODEWORD_S10 0 + BIN_FEC_CODEWORD_S11 0 + BIN_FEC_CODEWORD_S12 0 + BIN_FEC_CODEWORD_S13 0 + BIN_FEC_CODEWORD_S14 0 + BIN_FEC_CODEWORD_S15 0 + BIN_FEC_CODEWORD_S16 0 + + + ``` + + + + **show interfaces description** This command displays the key fields of the interfaces such as Operational Status, Administrative Status, Alias and Description. From e96b672626cce0142d03c769c35b074249f79bfb Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Fri, 6 Sep 2024 18:56:48 +0000 Subject: [PATCH 02/12] add implementation Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 142 +++++++++++++++++------------------- 1 file changed, 66 insertions(+), 76 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 9287eb5af7..d5d7aecefb 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -18,6 +18,8 @@ HWSKU_JSON = 'hwsku.json' +REDIS_HOSTIP = "127.0.0.1" + # Read given JSON file def readJsonFile(fileName): try: @@ -646,6 +648,67 @@ def fec_stats(verbose, period, namespace, display): clicommon.run_command(cmd, display_cmd=verbose) + +def get_port_oid_mapping(): + ''' Returns dictionary of all ports interfaces and their OIDs. ''' + db = SonicV2Connector(host=REDIS_HOSTIP) + db.connect(db.COUNTERS_DB) + + port_oid_map = db.get_all(db.COUNTERS_DB, 'COUNTERS_PORT_NAME_MAP') + + db.close(db.COUNTERS_DB) + + return port_oid_map + +def fetch_fec_histogram(port_oid_map, target_port): + ''' Fetch and display FEC histogram for the given port. ''' + asic_db = SonicV2Connector(host=REDIS_HOSTIP) + asic_db.connect(asic_db.ASIC_DB) + + config_db = ConfigDBConnector() + config_db.connect() + + counter_db = SonicV2Connector(host=REDIS_HOSTIP) + counter_db.connect(counter_db.COUNTERS_DB) + + if target_port not in port_oid_map: + click.echo('Port {} not found in COUNTERS_PORT_NAME_MAP'.format(target_port), err=True) + raise click.Abort() + + port_oid = port_oid_map[target_port] + asic_db_kvp = counter_db.get_all(counter_db.COUNTERS_DB, 'COUNTERS:{}'.format(port_oid)) + + if asic_db_kvp is not None: + # Capture and display only the relevant FEC codeword errors + fec_errors = {f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(17)} + + # Print FEC histogram + for bin_label, error_value in fec_errors.items(): + click.echo(f'{bin_label}: {error_value}') + else: + click.echo('No kvp found in ASIC DB for port {}, exiting'.format(target_port), err=True) + raise click.Abort() + + asic_db.close(asic_db.ASIC_DB) + config_db.close(config_db.CONFIG_DB) + counter_db.close(counter_db.COUNTERS_DB) + + +# 'fec-histogram' subcommand ("show interfaces counters fec-histogram") +@counters.command('fec-histogram') +@multi_asic_util.multi_asic_click_options +@click.argument('interfacename', required=True) +def fec_histogram(interfacename, namespace, display): + """Show interface counters fec-histogram""" + port_oid_map = get_port_oid_mapping() + + # Try to convert interface name from alias + interfacename = try_convert_interfacename_from_alias(click.get_current_context(), interfacename) + + # Fetch and display the FEC histogram + fetch_fec_histogram(port_oid_map, interfacename) + + # 'rates' subcommand ("show interfaces counters rates") @counters.command() @click.option('-p', '--period') @@ -719,7 +782,7 @@ def autoneg_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'autoneg'] - # ignore the display option when interface name is passed + #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -735,8 +798,6 @@ def autoneg_status(interfacename, namespace, display, verbose): # # link-training group (show interfaces link-training ...) # - - @interfaces.group(name='link-training', cls=clicommon.AliasedGroup) def link_training(): """Show interface link-training information""" @@ -754,7 +815,7 @@ def link_training_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'link_training'] - # ignore the display option when interface name is passed + #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -787,7 +848,7 @@ def fec_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'fec'] - # ignore the display option when interface name is passed + #ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -799,74 +860,3 @@ def fec_status(interfacename, namespace, display, verbose): cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) - -# -# switchport group (show interfaces switchport ...) -# - - -@interfaces.group(name='switchport', cls=clicommon.AliasedGroup) -def switchport(): - """Show interface switchport information""" - pass - - -@switchport.command(name="config") -@clicommon.pass_db -def switchport_mode_config(db): - """Show interface switchport config information""" - - port_data = list(db.cfgdb.get_table('PORT').keys()) - portchannel_data = list(db.cfgdb.get_table('PORTCHANNEL').keys()) - - portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') - - for interface in port_data: - if clicommon.interface_is_in_portchannel(portchannel_member_table, interface): - port_data.remove(interface) - - keys = port_data + portchannel_data - - def tablelize(keys): - table = [] - - for key in natsorted(keys): - r = [clicommon.get_interface_name_for_display(db, key), - clicommon.get_interface_switchport_mode(db, key), - clicommon.get_interface_untagged_vlan_members(db, key), - clicommon.get_interface_tagged_vlan_members(db, key)] - table.append(r) - - return table - - header = ['Interface', 'Mode', 'Untagged', 'Tagged'] - click.echo(tabulate(tablelize(keys), header, tablefmt="simple", stralign='left')) - - -@switchport.command(name="status") -@clicommon.pass_db -def switchport_mode_status(db): - """Show interface switchport status information""" - - port_data = list(db.cfgdb.get_table('PORT').keys()) - portchannel_data = list(db.cfgdb.get_table('PORTCHANNEL').keys()) - - portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') - - for interface in port_data: - if clicommon.interface_is_in_portchannel(portchannel_member_table, interface): - port_data.remove(interface) - - keys = port_data + portchannel_data - - def tablelize(keys): - table = [] - - for key in natsorted(keys): - r = [clicommon.get_interface_name_for_display(db, key), clicommon.get_interface_switchport_mode(db, key)] - table.append(r) - - return table - - header = ['Interface', 'Mode'] - click.echo(tabulate(tablelize(keys), header, tablefmt="simple", stralign='left')) From 3c50652ee35528416408d7d0f9a3cbd02e772c85 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Fri, 6 Sep 2024 19:34:30 +0000 Subject: [PATCH 03/12] add changes Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 80 +++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index d5d7aecefb..8e5eb52743 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -680,7 +680,8 @@ def fetch_fec_histogram(port_oid_map, target_port): if asic_db_kvp is not None: # Capture and display only the relevant FEC codeword errors - fec_errors = {f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(17)} + fec_errors = {f'BIN{i}': asic_db_kvp.get + (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(17)} # Print FEC histogram for bin_label, error_value in fec_errors.items(): @@ -782,7 +783,7 @@ def autoneg_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'autoneg'] - #ignore the display option when interface name is passed + # ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -815,7 +816,7 @@ def link_training_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'link_training'] - #ignore the display option when interface name is passed + # ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -848,7 +849,7 @@ def fec_status(interfacename, namespace, display, verbose): cmd = ['intfutil', '-c', 'fec'] - #ignore the display option when interface name is passed + # ignore the display option when interface name is passed if interfacename is not None: interfacename = try_convert_interfacename_from_alias(ctx, interfacename) @@ -860,3 +861,74 @@ def fec_status(interfacename, namespace, display, verbose): cmd += ['-n', str(namespace)] clicommon.run_command(cmd, display_cmd=verbose) + +# +# switchport group (show interfaces switchport ...) +# + + +@interfaces.group(name='switchport', cls=clicommon.AliasedGroup) +def switchport(): + """Show interface switchport information""" + pass + + +@switchport.command(name="config") +@clicommon.pass_db +def switchport_mode_config(db): + """Show interface switchport config information""" + + port_data = list(db.cfgdb.get_table('PORT').keys()) + portchannel_data = list(db.cfgdb.get_table('PORTCHANNEL').keys()) + + portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') + + for interface in port_data: + if clicommon.interface_is_in_portchannel(portchannel_member_table, interface): + port_data.remove(interface) + + keys = port_data + portchannel_data + + def tablelize(keys): + table = [] + + for key in natsorted(keys): + r = [clicommon.get_interface_name_for_display(db, key), + clicommon.get_interface_switchport_mode(db, key), + clicommon.get_interface_untagged_vlan_members(db, key), + clicommon.get_interface_tagged_vlan_members(db, key)] + table.append(r) + + return table + + header = ['Interface', 'Mode', 'Untagged', 'Tagged'] + click.echo(tabulate(tablelize(keys), header, tablefmt="simple", stralign='left')) + + +@switchport.command(name="status") +@clicommon.pass_db +def switchport_mode_status(db): + """Show interface switchport status information""" + + port_data = list(db.cfgdb.get_table('PORT').keys()) + portchannel_data = list(db.cfgdb.get_table('PORTCHANNEL').keys()) + + portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') + + for interface in port_data: + if clicommon.interface_is_in_portchannel(portchannel_member_table, interface): + port_data.remove(interface) + + keys = port_data + portchannel_data + + def tablelize(keys): + table = [] + + for key in natsorted(keys): + r = [clicommon.get_interface_name_for_display(db, key), clicommon.get_interface_switchport_mode(db, key)] + table.append(r) + + return table + + header = ['Interface', 'Mode'] + click.echo(tabulate(tablelize(keys), header, tablefmt="simple", stralign='left')) From 8c1d4429466e2b910d08406f950d662525079eea Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Fri, 6 Sep 2024 19:39:00 +0000 Subject: [PATCH 04/12] add changes Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 8e5eb52743..0402acad77 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -660,6 +660,7 @@ def get_port_oid_mapping(): return port_oid_map + def fetch_fec_histogram(port_oid_map, target_port): ''' Fetch and display FEC histogram for the given port. ''' asic_db = SonicV2Connector(host=REDIS_HOSTIP) @@ -702,10 +703,10 @@ def fetch_fec_histogram(port_oid_map, target_port): def fec_histogram(interfacename, namespace, display): """Show interface counters fec-histogram""" port_oid_map = get_port_oid_mapping() - + # Try to convert interface name from alias interfacename = try_convert_interfacename_from_alias(click.get_current_context(), interfacename) - + # Fetch and display the FEC histogram fetch_fec_histogram(port_oid_map, interfacename) @@ -799,6 +800,8 @@ def autoneg_status(interfacename, namespace, display, verbose): # # link-training group (show interfaces link-training ...) # + + @interfaces.group(name='link-training', cls=clicommon.AliasedGroup) def link_training(): """Show interface link-training information""" From cd3e8c29ae94a00e3df38980673847bd5f5c3687 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Fri, 6 Sep 2024 20:29:58 +0000 Subject: [PATCH 05/12] add UT Signed-off-by: Vaibhav Dahiya --- tests/mock_tables/counters_db.json | 19 ++++++++++++++++++- tests/portstat_test.py | 11 +++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 2f16c7014d..28370e1f70 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -882,7 +882,24 @@ "SAI_PORT_STAT_ETHER_STATS_JABBERS": "0", "SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES": "130402", "SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES": "3", - "SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS": "4" + "SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS": "4", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S0": "1000000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S1": "900000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S2": "800000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S3": "700000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S4": "600000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S5": "500000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S6": "400000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S7": "300000", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S8": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S9": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S10": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S11": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S12": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S13": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15": "0", + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S16": "0" }, "COUNTERS:oid:0x1000000000013": { "SAI_PORT_STAT_IF_IN_UCAST_PKTS": "4", diff --git a/tests/portstat_test.py b/tests/portstat_test.py index 3af704e66e..f2fe01e258 100644 --- a/tests/portstat_test.py +++ b/tests/portstat_test.py @@ -337,6 +337,17 @@ def test_show_intf_fec_counters(self): assert return_code == 0 assert result == intf_fec_counters + + def test_show_intf_counters_fec_histogram(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["interfaces"].commands["counters"].commands["fec-histogram"], ["Ethernet0"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == intf_fec_counters + + def test_show_intf_fec_counters_period(self): runner = CliRunner() result = runner.invoke(show.cli.commands["interfaces"].commands["counters"].commands["fec-stats"], From e14d149820e2c71f839a845914be44a52231bbb3 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Fri, 6 Sep 2024 21:03:00 +0000 Subject: [PATCH 06/12] fix test Signed-off-by: Vaibhav Dahiya --- tests/portstat_test.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/portstat_test.py b/tests/portstat_test.py index f2fe01e258..6cb5ef082b 100644 --- a/tests/portstat_test.py +++ b/tests/portstat_test.py @@ -42,6 +42,26 @@ Ethernet8 N/A 100,317 0 0 """ +intf_fec_counters_fec_hist = """\ +BIN0: 1000000 +BIN1: 900000 +BIN2: 800000 +BIN3: 700000 +BIN4: 600000 +BIN5: 500000 +BIN6: 400000 +BIN7: 300000 +BIN8: 0 +BIN9: 0 +BIN10: 0 +BIN11: 0 +BIN12: 0 +BIN13: 0 +BIN14: 0 +BIN15: 0 +BIN16: 0 +""" + intf_fec_counters_period = """\ The rates are calculated within 3 seconds period IFACE STATE FEC_CORR FEC_UNCORR FEC_SYMBOL_ERR @@ -337,7 +357,6 @@ def test_show_intf_fec_counters(self): assert return_code == 0 assert result == intf_fec_counters - def test_show_intf_counters_fec_histogram(self): runner = CliRunner() result = runner.invoke( @@ -345,8 +364,7 @@ def test_show_intf_counters_fec_histogram(self): print(result.exit_code) print(result.output) assert result.exit_code == 0 - assert result.output == intf_fec_counters - + assert result.output == intf_fec_counters_fec_hist def test_show_intf_fec_counters_period(self): runner = CliRunner() From 6bed7b7b115ecdfb7a67f7caf054dc6e259c6bda Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Sun, 8 Sep 2024 21:16:47 +0000 Subject: [PATCH 07/12] correct doc Signed-off-by: Vaibhav Dahiya --- doc/Command-Reference.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 2584469b4f..5efc62d437 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -4933,26 +4933,25 @@ In a FEC histogram, "bins" represent ranges of errors or specific categories of ``` admin@str-s6000-acs-11:/usr/bin$ show interface counters fec-histogram -i - Symbol Errors Per Codeword Codewords - -------------------------- --------- - BIN_FEC_CODEWORD_S0 4075208478588 - BIN_FEC_CODEWORD_S1 7 - BIN_FEC_CODEWORD_S2 0 - BIN_FEC_CODEWORD_S3 0 - BIN_FEC_CODEWORD_S4 0 - BIN_FEC_CODEWORD_S5 0 - BIN_FEC_CODEWORD_S6 0 - BIN_FEC_CODEWORD_S7 0 - BIN_FEC_CODEWORD_S8 0 - BIN_FEC_CODEWORD_S9 0 - BIN_FEC_CODEWORD_S10 0 - BIN_FEC_CODEWORD_S11 0 - BIN_FEC_CODEWORD_S12 0 - BIN_FEC_CODEWORD_S13 0 - BIN_FEC_CODEWORD_S14 0 - BIN_FEC_CODEWORD_S15 0 - BIN_FEC_CODEWORD_S16 0 - +Symbol Errors Per Codeword Codewords +-------------------------- --------- +BIN0: 1000000 +BIN1: 900000 +BIN2: 800000 +BIN3: 700000 +BIN4: 600000 +BIN5: 500000 +BIN6: 400000 +BIN7: 300000 +BIN8: 0 +BIN9: 0 +BIN10: 0 +BIN11: 0 +BIN12: 0 +BIN13: 0 +BIN14: 0 +BIN15: 0 +BIN16: 0 ``` From 59490edfb88861252056f463c99c66aeaa269240 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Mon, 9 Sep 2024 23:38:58 +0000 Subject: [PATCH 08/12] add changes Signed-off-by: Vaibhav Dahiya --- doc/Command-Reference.md | 1 - show/interfaces/__init__.py | 17 ++++++++++----- tests/mock_tables/counters_db.json | 3 +-- tests/portstat_test.py | 35 +++++++++++++++--------------- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 5efc62d437..be0bd14fdd 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -4951,7 +4951,6 @@ BIN12: 0 BIN13: 0 BIN14: 0 BIN15: 0 -BIN16: 0 ``` diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 0402acad77..7c7010e645 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -680,13 +680,18 @@ def fetch_fec_histogram(port_oid_map, target_port): asic_db_kvp = counter_db.get_all(counter_db.COUNTERS_DB, 'COUNTERS:{}'.format(port_oid)) if asic_db_kvp is not None: - # Capture and display only the relevant FEC codeword errors - fec_errors = {f'BIN{i}': asic_db_kvp.get - (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(17)} + fec_errors = {f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} + + # Prepare the data for tabulation + table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()] + + # Define headers + headers = ["Symbol Errors Per Codeword", "Codewords"] + + # Print FEC histogram using tabulate + click.echo(tabulate(table_data, headers=headers, tablefmt="plain")) + - # Print FEC histogram - for bin_label, error_value in fec_errors.items(): - click.echo(f'{bin_label}: {error_value}') else: click.echo('No kvp found in ASIC DB for port {}, exiting'.format(target_port), err=True) raise click.Abort() diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 28370e1f70..9e553c2901 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -898,8 +898,7 @@ "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S12": "0", "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S13": "0", "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14": "0", - "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15": "0", - "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S16": "0" + "SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15": "0" }, "COUNTERS:oid:0x1000000000013": { "SAI_PORT_STAT_IF_IN_UCAST_PKTS": "4", diff --git a/tests/portstat_test.py b/tests/portstat_test.py index 6cb5ef082b..328b691ca3 100644 --- a/tests/portstat_test.py +++ b/tests/portstat_test.py @@ -43,23 +43,24 @@ """ intf_fec_counters_fec_hist = """\ -BIN0: 1000000 -BIN1: 900000 -BIN2: 800000 -BIN3: 700000 -BIN4: 600000 -BIN5: 500000 -BIN6: 400000 -BIN7: 300000 -BIN8: 0 -BIN9: 0 -BIN10: 0 -BIN11: 0 -BIN12: 0 -BIN13: 0 -BIN14: 0 -BIN15: 0 -BIN16: 0 +Symbol Errors Per Codeword Codewords +-------------------------- --------- +BIN0: 1000000 +BIN1: 900000 +BIN2: 800000 +BIN3: 700000 +BIN4: 600000 +BIN5: 500000 +BIN6: 400000 +BIN7: 300000 +BIN8: 0 +BIN9: 0 +BIN10: 0 +BIN11: 0 +BIN12: 0 +BIN13: 0 +BIN14: 0 +BIN15: 0 """ intf_fec_counters_period = """\ From 777611fc0bc7b46bbaf80e32815e6d2766dac543 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Mon, 9 Sep 2024 23:52:23 +0000 Subject: [PATCH 09/12] add cosmetic fix Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 7c7010e645..6f793e6803 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -680,18 +680,17 @@ def fetch_fec_histogram(port_oid_map, target_port): asic_db_kvp = counter_db.get_all(counter_db.COUNTERS_DB, 'COUNTERS:{}'.format(port_oid)) if asic_db_kvp is not None: - fec_errors = {f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} - - # Prepare the data for tabulation - table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()] - - # Define headers - headers = ["Symbol Errors Per Codeword", "Codewords"] - - # Print FEC histogram using tabulate - click.echo(tabulate(table_data, headers=headers, tablefmt="plain")) - - + fec_errors = {f'BIN{i}': asic_db_kvp.get + (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} + + # Prepare the data for tabulation + table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()] + + # Define headers + headers = ["Symbol Errors Per Codeword", "Codewords"] + + # Print FEC histogram using tabulate + click.echo(tabulate(table_data, headers=headers)) else: click.echo('No kvp found in ASIC DB for port {}, exiting'.format(target_port), err=True) raise click.Abort() From 486992e44ebadd84eeb8d8dcc756ed28f91dc787 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Tue, 10 Sep 2024 00:21:30 +0000 Subject: [PATCH 10/12] add fixes Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 8 ++++---- tests/portstat_test.py | 36 ++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 6f793e6803..c8b286de03 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -681,14 +681,14 @@ def fetch_fec_histogram(port_oid_map, target_port): if asic_db_kvp is not None: fec_errors = {f'BIN{i}': asic_db_kvp.get - (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} - + (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} + # Prepare the data for tabulation table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()] - + # Define headers headers = ["Symbol Errors Per Codeword", "Codewords"] - + # Print FEC histogram using tabulate click.echo(tabulate(table_data, headers=headers)) else: diff --git a/tests/portstat_test.py b/tests/portstat_test.py index 328b691ca3..af9814f812 100644 --- a/tests/portstat_test.py +++ b/tests/portstat_test.py @@ -43,24 +43,24 @@ """ intf_fec_counters_fec_hist = """\ -Symbol Errors Per Codeword Codewords --------------------------- --------- -BIN0: 1000000 -BIN1: 900000 -BIN2: 800000 -BIN3: 700000 -BIN4: 600000 -BIN5: 500000 -BIN6: 400000 -BIN7: 300000 -BIN8: 0 -BIN9: 0 -BIN10: 0 -BIN11: 0 -BIN12: 0 -BIN13: 0 -BIN14: 0 -BIN15: 0 +Symbol Errors Per Codeword Codewords +---------------------------- ----------- +BIN0 1000000 +BIN1 900000 +BIN2 800000 +BIN3 700000 +BIN4 600000 +BIN5 500000 +BIN6 400000 +BIN7 300000 +BIN8 0 +BIN9 0 +BIN10 0 +BIN11 0 +BIN12 0 +BIN13 0 +BIN14 0 +BIN15 0 """ intf_fec_counters_period = """\ From 1a79116283597d0104e3c9bb6f2df511b1273010 Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Tue, 10 Sep 2024 00:26:23 +0000 Subject: [PATCH 11/12] pep 8 Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index c8b286de03..0ce37db05f 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -680,8 +680,11 @@ def fetch_fec_histogram(port_oid_map, target_port): asic_db_kvp = counter_db.get_all(counter_db.COUNTERS_DB, 'COUNTERS:{}'.format(port_oid)) if asic_db_kvp is not None: - fec_errors = {f'BIN{i}': asic_db_kvp.get - (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} + + fec_errors = { + f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') + for i in range(16) + } # Prepare the data for tabulation table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()] From 8290b0d5e3409005450bff760eb76969e72a65df Mon Sep 17 00:00:00 2001 From: Vaibhav Dahiya Date: Tue, 10 Sep 2024 00:53:43 +0000 Subject: [PATCH 12/12] add indentation Signed-off-by: Vaibhav Dahiya --- show/interfaces/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index 0ce37db05f..f8889e6c32 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -681,10 +681,8 @@ def fetch_fec_histogram(port_oid_map, target_port): if asic_db_kvp is not None: - fec_errors = { - f'BIN{i}': asic_db_kvp.get(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') - for i in range(16) - } + fec_errors = {f'BIN{i}': asic_db_kvp.get + (f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)} # Prepare the data for tabulation table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()]