def __init__(self, db_id: int, connector: str, gearbox: Gearbox): DVSDatabase.__init__(self, db_id, connector) self.gearbox = gearbox self.ports = {} self._wait_for_gb_asic_db_to_initialize() for connector in self.get_keys( "ASIC_STATE:SAI_OBJECT_TYPE_PORT_CONNECTOR"): fvs = self.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_PORT_CONNECTOR", connector) system_port_oid = fvs.get( "SAI_PORT_CONNECTOR_ATTR_SYSTEM_SIDE_PORT_ID") line_port_oid = fvs.get( "SAI_PORT_CONNECTOR_ATTR_LINE_SIDE_PORT_ID") fvs = self.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_PORT", system_port_oid) system_lanes = fvs.get("SAI_PORT_ATTR_HW_LANE_LIST").split(":")[-1] fvs = self.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_PORT", line_port_oid) line_lanes = fvs.get("SAI_PORT_ATTR_HW_LANE_LIST").split(":")[-1] for i in self.gearbox.interfaces: intf = self.gearbox.interfaces[i] if intf["system_lanes"] == system_lanes: assert intf["line_lanes"] == line_lanes self.ports[intf["index"]] = (system_port_oid, line_port_oid) assert len(self.ports) == len(self.gearbox.interfaces)
def __init__(self, db_id: str, connector: str): DVSDatabase.__init__(self, db_id, connector) # Get default .1Q Vlan ID self.default_vlan_id = self.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_VLAN", 1)[0] # Build port OID to front port name mapping self.portoidmap = {} self.portnamemap = {} self.hostifoidmap = {} self.hostifnamemap = {} keys = self.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF", NUM_PORTS) for k in keys: fvs = self.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF", k) port_oid = fvs.get("SAI_HOSTIF_ATTR_OBJ_ID") port_name = fvs.get("SAI_HOSTIF_ATTR_NAME") self.portoidmap[port_oid] = port_name self.portnamemap[port_name] = port_oid self.hostifoidmap[k] = port_name self.hostifnamemap[port_name] = k # Get default ACL table and ACL rules self.default_acl_tables = self.get_keys( "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") assert len(self.default_acl_tables) >= 0 self.default_acl_entries = self.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY", 0)
def test_chassis_app_db_sync(self, vct): """Test chassis app db syncing. This test is for verifying the database sync mechanism. With the virtual chassis setup, it is verified that at least one database entry is synced from line card to supervisor card. An interface entry is used as sample database entry for verification of syncing mechanism. """ dvss = vct.dvss for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) keys = chassis_app_db.get_keys("SYSTEM_INTERFACE") assert len(keys), "No chassis app db syncing is done"
def get_asic_db(self): if not self.asic_db: db = DVSDatabase(self.ASIC_DB_ID, self.redis_sock) db.default_acl_tables = self.asicdb.default_acl_tables db.default_acl_entries = self.asicdb.default_acl_entries db.port_name_map = self.asicdb.portnamemap db.default_vlan_id = self.asicdb.default_vlan_id db.port_to_id_map = self.asicdb.portoidmap db.hostif_name_map = self.asicdb.hostifnamemap self.asic_db = db return self.asic_db
def test_GearboxCounter(self, dvs, gbasic, enable_port_counter, testlog): counters_db = DVSDatabase(swsscommon.COUNTERS_DB, dvs.redis_sock) gb_counters_db = DVSDatabase(swsscommon.GB_COUNTERS_DB, dvs.redis_sock) intf = gbasic.gearbox.interfaces["0"] port_oid = counters_db.get_entry("COUNTERS_PORT_NAME_MAP", "")[intf["name"]] system_port_oid, line_port_oid = gbasic.ports["0"] fvs = gb_counters_db.wait_for_entry("COUNTERS", system_port_oid) assert fvs.get("SAI_PORT_STAT_IF_OUT_ERRORS") fvs = gb_counters_db.wait_for_entry("COUNTERS", line_port_oid) assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS") fvs = counters_db.wait_for_entry("COUNTERS", port_oid) assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS") fvs = counters_db.wait_for_entry("COUNTERS", port_oid) assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS")
def set_lag_id_boundaries(self, vct): """This functions sets lag id boundaries in the chassis app db. In VOQ systems the lag id boundaries need to be set before configuring any PortChannels. The lag id boundaries are used by lag id allocator while adding a PortChannel to the asic db. Note: In real systems, the lag id boundries are taken from a platform specific file. For testing we assume the chassis capability with maximum 2 lags so that we can test the lag id allocator table full error with less number of PortChannel configuration """ dvss = vct.dvss for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) chassis_app_db.db_connection.set("SYSTEM_LAG_ID_START", "1") chassis_app_db.db_connection.set("SYSTEM_LAG_ID_END", "2") break
def test_chassis_system_neigh(self, vct): """Test neigh record creation and syncing to chassis app db. This test validates that: (i) Local neighbor entry is created with encap index (ii) Local neighbor is synced to chassis ap db with assigned encap index TODO: (iii) Remote neighbor entry is created in ASIC_DB with received encap index """ dvss = vct.dvss print("name {}".format(dvss.keys())) for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # Neighbor record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id == "0": # Add a static neighbor _, res = dvs.runcmd(['sh', "-c", "ip neigh show"]) _, res = dvs.runcmd([ 'sh', "-c", "ip neigh add 10.8.101.2 lladdr 00:01:02:03:04:05 dev Ethernet0" ]) assert res == "", "Error configuring static neigh" asic_db = dvs.get_asic_db() asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", 1) neighkeys = asic_db.get_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY") assert len(neighkeys), "No neigh entries in ASIC_DB" # Check for presence of the neighbor in ASIC_DB test_neigh = "" for nkey in neighkeys: ne = ast.literal_eval(nkey) if ne['ip'] == '10.8.101.2': test_neigh = nkey break assert test_neigh != "", "Neigh not found in ASIC_DB" # Check for presence of encap index, retrieve and store it for sync verification test_neigh_entry = asic_db.wait_for_entry( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_neigh) test_neigh_entry_attrs = asic_db.wait_for_fields( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_neigh, ["SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX"]) print(test_neigh) print(test_neigh_entry) print(test_neigh_entry_attrs) encap_index = test_neigh_entry_attrs[ "SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX"] assert encap_index != "" and encap_index != None, "VOQ encap index is not programmed in ASIC_DB" break # Verify neighbor record syncing with encap index dvss = vct.dvss for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) chassis_app_db.wait_for_n_keys("SYSTEM_NEIGH", 1) sysneighkeys = chassis_app_db.get_keys("SYSTEM_NEIGH") print(sysneighkeys) test_sysneigh = "" for sysnk in sysneighkeys: sysnk_tok = sysnk.split("|") assert len( sysnk_tok ) == 3, "Invalid system neigh key in chassis app db" if sysnk_tok[2] == "10.8.101.2": test_sysneigh = sysnk break assert test_sysneigh != "", "Neigh is not sync-ed to chassis app db" test_sysneigh_entry = chassis_app_db.get_entry( "SYSTEM_NEIGH", test_sysneigh) sys_neigh_encap_index = test_sysneigh_entry.get("encap_index") assert sys_neigh_encap_index != "", "System neigh in chassis app db does not have encap index" assert encap_index == sys_neigh_encap_index, "Encap index not sync-ed correctly" break
def test_chassis_system_lag_id_allocator_del_id(self, vct): """Test lag id allocator's release id and re-use id processing. Pre-requisite: (i) Test case: test_chassis_system_lag (ii) Test case: test_chassis_system_lag_id_allocator_table_full This test validates that (i) Portchannel is deleted and id allocator does not return error (ii) Should be able to add PortChannel to re-use released id (iii) Deleted portchaneels are removed from chassis app db (iv) Remote asics remove the system lag corresponding to the deleted PortChannels """ if vct is None: return test_lag1_name = "PortChannel0001" test_lag1_member = "Ethernet4" test_lag2_name = "PortChannel0002" test_lag3_name = "PortChannel0003" # Create a PortChannel in a line card 1 (owner line card) dvss = vct.dvss for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") # Get the host name and asic name for the system lag alias verification cfg_hostname = metatbl.get("hostname") assert cfg_hostname != "", "Got error in getting hostname from CONFIG_DB DEVICE_METADATA" cfg_asic_name = metatbl.get("asic_name") assert cfg_asic_name != "", "Got error in getting asic_name from CONFIG_DB DEVICE_METADATA" cfg_switch_type = metatbl.get("switch_type") # Portchannel record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id == "0": # At this point we have 2 port channels test_lag1_name and test_lag2_name. # These were created by the above two test cases. Now delete the PortChannel # test_lag1_name and verify that the lag is removed and add test_lag3_name to # test for lag id allocator allocating newly available lag id # Connect to app db: lag table and lag member table app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) psTbl_lag = swsscommon.ProducerStateTable( app_db, "LAG_TABLE") psTbl_lagMember = swsscommon.ProducerStateTable( app_db, "LAG_MEMBER_TABLE") # Make sure presence of 2 port channels before deleting asic_db = dvs.get_asic_db() lagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 2) assert len( lagkeys ) == 2, "Expected 2 PortChannels are not available" # Make sure presence of total of 1 lag member added in test_lag1_name # No lag member added in test_lag2_name lagmemberkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", 1) assert len( lagmemberkeys ) == 1, "Expected 1 LAG members are not available" # Delete port channel member of PortChannel test_lag1_name psTbl_lagMember.delete( f"{test_lag1_name}:{test_lag1_member}") # Verify the lag member is removed from asic db lagmemberkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", 0) assert len( lagmemberkeys ) == 0, "Deleted LAG member is not removed from asic db" # Delete PortChannel test_lag1_name psTbl_lag.delete(f"{test_lag1_name}") # Verify deletion of the PorChannel asic_db = dvs.get_asic_db() lagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 1) assert len( lagkeys ) == 1, "Two LAG entries in asic db even after deleting a PortChannel" # Create PortChannel test_lag3_name. This should be addedd successfully since deleting # PortChannel test_lag1_name made a lag id available for allocation fvs = swsscommon.FieldValuePairs([("admin", "up"), ("mtu", "9100")]) psTbl_lag.set(f"{test_lag3_name}", fvs) # Verify creation of the additional PortChannel after making space for more # PortChannels by deleting some PortChannels asic_db = dvs.get_asic_db() lagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 2) assert len( lagkeys ) == 2, "Two configured LAG entries are not available in asic db" # Check for the presence of voq system port aggregate id attribute for 2 LAGs lag_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", lagkeys[0]) spa_id = lag_entry.get( "SAI_LAG_ATTR_SYSTEM_PORT_AGGREGATE_ID") assert spa_id != "", "VOQ System port aggregate id not present for the LAG 1" lag_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", lagkeys[1]) spa_id = lag_entry.get( "SAI_LAG_ATTR_SYSTEM_PORT_AGGREGATE_ID") assert spa_id != "", "VOQ System port aggregate id not present for the LAG 2" # Now delete all the PortChannels so that we can veify the chassis app db # clearing and remote asics clearing psTbl_lag.delete(f"{test_lag2_name}") psTbl_lag.delete(f"{test_lag3_name}") # Verify deletion of all PortChannels asic_db = dvs.get_asic_db() lagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 0) assert len( lagkeys ) == 0, "LAG entries in asic db even after deleting all PortChannels" break # Check syncing deletion of the PortChannels and PortChannel member in chasiss app db for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) syslagkeys = chassis_app_db.wait_for_n_keys( "SYSTEM_LAG_TABLE", 0) assert len(syslagkeys ) == 0, "Stale system lag entries in chassis app db" syslagmemberkeys = chassis_app_db.wait_for_n_keys( "SYSTEM_LAG_MEMBER_TABLE", 0) assert len( syslagmemberkeys ) == 0, "Stale system lag member entries in chassis app db" break # Verify removal of remote system lag in non-owner line card # Verify removal of system lag menbers in non-owner line card for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # System LAG info verifiation done in non-owner line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id != "0": # Linecard other than linecard 1 (owner line card) asic_db = dvs.get_asic_db() remotesyslagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 0) assert len( remotesyslagkeys ) == 0, "Stale remote system lag entries in asic db" # Verify cleaning of system lag members lagmemberkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", 0) assert len( lagmemberkeys ) == 0, "Stale system lag member entries in asic db" break
def test_chassis_system_lag(self, vct): """Test PortChannel in VOQ based chassis systems. This test validates that (i) PortChannel is created in local asic with system port aggregator id (system lag id) - Unique lag id is allocated from chassis app db in supervisor card - The unique lag id is sent in system port aggregator id attribute (ii) PortChannel members are successfully added in the PortChannel created (iii) Local PortChannel is synced in chassis app db (iv) PortChannel members addition is synced in the chassis app db (v) System LAG is created for the remote PortChannel with system lag id. (vi) System LAG of remote Portchannel has members with system port id """ if vct is None: return test_lag1_name = "PortChannel0001" test_lag1_member = "Ethernet4" # Set the lag id boundaries in the chassis ap db self.set_lag_id_boundaries(vct) # Create a PortChannel in a line card 1 (owner line card) dvss = vct.dvss for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") # Get the host name and asic name for the system lag alias verification cfg_hostname = metatbl.get("hostname") assert cfg_hostname != "", "Got error in getting hostname from CONFIG_DB DEVICE_METADATA" cfg_asic_name = metatbl.get("asic_name") assert cfg_asic_name != "", "Got error in getting asic_name from CONFIG_DB DEVICE_METADATA" cfg_switch_type = metatbl.get("switch_type") # Portchannel record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id == "0": # Connect to app db: lag table and lag member table app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) psTbl_lag = swsscommon.ProducerStateTable( app_db, "LAG_TABLE") psTbl_lagMember = swsscommon.ProducerStateTable( app_db, "LAG_MEMBER_TABLE") # Create PortChannel fvs = swsscommon.FieldValuePairs([("admin", "up"), ("mtu", "9100")]) psTbl_lag.set(f"{test_lag1_name}", fvs) # Verify creation of the PorChannel with voq system port aggregator id in asic db asic_db = dvs.get_asic_db() lagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 1) assert len( lagkeys ) == 1, "The LAG entry for configured PortChannel is not available in asic db" # Check for the presence of voq system port aggregate id attribute lag_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", lagkeys[0]) spa_id = lag_entry.get( "SAI_LAG_ATTR_SYSTEM_PORT_AGGREGATE_ID") assert spa_id != "", "VOQ System port aggregate id not present for the LAG" # Add port channel member fvs = swsscommon.FieldValuePairs([("status", "enabled")]) psTbl_lagMember.set(f"{test_lag1_name}:{test_lag1_member}", fvs) # Check for presence of lag member added lagmemberkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", 1) assert len( lagmemberkeys ) == 1, "The LAG member for configured PortChannel is not available in asic db" break # Check syncing of the PortChannel and PortChannel member in chasiss app db for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) syslagkeys = chassis_app_db.wait_for_n_keys( "SYSTEM_LAG_TABLE", 1) assert len( syslagkeys ) == 1, "System lag entry is not available in chassis app db" # system lag alias (key) should be unique across chassis. To ensure such uniqueness, # the system lag name is derived from hostname, asic_name and PortChannel name # Verify for correct name assert f"{cfg_hostname}|{cfg_asic_name}|{test_lag1_name}" in syslagkeys[ 0], "Invalid unique system lag name" # Verify lag id of the system lag in chassis app db syslag_entry = chassis_app_db.get_entry( "SYSTEM_LAG_TABLE", syslagkeys[0]) remote_lag_id = syslag_entry.get("lag_id") assert remote_lag_id != "", "Lag id is not present in the sytem lag table in chassis app db" # This id must be same as the id allocated in owner linecard. assert remote_lag_id == spa_id, "System lag id in chassis app db is not same as allocated lag id" syslagmemberkeys = chassis_app_db.wait_for_n_keys( "SYSTEM_LAG_MEMBER_TABLE", 1) assert len( syslagmemberkeys ) == 1, "No system lag member entries in chassis app db" break # Verify programming of remote system lag with received system lag id in non-owner line card # Verify programming of lag menbers with system port id in non-owner line card for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # System LAG info verifiation done in non-owner line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id != "0": # Linecard other than linecard 1 (owner line card) asic_db = dvs.get_asic_db() remotesyslagkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", 1) assert len( remotesyslagkeys ) == 1, "No remote system lag entries in ASIC_DB" remotesyslag_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_LAG", remotesyslagkeys[0]) remote_lag_id = remotesyslag_entry.get( "SAI_LAG_ATTR_SYSTEM_PORT_AGGREGATE_ID") assert remote_lag_id != "", "Lag id not present in the remote syslag entry in asic db" assert remote_lag_id == spa_id, "Remote system lag programmed with wrong lag id" # Verify remote system lag has system port as member lagmemberkeys = asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", 1) assert len( lagmemberkeys ) == 1, "The LAG member for remote system lag is not available in asic db" remotelagmember_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", lagmemberkeys[0]) member_port_id = remotelagmember_entry.get( "SAI_LAG_MEMBER_ATTR_PORT_ID") #Verify that the member is a system port assert "oid:0x5d" in member_port_id, "System LAG member is not system port" break
def test_chassis_system_neigh(self, vct): """Test neigh record create/delete and syncing to chassis app db. This test validates that: (i) Local neighbor entry is created with encap index (ii) Local neighbor is synced to chassis ap db with assigned encap index (iii) Remote neighbor entry is created in ASIC_DB with received encap index (iv) Local neighbor entry is deleted when neighbor is deleted (v) Local neighbor delete is synced to chassis ap db (vi) Remote neighbor entry is cleared in ASIC_DB """ if vct is None: return # We use Ethernet0 as inband port in each line card. In real hardware, this will be a # special port used for inband. For testing purpose, we need port record and rif record # for the inband interface and valid kernel interface. Since Ethernet0 is already # setup, the port record, rif record and kernel interface already exist. So we use it # for testing inband_port = "Ethernet0" # Configure port type inband interface self.config_inbandif_port(vct, inband_port) # Test neighbor on Ethernet4 since Ethernet0 is used as Inband port test_neigh_dev = "Ethernet4" test_neigh_ip = "10.8.104.3" test_neigh_mac = "00:01:02:03:04:05" dvss = vct.dvss print("name {}".format(dvss.keys())) for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # Neighbor record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id == "0": # Add a static neighbor _, res = dvs.runcmd(['sh', "-c", "ip neigh show"]) _, res = dvs.runcmd([ 'sh', "-c", f"ip neigh add {test_neigh_ip} lladdr {test_neigh_mac} dev {test_neigh_dev}" ]) assert res == "", "Error configuring static neigh" asic_db = dvs.get_asic_db() asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", 1) neighkeys = asic_db.get_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY") assert len(neighkeys), "No neigh entries in ASIC_DB" # Check for presence of the neighbor in ASIC_DB test_neigh = "" for nkey in neighkeys: ne = ast.literal_eval(nkey) if ne['ip'] == test_neigh_ip: test_neigh = nkey break assert test_neigh != "", "Neigh not found in ASIC_DB" # Preserve test neigh asic db key for delete verification later test_neigh_asic_db_key = test_neigh # Check for presence of encap index, retrieve and store it for sync verification test_neigh_entry = asic_db.wait_for_entry( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_neigh) test_neigh_entry_attrs = asic_db.wait_for_fields( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_neigh, ["SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX"]) print(test_neigh) print(test_neigh_entry) print(test_neigh_entry_attrs) encap_index = test_neigh_entry_attrs[ "SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX"] assert encap_index != "" and encap_index != None, "VOQ encap index is not programmed in ASIC_DB" break # Verify neighbor record syncing with encap index for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) chassis_app_db.wait_for_n_keys("SYSTEM_NEIGH", 1) sysneighkeys = chassis_app_db.get_keys("SYSTEM_NEIGH") print(sysneighkeys) test_sysneigh = "" for sysnk in sysneighkeys: sysnk_tok = sysnk.split("|") assert len( sysnk_tok ) == 3, "Invalid system neigh key in chassis app db" if sysnk_tok[2] == test_neigh_ip: test_sysneigh = sysnk break assert test_sysneigh != "", "Neigh is not sync-ed to chassis app db" # Preserve test sys neigh chassis app db key for delete verification later test_sysneigh_chassis_app_db_key = test_sysneigh test_sysneigh_entry = chassis_app_db.get_entry( "SYSTEM_NEIGH", test_sysneigh) sys_neigh_encap_index = test_sysneigh_entry.get("encap_index") assert sys_neigh_encap_index != "", "System neigh in chassis app db does not have encap index" assert encap_index == sys_neigh_encap_index, "Encap index not sync-ed correctly" break # Verify programming of remote neighbor in asic db and programming of static route and static # neigh in the kernel for the remote neighbor. The neighbor created in linecard 1 will be a # remote neighbor in other linecards. Verity existence of the test neighbor in linecards other # than linecard 1 for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # Neighbor record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id != "0": # Linecard other than linecard 1 asic_db = dvs.get_asic_db() asic_db.wait_for_n_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", 1) neighkeys = asic_db.get_keys( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY") assert len(neighkeys), "No neigh entries in ASIC_DB" # Check for presence of the remote neighbor in ASIC_DB remote_neigh = "" for nkey in neighkeys: ne = ast.literal_eval(nkey) if ne['ip'] == test_neigh_ip: remote_neigh = nkey break assert remote_neigh != "", "Remote neigh not found in ASIC_DB" # Preserve remote neigh asic db neigh key for delete verification later test_remote_neigh_asic_db_key = remote_neigh # Check for kernel entries _, output = dvs.runcmd("ip neigh show") assert f"{test_neigh_ip} dev {inband_port}" in output, "Kernel neigh not found for remote neighbor" _, output = dvs.runcmd("ip route show") assert f"{test_neigh_ip} dev {inband_port} scope link" in output, "Kernel route not found for remote neighbor" # Check for ASIC_DB entries. # Check for presence of encap index, retrieve and store it for sync verification remote_neigh_entry = asic_db.get_entry( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", remote_neigh) # Validate encap index remote_encap_index = remote_neigh_entry.get( "SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX") assert remote_encap_index != "", "VOQ encap index is not programmed for remote neigh in ASIC_DB" assert remote_encap_index == encap_index, "Encap index of remote neigh mismatch with allocated encap index" # Validate MAC mac = remote_neigh_entry.get( "SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS") assert mac != "", "MAC address is not programmed for remote neigh in ASIC_DB" assert mac == test_neigh_mac, "Encap index of remote neigh mismatch with allocated encap index" # Check for other mandatory attributes # For remote neighbors, is_local must be "false" is_local = remote_neigh_entry.get( "SAI_NEIGHBOR_ENTRY_ATTR_IS_LOCAL") assert is_local != "", "is_local attribute is not programmed for remote neigh in ASIC_DB" assert is_local == "false", "is_local attribute is true for remote neigh" break # Verify system neighbor delete and clearing for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # Neighbor record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id == "0": # Delete the static neighbor neighbor _, res = dvs.runcmd([ 'sh', "-c", f"ip neigh del {test_neigh_ip} dev {test_neigh_dev}" ]) assert res == "", "Error deleting static neigh" # Check for presence of the neighbor in ASIC_DB. The deleted neighbor should # not be present in the asic db asic_db = dvs.get_asic_db() neighkeys = asic_db.wait_for_deleted_entry( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_neigh_asic_db_key) assert len( neighkeys) == 0, "Stale neigh entry found in ASIC_DB" break # Verify syncing of neighbor record delete in chassis app db dvss = vct.dvss for name in dvss.keys(): if name.startswith("supervisor"): dvs = dvss[name] chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock) sysneighkeys = chassis_app_db.wait_for_deleted_entry( "SYSTEM_NEIGH", test_sysneigh_chassis_app_db_key) assert len( sysneighkeys) == 0, "Stale neigh entry in chassis app db" break # Verify clearing of remote neighbor in non-owner linecard dvss = vct.dvss for name in dvss.keys(): dvs = dvss[name] config_db = dvs.get_config_db() metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") cfg_switch_type = metatbl.get("switch_type") # Neighbor record verifiation done in line card if cfg_switch_type == "voq": lc_switch_id = metatbl.get("switch_id") assert lc_switch_id != "", "Got error in getting switch_id from CONFIG_DB DEVICE_METADATA" if lc_switch_id != "0": # Linecard other than linecard 1 # Check for presence of the remote neighbor in ASIC_DB. The remote neighbor corresponding # to the deleted static neigbor should not be present asic_db = dvs.get_asic_db() neighkeys = asic_db.wait_for_deleted_entry( "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY", test_remote_neigh_asic_db_key) assert len(neighkeys) == 0, "Stale remote neigh in ASIC_DB" # Check for kernel entries. Kernel entries (neigh and route) should have been removed _, output = dvs.runcmd("ip neigh show") assert f"{test_neigh_ip} dev {inband_port}" not in output, "Kernel neigh of remote neighbor not removed" _, output = dvs.runcmd("ip route show") assert f"{test_neigh_ip} dev {inband_port} scope link" not in output, "Kernel route of remote neighbor not removed" break # Cleanup inband if configuration self.del_inbandif_port(vct, inband_port)
def get_state_db(self): if not self.state_db: self.state_db = DVSDatabase(self.STATE_DB_ID, self.redis_sock) return self.state_db
def get_flex_db(self): if not self.flex_db: self.flex_db = DVSDatabase(self.FLEX_COUNTER_DB_ID, self.redis_sock) return self.flex_db
def get_config_db(self): if not self.config_db: self.config_db = DVSDatabase(self.CONFIG_DB_ID, self.redis_sock) return self.config_db
def get_counters_db(self): if not self.counters_db: self.counters_db = DVSDatabase(self.COUNTERS_DB_ID, self.redis_sock) return self.counters_db
def get_app_db(self): if not self.app_db: self.app_db = DVSDatabase(self.APP_DB_ID, self.redis_sock) return self.app_db