Esempio n. 1
0
    def check_deleted_route_entries(self, destinations):
        def _access_function():
            route_entries = self.adb.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
            route_destinations = [
                json.loads(route_entry)["dest"]
                for route_entry in route_entries
            ]
            return (all(destination not in route_destinations
                        for destination in destinations), None)

        wait_for_result(_access_function, DVSDatabase.DEFAULT_POLLING_CONFIG)
Esempio n. 2
0
    def check_route_entries_with_vrf(self, destinations, vrf_oids):
        def _access_function():
            route_entries = self.adb.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
            route_destination_vrf = [(json.loads(route_entry)["dest"],
                                      json.loads(route_entry)["vr"])
                                     for route_entry in route_entries]
            return (all(
                (destination, vrf_oid) in route_destination_vrf
                for destination, vrf_oid in zip(destinations, vrf_oids)), None)

        wait_for_result(_access_function)
Esempio n. 3
0
    def check_route_entries(self, destinations):
        def _access_function():
            route_entries = self.adb.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
            route_destinations = [
                json.loads(route_entry)["dest"]
                for route_entry in route_entries
            ]
            return (all(destination in route_destinations
                        for destination in destinations), None)

        wait_for_result(_access_function)
Esempio n. 4
0
    def check_sub_port_intf_route_entries(self):
        expected_destinations = [self.IPV4_TOME_UNDER_TEST,
                                 self.IPV4_SUBNET_UNDER_TEST,
                                 self.IPV6_TOME_UNDER_TEST,
                                 self.IPV6_SUBNET_UNDER_TEST]

        def _access_function():
            raw_route_entries = self.asic_db.get_keys(ASIC_ROUTE_ENTRY_TABLE)
            route_destinations = [str(json.loads(raw_route_entry)["dest"])
                                  for raw_route_entry in raw_route_entries]
            return (all(dest in route_destinations for dest in expected_destinations), None)

        wait_for_result(_access_function, DVSDatabase.DEFAULT_POLLING_CONFIG)
Esempio n. 5
0
    def check_inseg_entries(self, present, labels):
        def _access_function():
            inseg_entries = self.adb.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_INSEG_ENTRY")
            inseg_labels = [
                json.loads(inseg_entry)["label"]
                for inseg_entry in inseg_entries
            ]
            if present:
                return (all(label in inseg_labels for label in labels), None)
            else:
                return (all(label not in inseg_labels
                            for label in labels), None)

        wait_for_result(_access_function)
Esempio n. 6
0
def validate_asic_nhg_router_interface(asic_db, ipprefix):
    def _access_function():
        false_ret = (False, '')
        keys = asic_db.get_keys(ASIC_ROUTE_TB)
        key = ''
        route_exists = False
        for k in keys:
            rt_key = json.loads(k)
            if rt_key['dest'] == ipprefix:
                route_exists = True
                key = k
        if not route_exists:
            return false_ret

        fvs = asic_db.get_entry(ASIC_ROUTE_TB, key)
        if not fvs:
            return false_ret

        rifid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
        fvs = asic_db.get_entry(ASIC_RIF, rifid)
        if not fvs:
            return false_ret

        return (True, rifid)

    _, result = wait_for_result(
        _access_function, failure_message="Route pointing to RIF not found")
    return result
Esempio n. 7
0
def validate_asic_nhg_regular_ecmp(asic_db, ipprefix):
    def _access_function():
        false_ret = (False, '')
        keys = asic_db.get_keys(ASIC_ROUTE_TB)
        key = ''
        route_exists = False
        for k in keys:
            rt_key = json.loads(k)
            if rt_key['dest'] == ipprefix:
                route_exists = True
                key = k
        if not route_exists:
            return false_ret
        fvs = asic_db.get_entry(ASIC_ROUTE_TB, key)
        if not fvs:
            return false_ret
        nhgid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
        fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP",
                                nhgid)
        if not fvs:
            return false_ret
        nhg_type = fvs.get("SAI_NEXT_HOP_GROUP_ATTR_TYPE")
        if nhg_type != "SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP":
            return false_ret
        return (True, nhgid)

    status, result = wait_for_result(_access_function,
                                     DVSDatabase.DEFAULT_POLLING_CONFIG)
    if not status:
        assert not polling_config.strict, \
                f"SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP not found"
    return result
Esempio n. 8
0
    def wait_for_entry(self,
                       table_name,
                       key,
                       polling_config=DEFAULT_POLLING_CONFIG):
        """
            Gets the entry stored at `key` in the specified table. This method
            will wait for the entry to exist.

            Args:
                table_name (str): The name of the table where the entry is
                    stored.
                key (str): The key that maps to the entry being retrieved.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                Dict[str, str]: The entry stored at `key`. If no entry is found,
                then an empty Dict will be returned.

        """
        def _access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (bool(fv_pairs), fv_pairs)

        status, result = wait_for_result(
            _access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                "Entry not found: key=\"{}\", table=\"{}\"".format(key, table_name)

        return result
Esempio n. 9
0
def validate_asic_nhg_fine_grained_ecmp(asic_db, ipprefix, size):
    def _access_function():
        false_ret = (False, '')
        keys = asic_db.get_keys(ASIC_ROUTE_TB)
        key = ''
        route_exists = False
        for k in keys:
            rt_key = json.loads(k)
            if rt_key['dest'] == ipprefix:
                route_exists = True
                key = k
        if not route_exists:
            return false_ret

        fvs = asic_db.get_entry(ASIC_ROUTE_TB, key)
        if not fvs:
            return false_ret

        nhgid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
        fvs = asic_db.get_entry(ASIC_NHG, nhgid)
        if not fvs:
            return false_ret

        nhg_type = fvs.get("SAI_NEXT_HOP_GROUP_ATTR_TYPE")
        if nhg_type != "SAI_NEXT_HOP_GROUP_TYPE_FINE_GRAIN_ECMP":
            return false_ret
        nhg_cfg_size = fvs.get("SAI_NEXT_HOP_GROUP_ATTR_CONFIGURED_SIZE")
        if int(nhg_cfg_size) != size:
            return false_ret
        return (True, nhgid)

    _, result = wait_for_result(
        _access_function, failure_message="Fine Grained ECMP route not found")
    return result
Esempio n. 10
0
    def wait_for_deleted_keys(self,
                              table_name,
                              deleted_keys,
                              polling_config=DEFAULT_POLLING_CONFIG):
        """
            Checks if the specified keys no longer exist in the table. This
            method will wait for the keys to be deleted.

            Args:
                table_name (str): The name of the table from which to fetch
                    the keys.
                deleted_keys (List[str]): The keys we expect to be removed from
                    the table.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                List[str]: The keys stored in the table. If no keys are found,
                then an empty List will be returned.
        """
        def _access_function():
            keys = self.get_keys(table_name)
            return (all(key not in keys for key in deleted_keys), keys)

        status, result = wait_for_result(
            _access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                "Unexpected keys found: expected={}, received={}, table=\"{}\""\
                .format(deleted_keys, result, table_name)

        return result
Esempio n. 11
0
def validate_asic_nhg_regular_ecmp(asic_db, ipprefix):
    def _access_function():
        false_ret = (False, '')
        keys = asic_db.get_keys(ASIC_ROUTE_TB)
        key = ''
        route_exists = False
        for k in keys:
            rt_key = json.loads(k)
            if rt_key['dest'] == ipprefix:
                route_exists = True
                key = k
        if not route_exists:
            return false_ret

        fvs = asic_db.get_entry(ASIC_ROUTE_TB, key)
        if not fvs:
            return false_ret

        nhgid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
        fvs = asic_db.get_entry(ASIC_NHG, nhgid)
        if not fvs:
            return false_ret

        nhg_type = fvs.get("SAI_NEXT_HOP_GROUP_ATTR_TYPE")
        if nhg_type != "SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP":
            return false_ret
        return (True, nhgid)

    _, result = wait_for_result(
        _access_function,
        failure_message=
        "SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP not found")
    return result
Esempio n. 12
0
    def wait_for_entry(self,
                       table_name,
                       key,
                       polling_config=DEFAULT_POLLING_CONFIG):
        """
            Gets the entry stored at `key` in the specified table. This method
            will wait for the entry to exist.

            Args:
                table_name (str): The name of the table where the entry is
                    stored.
                key (str): The key that maps to the entry being retrieved.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                Dict[str, str]: The entry stored at `key`. If no entry is found,
                then an empty Dict will be returned.

        """
        def _access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (bool(fv_pairs), fv_pairs)

        return wait_for_result(_access_function, polling_config)
Esempio n. 13
0
    def wait_for_exact_match(self,
                             table_name,
                             key,
                             expected_entry,
                             polling_config=DEFAULT_POLLING_CONFIG):
        """
            Checks if the provided entry matches the entry stored at `key`
            in the specified table. This method will wait for the exact entry
            to exist.

            Args:
                table_name (str): The name of the table where the entry is
                    stored.
                key (str): The key that maps to the entry being checked.
                expected_entry (dict): The entry we expect to see.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                Dict[str, str]: The entry stored at `key`. If no entry is found,
                then an empty Dict will be returned.
        """
        def _access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (fv_pairs == expected_entry, fv_pairs)

        status, result = wait_for_result(
            _access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                "Exact match not found: expected={}, received={}, \
                key=\"{}\", table=\"{}\""                                         .format(expected_entry, result, key, table_name)

        return result
Esempio n. 14
0
    def wait_for_field_negative_match(
        self,
        table_name: str,
        key: str,
        old_fields: Dict[str, str],
        polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> Dict[str, str]:
        """Wait for the entry stored at `key` to have different field/value pairs than the ones specified.

        This method is useful if you expect some field to change, but you don't know their exact values.

        Args:
            table_name: The name of the table where the entry is stored.
            key: The key that maps to the entry being checked.
            old_fields: The original field/value pairs we expect to change.
            polling_config: The parameters to use to poll the db.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def __access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (all(k in fv_pairs and fv_pairs[k] != v
                        for k, v in old_fields.items()), fv_pairs)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                f"Did not expect field/values to match, but they did: provided={old_fields}, \
                received={result}, key=\"{key}\", table=\"{table_name}\""

        return result
Esempio n. 15
0
    def wait_for_exact_match(
        self,
        table_name: str,
        key: str,
        expected_entry: Dict[str, str],
        polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> Dict[str, str]:
        """Wait for the entry stored at `key` to match `expected_entry` and retrieve it.

        This method is useful if you care about *all* the fields stored in the specfied entry.

        Args:
            table_name: The name of the table where the entry is stored.
            key: The key that maps to the entry being checked.
            expected_entry: The entry we expect to see.
            polling_config: The parameters to use to poll the db.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def __access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (fv_pairs == expected_entry, fv_pairs)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                f"Exact match not found: expected={expected_entry}, received={result}, \
                key=\"{key}\", table=\"{table_name}\""

        return result
Esempio n. 16
0
    def wait_for_fields(
        self,
        table_name: str,
        key: str,
        expected_fields: List[str],
        polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> Dict[str, str]:
        """Wait for the entry stored at `key` to have the specified fields and retrieve it.

        This method is useful if you only care about a subset of the fields stored in the
        specified entry.

        Args:
            table_name: The name of the table where the entry is stored.
            key: The key that maps to the entry being checked.
            expected_fields: The fields that we expect to see in the entry.
            polling_config: The parameters to use to poll the db.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def __access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (all(field in fv_pairs
                        for field in expected_fields), fv_pairs)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                f"Expected fields not found: expected={expected_fields}, \
                received={result}, key=\"{key}\", table=\"{table_name}\""

        return result
Esempio n. 17
0
    def get_ip_prefix_nhg_oid(self, ip_prefix):
        def _access_function():
            route_entry_found = False

            raw_route_entry_keys = self.asic_db.get_keys(
                ASIC_ROUTE_ENTRY_TABLE)
            for raw_route_entry_key in raw_route_entry_keys:
                route_entry_key = json.loads(raw_route_entry_key)
                if route_entry_key["dest"] == ip_prefix:
                    route_entry_found = True
                    break

            return (route_entry_found, raw_route_entry_key)

        (route_entry_found,
         raw_route_entry_key) = wait_for_result(_access_function)

        fvs = self.asic_db.get_entry(ASIC_ROUTE_ENTRY_TABLE,
                                     raw_route_entry_key)

        nhg_oid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID", "")
        assert nhg_oid != ""
        assert nhg_oid != "oid:0x0"

        return nhg_oid
Esempio n. 18
0
    def wait_for_deleted_entry(self,
                               table_name,
                               key,
                               polling_config=DEFAULT_POLLING_CONFIG):
        """
            Checks if there is any entry stored at `key` in the specified
            table. This method will wait for the entry to be empty.

            Args:
                table_name (str): The name of the table being checked.
                key (str): The key to be checked.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                Dict[str, str]: The entry stored at `key`. If no entry is found,
                then an empty Dict will be returned.
        """
        def _access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (not bool(fv_pairs), fv_pairs)

        status, result = wait_for_result(
            _access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                "Entry still exists: entry={}, key=\"{}\", table=\"{}\""\
                .format(result, key, table_name)

        return result
Esempio n. 19
0
    def check_nexthop(self, present, nhtype, ip, ostype, labels):
        def _access_function():
            nhs = self.adb.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP")
            for nh in nhs:
                fvs = self.adb.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP",
                                         nh)
                if fvs.get("SAI_NEXT_HOP_ATTR_TYPE") != nhtype: continue
                if fvs.get("SAI_NEXT_HOP_ATTR_IP") != ip: continue
                if nhtype == "SAI_NEXT_HOP_TYPE_IP": return (present, None)
                if nhtype != "SAI_NEXT_HOP_TYPE_MPLS": continue
                if fvs.get("SAI_NEXT_HOP_ATTR_OUTSEG_TYPE") != ostype: continue
                if fvs.get("SAI_NEXT_HOP_ATTR_LABELSTACK") == labels:
                    return (present, None)
            return (not present, None)

        wait_for_result(_access_function)
Esempio n. 20
0
    def wait_for_deleted_keys(
            self,
            table_name: str,
            deleted_keys: List[str],
            polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> List[str]:
        """Wait for the specfied keys to no longer exist in the table.

        Args:
            table_name: The name of the table from which to fetch the keys.
            deleted_keys: The keys we expect to be removed from the table.
            polling_config: The parameters to use to poll the db.

        Returns:
            The keys stored in the table. If no keys are found, then an empty List is returned.
        """
        def __access_function():
            keys = self.get_keys(table_name)
            return (all(key not in keys for key in deleted_keys), keys)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            expected = [key for key in result if key not in deleted_keys]
            assert not polling_config.strict, \
                f"Unexpected keys found: expected={expected}, received={result}, \
                table=\"{table_name}\""

        return result
Esempio n. 21
0
    def wait_for_deleted_entry(
        self,
        table_name: str,
        key: str,
        polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> Dict[str, str]:
        """Wait for no entry to exist at `key` in the specified table.

        Args:
            table_name: The name of the table being checked.
            key: The key to be checked.
            polling_config: The parameters to use to poll the db.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def __access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (not bool(fv_pairs), fv_pairs)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                f"Entry still exists: entry={result}, key=\"{key}\", table=\"{table_name}\""

        return result
Esempio n. 22
0
    def wait_for_n_keys(self,
                        table_name,
                        num_keys,
                        polling_config=DEFAULT_POLLING_CONFIG):
        """
            Gets all of the keys stored in the specified table. This method
            will wait for the specified number of keys.

            Args:
                table_name (str): The name of the table from which to fetch
                    the keys.
                num_keys (int): The expected number of keys to retrieve from
                    the table.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                List[str]: The keys stored in the table. If no keys are found,
                then an empty List will be returned.
        """
        def _access_function():
            keys = self.get_keys(table_name)
            return (len(keys) == num_keys, keys)

        status, result = wait_for_result(
            _access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                "Unexpected number of keys: expected={}, received={} ({}), table=\"{}\""\
                .format(num_keys, len(result), result, table_name)

        return result
Esempio n. 23
0
    def wait_for_n_keys(self,
                        table_name,
                        num_keys,
                        polling_config=DEFAULT_POLLING_CONFIG):
        """
            Gets all of the keys stored in the specified table. This method
            will wait for the specified number of keys.

            Args:
                table_name (str): The name of the table from which to fetch
                    the keys.
                num_keys (int): The expected number of keys to retrieve from
                    the table.
                polling_config (PollingConfig): The parameters to use to poll
                    the db.

            Returns:
                List[str]: The keys stored in the table. If no keys are found,
                then an empty List will be returned.
        """
        def _access_function():
            keys = self.get_keys(table_name)
            return (len(keys) == num_keys, keys)

        return wait_for_result(_access_function, polling_config)
Esempio n. 24
0
    def wait_for_n_keys(
            self,
            table_name: str,
            num_keys: int,
            polling_config: PollingConfig = DEFAULT_POLLING_CONFIG
    ) -> List[str]:
        """Wait for the specified number of keys to exist in the table.

        Args:
            table_name: The name of the table from which to fetch the keys.
            num_keys: The expected number of keys to retrieve from the table.
            polling_config: The parameters to use to poll the db.

        Returns:
            The keys stored in the table. If no keys are found, then an empty List is returned.
        """
        def __access_function():
            keys = self.get_keys(table_name)
            return (len(keys) == num_keys, keys)

        status, result = wait_for_result(
            __access_function, self._disable_strict_polling(polling_config))

        if not status:
            assert not polling_config.strict, \
                f"Unexpected number of keys: expected={num_keys}, \
                received={len(result)} ({result}), table=\"{table_name}\""

        return result
Esempio n. 25
0
def verify_programmed_fg_asic_db_entry(asic_db, nh_memb_exp_count, nh_oid_map,
                                       nhgid, bucket_size):
    def _access_function():
        false_ret = (False, None)
        ret = True
        nh_memb_count = {}
        for key in nh_memb_exp_count:
            nh_memb_count[key] = 0

        members = asic_db.get_keys(ASIC_NHG_MEMB)
        memb_dict = {}

        for member in members:
            fvs = asic_db.get_entry(ASIC_NHG_MEMB, member)
            if fvs == {}:
                return false_ret
            index = -1
            nh_oid = "0"
            memb_nhgid = "0"
            for key, val in fvs.items():
                if key == "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_INDEX":
                    index = int(val)
                elif key == "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID":
                    nh_oid = val
                elif key == "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID":
                    memb_nhgid = val
            if memb_nhgid == "0":
                print("memb_nhgid was not set")
                return false_ret
            if memb_nhgid != nhgid:
                continue
            if (index == -1 or nh_oid == "0"
                    or nh_oid_map.get(nh_oid, "NULL") == "NULL"
                    or nh_oid_map.get(nh_oid) not in nh_memb_exp_count):
                print("Invalid nh: nh_oid " + nh_oid + " index " + str(index))
                if nh_oid_map.get(nh_oid, "NULL") == "NULL":
                    print("nh_oid is null")
                if nh_oid_map.get(nh_oid) not in nh_memb_exp_count:
                    print("nh_memb_exp_count is " + str(nh_memb_exp_count) +
                          " nh_oid_map val is " + nh_oid_map.get(nh_oid))
                return false_ret
            memb_dict[index] = nh_oid_map.get(nh_oid)
        idxs = [0] * bucket_size
        for idx, memb in memb_dict.items():
            nh_memb_count[memb] = 1 + nh_memb_count[memb]
            idxs[idx] = idxs[idx] + 1

        for key in nh_memb_exp_count:
            ret = ret and (nh_memb_count[key] == nh_memb_exp_count[key])
        for idx in idxs:
            ret = ret and (idx == 1)
        if ret != True:
            print("Expected member count was " + str(nh_memb_exp_count) +
                  " Received was " + str(nh_memb_count))
            print("Indexes arr was " + str(idxs))
        return (ret, nh_memb_count)

    status, result = wait_for_result(_access_function)
    assert status, f"Exact match not found: expected={nh_memb_exp_count}, received={result}"
    return result
Esempio n. 26
0
    def wait_for_n_keys(
        self,
        table_name: str,
        num_keys: int,
        polling_config: PollingConfig = PollingConfig(),
        failure_message: str = None,
    ) -> List[str]:
        """Wait for the specified number of keys to exist in the table.

        Args:
            table_name: The name of the table from which to fetch the keys.
            num_keys: The expected number of keys to retrieve from the table.
            polling_config: The parameters to use to poll the db.
            failure_message: The message to print if the call times out. This will only take effect
                if the PollingConfig is set to strict.

        Returns:
            The keys stored in the table. If no keys are found, then an empty List is returned.
        """
        def access_function():
            keys = self.get_keys(table_name)
            return (len(keys) == num_keys, keys)

        status, result = wait_for_result(
            access_function, self._disable_strict_polling(polling_config))

        if not status:
            message = failure_message or (
                f"Unexpected number of keys: expected={num_keys}, received={len(result)} "
                f'({result}), table="{table_name}"')
            assert not polling_config.strict, message

        return result
Esempio n. 27
0
    def wait_for_deleted_keys(
        self,
        table_name: str,
        deleted_keys: List[str],
        polling_config: PollingConfig = PollingConfig(),
        failure_message: str = None,
    ) -> List[str]:
        """Wait for the specfied keys to no longer exist in the table.

        Args:
            table_name: The name of the table from which to fetch the keys.
            deleted_keys: The keys we expect to be removed from the table.
            polling_config: The parameters to use to poll the db.
            failure_message: The message to print if the call times out. This will only take effect
                if the PollingConfig is set to strict.

        Returns:
            The keys stored in the table. If no keys are found, then an empty List is returned.
        """
        def access_function():
            keys = self.get_keys(table_name)
            return (all(key not in keys for key in deleted_keys), keys)

        status, result = wait_for_result(
            access_function, self._disable_strict_polling(polling_config))

        if not status:
            expected = [key for key in result if key not in deleted_keys]
            message = failure_message or (
                f"Unexpected keys found: expected={expected}, received={result}, "
                f'table="{table_name}"')
            assert not polling_config.strict, message

        return result
Esempio n. 28
0
    def wait_for_entry(
        self,
        table_name: str,
        key: str,
        polling_config: PollingConfig = PollingConfig(),
        failure_message: str = None,
    ) -> Dict[str, str]:
        """Wait for the entry stored at `key` in the specified table to exist and retrieve it.

        Args:
            table_name: The name of the table where the entry is stored.
            key: The key that maps to the entry being retrieved.
            polling_config: The parameters to use to poll the db.
            failure_message: The message to print if the call times out. This will only take effect
                if the PollingConfig is set to strict.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (bool(fv_pairs), fv_pairs)

        message = failure_message or f'Entry not found: key="{key}", table="{table_name}"'
        _, result = wait_for_result(access_function, polling_config, message)

        return result
Esempio n. 29
0
    def wait_for_deleted_entry(
        self,
        table_name: str,
        key: str,
        polling_config: PollingConfig = PollingConfig(),
        failure_message: str = None,
    ) -> Dict[str, str]:
        """Wait for no entry to exist at `key` in the specified table.

        Args:
            table_name: The name of the table being checked.
            key: The key to be checked.
            polling_config: The parameters to use to poll the db.
            failure_message: The message to print if the call times out. This will only take effect
                if the PollingConfig is set to strict.

        Returns:
            The entry stored at `key`. If no entry is found, then an empty Dict is returned.
        """
        def access_function():
            fv_pairs = self.get_entry(table_name, key)
            return (not bool(fv_pairs), fv_pairs)

        status, result = wait_for_result(
            access_function, self._disable_strict_polling(polling_config))

        if not status:
            message = failure_message or (
                f'Entry still exists: entry={result}, key="{key}", table="{table_name}"'
            )
            assert not polling_config.strict, message

        return result
Esempio n. 30
0
    def check_route_entries_nexthop(self, destinations, vrf_oids, nexthops):
        def _access_function_nexthop():
            nexthop_entries = self.adb.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP")
            nexthop_oids = dict([(self.adb.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP", key)["SAI_NEXT_HOP_ATTR_IP"], key)
                                 for key in nexthop_entries])
            return (all(nexthop in nexthop_oids for nexthop in nexthops), nexthop_oids)

        status, nexthop_oids = wait_for_result(_access_function_nexthop)

        def _access_function_route_nexthop():
            route_entries = self.adb.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
            route_destination_nexthop = dict([((json.loads(route_entry)["dest"], json.loads(route_entry)["vr"]), 
                                               self.adb.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY", route_entry).get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID"))
                                               for route_entry in route_entries])
            return (all(route_destination_nexthop.get((destination, vrf_oid)) == nexthop_oids.get(nexthop)
                        for destination, vrf_oid, nexthop in zip(destinations, vrf_oids, nexthops)), None)

        wait_for_result(_access_function_route_nexthop)