diff --git a/dump/plugins/fdb.py b/dump/plugins/fdb.py new file mode 100644 index 000000000000..c08b8d592ebc --- /dev/null +++ b/dump/plugins/fdb.py @@ -0,0 +1,96 @@ +from dump.match_infra import MatchRequest +from dump.helper import create_template_dict +from .executor import Executor + + +class Fdb(Executor): + """ + Debug Dump Plugin for FDB Module + """ + ARG_NAME = "Vlan:fdb_entry" + + def __init__(self, match_engine=None): + super().__init__(match_engine) + + def get_all_args(self, ns=""): + req = MatchRequest(db="STATE_DB", table="FDB_TABLE", key_pattern="*", ns=ns) + ret = self.match_engine.fetch(req) + fdb_entries = ret["keys"] + return [key.split("|")[-1] for key in fdb_entries] + + def execute(self, params): + self.ret_temp = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + fdb_entry = params[Fdb.ARG_NAME] + self.ns = params["namespace"] + self.init_fdb_appl_info(fdb_entry) + self.init_asic_fdb_info(fdb_entry) + self.init_state_fdb_info(fdb_entry) + return self.ret_temp + + def init_state_fdb_info(self, fdb_name): + req = MatchRequest(db="STATE_DB", table="FDB_TABLE", key_pattern=fdb_name, ns=self.ns) + ret = self.match_engine.fetch(req) + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) + + def init_fdb_appl_info(self, fdb_name): + req = MatchRequest(db="APPL_DB", table="FDB_TABLE", key_pattern=fdb_name, ns=self.ns) + ret = self.match_engine.fetch(req) + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) + req = MatchRequest(db="APPL_DB", table="VXLAN_FDB_TABLE", key_pattern=fdb_name, ns=self.ns) + ret = self.match_engine.fetch(req) + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) + req = MatchRequest(db="APPL_DB", table="MCLAG_FDB_TABLE", key_pattern=fdb_name, ns=self.ns) + ret = self.match_engine.fetch(req) + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) + + def init_asic_fdb_info(self, fdb_name): + # One colon between Vlan and MAC and 5 colons in mac address are expected in key + if fdb_name.count(':') != 6: + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + return + + key_split = fdb_name.split(":",1) + vlan_name = key_split[0] + mac = key_split[1] + if vlan_name[0:4] != "Vlan" or not vlan_name[4:].isnumeric(): + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + return + + vlan_num = int(vlan_name[4:]) + # Find the table named "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:*" in which SAI_VLAN_AT'TR_VLAN_ID = vlan_num + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_VLAN", key_pattern="*", field="SAI_VLAN_ATTR_VLAN_ID", + value=str(vlan_num), ns=self.ns) + ret = self.match_engine.fetch(req) + if not ret["error"] and len(ret["keys"]) == 1: + vlan_obj = ret["keys"][0].split(":",2)[-1] + else: + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + return + + # ASIC_DB FDB format is bvid:vlan_obj + mac:mac_address + switch id which is wildcard here + fdb_key = '{"bvid":"' + vlan_obj + '","mac":"' + mac.upper() + '"*}' + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", key_pattern=fdb_key, + return_fields=["SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"], ns=self.ns) + ret = self.match_engine.fetch(req) + bridge_port_id = "" + if not ret["error"] and len(ret["keys"]) != 0: + asic_fdb_key = ret["keys"][0] + if asic_fdb_key in ret["return_values"] and "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" in ret["return_values"][asic_fdb_key]: + bridge_port_id = ret["return_values"][asic_fdb_key]["SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"] + else: + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + + if bridge_port_id: + bridge_port_req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT", + key_pattern = bridge_port_id, ns = self.ns) + bridge_ret = self.match_engine.fetch(bridge_port_req) + if not bridge_ret["error"] and len(bridge_ret["keys"]) != 0: + self.ret_temp[bridge_port_req.db]["keys"].append(bridge_ret["keys"][0]) + else: + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + + + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) diff --git a/tests/dump_input/fdb/appl_db.json b/tests/dump_input/fdb/appl_db.json new file mode 100644 index 000000000000..84fcbee047a0 --- /dev/null +++ b/tests/dump_input/fdb/appl_db.json @@ -0,0 +1,15 @@ +{ + "FDB_TABLE:Vlan10:04:3f:72:ce:80:8b":{ + "port" : "Ethernet252", + "type" : "static" + }, + "VXLAN_FDB_TABLE:Vlan10:04:3f:72:ce:80:8c":{ + "port" : "Ethernet252", + "type" : "dynamic", + "end_point_ip" : "192.234.11.233" + }, + "MCLAG_FDB_TABLE:Vlan10:04:3f:72:ce:80:8d":{ + "port" : "Ethernet252", + "type" : "dynamic" + } +} diff --git a/tests/dump_input/fdb/asic_db.json b/tests/dump_input/fdb/asic_db.json new file mode 100644 index 000000000000..ab20768c44b8 --- /dev/null +++ b/tests/dump_input/fdb/asic_db.json @@ -0,0 +1,48 @@ +{ + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d22\",\"mac\":\"04:3F:72:E3:70:08\",\"switch_id\":\"oid:0x21000000000000\"}":{ + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" : "oid:0x3a000000000d23", + "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:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8B\",\"switch_id\":\"oid:0x21000000000000\"}":{ + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" : "oid:0x3a000000000d18", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_STATIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION" : "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8C\",\"switch_id\":\"oid:0x21000000000000\"}":{ + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" : "oid:0x3a000000000d18", + "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:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8D\",\"switch_id\":\"oid:0x21000000000000\"}":{ + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" : "oid:0x3a000000000d18", + "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:0x26000000000d1c\",\"mac\":\"04:3F:72:CE:80:8B\",\"switch_id\":\"oid:0x21000000000000\"}":{ + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" : "oid:0x3a000000000d55", + "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:0x26000000000d22": { + "SAI_VLAN_ATTR_VLAN_ID" : "50" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x26000000000d20": { + "SAI_VLAN_ATTR_VLAN_ID" : "10" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x26000000000d1c": { + "SAI_VLAN_ATTR_VLAN_ID" : "690" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000d23":{ + "SAI_BRIDGE_PORT_ATTR_TYPE" : "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x100000000093e", + "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:0x3a000000000d18":{ + "SAI_BRIDGE_PORT_ATTR_TYPE" : "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x100000000053f", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE" : "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE" : "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + } +} diff --git a/tests/dump_input/fdb/state_db.json b/tests/dump_input/fdb/state_db.json new file mode 100644 index 000000000000..d24e65618fb2 --- /dev/null +++ b/tests/dump_input/fdb/state_db.json @@ -0,0 +1,30 @@ +{ + "FDB_TABLE|Vlan50:04:3f:72:e3:70:08":{ + "port" : "Ethernet0", + "type" : "dynamic" + }, + "FDB_TABLE|Vlan10:04:3f:72:ce:80:8b":{ + "port" : "Ethernet252", + "type" : "static" + }, + "FDB_TABLE|Vlan10:04:3f:72:ce:80:8c":{ + "port" : "Ethernet252", + "type" : "dynamic" + }, + "FDB_TABLE|Vlan10:04:3f:72:ce:80:8d":{ + "port" : "Ethernet252", + "type" : "dynamic" + }, + "FDB_TABLE|Vlan690:04:3f:72:ce:80:8b":{ + "port" : "Ethernet248", + "type" : "dynamic" + }, + "FDB_TABLE|Vlan40:04:3f:72:e3:70:09":{ + "port" : "PortChannel0002", + "type" : "dynamic" + }, + "FDB_TABLE|Vlan691:04:3f:72:ce:80:8b":{ + "port" : "Ethernet248", + "type" : "dynamic" + } +} diff --git a/tests/dump_tests/module_tests/fdb_test.py b/tests/dump_tests/module_tests/fdb_test.py new file mode 100644 index 000000000000..7e2e8b88ede5 --- /dev/null +++ b/tests/dump_tests/module_tests/fdb_test.py @@ -0,0 +1,227 @@ +import json +import os +import sys +import jsonpatch +import unittest +import pytest +from deepdiff import DeepDiff +from mock import patch +from dump.helper import create_template_dict, populate_mock +from dump.plugins.fdb import Fdb +from dump.match_infra import MatchEngine, ConnectionPool +from swsscommon.swsscommon import SonicV2Connector + +# Location for dedicated db's used for UT +module_tests_path = os.path.dirname(__file__) +dump_tests_path = os.path.join(module_tests_path, "../") +tests_path = os.path.join(dump_tests_path, "../") +dump_test_input = os.path.join(tests_path, "dump_input") +fdb_files_path = os.path.join(dump_test_input, "fdb") + +# Define the mock files to read from +dedicated_dbs = {} +dedicated_dbs['APPL_DB'] = os.path.join(fdb_files_path, "appl_db.json") +dedicated_dbs['ASIC_DB'] = os.path.join(fdb_files_path, "asic_db.json") +dedicated_dbs['STATE_DB'] = os.path.join(fdb_files_path, "state_db.json") + + + +@pytest.fixture(scope="class", autouse=True) +def match_engine(): + + print("SETUP") + os.environ["VERBOSE"] = "1" + + # Monkey Patch the SonicV2Connector Object + from ...mock_tables import dbconnector + db = SonicV2Connector() + + # popualate the db with mock data + db_names = list(dedicated_dbs.keys()) + try: + populate_mock(db, db_names, dedicated_dbs) + except Exception as e: + assert False, "Mock initialization failed: " + str(e) + + # Initialize connection pool + conn_pool = ConnectionPool() + DEF_NS = '' # Default Namespace + conn_pool.cache = {DEF_NS: {'conn': db, + 'connected_to': set(db_names)}} + + # Initialize match_engine + match_engine = MatchEngine(conn_pool) + yield match_engine + print("TEARDOWN") + os.environ["VERBOSE"] = "0" + + +@pytest.mark.usefixtures("match_engine") +class TestFdbModule: + def test_fdb_asic_learn_state(self, match_engine): + """ + Scenario: When FDB is learnt through hardware + """ + params = {Fdb.ARG_NAME: "Vlan50:04:3f:72:e3:70:08", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan50:04:3f:72:e3:70:08") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000d23") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d22\",\"mac\":\"04:3F:72:E3:70:08\",\"switch_id\":\"oid:0x21000000000000\"}") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_fdb_app_program_state(self, match_engine): + """ + Scenario: When FDB is learnt through EVPN + """ + params = {Fdb.ARG_NAME: "Vlan10:04:3f:72:ce:80:8b", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["APPL_DB"]["keys"].append("FDB_TABLE:Vlan10:04:3f:72:ce:80:8b") + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan10:04:3f:72:ce:80:8b") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000d18") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8B\",\"switch_id\":\"oid:0x21000000000000\"}") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_fdb_evpn_learn_state(self, match_engine): + """ + Scenario: When FDB is learnt through EVPN + """ + params = {Fdb.ARG_NAME: "Vlan10:04:3f:72:ce:80:8c", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["APPL_DB"]["keys"].append("VXLAN_FDB_TABLE:Vlan10:04:3f:72:ce:80:8c") + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan10:04:3f:72:ce:80:8c") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000d18") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8C\",\"switch_id\":\"oid:0x21000000000000\"}") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_fdb_mclag_sync_state(self, match_engine): + """ + Scenario: When FDB is learnt through EVPN + """ + params = {Fdb.ARG_NAME: "Vlan10:04:3f:72:ce:80:8d", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["APPL_DB"]["keys"].append("MCLAG_FDB_TABLE:Vlan10:04:3f:72:ce:80:8d") + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan10:04:3f:72:ce:80:8d") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000d18") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d20\",\"mac\":\"04:3F:72:CE:80:8D\",\"switch_id\":\"oid:0x21000000000000\"}") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_missing_asic_bridgeport(self, match_engine): + """ + Scenario: When FDB is learnt through hardware but bridge port is missing + """ + params = {Fdb.ARG_NAME: "Vlan690:04:3f:72:ce:80:8b", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan690:04:3f:72:ce:80:8b") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["keys"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000d1c\",\"mac\":\"04:3F:72:CE:80:8B\",\"switch_id\":\"oid:0x21000000000000\"}") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_missing_asic_vlan(self, match_engine): + """ + Scenario: When FDB is learnt through hardware but vlan is missing + """ + params = {Fdb.ARG_NAME: "Vlan40:04:3f:72:e3:70:09", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan40:04:3f:72:e3:70:09") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_missing_asic(self, match_engine): + """ + Scenario: When FDB is learnt through hardware but asic db is deleted + """ + params = {Fdb.ARG_NAME: "Vlan691:04:3f:72:ce:80:8b", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["keys"].append("FDB_TABLE|Vlan691:04:3f:72:ce:80:8b") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_no_fdb(self, match_engine): + """ + Scenario: When no entry for the fdb is present in any of the db's + """ + params = {Fdb.ARG_NAME: "Vlan691:04:3f:72:ce:80:8c", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["tables_not_found"].append("FDB_TABLE") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_invalid_key(self, match_engine): + """ + Scenario: When invalid fdb key is given as input + """ + params = {Fdb.ARG_NAME: "012345abcdef", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["tables_not_found"].append("FDB_TABLE") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_invalid_mac(self, match_engine): + """ + Scenario: When invalid fdb key is given as input + """ + params = {Fdb.ARG_NAME: "Vlan690:012345abcdef", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["tables_not_found"].append("FDB_TABLE") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_invalid_vlan(self, match_engine): + """ + Scenario: When invalid fdb key is given as input + """ + params = {Fdb.ARG_NAME: "Vlan6900:04:3f:72:ce:80:8b", "namespace": ""} + m_fdb = Fdb(match_engine) + returned = m_fdb.execute(params) + expect = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) + expect["STATE_DB"]["tables_not_found"].append("FDB_TABLE") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") + expect["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") + ddiff = DeepDiff(returned, expect, ignore_order=True) + assert not ddiff, ddiff + + def test_all_args(self, match_engine): + """ + Scenario: Verify Whether the get_all_args method is working as expected + """ + params = {} + m_fdb = Fdb(match_engine) + returned = m_fdb.get_all_args("") + expect = ["Vlan50:04:3f:72:e3:70:08", "Vlan10:04:3f:72:ce:80:8b", "Vlan10:04:3f:72:ce:80:8c", "Vlan10:04:3f:72:ce:80:8d", "Vlan690:04:3f:72:ce:80:8b", "Vlan40:04:3f:72:e3:70:09", "Vlan691:04:3f:72:ce:80:8b"] + ddiff = DeepDiff(expect, returned, ignore_order=True) + assert not ddiff, ddiff