Ejemplo n.º 1
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"
Ejemplo n.º 2
0
    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_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)