From d9f3afe5b34ef0f03f4137f607bc73bc625631ed Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Tue, 18 Jan 2022 10:01:01 -0800 Subject: [PATCH] [fdbshow] Adding more options for fdbshow and show mac (#1982) #### What I did Added more options to filter output in show mac and fdbshow command. Introduced options for filter by address and filter by type. Added one more option to display only count. Introduced show command to display fdb aging time in the switch. #### How I did it Modifying fdbshow and show scripts to include the above-mentioned options #### How to verify it Added UT for all the newly introduced options and commands #### Previous command output (if the output of a command-line utility has changed) ``` show mac -h Usage: show mac [OPTIONS] Show MAC (FDB) entries Options: -v, --vlan TEXT -p, --port TEXT --verbose Enable verbose output -h, -?, --help Show this message and exit. ``` #### New command output (if the output of a command-line utility has changed) ``` show mac -h Usage: show mac [OPTIONS] COMMAND [ARGS]... Show MAC (FDB) entries Options: -v, --vlan TEXT -p, --port TEXT -a, --address TEXT -t, --type TEXT -c, --count --verbose Enable verbose output -h, -?, --help Show this message and exit. Commands: aging-time show mac No. Vlan MacAddress Port Type ----- ------ ----------------- ----------- ------- 1 10 98:03:9B:82:BB:5B Ethernet60 Dynamic 2 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic 3 10 EC:0D:9A:CD:91:73 Ethernet124 Dynamic Total number of entries 3 show mac --address EC:0D:9A:CD:91:72 No. Vlan MacAddress Port Type ----- ------ ----------------- ---------- ------- 1 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic show mac --count Total number of entries 3 show mac --type Dynamic No. Vlan MacAddress Port Type ----- ------ ----------------- ----------- ------- 1 10 98:03:9B:82:BB:5B Ethernet60 Dynamic 2 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic 3 10 EC:0D:9A:CD:91:73 Ethernet124 Dynamic Total number of entries 3 show mac aging-time Aging time for switch is 600 seconds ``` --- doc/Command-Reference.md | 156 ++++---- scripts/fdbshow | 87 +++-- show/main.py | 38 +- tests/fdbshow_input/appl_db.json | 5 + tests/fdbshow_input/appl_db_no_age.json | 5 + tests/fdbshow_input/asic_db_mac_case.json | 20 + tests/fdbshow_input/asic_db_no_static.json | 65 ++++ tests/fdbshow_input/counters_db.json | 3 +- tests/fdbshow_test.py | 404 ++++++++++++++++++++- 9 files changed, 675 insertions(+), 108 deletions(-) create mode 100644 tests/fdbshow_input/appl_db.json create mode 100644 tests/fdbshow_input/appl_db_no_age.json create mode 100644 tests/fdbshow_input/asic_db_mac_case.json create mode 100644 tests/fdbshow_input/asic_db_no_static.json diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 294695a72de6..61955eab361a 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -8920,90 +8920,122 @@ This command displays the MAC (FDB) entries either in full or partial as given b 1) show mac - displays the full table 2) show mac -v - displays the MACs learnt on the particular VLAN ID. 3) show mac -p - displays the MACs learnt on the particular port. +4) show mac -a - display the MACs that match a specific mac-address +5) show mac -t - display the MACs that match a specific type (static/dynamic) +6) show mac -c - display the count of MAC addresses +To show the default MAC address aging time on the switch. - Usage: ``` - show mac [-v ] [-p ] + show mac [-v ] [-p ] [-a ] [-t ] [-c] ``` - Example: ``` admin@sonic:~$ show mac - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` -Optionally, you can specify a VLAN ID or interface name in order to display only that particular entries +Optionally, you can specify a VLAN ID or interface name or type or mac-address in order to display only that particular entries - Examples: ``` admin@sonic:~$ show mac -v 1000 - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` ``` admin@sonic:~$ show mac -p Ethernet192 - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` + ``` + admin@sonic:~$ show mac -a E2:8C:56:85:4A:CD + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + Total number of entries 1 + ``` + ``` + admin@sonic:~$ show mac -t Static + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 2 1000 50:96:23:AD:F1:65 Ethernet192 Static + 2 1000 C6:C9:5E:AE:24:42 Ethernet192 Static + Total number of entries 2 + ``` + ``` + admin@sonic:~$ show mac -c + Total number of entries 18 + ``` + +**show mac aging-time** + +This command displays the default mac aging time on the switch + + ``` + admin@sonic:~$ show mac aging-time + Aging time for switch is 600 seconds + ``` **sonic-clear fdb all** diff --git a/scripts/fdbshow b/scripts/fdbshow index 80fd908de662..cbf8b4039449 100755 --- a/scripts/fdbshow +++ b/scripts/fdbshow @@ -30,6 +30,7 @@ import argparse import json import sys import os +import re # mock the redis for unit test purposes # try: # pragma: no cover @@ -43,7 +44,9 @@ try: # pragma: no cover "2": 'asic_db_def_vlan', "3": 'asic_db_no_fdb', "4": 'asic_db_no_bridge', - "5": 'asic_db_fetch_except'} + "5": 'asic_db_fetch_except', + "6": 'asic_db_no_static', + "7": 'asic_db_mac_case'} mock_db_path = os.path.join(test_path, "fdbshow_input") file_name = mock_variants[os.environ["FDBSHOW_MOCK"]] jsonfile_asic = os.path.join(mock_db_path, file_name) @@ -53,7 +56,6 @@ try: # pragma: no cover except KeyError: # pragma: no cover pass -from natsort import natsorted from swsssdk import port_util from swsscommon.swsscommon import SonicV2Connector from tabulate import tabulate @@ -61,7 +63,6 @@ from tabulate import tabulate class FdbShow(object): HEADER = ['No.', 'Vlan', 'MacAddress', 'Port', 'Type'] - FDB_COUNT = 0 def __init__(self): super(FdbShow,self).__init__() @@ -135,18 +136,7 @@ class FdbShow(object): return - def get_iter_index(self, key_value, pos=0): - """ - Get the starting index of matched entry - """ - if pos != 0: - self.bridge_mac_list = natsorted(self.bridge_mac_list, key = lambda x: x[pos]) - - keys = [r[pos] for r in self.bridge_mac_list] - return keys.index(key_value) - - - def display(self, vlan, port): + def display(self, vlan, port, address, entry_type, count): """ Display the FDB entries for specified vlan/port. @todo: - PortChannel support @@ -154,22 +144,55 @@ class FdbShow(object): output = [] if vlan is not None: - vlan = int(vlan) - s_index = self.get_iter_index(vlan) - self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:] - if fdb[0] == vlan] - if port is not None: - s_index = self.get_iter_index(port, 2) - self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:] - if fdb[2] == port] + vlan_val = int(vlan) + + if address is not None: + address = address.upper() - for fdb in self.bridge_mac_list: - self.FDB_COUNT += 1 - output.append([self.FDB_COUNT, fdb[0], fdb[1], fdb[2], fdb[3]]) + if entry_type is not None: + entry_type = entry_type.capitalize() - print(tabulate(output, self.HEADER)) - print("Total number of entries {0}".format(self.FDB_COUNT)) + self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list + if (vlan is None or fdb[0] == vlan_val) and + (port is None or fdb[2] == port) and + (address is None or fdb[1] == address) and + (entry_type is None or fdb[3] == entry_type)] + if not count: + fdb_index = 1 + for fdb in self.bridge_mac_list: + output.append([fdb_index, fdb[0], fdb[1], fdb[2], fdb[3]]) + fdb_index += 1 + print(tabulate(output, self.HEADER)) + + print("Total number of entries {0}".format(len(self.bridge_mac_list))) + + def validate_params(self, vlan, port, address, entry_type): + if vlan is not None: + if not vlan.isnumeric(): + print("Error: Invalid vlan id {0}".format(vlan)) + return False + + vlan_val = int(vlan) + if (vlan_val not in range(1,4096)): + print("Error: Invalid vlan id {0}".format(vlan)) + return False + + if port is not None and port not in self.if_name_map: + print("Error: Invalid port {0}".format(port)) + return False + + if address is not None: + mac_addr_pattern ="^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$" + if not re.match(mac_addr_pattern, address): + print("Error: Invalid mac address {0}".format(address)) + return False + + if entry_type is not None and entry_type.capitalize() not in ["Static", "Dynamic"]: + print("Error: Invalid type {0}". format(entry_type)) + return False + + return True def main(): @@ -177,11 +200,17 @@ def main(): formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('-p', '--port', type=str, help='FDB learned on specific port: Ethernet0', default=None) parser.add_argument('-v', '--vlan', type=str, help='FDB learned on specific Vlan: 1001', default=None) + parser.add_argument('-a', '--address', type=str, help='FDB display based on specific mac address', default=None) + parser.add_argument('-t', '--type', type=str, help='FDB display of specific type of mac address', default=None) + parser.add_argument('-c', '--count', action='store_true', help='FDB display count of mac address') args = parser.parse_args() try: fdb = FdbShow() - fdb.display(args.vlan, args.port) + if not fdb.validate_params(args.vlan, args.port, args.address, args.type): + sys.exit(1) + + fdb.display(args.vlan, args.port, args.address, args.type, args.count) except Exception as e: print(str(e)) sys.exit(1) diff --git a/show/main.py b/show/main.py index d016b6fbc28a..528ad81e84a3 100755 --- a/show/main.py +++ b/show/main.py @@ -722,13 +722,20 @@ def pwm_headroom_pool(): # 'mac' command ("show mac ...") # -@cli.command() +@cli.group(cls=clicommon.AliasedGroup, invoke_without_command="true") +@click.pass_context @click.option('-v', '--vlan') @click.option('-p', '--port') +@click.option('-a', '--address') +@click.option('-t', '--type') +@click.option('-c', '--count', is_flag=True) @click.option('--verbose', is_flag=True, help="Enable verbose output") -def mac(vlan, port, verbose): +def mac(ctx, vlan, port, address, type, count, verbose): """Show MAC (FDB) entries""" + if ctx.invoked_subcommand is not None: + return + cmd = "fdbshow" if vlan is not None: @@ -737,8 +744,35 @@ def mac(vlan, port, verbose): if port is not None: cmd += " -p {}".format(port) + if address is not None: + cmd += " -a {}".format(address) + + if type is not None: + cmd += " -t {}".format(type) + + if count: + cmd += " -c" + run_command(cmd, display_cmd=verbose) +@mac.command('aging-time') +@click.pass_context +def aging_time(ctx): + app_db = SonicV2Connector() + app_db.connect(app_db.APPL_DB) + table = "SWITCH_TABLE*" + keys = app_db.keys(app_db.APPL_DB, table) + + if not keys: + click.echo("Aging time not configured for the switch") + return + + for key in keys: + fdb_aging_time = app_db.get(app_db.APPL_DB, key, 'fdb_aging_time') + if fdb_aging_time is not None: + click.echo("Aging time for {} is {} seconds".format(key.split(':')[-1], fdb_aging_time)) + else: + click.echo("Aging time not configured for the {}".format(key.split(':')[-1])) # # 'show route-map' command ("show route-map") # diff --git a/tests/fdbshow_input/appl_db.json b/tests/fdbshow_input/appl_db.json new file mode 100644 index 000000000000..d2e077a975fc --- /dev/null +++ b/tests/fdbshow_input/appl_db.json @@ -0,0 +1,5 @@ +{ + "SWITCH_TABLE:switch": { + "fdb_aging_time" : "600" + } +} diff --git a/tests/fdbshow_input/appl_db_no_age.json b/tests/fdbshow_input/appl_db_no_age.json new file mode 100644 index 000000000000..2465b3a4d983 --- /dev/null +++ b/tests/fdbshow_input/appl_db_no_age.json @@ -0,0 +1,5 @@ +{ + "SWITCH_TABLE:switch": { + "ecmp_hash_seed" : "600" + } +} diff --git a/tests/fdbshow_input/asic_db_mac_case.json b/tests/fdbshow_input/asic_db_mac_case.json new file mode 100644 index 000000000000..944de57621e6 --- /dev/null +++ b/tests/fdbshow_input/asic_db_mac_case.json @@ -0,0 +1,20 @@ +{ + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000005cb": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000528", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000005c5\",\"mac\":\"34:5F:78:9A:BC:DE\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000005c5": { + "SAI_VLAN_ATTR_VLAN_ID": "2" + } +} diff --git a/tests/fdbshow_input/asic_db_no_static.json b/tests/fdbshow_input/asic_db_no_static.json new file mode 100644 index 000000000000..528a9ec479f2 --- /dev/null +++ b/tests/fdbshow_input/asic_db_no_static.json @@ -0,0 +1,65 @@ +{ + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000005cb": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000528", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000006cd": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000549", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000007ef": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000fff", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000005c5\",\"mac\":\"11:22:33:44:55:66\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"66:55:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005ff", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"77:55:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a000000000fff", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"77:66:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000007ef", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"vlan\":\"5\",\"mac\":\"77:66:55:44:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000006cd", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"mac\":\"77:66:55:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000007ef", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000005c5": { + "SAI_VLAN_ATTR_VLAN_ID": "2" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000007c7": { + "SAI_VLAN_ATTR_VLAN_ID": "4" + } +} diff --git a/tests/fdbshow_input/counters_db.json b/tests/fdbshow_input/counters_db.json index acf46e0395b9..14da634911f5 100644 --- a/tests/fdbshow_input/counters_db.json +++ b/tests/fdbshow_input/counters_db.json @@ -1,7 +1,8 @@ { "COUNTERS_PORT_NAME_MAP": { "Ethernet0": "oid:0x1000000000528", - "Ethernet4": "oid:0x1000000000549" + "Ethernet4": "oid:0x1000000000549", + "Ethernet8": "oid:0x1000000000550" }, "COUNTERS_LAG_NAME_MAP": { "": "" diff --git a/tests/fdbshow_test.py b/tests/fdbshow_test.py index 3da84879f5ef..8814a6b323e5 100755 --- a/tests/fdbshow_test.py +++ b/tests/fdbshow_test.py @@ -18,6 +18,14 @@ Total number of entries 2 """ +show_mac_aging_time_output = """\ +Aging time for switch is 600 seconds +""" + +show_mac_aging_time_not_present_output = """\ +Aging time not configured for the switch +""" + show_mac_output = """\ No. Vlan MacAddress Port Type ----- ------ ----------------- ------------- ------- @@ -29,6 +37,10 @@ Total number of entries 5 """ +show_mac_count_output = """\ +Total number of entries 5 +""" + show_mac__port_vlan_output = """\ No. Vlan MacAddress Port Type ----- ------ ----------------- --------- ------- @@ -36,20 +48,99 @@ Total number of entries 1 """ +show_mac__address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__address_case_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 2 34:5F:78:9A:BC:DE Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__port_address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 4 66:55:44:33:22:11 Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__vlan_address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 4 66:55:44:33:22:11 Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__type_case_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- ------------- ------- + 1 2 11:22:33:44:55:66 Ethernet0 Dynamic + 2 4 66:55:44:33:22:11 Ethernet0 Dynamic + 3 4 77:66:44:33:22:11 1000000000fff Dynamic + 4 5 77:66:55:44:22:11 Ethernet4 Dynamic +Total number of entries 4 +""" + +show_mac__port_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__vlan_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__address_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__port_vlan_address_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + show_mac_no_results_output = """\ No. Vlan MacAddress Port Type ----- ------ ------------ ------ ------ Total number of entries 0 """ -show_mac_no_port_output = """\ -'Ethernet20' is not in list +show_mac_invalid_port_output= """\ +Error: Invalid port eth123 """ -show_mac_no_vlan_output = """\ -123 is not in list +show_mac_invalid_vlan_output= """\ +Error: Invalid vlan id 10000 """ +show_mac_invalid_type_output= """\ +Error: Invalid type both +""" +show_mac_invalid_address_output= """\ +Error: Invalid mac address 12:345:67:a9:bc:d +""" class TestFdbshow(): @pytest.fixture(scope="class", autouse=True) @@ -86,6 +177,36 @@ def test_show_mac_def_vlan(self): assert return_code == 0 assert result == show_mac_output_with_def_vlan + def test_show_mac_aging_time(self): + self.set_mock_variant("1") + from .mock_tables import dbconnector + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + mock_db_path = os.path.join(test_path, "fdbshow_input") + jsonfile_appl = os.path.join(mock_db_path, 'appl_db') + dbconnector.dedicated_dbs['APPL_DB'] = jsonfile_appl + result = self.runner.invoke(show.cli.commands["mac"].commands["aging-time"], []) + dbconnector.dedicated_dbs['APPL_DB'] = None + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_aging_time_output + + def test_show_mac_no_aging_time(self): + self.set_mock_variant("1") + from .mock_tables import dbconnector + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + mock_db_path = os.path.join(test_path, "fdbshow_input") + jsonfile_appl = os.path.join(mock_db_path, 'appl_db_no_age') + dbconnector.dedicated_dbs['APPL_DB'] = jsonfile_appl + result = self.runner.invoke(show.cli.commands["mac"].commands["aging-time"], []) + dbconnector.dedicated_dbs['APPL_DB'] = None + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_aging_time_not_present_output + def test_show_mac(self): self.set_mock_variant("1") @@ -101,6 +222,21 @@ def test_show_mac(self): assert return_code == 0 assert result == show_mac_output + def test_show_mac_count(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], ["-c"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_count_output + + return_code, result = get_result_and_return_code('fdbshow -c') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_count_output + def test_show_mac_port_vlan(self): self.set_mock_variant("1") @@ -116,20 +252,170 @@ def test_show_mac_port_vlan(self): assert return_code == 0 assert result == show_mac__port_vlan_output + def test_show_mac_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 11:22:33:66:55:44") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_output + + return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_output + + def test_show_mac_address_case(self): + self.set_mock_variant("7") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 34:5f:78:9a:bc:de") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_case_output + + return_code, result = get_result_and_return_code('fdbshow -a 34:5f:78:9a:bc:de') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_case_output + + def test_show_mac_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__type_output + + return_code, result = get_result_and_return_code('fdbshow -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__type_output + + def test_show_mac_type_case(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t dynamic") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__type_case_output + + return_code, result = get_result_and_return_code('fdbshow -t DYNAMIC') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__type_case_output + + def test_show_mac_port_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 66:55:44:33:22:11 -p Ethernet0") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -p Ethernet0') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_address_output + + def test_show_mac_vlan_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 66:55:44:33:22:11 -v 4") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__vlan_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -v 4') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__vlan_address_output + + def test_show_mac_port_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet4 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_type_output + + return_code, result = get_result_and_return_code('fdbshow -p Ethernet4 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_type_output + + def test_show_mac_vlan_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 3 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__vlan_type_output + + return_code, result = get_result_and_return_code('fdbshow -v 3 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__vlan_type_output + + def test_show_mac_address_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 11:22:33:66:55:44 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_type_output + + return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_type_output + + def test_show_mac_port_vlan_address_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 3 -p Ethernet4 -a 11:22:33:66:55:44 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_vlan_address_type_output + + return_code, result = get_result_and_return_code('fdbshow -v 3 -p Ethernet4 -a 11:22:33:66:55:44 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_vlan_address_type_output + def test_show_mac_no_port(self): self.set_mock_variant("1") - result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet20") + result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet8") print(result.exit_code) print(result.output) - assert result.exit_code == 1 - assert result.output == show_mac_no_port_output + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -p Ethernet20') + return_code, result = get_result_and_return_code('fdbshow -p Ethernet8') print("return_code: {}".format(return_code)) print("result = {}".format(result)) - assert return_code == 1 - assert result == show_mac_no_port_output.strip("\n") + assert return_code == 0 + assert result == show_mac_no_results_output def test_show_mac_no_vlan(self): self.set_mock_variant("1") @@ -137,14 +423,44 @@ def test_show_mac_no_vlan(self): result = self.runner.invoke(show.cli.commands["mac"], "-v 123") print(result.exit_code) print(result.output) - assert result.exit_code == 1 - assert result.output == show_mac_no_vlan_output + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output return_code, result = get_result_and_return_code('fdbshow -v 123') print("return_code: {}".format(return_code)) print("result = {}".format(result)) - assert return_code == 1 - assert result == show_mac_no_vlan_output.strip("\n") + assert return_code == 0 + assert result == show_mac_no_results_output + + def test_show_mac_no_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 12:34:56:78:9A:BC") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output + + return_code, result = get_result_and_return_code('fdbshow -a 12:34:56:78:9A:BC') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_no_results_output + + def test_show_mac_no_type(self): + self.set_mock_variant("6") + + result = self.runner.invoke(show.cli.commands["mac"], ["-t Static"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output + + return_code, result = get_result_and_return_code('fdbshow -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_no_results_output def test_show_mac_no_fdb(self): self.set_mock_variant("3") @@ -196,3 +512,63 @@ def test_show_fetch_except(self): print("result = {}".format(output)) assert return_code == 1 assert "Failed to get Vlan id for bvid oid:0x260000000007c7" in output + + def test_show_mac_invalid_port(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-p eth123") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_port_output + + return_code, result = get_result_and_return_code('fdbshow -p eth123') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_port_output.strip("\n") + + def test_show_mac_invalid_vlan(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 10000") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_vlan_output + + return_code, result = get_result_and_return_code('fdbshow -v 10000') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_vlan_output.strip("\n") + + def test_show_mac_invalid_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t both") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_type_output + + return_code, result = get_result_and_return_code('fdbshow -t both') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_type_output.strip("\n") + + def test_show_mac_invalid_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 12:345:67:a9:bc:d") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 12:345:67:a9:bc:d') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_address_output.strip("\n")