diff --git a/scripts/pfcstat b/scripts/pfcstat index 094c6e9380..de06fd9f2a 100755 --- a/scripts/pfcstat +++ b/scripts/pfcstat @@ -34,16 +34,18 @@ try: except KeyError: pass -from utilities_common.netstat import ns_diff, STATUS_NA, format_number_with_comma +from utilities_common.netstat import ns_diff, STATUS_NA, format_number_with_comma, format_ms_as_datetime from utilities_common import multi_asic as multi_asic_util from utilities_common import constants from utilities_common.cli import json_serial, UserCache PStats = namedtuple("PStats", "pfc0, pfc1, pfc2, pfc3, pfc4, pfc5, pfc6, pfc7") -header_Rx = ['Port Rx', 'PFC0', 'PFC1', 'PFC2', 'PFC3', 'PFC4', 'PFC5', 'PFC6', 'PFC7'] -header_Tx = ['Port Tx', 'PFC0', 'PFC1', 'PFC2', 'PFC3', 'PFC4', 'PFC5', 'PFC6', 'PFC7'] +pfc_titles = ['PFC0', 'PFC1', 'PFC2', 'PFC3', 'PFC4', 'PFC5', 'PFC6', 'PFC7'] + +header_Rx = ['Port Rx'] + pfc_titles +header_Tx = ['Port Tx'] + pfc_titles counter_bucket_rx_dict = { 'SAI_PORT_STAT_PFC_0_RX_PKTS': 0, @@ -68,7 +70,12 @@ counter_bucket_tx_dict = { } +HistStats = namedtuple("HistStats", "numTransitions, totalPauseTime, recentPauseTimestamp, recentPauseTime") +history_stat_fields = ["TOTAL_PAUSE_TRANSITIONS_", "TOTAL_PAUSE_TIME_MS_", "RECENT_PAUSE_TIMESTAMP_", "RECENT_PAUSE_TIME_MS_"] +header_hist = ['Port', 'Priority', 'RX Pause Transitions', 'Total RX Pause Time MS', 'Recent RX Pause Time MS', 'Recent RX Pause Timestamp'] + COUNTER_TABLE_PREFIX = "COUNTERS:" +PFC_STAT_HISTORY_TABLE_PREFIX = "PFC_STAT_HISTORY:" COUNTERS_PORT_NAME_MAP = "COUNTERS_PORT_NAME_MAP" class Pfcstat(object): @@ -77,6 +84,7 @@ class Pfcstat(object): self.db = None self.config_db = None self.cnstat_dict = OrderedDict() + self.hist_dict = OrderedDict() @multi_asic_util.run_on_multi_asic def collect_cnstat(self, rx): @@ -126,6 +134,55 @@ class Pfcstat(object): ) self.cnstat_dict.update(cnstat_dict) + @multi_asic_util.run_on_multi_asic + def collect_history(self): + """ + Get the history stats from database. + """ + def get_history_stats(table_id): + """ + Get the history from specific table. + """ + pfc_dict = OrderedDict() + for pfc_index, pfc in enumerate(pfc_titles): + fields = [STATUS_NA] * len(history_stat_fields) + # TOTAL_PAUSE_TRANSITIONS_0, TOTAL_PAUSE_TIME_MS_0, ... + for stat_index, stat_name in enumerate(history_stat_fields): + full_table_id = PFC_STAT_HISTORY_TABLE_PREFIX + table_id + full_stat_name = stat_name + str(pfc_index) + + hist_data = self.db.get( + self.db.COUNTERS_DB, full_table_id, full_stat_name + ) + if hist_data is not None: + fields[stat_index] = str(int(hist_data)) + stats = HistStats._make(fields)._asdict() + + pfc_dict[pfc] = stats + return pfc_dict + + # get the port name : oid map + counter_port_name_map = self.db.get_all( + self.db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP + ) + if counter_port_name_map is None: + return + display_ports_set = set(counter_port_name_map.keys()) + if self.multi_asic.display_option == constants.DISPLAY_EXTERNAL: + display_ports_set = get_external_ports( + display_ports_set, self.multi_asic.current_namespace + ) + # Build a dictionary of the stats + hist_dict = OrderedDict() + hist_dict['time'] = datetime.datetime.now() + if counter_port_name_map is not None: + for port in natsorted(counter_port_name_map): + if port in display_ports_set: + hist_dict[port] = get_history_stats( + counter_port_name_map[port] + ) + self.hist_dict.update(hist_dict) + def get_cnstat(self, rx): """ Get the counters info from database. @@ -134,6 +191,14 @@ class Pfcstat(object): self.collect_cnstat(rx) return self.cnstat_dict + def get_history(self): + """ + Get the history stats from database. + """ + self.hist_dict.clear() + self.collect_history() + return self.hist_dict + def cnstat_print(self, cnstat_dict, rx): """ Print the cnstat. @@ -197,6 +262,51 @@ class Pfcstat(object): else: print(tabulate(table, header_Tx, tablefmt='simple', stralign='right')) + def history_diff_print(self, hist_new_dict, hist_old_dict={}): + """ + Print the difference between two cnstat history results. + """ + table = [] + # time : <>, ethernet0 : { pfc0: {}, pfc1: {} }, ethernet1 :{} + for key, pfc_dict in hist_new_dict.items(): + if key == 'time': + continue + # old dict has this port + if key in hist_old_dict: + for pfc, stat in pfc_dict.items(): + old_stat = None + if pfc in hist_old_dict.get(key): + old_stat = hist_old_dict.get(key).get(pfc) + # old dict [ port ] has this priority data + if old_stat is not None: + table.append((key, + pfc, + ns_diff(stat['numTransitions'], old_stat['numTransitions']), + ns_diff(stat['totalPauseTime'], old_stat['totalPauseTime']), + format_number_with_comma(stat['recentPauseTime']), + format_ms_as_datetime(stat['recentPauseTimestamp']))) + # use the new data only for this port for this priority + else: + table.append((key, + pfc, + format_number_with_comma(stat['numTransitions']), + format_number_with_comma(stat['totalPauseTime']), + format_number_with_comma(stat['recentPauseTime']), + format_ms_as_datetime(stat['recentPauseTimestamp']))) + # use the new data only for this port + else: + for pfc, stat in pfc_dict.items(): + table.append((key, + pfc, + format_number_with_comma(stat['numTransitions']), + format_number_with_comma(stat['totalPauseTime']), + format_number_with_comma(stat['recentPauseTime']), + format_ms_as_datetime(stat['recentPauseTimestamp']))) + # empty line between interfaces + table.append([]) + + print(tabulate(table, header_hist, tablefmt='simple', stralign='right')) + def main(): parser = argparse.ArgumentParser(description='Display the pfc counters', formatter_class=argparse.RawTextHelpFormatter, @@ -207,6 +317,9 @@ Examples: pfcstat -d pfcstat -n asic1 pfcstat -s all -n asic0 + pfcstat --history + pfcstat -n asic1 --history + pfcstat -s all -n asic0 --history """) parser.add_argument( '-c', '--clear', action='store_true', @@ -221,11 +334,18 @@ Examples: parser.add_argument('-n', '--namespace', default=None, help='Display interfaces for specific namespace' ) - parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0') + parser.add_argument( + '-v', '--version', action='version', version='%(prog)s 1.0' + ) + parser.add_argument( + '--history', action="store_true", help="Display historical PFC statistics" + ) + args = parser.parse_args() save_fresh_stats = args.clear delete_all_stats = args.delete + show_pfc_history = args.history cache = UserCache() cnstat_file = 'pfcstat' @@ -233,6 +353,7 @@ Examples: cnstat_dir = cache.get_directory() cnstat_fqn_file_rx = os.path.join(cnstat_dir, "{}rx".format(cnstat_file)) cnstat_fqn_file_tx = os.path.join(cnstat_dir, "{}tx".format(cnstat_file)) + hist_fqn_file = cnstat_fqn_file_rx + "_hist" # if '-c' option is provided get stats from all (frontend and backend) ports if save_fresh_stats: @@ -244,55 +365,84 @@ Examples: if delete_all_stats: cache.remove() - """ - Get the counters of pfc rx counter - """ - cnstat_dict_rx = deepcopy(pfcstat.get_cnstat(True)) - - """ - Get the counters of pfc tx counter - """ - cnstat_dict_tx = deepcopy(pfcstat.get_cnstat(False)) - + # clear both counters + history if save_fresh_stats: + # Get the counters of pfc rx counter + cnstat_dict_rx = deepcopy(pfcstat.get_cnstat(True)) + # Get the counters of pfc tx counter + cnstat_dict_tx = deepcopy(pfcstat.get_cnstat(False)) + # Get the history stats of pfc rx + hist_dict = deepcopy(pfcstat.get_history()) + try: json.dump(cnstat_dict_rx, open(cnstat_fqn_file_rx, 'w'), default=json_serial) json.dump(cnstat_dict_tx, open(cnstat_fqn_file_tx, 'w'), default=json_serial) + json.dump(hist_dict, open(hist_fqn_file, 'w'), default=json_serial) except IOError as e: print(e.errno, e) sys.exit(e.errno) else: - print("Clear saved counters") + print("Clear saved PFC counters and history") sys.exit(0) + # save history stats separately + if show_pfc_history: + """ + Get the history stats of pfc rx + """ + hist_dict = deepcopy(pfcstat.get_history()) + + """ + Print the pfc history stats + """ + if os.path.isfile(hist_fqn_file): + try: + hist_cached_dict = json.load(open(hist_fqn_file, 'r')) + print("Last cached time was " + str(hist_cached_dict.get('time'))) + pfcstat.history_diff_print(hist_dict, hist_cached_dict) + except IOError as e: + print(e.errno, e) + else: + pfcstat.history_diff_print(hist_dict) - """ - Print the counters of pfc rx counter - """ - if os.path.isfile(cnstat_fqn_file_rx): - try: - cnstat_cached_dict = json.load(open(cnstat_fqn_file_rx, 'r')) - print("Last cached time was " + str(cnstat_cached_dict.get('time'))) - pfcstat.cnstat_diff_print(cnstat_dict_rx, cnstat_cached_dict, True) - except IOError as e: - print(e.errno, e) else: - pfcstat.cnstat_print(cnstat_dict_rx, True) + """ + Get the counters of pfc rx counter + """ + cnstat_dict_rx = deepcopy(pfcstat.get_cnstat(True)) - print("") + """ + Get the counters of pfc tx counter + """ + cnstat_dict_tx = deepcopy(pfcstat.get_cnstat(False)) - """ - Print the counters of pfc tx counter - """ - if os.path.isfile(cnstat_fqn_file_tx): - try: - cnstat_cached_dict = json.load(open(cnstat_fqn_file_tx, 'r')) - print("Last cached time was " + str(cnstat_cached_dict.get('time'))) - pfcstat.cnstat_diff_print(cnstat_dict_tx, cnstat_cached_dict, False) - except IOError as e: - print(e.errno, e) - else: - pfcstat.cnstat_print(cnstat_dict_tx, False) + """ + Print the counters of pfc rx counter + """ + if os.path.isfile(cnstat_fqn_file_rx): + try: + cnstat_cached_dict = json.load(open(cnstat_fqn_file_rx, 'r')) + print("Last cached time was " + str(cnstat_cached_dict.get('time'))) + pfcstat.cnstat_diff_print(cnstat_dict_rx, cnstat_cached_dict, True) + except IOError as e: + print(e.errno, e) + else: + pfcstat.cnstat_print(cnstat_dict_rx, True) + + print("") + + """ + Print the counters of pfc tx counter + """ + if os.path.isfile(cnstat_fqn_file_tx): + try: + cnstat_cached_dict = json.load(open(cnstat_fqn_file_tx, 'r')) + print("Last cached time was " + str(cnstat_cached_dict.get('time'))) + pfcstat.cnstat_diff_print(cnstat_dict_tx, cnstat_cached_dict, False) + except IOError as e: + print(e.errno, e) + else: + pfcstat.cnstat_print(cnstat_dict_tx, False) sys.exit(0) diff --git a/show/main.py b/show/main.py index f71567d008..2fe86e4731 100755 --- a/show/main.py +++ b/show/main.py @@ -638,13 +638,16 @@ def pfc(): # 'counters' subcommand ("show interfaces pfccounters") @pfc.command() @multi_asic_util.multi_asic_click_options +@click.option('--history', is_flag=True, help="Display historical PFC statistics") @click.option('--verbose', is_flag=True, help="Enable verbose output") -def counters(namespace, display, verbose): +def counters(namespace, history, display, verbose): """Show pfc counters""" cmd = ['pfcstat', '-s', str(display)] if namespace is not None: cmd += ['-n', str(namespace)] + if history: + cmd += ['--history'] run_command(cmd, display_cmd=verbose) diff --git a/tests/mock_tables/asic0/counters_db.json b/tests/mock_tables/asic0/counters_db.json index 610662a019..fd02b58471 100644 --- a/tests/mock_tables/asic0/counters_db.json +++ b/tests/mock_tables/asic0/counters_db.json @@ -1911,6 +1911,142 @@ "COUNTERS:oid:0x21000000000000": { "SAI_SWITCH_STAT_IN_DROP_REASON_RANGE_BASE": "1000" }, + "PFC_STAT_HISTORY:oid:0x1000000000002": { + "TOTAL_PAUSE_TRANSITIONS_0": "12", + "TOTAL_PAUSE_TIME_MS_0":"12000", + "RECENT_PAUSE_TIMESTAMP_0":"1200000000000", + "RECENT_PAUSE_TIME_MS_0":"1200", + "TOTAL_PAUSE_TRANSITIONS_1": "21", + "TOTAL_PAUSE_TIME_MS_1":"20001", + "RECENT_PAUSE_TIMESTAMP_1":"2000000000001", + "RECENT_PAUSE_TIME_MS_1":"2001", + "TOTAL_PAUSE_TRANSITIONS_2": "22", + "TOTAL_PAUSE_TIME_MS_2":"20002", + "RECENT_PAUSE_TIMESTAMP_2":"2000000000002", + "RECENT_PAUSE_TIME_MS_2":"2002", + "TOTAL_PAUSE_TRANSITIONS_3": "23", + "TOTAL_PAUSE_TIME_MS_3":"20003", + "RECENT_PAUSE_TIMESTAMP_3":"2000000000003", + "RECENT_PAUSE_TIME_MS_3":"2003", + "TOTAL_PAUSE_TRANSITIONS_4": "24", + "TOTAL_PAUSE_TIME_MS_4":"20004", + "RECENT_PAUSE_TIMESTAMP_4":"2000000000004", + "RECENT_PAUSE_TIME_MS_4":"2004", + "TOTAL_PAUSE_TRANSITIONS_5": "25", + "TOTAL_PAUSE_TIME_MS_5":"20005", + "RECENT_PAUSE_TIMESTAMP_5":"2000000000005", + "RECENT_PAUSE_TIME_MS_5":"2005", + "TOTAL_PAUSE_TRANSITIONS_6": "26", + "TOTAL_PAUSE_TIME_MS_6":"20006", + "RECENT_PAUSE_TIMESTAMP_6":"2000000000006", + "RECENT_PAUSE_TIME_MS_6":"2006", + "TOTAL_PAUSE_TRANSITIONS_7": "27", + "TOTAL_PAUSE_TIME_MS_7":"20007", + "RECENT_PAUSE_TIMESTAMP_7":"2000000000007", + "RECENT_PAUSE_TIME_MS_7":"2007" + }, + "PFC_STAT_HISTORY:oid:0x1000000000004": { + "TOTAL_PAUSE_TRANSITIONS_0": "14", + "TOTAL_PAUSE_TIME_MS_0":"14000", + "RECENT_PAUSE_TIMESTAMP_0":"1400000000000", + "RECENT_PAUSE_TIME_MS_0":"1400", + "TOTAL_PAUSE_TRANSITIONS_1": "41", + "TOTAL_PAUSE_TIME_MS_1":"40001", + "RECENT_PAUSE_TIMESTAMP_1":"4000000000001", + "RECENT_PAUSE_TIME_MS_1":"4001", + "TOTAL_PAUSE_TRANSITIONS_2": "42", + "TOTAL_PAUSE_TIME_MS_2":"40002", + "RECENT_PAUSE_TIMESTAMP_2":"4000000000002", + "RECENT_PAUSE_TIME_MS_2":"4002", + "TOTAL_PAUSE_TRANSITIONS_3": "43", + "TOTAL_PAUSE_TIME_MS_3":"40003", + "RECENT_PAUSE_TIMESTAMP_3":"4000000000003", + "RECENT_PAUSE_TIME_MS_3":"4003", + "TOTAL_PAUSE_TRANSITIONS_4": "44", + "TOTAL_PAUSE_TIME_MS_4":"40004", + "RECENT_PAUSE_TIMESTAMP_4":"4000000000004", + "RECENT_PAUSE_TIME_MS_4":"4004", + "TOTAL_PAUSE_TRANSITIONS_5": "45", + "TOTAL_PAUSE_TIME_MS_5":"40005", + "RECENT_PAUSE_TIMESTAMP_5":"4000000000005", + "RECENT_PAUSE_TIME_MS_5":"4005", + "TOTAL_PAUSE_TRANSITIONS_6": "46", + "TOTAL_PAUSE_TIME_MS_6":"40006", + "RECENT_PAUSE_TIMESTAMP_6":"4000000000006", + "RECENT_PAUSE_TIME_MS_6":"4006", + "TOTAL_PAUSE_TRANSITIONS_7": "47", + "TOTAL_PAUSE_TIME_MS_7":"40007", + "RECENT_PAUSE_TIMESTAMP_7":"4000000000007", + "RECENT_PAUSE_TIME_MS_7":"4007" + }, + "PFC_STAT_HISTORY:oid:0x1000000000006": { + "TOTAL_PAUSE_TRANSITIONS_0": "16", + "TOTAL_PAUSE_TIME_MS_0":"16000", + "RECENT_PAUSE_TIMESTAMP_0":"1600000000000", + "RECENT_PAUSE_TIME_MS_0":"1600", + "TOTAL_PAUSE_TRANSITIONS_1": "61", + "TOTAL_PAUSE_TIME_MS_1":"60001", + "RECENT_PAUSE_TIMESTAMP_1":"6000000000001", + "RECENT_PAUSE_TIME_MS_1":"6001", + "TOTAL_PAUSE_TRANSITIONS_2": "62", + "TOTAL_PAUSE_TIME_MS_2":"60002", + "RECENT_PAUSE_TIMESTAMP_2":"6000000000002", + "RECENT_PAUSE_TIME_MS_2":"6002", + "TOTAL_PAUSE_TRANSITIONS_3": "63", + "TOTAL_PAUSE_TIME_MS_3":"60003", + "RECENT_PAUSE_TIMESTAMP_3":"6000000000003", + "RECENT_PAUSE_TIME_MS_3":"6003", + "TOTAL_PAUSE_TRANSITIONS_4": "64", + "TOTAL_PAUSE_TIME_MS_4":"60004", + "RECENT_PAUSE_TIMESTAMP_4":"6000000000004", + "RECENT_PAUSE_TIME_MS_4":"6004", + "TOTAL_PAUSE_TRANSITIONS_5": "65", + "TOTAL_PAUSE_TIME_MS_5":"60005", + "RECENT_PAUSE_TIMESTAMP_5":"6000000000005", + "RECENT_PAUSE_TIME_MS_5":"6005", + "TOTAL_PAUSE_TRANSITIONS_6": "66", + "TOTAL_PAUSE_TIME_MS_6":"60006", + "RECENT_PAUSE_TIMESTAMP_6":"6000000000006", + "RECENT_PAUSE_TIME_MS_6":"6006", + "TOTAL_PAUSE_TRANSITIONS_7": "67", + "TOTAL_PAUSE_TIME_MS_7":"60007", + "RECENT_PAUSE_TIMESTAMP_7":"6000000000007", + "RECENT_PAUSE_TIME_MS_7":"6007" + }, + "PFC_STAT_HISTORY:oid:0x1000000000008": { + "TOTAL_PAUSE_TRANSITIONS_0": "18", + "TOTAL_PAUSE_TIME_MS_0":"18000", + "RECENT_PAUSE_TIMESTAMP_0":"1800000000000", + "RECENT_PAUSE_TIME_MS_0":"1800", + "TOTAL_PAUSE_TRANSITIONS_1": "81", + "TOTAL_PAUSE_TIME_MS_1":"80001", + "RECENT_PAUSE_TIMESTAMP_1":"8000000000001", + "RECENT_PAUSE_TIME_MS_1":"8001", + "TOTAL_PAUSE_TRANSITIONS_2": "82", + "TOTAL_PAUSE_TIME_MS_2":"80002", + "RECENT_PAUSE_TIMESTAMP_2":"8000000000002", + "RECENT_PAUSE_TIME_MS_2":"8002", + "TOTAL_PAUSE_TRANSITIONS_3": "83", + "TOTAL_PAUSE_TIME_MS_3":"80003", + "RECENT_PAUSE_TIMESTAMP_3":"8000000000003", + "RECENT_PAUSE_TIME_MS_3":"8003", + "TOTAL_PAUSE_TRANSITIONS_4": "84", + "TOTAL_PAUSE_TIME_MS_4":"80004", + "RECENT_PAUSE_TIMESTAMP_4":"8000000000004", + "RECENT_PAUSE_TIME_MS_4":"8004", + "TOTAL_PAUSE_TRANSITIONS_5": "85", + "TOTAL_PAUSE_TIME_MS_5":"80005", + "RECENT_PAUSE_TIMESTAMP_5":"8000000000005", + "RECENT_PAUSE_TIME_MS_5":"8005", + "TOTAL_PAUSE_TRANSITIONS_6": "86", + "TOTAL_PAUSE_TIME_MS_6":"80006", + "RECENT_PAUSE_TIMESTAMP_6":"8000000000006", + "RECENT_PAUSE_TIME_MS_6":"8006", + "TOTAL_PAUSE_TRANSITIONS_7": "87", + "TOTAL_PAUSE_TIME_MS_7":"80007", + "RECENT_PAUSE_TIMESTAMP_7":"8000000000007", + "RECENT_PAUSE_TIME_MS_7":"8007" + }, "RATES:oid:0x1000000000002": { "RX_BPS": "0", "RX_PPS": "0", diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 1dfdaaac74..b408c80e76 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -2228,6 +2228,108 @@ "SAI_QUEUE_STAT_PACKETS": "54", "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES": "97" }, + "PFC_STAT_HISTORY:oid:0x1000000000012": { + "TOTAL_PAUSE_TRANSITIONS_0": "12", + "TOTAL_PAUSE_TIME_MS_0":"12000", + "RECENT_PAUSE_TIMESTAMP_0":"1200000000000", + "RECENT_PAUSE_TIME_MS_0":"1200", + "TOTAL_PAUSE_TRANSITIONS_1": "21", + "TOTAL_PAUSE_TIME_MS_1":"20001", + "RECENT_PAUSE_TIMESTAMP_1":"2000000000001", + "RECENT_PAUSE_TIME_MS_1":"2001", + "TOTAL_PAUSE_TRANSITIONS_2": "22", + "TOTAL_PAUSE_TIME_MS_2":"20002", + "RECENT_PAUSE_TIMESTAMP_2":"2000000000002", + "RECENT_PAUSE_TIME_MS_2":"2002", + "TOTAL_PAUSE_TRANSITIONS_3": "23", + "TOTAL_PAUSE_TIME_MS_3":"20003", + "RECENT_PAUSE_TIMESTAMP_3":"2000000000003", + "RECENT_PAUSE_TIME_MS_3":"2003", + "TOTAL_PAUSE_TRANSITIONS_4": "24", + "TOTAL_PAUSE_TIME_MS_4":"20004", + "RECENT_PAUSE_TIMESTAMP_4":"2000000000004", + "RECENT_PAUSE_TIME_MS_4":"2004", + "TOTAL_PAUSE_TRANSITIONS_5": "25", + "TOTAL_PAUSE_TIME_MS_5":"20005", + "RECENT_PAUSE_TIMESTAMP_5":"2000000000005", + "RECENT_PAUSE_TIME_MS_5":"2005", + "TOTAL_PAUSE_TRANSITIONS_6": "26", + "TOTAL_PAUSE_TIME_MS_6":"20006", + "RECENT_PAUSE_TIMESTAMP_6":"2000000000006", + "RECENT_PAUSE_TIME_MS_6":"2006", + "TOTAL_PAUSE_TRANSITIONS_7": "27", + "TOTAL_PAUSE_TIME_MS_7":"20007", + "RECENT_PAUSE_TIMESTAMP_7":"2000000000007", + "RECENT_PAUSE_TIME_MS_7":"2007" + }, + "PFC_STAT_HISTORY:oid:0x1000000000013": { + "TOTAL_PAUSE_TRANSITIONS_0": "14", + "TOTAL_PAUSE_TIME_MS_0":"14000", + "RECENT_PAUSE_TIMESTAMP_0":"1400000000000", + "RECENT_PAUSE_TIME_MS_0":"1400", + "TOTAL_PAUSE_TRANSITIONS_1": "41", + "TOTAL_PAUSE_TIME_MS_1":"40001", + "RECENT_PAUSE_TIMESTAMP_1":"4000000000001", + "RECENT_PAUSE_TIME_MS_1":"4001", + "TOTAL_PAUSE_TRANSITIONS_2": "42", + "TOTAL_PAUSE_TIME_MS_2":"40002", + "RECENT_PAUSE_TIMESTAMP_2":"4000000000002", + "RECENT_PAUSE_TIME_MS_2":"4002", + "TOTAL_PAUSE_TRANSITIONS_3": "43", + "TOTAL_PAUSE_TIME_MS_3":"40003", + "RECENT_PAUSE_TIMESTAMP_3":"4000000000003", + "RECENT_PAUSE_TIME_MS_3":"4003", + "TOTAL_PAUSE_TRANSITIONS_4": "44", + "TOTAL_PAUSE_TIME_MS_4":"40004", + "RECENT_PAUSE_TIMESTAMP_4":"4000000000004", + "RECENT_PAUSE_TIME_MS_4":"4004", + "TOTAL_PAUSE_TRANSITIONS_5": "45", + "TOTAL_PAUSE_TIME_MS_5":"40005", + "RECENT_PAUSE_TIMESTAMP_5":"4000000000005", + "RECENT_PAUSE_TIME_MS_5":"4005", + "TOTAL_PAUSE_TRANSITIONS_6": "46", + "TOTAL_PAUSE_TIME_MS_6":"40006", + "RECENT_PAUSE_TIMESTAMP_6":"4000000000006", + "RECENT_PAUSE_TIME_MS_6":"4006", + "TOTAL_PAUSE_TRANSITIONS_7": "47", + "TOTAL_PAUSE_TIME_MS_7":"40007", + "RECENT_PAUSE_TIMESTAMP_7":"4000000000007", + "RECENT_PAUSE_TIME_MS_7":"4007" + }, + "PFC_STAT_HISTORY:oid:0x1000000000014": { + "TOTAL_PAUSE_TRANSITIONS_0": "18", + "TOTAL_PAUSE_TIME_MS_0":"18000", + "RECENT_PAUSE_TIMESTAMP_0":"1800000000000", + "RECENT_PAUSE_TIME_MS_0":"1800", + "TOTAL_PAUSE_TRANSITIONS_1": "81", + "TOTAL_PAUSE_TIME_MS_1":"80001", + "RECENT_PAUSE_TIMESTAMP_1":"8000000000001", + "RECENT_PAUSE_TIME_MS_1":"8001", + "TOTAL_PAUSE_TRANSITIONS_2": "82", + "TOTAL_PAUSE_TIME_MS_2":"80002", + "RECENT_PAUSE_TIMESTAMP_2":"8000000000002", + "RECENT_PAUSE_TIME_MS_2":"8002", + "TOTAL_PAUSE_TRANSITIONS_3": "83", + "TOTAL_PAUSE_TIME_MS_3":"80003", + "RECENT_PAUSE_TIMESTAMP_3":"8000000000003", + "RECENT_PAUSE_TIME_MS_3":"8003", + "TOTAL_PAUSE_TRANSITIONS_4": "84", + "TOTAL_PAUSE_TIME_MS_4":"80004", + "RECENT_PAUSE_TIMESTAMP_4":"8000000000004", + "RECENT_PAUSE_TIME_MS_4":"8004", + "TOTAL_PAUSE_TRANSITIONS_5": "85", + "TOTAL_PAUSE_TIME_MS_5":"80005", + "RECENT_PAUSE_TIMESTAMP_5":"8000000000005", + "RECENT_PAUSE_TIME_MS_5":"8005", + "TOTAL_PAUSE_TRANSITIONS_6": "86", + "TOTAL_PAUSE_TIME_MS_6":"80006", + "RECENT_PAUSE_TIMESTAMP_6":"8000000000006", + "RECENT_PAUSE_TIME_MS_6":"8006", + "TOTAL_PAUSE_TRANSITIONS_7": "87", + "TOTAL_PAUSE_TIME_MS_7":"80007", + "RECENT_PAUSE_TIMESTAMP_7":"8000000000007", + "RECENT_PAUSE_TIME_MS_7":"8007" + }, "USER_WATERMARKS:oid:0x1a00000000034f": { "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES": "100", "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES": "100" diff --git a/tests/pfcstat_test.py b/tests/pfcstat_test.py index 23d184cc36..959884af83 100644 --- a/tests/pfcstat_test.py +++ b/tests/pfcstat_test.py @@ -28,6 +28,38 @@ Ethernet8 1,810 811 812 813 814 815 816 817 """ +show_pfc_counters_history_output = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +--------- ---------- ---------------------- ------------------------ ------------------------- --------------------------- +Ethernet0 PFC0 12 12,000 1,200 01/10/2008, 21:20:00 +Ethernet0 PFC1 21 20,001 2,001 05/18/2033, 03:33:20 +Ethernet0 PFC2 22 20,002 2,002 05/18/2033, 03:33:20 +Ethernet0 PFC3 23 20,003 2,003 05/18/2033, 03:33:20 +Ethernet0 PFC4 24 20,004 2,004 05/18/2033, 03:33:20 +Ethernet0 PFC5 25 20,005 2,005 05/18/2033, 03:33:20 +Ethernet0 PFC6 26 20,006 2,006 05/18/2033, 03:33:20 +Ethernet0 PFC7 27 20,007 2,007 05/18/2033, 03:33:20 + +Ethernet4 PFC0 14 14,000 1,400 05/13/2014, 16:53:20 +Ethernet4 PFC1 41 40,001 4,001 10/02/2096, 07:06:40 +Ethernet4 PFC2 42 40,002 4,002 10/02/2096, 07:06:40 +Ethernet4 PFC3 43 40,003 4,003 10/02/2096, 07:06:40 +Ethernet4 PFC4 44 40,004 4,004 10/02/2096, 07:06:40 +Ethernet4 PFC5 45 40,005 4,005 10/02/2096, 07:06:40 +Ethernet4 PFC6 46 40,006 4,006 10/02/2096, 07:06:40 +Ethernet4 PFC7 47 40,007 4,007 10/02/2096, 07:06:40 + +Ethernet8 PFC0 18 18,000 1,800 01/15/2027, 08:00:00 +Ethernet8 PFC1 81 80,001 8,001 07/06/2223, 14:13:20 +Ethernet8 PFC2 82 80,002 8,002 07/06/2223, 14:13:20 +Ethernet8 PFC3 83 80,003 8,003 07/06/2223, 14:13:20 +Ethernet8 PFC4 84 80,004 8,004 07/06/2223, 14:13:20 +Ethernet8 PFC5 85 80,005 8,005 07/06/2223, 14:13:20 +Ethernet8 PFC6 86 80,006 8,006 07/06/2223, 14:13:20 +Ethernet8 PFC7 87 80,007 8,007 07/06/2223, 14:13:20 + +""" + show_pfc_counters_output_with_clear = ["""\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 --------- ------ ------ ------ ------ ------ ------ ------ ------ @@ -42,6 +74,38 @@ Ethernet8 0 0 0 0 0 0 0 0 """] +show_pfc_counters_history_output_with_clear = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +--------- ---------- ---------------------- ------------------------ ------------------------- --------------------------- +Ethernet0 PFC0 0 0 1,200 01/10/2008, 21:20:00 +Ethernet0 PFC1 0 0 2,001 05/18/2033, 03:33:20 +Ethernet0 PFC2 0 0 2,002 05/18/2033, 03:33:20 +Ethernet0 PFC3 0 0 2,003 05/18/2033, 03:33:20 +Ethernet0 PFC4 0 0 2,004 05/18/2033, 03:33:20 +Ethernet0 PFC5 0 0 2,005 05/18/2033, 03:33:20 +Ethernet0 PFC6 0 0 2,006 05/18/2033, 03:33:20 +Ethernet0 PFC7 0 0 2,007 05/18/2033, 03:33:20 + +Ethernet4 PFC0 0 0 1,400 05/13/2014, 16:53:20 +Ethernet4 PFC1 0 0 4,001 10/02/2096, 07:06:40 +Ethernet4 PFC2 0 0 4,002 10/02/2096, 07:06:40 +Ethernet4 PFC3 0 0 4,003 10/02/2096, 07:06:40 +Ethernet4 PFC4 0 0 4,004 10/02/2096, 07:06:40 +Ethernet4 PFC5 0 0 4,005 10/02/2096, 07:06:40 +Ethernet4 PFC6 0 0 4,006 10/02/2096, 07:06:40 +Ethernet4 PFC7 0 0 4,007 10/02/2096, 07:06:40 + +Ethernet8 PFC0 0 0 1,800 01/15/2027, 08:00:00 +Ethernet8 PFC1 0 0 8,001 07/06/2223, 14:13:20 +Ethernet8 PFC2 0 0 8,002 07/06/2223, 14:13:20 +Ethernet8 PFC3 0 0 8,003 07/06/2223, 14:13:20 +Ethernet8 PFC4 0 0 8,004 07/06/2223, 14:13:20 +Ethernet8 PFC5 0 0 8,005 07/06/2223, 14:13:20 +Ethernet8 PFC6 0 0 8,006 07/06/2223, 14:13:20 +Ethernet8 PFC7 0 0 8,007 07/06/2223, 14:13:20 + +""" + show_pfc_counters_output_diff = """\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 --------- ------ ------ ------ ------ ------ ------ ------ ------ @@ -76,6 +140,65 @@ Ethernet-BP260 N/A N/A N/A N/A N/A N/A N/A N/A """ +show_pfc_counters_history_all = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +-------------- ---------- ---------------------- ------------------------ ------------------------- --------------------------- + Ethernet0 PFC0 12 12,000 1,200 01/10/2008, 21:20:00 + Ethernet0 PFC1 21 20,001 2,001 05/18/2033, 03:33:20 + Ethernet0 PFC2 22 20,002 2,002 05/18/2033, 03:33:20 + Ethernet0 PFC3 23 20,003 2,003 05/18/2033, 03:33:20 + Ethernet0 PFC4 24 20,004 2,004 05/18/2033, 03:33:20 + Ethernet0 PFC5 25 20,005 2,005 05/18/2033, 03:33:20 + Ethernet0 PFC6 26 20,006 2,006 05/18/2033, 03:33:20 + Ethernet0 PFC7 27 20,007 2,007 05/18/2033, 03:33:20 + + Ethernet4 PFC0 14 14,000 1,400 05/13/2014, 16:53:20 + Ethernet4 PFC1 41 40,001 4,001 10/02/2096, 07:06:40 + Ethernet4 PFC2 42 40,002 4,002 10/02/2096, 07:06:40 + Ethernet4 PFC3 43 40,003 4,003 10/02/2096, 07:06:40 + Ethernet4 PFC4 44 40,004 4,004 10/02/2096, 07:06:40 + Ethernet4 PFC5 45 40,005 4,005 10/02/2096, 07:06:40 + Ethernet4 PFC6 46 40,006 4,006 10/02/2096, 07:06:40 + Ethernet4 PFC7 47 40,007 4,007 10/02/2096, 07:06:40 + + Ethernet-BP0 PFC0 16 16,000 1,600 09/13/2020, 12:26:40 + Ethernet-BP0 PFC1 61 60,001 6,001 02/18/2160, 10:40:00 + Ethernet-BP0 PFC2 62 60,002 6,002 02/18/2160, 10:40:00 + Ethernet-BP0 PFC3 63 60,003 6,003 02/18/2160, 10:40:00 + Ethernet-BP0 PFC4 64 60,004 6,004 02/18/2160, 10:40:00 + Ethernet-BP0 PFC5 65 60,005 6,005 02/18/2160, 10:40:00 + Ethernet-BP0 PFC6 66 60,006 6,006 02/18/2160, 10:40:00 + Ethernet-BP0 PFC7 67 60,007 6,007 02/18/2160, 10:40:00 + + Ethernet-BP4 PFC0 18 18,000 1,800 01/15/2027, 08:00:00 + Ethernet-BP4 PFC1 81 80,001 8,001 07/06/2223, 14:13:20 + Ethernet-BP4 PFC2 82 80,002 8,002 07/06/2223, 14:13:20 + Ethernet-BP4 PFC3 83 80,003 8,003 07/06/2223, 14:13:20 + Ethernet-BP4 PFC4 84 80,004 8,004 07/06/2223, 14:13:20 + Ethernet-BP4 PFC5 85 80,005 8,005 07/06/2223, 14:13:20 + Ethernet-BP4 PFC6 86 80,006 8,006 07/06/2223, 14:13:20 + Ethernet-BP4 PFC7 87 80,007 8,007 07/06/2223, 14:13:20 + +Ethernet-BP256 PFC0 N/A N/A N/A N/A +Ethernet-BP256 PFC1 N/A N/A N/A N/A +Ethernet-BP256 PFC2 N/A N/A N/A N/A +Ethernet-BP256 PFC3 N/A N/A N/A N/A +Ethernet-BP256 PFC4 N/A N/A N/A N/A +Ethernet-BP256 PFC5 N/A N/A N/A N/A +Ethernet-BP256 PFC6 N/A N/A N/A N/A +Ethernet-BP256 PFC7 N/A N/A N/A N/A + +Ethernet-BP260 PFC0 N/A N/A N/A N/A +Ethernet-BP260 PFC1 N/A N/A N/A N/A +Ethernet-BP260 PFC2 N/A N/A N/A N/A +Ethernet-BP260 PFC3 N/A N/A N/A N/A +Ethernet-BP260 PFC4 N/A N/A N/A N/A +Ethernet-BP260 PFC5 N/A N/A N/A N/A +Ethernet-BP260 PFC6 N/A N/A N/A N/A +Ethernet-BP260 PFC7 N/A N/A N/A N/A + +""" + show_pfc_counters_all_with_clear = ["""\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 -------------- ------ ------ ------ ------ ------ ------ ------ ------ @@ -96,6 +219,65 @@ Ethernet-BP260 0 0 0 0 0 0 0 0 """] +show_pfc_counters_history_all_with_clear = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +-------------- ---------- ---------------------- ------------------------ ------------------------- --------------------------- + Ethernet0 PFC0 0 0 1,200 01/10/2008, 21:20:00 + Ethernet0 PFC1 0 0 2,001 05/18/2033, 03:33:20 + Ethernet0 PFC2 0 0 2,002 05/18/2033, 03:33:20 + Ethernet0 PFC3 0 0 2,003 05/18/2033, 03:33:20 + Ethernet0 PFC4 0 0 2,004 05/18/2033, 03:33:20 + Ethernet0 PFC5 0 0 2,005 05/18/2033, 03:33:20 + Ethernet0 PFC6 0 0 2,006 05/18/2033, 03:33:20 + Ethernet0 PFC7 0 0 2,007 05/18/2033, 03:33:20 + + Ethernet4 PFC0 0 0 1,400 05/13/2014, 16:53:20 + Ethernet4 PFC1 0 0 4,001 10/02/2096, 07:06:40 + Ethernet4 PFC2 0 0 4,002 10/02/2096, 07:06:40 + Ethernet4 PFC3 0 0 4,003 10/02/2096, 07:06:40 + Ethernet4 PFC4 0 0 4,004 10/02/2096, 07:06:40 + Ethernet4 PFC5 0 0 4,005 10/02/2096, 07:06:40 + Ethernet4 PFC6 0 0 4,006 10/02/2096, 07:06:40 + Ethernet4 PFC7 0 0 4,007 10/02/2096, 07:06:40 + + Ethernet-BP0 PFC0 0 0 1,600 09/13/2020, 12:26:40 + Ethernet-BP0 PFC1 0 0 6,001 02/18/2160, 10:40:00 + Ethernet-BP0 PFC2 0 0 6,002 02/18/2160, 10:40:00 + Ethernet-BP0 PFC3 0 0 6,003 02/18/2160, 10:40:00 + Ethernet-BP0 PFC4 0 0 6,004 02/18/2160, 10:40:00 + Ethernet-BP0 PFC5 0 0 6,005 02/18/2160, 10:40:00 + Ethernet-BP0 PFC6 0 0 6,006 02/18/2160, 10:40:00 + Ethernet-BP0 PFC7 0 0 6,007 02/18/2160, 10:40:00 + + Ethernet-BP4 PFC0 0 0 1,800 01/15/2027, 08:00:00 + Ethernet-BP4 PFC1 0 0 8,001 07/06/2223, 14:13:20 + Ethernet-BP4 PFC2 0 0 8,002 07/06/2223, 14:13:20 + Ethernet-BP4 PFC3 0 0 8,003 07/06/2223, 14:13:20 + Ethernet-BP4 PFC4 0 0 8,004 07/06/2223, 14:13:20 + Ethernet-BP4 PFC5 0 0 8,005 07/06/2223, 14:13:20 + Ethernet-BP4 PFC6 0 0 8,006 07/06/2223, 14:13:20 + Ethernet-BP4 PFC7 0 0 8,007 07/06/2223, 14:13:20 + +Ethernet-BP256 PFC0 N/A N/A N/A N/A +Ethernet-BP256 PFC1 N/A N/A N/A N/A +Ethernet-BP256 PFC2 N/A N/A N/A N/A +Ethernet-BP256 PFC3 N/A N/A N/A N/A +Ethernet-BP256 PFC4 N/A N/A N/A N/A +Ethernet-BP256 PFC5 N/A N/A N/A N/A +Ethernet-BP256 PFC6 N/A N/A N/A N/A +Ethernet-BP256 PFC7 N/A N/A N/A N/A + +Ethernet-BP260 PFC0 N/A N/A N/A N/A +Ethernet-BP260 PFC1 N/A N/A N/A N/A +Ethernet-BP260 PFC2 N/A N/A N/A N/A +Ethernet-BP260 PFC3 N/A N/A N/A N/A +Ethernet-BP260 PFC4 N/A N/A N/A N/A +Ethernet-BP260 PFC5 N/A N/A N/A N/A +Ethernet-BP260 PFC6 N/A N/A N/A N/A +Ethernet-BP260 PFC7 N/A N/A N/A N/A + +""" + show_pfc_counters_all_asic = """\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 ------------ ------ ------ ------ ------ ------ ------ ------ ------ @@ -111,6 +293,48 @@ Ethernet-BP0 1,610 611 612 613 614 615 616 617 Ethernet-BP4 1,810 811 812 813 814 815 816 817 """ + +show_pfc_counters_history_all_asic = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +------------ ---------- ---------------------- ------------------------ ------------------------- --------------------------- + Ethernet0 PFC0 12 12,000 1,200 01/10/2008, 21:20:00 + Ethernet0 PFC1 21 20,001 2,001 05/18/2033, 03:33:20 + Ethernet0 PFC2 22 20,002 2,002 05/18/2033, 03:33:20 + Ethernet0 PFC3 23 20,003 2,003 05/18/2033, 03:33:20 + Ethernet0 PFC4 24 20,004 2,004 05/18/2033, 03:33:20 + Ethernet0 PFC5 25 20,005 2,005 05/18/2033, 03:33:20 + Ethernet0 PFC6 26 20,006 2,006 05/18/2033, 03:33:20 + Ethernet0 PFC7 27 20,007 2,007 05/18/2033, 03:33:20 + + Ethernet4 PFC0 14 14,000 1,400 05/13/2014, 16:53:20 + Ethernet4 PFC1 41 40,001 4,001 10/02/2096, 07:06:40 + Ethernet4 PFC2 42 40,002 4,002 10/02/2096, 07:06:40 + Ethernet4 PFC3 43 40,003 4,003 10/02/2096, 07:06:40 + Ethernet4 PFC4 44 40,004 4,004 10/02/2096, 07:06:40 + Ethernet4 PFC5 45 40,005 4,005 10/02/2096, 07:06:40 + Ethernet4 PFC6 46 40,006 4,006 10/02/2096, 07:06:40 + Ethernet4 PFC7 47 40,007 4,007 10/02/2096, 07:06:40 + +Ethernet-BP0 PFC0 16 16,000 1,600 09/13/2020, 12:26:40 +Ethernet-BP0 PFC1 61 60,001 6,001 02/18/2160, 10:40:00 +Ethernet-BP0 PFC2 62 60,002 6,002 02/18/2160, 10:40:00 +Ethernet-BP0 PFC3 63 60,003 6,003 02/18/2160, 10:40:00 +Ethernet-BP0 PFC4 64 60,004 6,004 02/18/2160, 10:40:00 +Ethernet-BP0 PFC5 65 60,005 6,005 02/18/2160, 10:40:00 +Ethernet-BP0 PFC6 66 60,006 6,006 02/18/2160, 10:40:00 +Ethernet-BP0 PFC7 67 60,007 6,007 02/18/2160, 10:40:00 + +Ethernet-BP4 PFC0 18 18,000 1,800 01/15/2027, 08:00:00 +Ethernet-BP4 PFC1 81 80,001 8,001 07/06/2223, 14:13:20 +Ethernet-BP4 PFC2 82 80,002 8,002 07/06/2223, 14:13:20 +Ethernet-BP4 PFC3 83 80,003 8,003 07/06/2223, 14:13:20 +Ethernet-BP4 PFC4 84 80,004 8,004 07/06/2223, 14:13:20 +Ethernet-BP4 PFC5 85 80,005 8,005 07/06/2223, 14:13:20 +Ethernet-BP4 PFC6 86 80,006 8,006 07/06/2223, 14:13:20 +Ethernet-BP4 PFC7 87 80,007 8,007 07/06/2223, 14:13:20 + +""" + show_pfc_counters_all = """\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 -------------- ------ ------ ------ ------ ------ ------ ------ ------ @@ -143,6 +367,29 @@ Ethernet4 1,410 411 412 413 414 415 416 417 """ +show_pfc_counters_history_asic0_frontend = """\ + Port Priority RX Pause Transitions Total RX Pause Time MS Recent RX Pause Time MS Recent RX Pause Timestamp +--------- ---------- ---------------------- ------------------------ ------------------------- --------------------------- +Ethernet0 PFC0 12 12,000 1,200 01/10/2008, 21:20:00 +Ethernet0 PFC1 21 20,001 2,001 05/18/2033, 03:33:20 +Ethernet0 PFC2 22 20,002 2,002 05/18/2033, 03:33:20 +Ethernet0 PFC3 23 20,003 2,003 05/18/2033, 03:33:20 +Ethernet0 PFC4 24 20,004 2,004 05/18/2033, 03:33:20 +Ethernet0 PFC5 25 20,005 2,005 05/18/2033, 03:33:20 +Ethernet0 PFC6 26 20,006 2,006 05/18/2033, 03:33:20 +Ethernet0 PFC7 27 20,007 2,007 05/18/2033, 03:33:20 + +Ethernet4 PFC0 14 14,000 1,400 05/13/2014, 16:53:20 +Ethernet4 PFC1 41 40,001 4,001 10/02/2096, 07:06:40 +Ethernet4 PFC2 42 40,002 4,002 10/02/2096, 07:06:40 +Ethernet4 PFC3 43 40,003 4,003 10/02/2096, 07:06:40 +Ethernet4 PFC4 44 40,004 4,004 10/02/2096, 07:06:40 +Ethernet4 PFC5 45 40,005 4,005 10/02/2096, 07:06:40 +Ethernet4 PFC6 46 40,006 4,006 10/02/2096, 07:06:40 +Ethernet4 PFC7 47 40,007 4,007 10/02/2096, 07:06:40 + +""" + show_pfc_counters_msaic_output_diff = """\ Port Rx PFC0 PFC1 PFC2 PFC3 PFC4 PFC5 PFC6 PFC7 -------------- ------ ------ ------ ------ ------ ------ ------ ------ @@ -169,7 +416,7 @@ def del_cached_stats(): cache.remove_all() -def pfc_clear(expected_output): +def pfc_clear(expected_output, pfc_stat_show_args=[]): counters_file_list = ['0tx', '0rx'] del_cached_stats() @@ -178,7 +425,7 @@ def pfc_clear(expected_output): ) return_code, result = get_result_and_return_code( - ['pfcstat', '-s', 'all'] + ['pfcstat', '-s', 'all'] + pfc_stat_show_args ) result_stat = [s for s in result.split("\n") if "Last cached" not in s] expected = expected_output.split("\n") @@ -196,6 +443,9 @@ def setup_class(cls): os.environ["UTILITIES_UNIT_TESTING"] = "2" del_cached_stats() + def setup_method(self, method): + del_cached_stats() + def test_pfc_counters(self): runner = CliRunner() result = runner.invoke( @@ -224,6 +474,34 @@ def test_pfc_counters_with_clear(self): def test_pfc_clear(self): pfc_clear(show_pfc_counters_output_diff) + + def test_pfc_counters_history(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["pfc"].commands["counters"], + ["--history"] + ) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_pfc_counters_history_output + + def test_pfc_counters_history_with_clear(self): + runner = CliRunner() + result = runner.invoke(clear.cli.commands['pfccounters'], []) + assert result.exit_code == 0 + result = runner.invoke( + show.cli.commands["pfc"].commands["counters"], + ["--history"] + ) + print(result.output) + show.run_command(['pfcstat', '-d']) + assert result.exit_code == 0 + assert "Last cached time was" in result.output + assert show_pfc_counters_history_output_with_clear in result.output + + def test_pfc_history_clear(self): + pfc_clear(show_pfc_counters_history_output_with_clear, ["--history"]) + @classmethod def teardown_class(cls): print("TEARDOWN") @@ -244,6 +522,9 @@ def setup_class(cls): os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" del_cached_stats() + def setup_method(self, method): + del_cached_stats() + def test_pfc_counters_all(self): runner = CliRunner() result = runner.invoke( @@ -292,6 +573,54 @@ def test_pfc_counters_asic_all(self): def test_masic_pfc_clear(self): pfc_clear(show_pfc_counters_msaic_output_diff) + def test_pfc_counters_history_all(self): + runner = CliRunner() + result = runner.invoke( + show.cli.commands["pfc"].commands["counters"], + ["--history"] + ) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_pfc_counters_history_all + + def test_pfc_counters_history_all_with_clear(self): + runner = CliRunner() + result = runner.invoke(clear.cli.commands['pfccounters'], []) + assert result.exit_code == 0 + result = runner.invoke( + show.cli.commands["pfc"].commands["counters"], + ["--history"] + ) + print(result.output) + show.run_command(['pfcstat', '-d']) + assert result.exit_code == 0 + assert "Last cached time was" in result.output + assert show_pfc_counters_history_all_with_clear in result.output + + def test_pfc_counters_history_frontend(self): + return_code, result = get_result_and_return_code( + ['pfcstat', '-s', 'frontend', '--history'] + ) + assert return_code == 0 + assert result == show_pfc_counters_history_asic0_frontend + + def test_pfc_counters_history_asic(self): + return_code, result = get_result_and_return_code( + ['pfcstat', '-n', 'asic0', '--history'] + ) + assert return_code == 0 + assert result == show_pfc_counters_history_asic0_frontend + + def test_pfc_counters_history_asic_all(self): + return_code, result = get_result_and_return_code( + ['pfcstat', '-n', 'asic0', '-s', 'all', '--history'] + ) + assert return_code == 0 + assert result == show_pfc_counters_history_all_asic + + def test_masic_pfc_history_clear(self): + pfc_clear(show_pfc_counters_history_all_with_clear, ["--history"]) + @classmethod def teardown_class(cls): print("TEARDOWN") diff --git a/utilities_common/netstat.py b/utilities_common/netstat.py index e32e28c745..4006acd040 100755 --- a/utilities_common/netstat.py +++ b/utilities_common/netstat.py @@ -1,5 +1,6 @@ # network statistics utility functions # +import datetime import json STATUS_NA = 'N/A' @@ -80,6 +81,14 @@ def format_number_with_comma(number_in_str): else: return number_in_str +def format_ms_as_datetime(number_in_str): + """ + Format the number of milliseconds since epoch to a date. + """ + if number_in_str.isdecimal(): + return datetime.datetime.fromtimestamp(int(number_in_str)/1000).strftime("%m/%d/%Y, %H:%M:%S") + else: + return number_in_str def format_brate(rate): """