From 38c04b2566c3ecf2109611628783dd1c8a1be99a Mon Sep 17 00:00:00 2001 From: Vratko Polak Date: Thu, 17 Aug 2023 14:53:26 +0200 Subject: feat(swasync): switch to polling mode Performance of adaptive mode is bad (different bug), keep continuity of ipsec swasync tests (when VPP allows). As 23.06-release does not have the new API message, the new CSIT code needs to be more careful around CRC checking. + Add new crc collection with the new API call used. + Also keep the old collection so older VPP does not fail. + Document how papi executor works with VPP without a message. + Prevent CRC checker from raising bodus errors with old VPP. Change-Id: I9ff933a8a9558289d22d55526905d63e7894378c Signed-off-by: Vratko Polak --- resources/libraries/python/IPsecUtil.py | 22 +++++++++++++---- resources/libraries/python/PapiExecutor.py | 1 + resources/libraries/python/VppApiCrc.py | 38 +++++++++++++++++------------- 3 files changed, 40 insertions(+), 21 deletions(-) (limited to 'resources/libraries/python') diff --git a/resources/libraries/python/IPsecUtil.py b/resources/libraries/python/IPsecUtil.py index 39c6a4ce2f..873b6af5d8 100644 --- a/resources/libraries/python/IPsecUtil.py +++ b/resources/libraries/python/IPsecUtil.py @@ -318,6 +318,8 @@ class IPsecUtil: def vpp_ipsec_set_async_mode(node, async_enable=1): """Set IPsec async mode on|off. + Unconditionally, attempt to switch crypto dispatch into polling mode. + :param node: VPP node to set IPsec async mode. :param async_enable: Async mode on or off. :type node: dict @@ -325,13 +327,23 @@ class IPsecUtil: :raises RuntimeError: If failed to set IPsec async mode or if no API reply received. """ - cmd = u"ipsec_set_async_mode" - err_msg = f"Failed to set IPsec async mode on host {node[u'host']}" - args = dict( - async_enable=async_enable - ) with PapiSocketExecutor(node) as papi_exec: + cmd = u"ipsec_set_async_mode" + err_msg = f"Failed to set IPsec async mode on host {node[u'host']}" + args = dict( + async_enable=async_enable + ) papi_exec.add(cmd, **args).get_reply(err_msg) + cmd = "crypto_set_async_dispatch_v2" + err_msg = "Failed to set dispatch mode." + args = dict(mode=0, adaptive=False) + try: + papi_exec.add(cmd, **args).get_reply(err_msg) + except (AttributeError, RuntimeError): + # Expected when VPP build does not have the _v2 yet + # (after and before the first CRC check). + # TODO: Fail here when testing of pre-23.10 builds is over. + pass @staticmethod def vpp_ipsec_crypto_sw_scheduler_set_worker( diff --git a/resources/libraries/python/PapiExecutor.py b/resources/libraries/python/PapiExecutor.py index b0fe6f5b7b..b629996042 100644 --- a/resources/libraries/python/PapiExecutor.py +++ b/resources/libraries/python/PapiExecutor.py @@ -995,6 +995,7 @@ class PapiSocketExecutor: :returns: Papi replies parsed into a dict-like object, with fields due to API (possibly including retval). :rtype: List[UserDict] + :raises AttributeError: If VPP does not know the command. :raises RuntimeError: If the replies are not all correct. """ vpp_instance = self.get_connected_client() diff --git a/resources/libraries/python/VppApiCrc.py b/resources/libraries/python/VppApiCrc.py index 761059f43e..a8947a18cb 100644 --- a/resources/libraries/python/VppApiCrc.py +++ b/resources/libraries/python/VppApiCrc.py @@ -75,8 +75,9 @@ class VppApiCrcChecker: Starts the same as _expected, but each time an encountered api,crc pair fits the expectation, the pair is removed from all collections - within this mapping. Ideally, the active mappings will become empty. - If not, it is an error, VPP removed or renamed a message CSIT needs.""" + within this mapping. It is fine if an api is missing + from some collections, as long as it is not missing from all collections + that remained in _expected.""" self._found = dict() """Mapping from API name to CRC string. @@ -325,12 +326,15 @@ class VppApiCrcChecker: if not report_missing: return missing = {name: mapp for name, mapp in self._missing.items() if mapp} - if missing: - missing_indented = json.dumps( - missing, indent=1, sort_keys=True, separators=[u",", u":"]) - self.log_and_raise( - f"API CRCs missing from .api.json:\n{missing_indented}" - ) + if set(missing.keys()) < set(self._expected.keys()): + # There is a collection where nothing is missing. + return + missing_indented = json.dumps( + missing, indent=1, sort_keys=True, separators=[u",", u":"] + ) + self.log_and_raise( + f"API CRCs missing from .api.json:\n{missing_indented}" + ) def check_api_name(self, api_name): """Fail if the api_name has no, or different from known CRC associated. @@ -375,23 +379,25 @@ class VppApiCrcChecker: self.log_and_raise( f"No active collection has API {api_name!r} with CRC {crc!r}" ) - options = self._options[api_name] + options = self._options.get(api_name, None) + if not options: + # None means CSIT is attempting a new API on an old VPP build. + # If that is an issue, the API has been reported as missing already. + return options.pop(u"vat_help", None) if options: self._reported[api_name] = crc logger.console(f"{api_name} used but has options {options}") def print_warnings(self): - """Call check_api_name for every API name in surviving collections. + """Call check_api_name for API names in surviving collections. Useful for VPP CRC checking job. - - Even though there usually is only one surviving collection, - the implementation has to be prepared for multiple collections, - and it should de-duplicate api names. + The API name is only checked when it appears + in all surviving collections. """ api_name_to_crc_maps = self._expected.values() - api_name_sets = [set(n2c.keys()) for n2c in api_name_to_crc_maps] - api_names = set().union(*api_name_sets) + api_name_sets = (set(n2c.keys()) for n2c in api_name_to_crc_maps) + api_names = set.intersection(*api_name_sets) for api_name in sorted(api_names): self.check_api_name(api_name) -- cgit 1.2.3-korg