X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FPapiExecutor.py;h=30a90473f53a4a8fec2fd287aa3d97b357ed1d68;hb=758d50dd77f6114b2d4fe0ca13d95ae111f7b110;hp=c2f966fb6d594660ae3ab1ea0f17c96fc0b4170f;hpb=92fbe3b8d880f9a3dd63e1309d76772b1685a037;p=csit.git diff --git a/resources/libraries/python/PapiExecutor.py b/resources/libraries/python/PapiExecutor.py index c2f966fb6d..30a90473f5 100644 --- a/resources/libraries/python/PapiExecutor.py +++ b/resources/libraries/python/PapiExecutor.py @@ -17,6 +17,8 @@ import binascii import json +from pprint import pformat + from robot.api import logger from resources.libraries.python.Constants import Constants @@ -288,20 +290,24 @@ class PapiExecutor(object): def __exit__(self, exc_type, exc_val, exc_tb): self._ssh.disconnect(self._node) - def add(self, csit_papi_command="vpp-stats", **kwargs): + def add(self, csit_papi_command="vpp-stats", history=True, **kwargs): """Add next command to internal command list; return self. The argument name 'csit_papi_command' must be unique enough as it cannot be repeated in kwargs. :param csit_papi_command: VPP API command. + :param history: Enable/disable adding command to PAPI command history. :param kwargs: Optional key-value arguments. :type csit_papi_command: str + :type history: bool :type kwargs: dict :returns: self, so that method chaining is possible. :rtype: PapiExecutor """ - PapiHistory.add_to_papi_history(self._node, csit_papi_command, **kwargs) + if history: + PapiHistory.add_to_papi_history( + self._node, csit_papi_command, **kwargs) self._api_command_list.append(dict(api_name=csit_papi_command, api_args=kwargs)) return self @@ -325,6 +331,25 @@ class PapiExecutor(object): return json.loads(stdout) + def get_stats_reply(self, err_msg="Failed to get statistics.", timeout=120): + """Get VPP Stats reply from VPP Python API. + + :param err_msg: The message used if the PAPI command(s) execution fails. + :param timeout: Timeout in seconds. + :type err_msg: str + :type timeout: int + :returns: Requested VPP statistics. + :rtype: list + """ + + args = self._api_command_list[0]['api_args'] + self._api_command_list = list() + + stdout, _ = self._execute_papi( + args, method='stats_request', err_msg=err_msg, timeout=timeout) + + return json.loads(stdout) + def get_replies(self, err_msg="Failed to get replies.", process_reply=True, ignore_errors=False, timeout=120): """Get reply/replies from VPP Python API. @@ -365,6 +390,21 @@ class PapiExecutor(object): method='dump', process_reply=process_reply, ignore_errors=ignore_errors, err_msg=err_msg, timeout=timeout) + @staticmethod + def dump_and_log(node, cmds): + """Dump and log requested information. + + :param node: DUT node. + :param cmds: Dump commands to be executed. + :type node: dict + :type cmds: list + """ + with PapiExecutor(node) as papi_exec: + for cmd in cmds: + dump = papi_exec.add(cmd).get_dump() + logger.debug("{cmd}:\n{data}".format( + cmd=cmd, data=pformat(dump.reply[0]["api_reply"]))) + @staticmethod def run_cli_cmd(node, cmd, log=True): """Run a CLI command. @@ -444,10 +484,13 @@ class PapiExecutor(object): :rtype: dict or str or int """ if isinstance(val, dict): - val_dict = dict() for val_k, val_v in val.iteritems(): - val_dict[str(val_k)] = process_value(val_v) - return val_dict + val[str(val_k)] = process_value(val_v) + return val + elif isinstance(val, list): + for idx, val_l in enumerate(val): + val[idx] = process_value(val_l) + return val else: return binascii.hexlify(val) if isinstance(val, str) else val @@ -473,12 +516,32 @@ class PapiExecutor(object): :returns: Processed API reply / a part of API reply. :rtype: dict """ + def process_value(val): + """Process value. + + :param val: Value to be processed. + :type val: object + :returns: Processed value. + :rtype: dict or str or int + """ + if isinstance(val, dict): + for val_k, val_v in val.iteritems(): + val[str(val_k)] = process_value(val_v) + return val + elif isinstance(val, list): + for idx, val_l in enumerate(val): + val[idx] = process_value(val_l) + return val + elif isinstance(val, unicode): + return binascii.unhexlify(val) + else: + return val + reply_dict = dict() reply_value = dict() for reply_key, reply_v in api_r.iteritems(): for a_k, a_v in reply_v.iteritems(): - reply_value[a_k] = binascii.unhexlify(a_v) \ - if isinstance(a_v, unicode) else a_v + reply_value[a_k] = process_value(a_v) reply_dict[reply_key] = reply_value return reply_dict @@ -519,7 +582,8 @@ class PapiExecutor(object): if not api_data: RuntimeError("No API data provided.") - json_data = json.dumps(api_data) if method == "stats" \ + json_data = json.dumps(api_data) \ + if method in ("stats", "stats_request") \ else json.dumps(self._process_api_data(api_data)) cmd = "{fw_dir}/{papi_provider} --method {method} --data '{json}'".\