aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python/PapiExecutor.py
diff options
context:
space:
mode:
authorVratko Polak <vrpolak@cisco.com>2019-07-30 10:40:50 +0200
committerVratko Polak <vrpolak@cisco.com>2019-07-31 08:00:05 +0000
commit29726f92698452f51033fc3ab52f112b74eae594 (patch)
tree7436f9dcd944c2f2b9c45fd0fb37d4ff96b6ce7a /resources/libraries/python/PapiExecutor.py
parentf966718dfe763e48f2cc89e9ede2408a0f782d1b (diff)
Add VPP API CRC checking
+ Include both checking at runtime and standalone static quick check. + Runtime checking does not look for missing messages, as messages belonging to disabled plugins are not visible. + Standalone check script has nice loud output. Change-Id: I1dfc3846d1bcdad0b09017d4ce8edd5028e17e0c Signed-off-by: Vratko Polak <vrpolak@cisco.com>
Diffstat (limited to 'resources/libraries/python/PapiExecutor.py')
-rw-r--r--resources/libraries/python/PapiExecutor.py36
1 files changed, 35 insertions, 1 deletions
diff --git a/resources/libraries/python/PapiExecutor.py b/resources/libraries/python/PapiExecutor.py
index a3f2479cff..792fa4c3b3 100644
--- a/resources/libraries/python/PapiExecutor.py
+++ b/resources/libraries/python/PapiExecutor.py
@@ -33,6 +33,7 @@ from resources.libraries.python.PythonThree import raise_from
from resources.libraries.python.PapiHistory import PapiHistory
from resources.libraries.python.ssh import (
SSH, SSHTimeout, exec_cmd_no_error, scp_node)
+from resources.libraries.python.VppApiCrc import VppApiCrcChecker
__all__ = ["PapiExecutor", "PapiSocketExecutor"]
@@ -67,6 +68,7 @@ def dictize(obj):
ret.__getitem__ = new_get
return ret
+
class PapiSocketExecutor(object):
"""Methods for executing VPP Python API commands on forwarded socket.
@@ -126,6 +128,8 @@ class PapiSocketExecutor(object):
# Class cache for reuse between instances.
cached_vpp_instance = None
+ api_json_directory = None
+ crc_checker_instance = None
def __init__(self, node, remote_vpp_socket="/run/vpp-api.sock"):
"""Store the given arguments, declare managed variables.
@@ -145,6 +149,20 @@ class PapiSocketExecutor(object):
self._local_vpp_socket = None
@property
+ def crc_checker(self):
+ """Return the cached instance or create new one from directory.
+
+ It is assumed self.api_json_directory is set, as a class variable.
+
+ :returns: Cached or newly created instance aware of .api.json content.
+ :rtype: VppApiCrc.VppApiCrcChecker
+ """
+ cls = self.__class__
+ if cls.crc_checker_instance is None:
+ cls.crc_checker_instance = VppApiCrcChecker(cls.api_json_directory)
+ return cls.crc_checker_instance
+
+ @property
def vpp_instance(self):
"""Return VPP instance with bindings to all API calls.
@@ -183,13 +201,17 @@ class PapiSocketExecutor(object):
exec_cmd_no_error(node, ["bash", "-c", "'" + inner_cmd + "'"])
scp_node(node, tmp_dir + "/papi.txz", "/tmp/papi.txz", get=True)
run(["tar", "xf", tmp_dir + "/papi.txz", "-C", tmp_dir])
+ cls.api_json_directory = tmp_dir + "/usr/share/vpp/api"
+ # Perform initial checks before .api.json files are gone,
+ # by accessing the property (which also creates its instance).
+ self.crc_checker
# When present locally, we finally can find the installation path.
package_path = glob.glob(tmp_dir + installed_papi_glob)[0]
# Package path has to be one level above the vpp_papi directory.
package_path = package_path.rsplit('/', 1)[0]
sys.path.append(package_path)
from vpp_papi.vpp_papi import VPPApiClient as vpp_class
- vpp_class.apidir = tmp_dir + "/usr/share/vpp/api"
+ vpp_class.apidir = cls.api_json_directory
# We need to create instance before removing from sys.path.
cls.cached_vpp_instance = vpp_class(
use_socket=True, server_address="TBD", async_thread=False,
@@ -315,6 +337,14 @@ class PapiSocketExecutor(object):
be repeated in kwargs.
Unless disabled, new entry to papi history is also added at this point.
+ Any pending conflicts from .api.json processing are raised.
+ Then the command name is checked for known CRCs.
+ Unsupported commands raise an exception, as CSIT change
+ should not start using messages without making sure which CRCs
+ are supported.
+ Each CRC issue is raised only once, so subsequent tests
+ can raise other issues.
+
:param csit_papi_command: VPP API command.
:param history: Enable/disable adding command to PAPI command history.
:param kwargs: Optional key-value arguments.
@@ -323,10 +353,13 @@ class PapiSocketExecutor(object):
:type kwargs: dict
:returns: self, so that method chaining is possible.
:rtype: PapiSocketExecutor
+ :raises RuntimeError: If unverified or conflicting CRC is encountered.
"""
+ self.crc_checker.report_initial_conflicts()
if history:
PapiHistory.add_to_papi_history(
self._node, csit_papi_command, **kwargs)
+ self.crc_checker.check_api_name(csit_papi_command)
self._api_command_list.append(
dict(api_name=csit_papi_command, api_args=kwargs))
return self
@@ -486,6 +519,7 @@ class PapiSocketExecutor(object):
if not isinstance(reply, list):
reply = [reply]
for item in reply:
+ self.crc_checker.check_api_name(item.__class__.__name__)
dict_item = dictize(item)
if "retval" in dict_item.keys():
# *_details messages do not contain retval.