Pylint fixes
[csit.git] / resources / libraries / python / honeycomb / HoneycombUtil.py
index 2f8392e..747c9da 100644 (file)
@@ -27,7 +27,8 @@ from enum import Enum, unique
 
 from robot.api import logger
 
-from resources.libraries.python.HTTPRequest import HTTPRequest
+from resources.libraries.python.ssh import SSH
+from resources.libraries.python.HTTPRequest import HTTPRequest, HTTPCodes
 from resources.libraries.python.constants import Constants as Const
 
 
@@ -86,7 +87,6 @@ class HoneycombError(Exception):
         self._msg = "{0}: {1}".format(self.__class__.__name__, msg)
         self._details = details
         if enable_logging:
-            logger.error(self._msg)
             logger.debug(self._details)
 
     def __repr__(self):
@@ -126,7 +126,7 @@ class HoneycombUtil(object):
         :param url_file: URL file. The argument contains only the name of file
         without extension, not the full path.
         :type url_file: str
-        :return: Requested path.
+        :returns: Requested path.
         :rtype: str
         """
 
@@ -178,7 +178,7 @@ class HoneycombUtil(object):
         :param path: Path to data we want to find.
         :type data: dict
         :type path: tuple
-        :return: Data represented by path.
+        :returns: Data represented by path.
         :rtype: str, dict, or list
         :raises HoneycombError: If the data has not been found.
         """
@@ -205,7 +205,7 @@ class HoneycombUtil(object):
         :param path: Path to data we want to remove.
         :type data: dict
         :type path: tuple
-        :return: Original data without removed part.
+        :returns: Original data without removed part.
         :rtype: dict
         """
 
@@ -245,7 +245,7 @@ class HoneycombUtil(object):
         :type data: dict
         :type path: tuple
         :type new_value: str, dict or list
-        :return: Original data with the new value.
+        :returns: Original data with the new value.
         :rtype: dict
         """
 
@@ -285,24 +285,30 @@ class HoneycombUtil(object):
         return origin_data
 
     @staticmethod
-    def get_honeycomb_data(node, url_file):
+    def get_honeycomb_data(node, url_file, path=""):
         """Retrieve data from Honeycomb according to given URL.
 
         :param node: Honeycomb node.
         :param url_file: URL file. The argument contains only the name of file
         without extension, not the full path.
+        :param path: Path which is added to the base path to identify the data.
         :type node: dict
         :type url_file: str
-        :return: Status code and content of response.
+        :type path: str
+        :returns: Status code and content of response.
         :rtype tuple
         """
 
-        path = HoneycombUtil.read_path_from_url_file(url_file)
+        base_path = HoneycombUtil.read_path_from_url_file(url_file)
+        path = base_path + path
         status_code, resp = HTTPRequest.get(node, path)
-        return status_code, loads(resp)
+        response = loads(resp)
+        if status_code != HTTPCodes.OK:
+            HoneycombUtil.read_log_tail(node)
+        return status_code, response
 
     @staticmethod
-    def put_honeycomb_data(node, url_file, data,
+    def put_honeycomb_data(node, url_file, data, path="",
                            data_representation=DataRepresentation.JSON):
         """Send configuration data using PUT request and return the status code
         and response content.
@@ -311,12 +317,14 @@ class HoneycombUtil(object):
         :param url_file: URL file. The argument contains only the name of file
         without extension, not the full path.
         :param data: Configuration data to be sent to Honeycomb.
+        :param path: Path which is added to the base path to identify the data.
         :param data_representation: How the data is represented.
         :type node: dict
         :type url_file: str
         :type data: dict, str
+        :type path: str
         :type data_representation: DataRepresentation
-        :return: Status code and content of response.
+        :returns: Status code and content of response.
         :rtype: tuple
         :raises HoneycombError: If the given data representation is not defined
         in HEADERS.
@@ -332,9 +340,15 @@ class HoneycombUtil(object):
 
         logger.trace(data)
 
-        path = HoneycombUtil.read_path_from_url_file(url_file)
-        return HTTPRequest.put(node=node, path=path, headers=header,
-                               payload=data)
+        base_path = HoneycombUtil.read_path_from_url_file(url_file)
+        path = base_path + path
+        logger.trace(path)
+        (status_code, response) = HTTPRequest.put(
+            node=node, path=path, headers=header, payload=data)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            HoneycombUtil.read_log_tail(node)
+        return status_code, response
 
     @staticmethod
     def post_honeycomb_data(node, url_file, data=None,
@@ -354,7 +368,7 @@ class HoneycombUtil(object):
         :type data: dict, str
         :type data_representation: DataRepresentation
         :type timeout: int
-        :return: Status code and content of response.
+        :returns: Status code and content of response.
         :rtype: tuple
         :raises HoneycombError: If the given data representation is not defined
         in HEADERS.
@@ -369,21 +383,72 @@ class HoneycombUtil(object):
             data = dumps(data)
 
         path = HoneycombUtil.read_path_from_url_file(url_file)
-        return HTTPRequest.post(node=node, path=path, headers=header,
-                                payload=data, timeout=timeout)
+        (status_code, response) = HTTPRequest.post(
+            node=node, path=path, headers=header, payload=data, timeout=timeout)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            HoneycombUtil.read_log_tail(node)
+        return status_code, response
 
     @staticmethod
-    def delete_honeycomb_data(node, url_file):
+    def delete_honeycomb_data(node, url_file, path=""):
         """Delete data from Honeycomb according to given URL.
 
         :param node: Honeycomb node.
         :param url_file: URL file. The argument contains only the name of file
         without extension, not the full path.
+        :param path: Path which is added to the base path to identify the data.
         :type node: dict
         :type url_file: str
-        :return: Status code and content of response.
+        :type path: str
+        :returns: Status code and content of response.
         :rtype tuple
         """
 
-        path = HoneycombUtil.read_path_from_url_file(url_file)
-        return HTTPRequest.delete(node, path)
+        base_path = HoneycombUtil.read_path_from_url_file(url_file)
+        path = base_path + path
+        (status_code, response) = HTTPRequest.delete(node, path)
+
+        if status_code != HTTPCodes.OK:
+            HoneycombUtil.read_log_tail(node)
+        return status_code, response
+
+    @staticmethod
+    def read_log_tail(node, lines=120):
+        """Read  the last N lines of the Honeycomb log file and print them
+        to robot log.
+
+        :param node: Honeycomb node.
+        :param lines: Number of lines to read.
+        :type node: dict
+        :type lines: int
+        :returns: Last N log lines.
+        :rtype: str
+        """
+
+        logger.trace(
+            "HTTP request failed, "
+            "obtaining last {0} lines of Honeycomb log...".format(lines))
+
+        ssh = SSH()
+        ssh.connect(node)
+        cmd = "tail -n {0} /var/log/honeycomb/honeycomb.log".format(lines)
+        # ssh also logs the reply on trace level
+        (_, stdout, _) = ssh.exec_command(cmd, timeout=30)
+
+        return stdout
+
+    @staticmethod
+    def archive_honeycomb_log(node):
+        """Copy honeycomb log file from DUT node to VIRL for archiving.
+
+        :param node: Honeycomb node.
+        :type node: dict
+        """
+
+        ssh = SSH()
+        ssh.connect(node)
+
+        cmd = "cp /var/log/honeycomb/honeycomb.log /scratch/"
+
+        ssh.exec_command_sudo(cmd)