+ except Exception as exc:
+ raise_from(RuntimeError(
+ "PAPI command(s) execution on host {host} "
+ "failed: {apis}".format(
+ host=self._node["host"], apis=api_data)), exc)
+ if ret_code != 0:
+ raise AssertionError(err_msg)
+
+ return stdout
+
+ def _execute(self, method='request', err_msg="", timeout=120):
+ """Turn internal command list into data and execute; return replies.
+
+ This method also clears the internal command list.
+
+ IMPORTANT!
+ Do not use this method in L1 keywords. Use:
+ - get_stats()
+ - get_replies()
+ - get_details()
+
+ :param method: VPP Python API method. Supported methods are: 'request',
+ 'dump' and 'stats'.
+ :param err_msg: The message used if the PAPI command(s) execution fails.
+ :param timeout: Timeout in seconds.
+ :type method: str
+ :type err_msg: str
+ :type timeout: int
+ :returns: Papi responses parsed into a dict-like object,
+ with field due to API or stats hierarchy.
+ :rtype: list of dict
+ :raises KeyError: If the reply is not correct.
+ """
+
+ local_list = self._api_command_list
+
+ # Clear first as execution may fail.
+ self._api_command_list = list()
+
+ stdout = self._execute_papi(
+ local_list, method=method, err_msg=err_msg, timeout=timeout)
+ replies = list()
+ try:
+ json_data = json.loads(stdout)
+ except ValueError as err:
+ raise_from(RuntimeError(err_msg), err)
+ for data in json_data:
+ if method == "request":
+ api_reply = self._process_reply(data["api_reply"])
+ # api_reply contains single key, *_reply.
+ obj = api_reply.values()[0]
+ retval = obj["retval"]
+ if retval != 0:
+ # TODO: What exactly to log and raise here?
+ err = AssertionError("Got retval {rv!r}".format(rv=retval))
+ raise_from(AssertionError(err_msg), err, level="INFO")
+ replies.append(obj)
+ elif method == "dump":
+ api_reply = self._process_reply(data["api_reply"])
+ # api_reply is a list where item contas single key, *_details.
+ for item in api_reply:
+ obj = item.values()[0]
+ replies.append(obj)
+ else:
+ # TODO: Implement support for stats.
+ raise RuntimeError("Unsuported method {method}".format(
+ method=method))
+
+ # TODO: Make logging optional?
+ logger.debug("PAPI replies: {replies}".format(replies=replies))
+
+ return replies