PAL: Fix processing of TRex tests
[csit.git] / resources / tools / presentation / input_data_parser.py
index 1e25138..8747f93 100644 (file)
@@ -287,14 +287,16 @@ class ExecutionChecker(ResultVisitor):
     )
     REGEX_TC_TAG = re.compile(r'\d+[tT]\d+[cC]')
 
-    REGEX_TC_NAME_OLD = re.compile(r'-\d+[tT]\d+[cC]-')
-
     REGEX_TC_NAME_NEW = re.compile(r'-\d+[cC]-')
 
     REGEX_TC_NUMBER = re.compile(r'tc\d{2}-')
 
     REGEX_TC_PAPI_CLI = re.compile(r'.*\((\d+.\d+.\d+.\d+.) - (.*)\)')
 
+    REGEX_SH_RUN_HOST = re.compile(
+        r'hostname=\"(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\",hook=\"(.*)\"'
+    )
+
     def __init__(self, metadata, mapping, ignore, for_output):
         """Initialisation.
 
@@ -358,7 +360,6 @@ class ExecutionChecker(ResultVisitor):
         # Dictionary defining the methods used to parse different types of
         # messages
         self.parse_msg = {
-            u"timestamp": self._get_timestamp,
             u"vpp-version": self._get_vpp_version,
             u"dpdk-version": self._get_dpdk_version,
             u"teardown-papi-history": self._get_papi_history,
@@ -610,18 +611,6 @@ class ExecutionChecker(ResultVisitor):
             finally:
                 self._msg_type = None
 
-    def _get_timestamp(self, msg):
-        """Called when extraction of timestamp is required.
-
-        :param msg: Message to process.
-        :type msg: Message
-        :returns: Nothing.
-        """
-
-        self._timestamp = msg.timestamp[:14]
-        self._data[u"metadata"][u"generated"] = self._timestamp
-        self._msg_type = None
-
     def _get_papi_history(self, msg):
         """Called when extraction of PAPI command history is required.
 
@@ -701,7 +690,7 @@ class ExecutionChecker(ResultVisitor):
 
         if self._telemetry_kw_counter > 1:
             return
-        if not msg.message.count(u"vpp_runtime_calls"):
+        if not msg.message.count(u"# TYPE vpp_runtime_calls"):
             return
 
         if u"telemetry-show-run" not in \
@@ -709,23 +698,33 @@ class ExecutionChecker(ResultVisitor):
             self._data[u"tests"][self._test_id][u"telemetry-show-run"] = dict()
 
         self._telemetry_msg_counter += 1
-        dut = f"dut{self._telemetry_msg_counter}"
+        groups = re.search(self.REGEX_SH_RUN_HOST, msg.message)
+        if not groups:
+            return
+        try:
+            host = groups.group(1)
+        except (AttributeError, IndexError):
+            host = u""
+        try:
+            sock = groups.group(2)
+        except (AttributeError, IndexError):
+            sock = u""
         runtime = {
             u"source_type": u"node",
-            u"source_id": dut,
+            u"source_id": host,
             u"msg_type": u"metric",
             u"log_level": u"INFO",
             u"timestamp": msg.timestamp,
             u"msg": u"show_runtime",
-            u"host": dut,  # No info, should be host IP
-            u"socket": u"",  # No info
+            u"host": host,
+            u"socket": sock,
             u"data": list()
         }
         for line in msg.message.splitlines():
             if not line.startswith(u"vpp_runtime_"):
                 continue
             try:
-                params, value = line.rsplit(u" ", maxsplit=2)[:-1]
+                params, value, timestamp = line.rsplit(u" ", maxsplit=2)
                 cut = params.index(u"{")
                 name = params[:cut].split(u"_", maxsplit=2)[-1]
                 labels = eval(
@@ -736,17 +735,17 @@ class ExecutionChecker(ResultVisitor):
                     {
                         u"name": name,
                         u"value": value,
+                        u"timestamp": timestamp,
                         u"labels": labels
                     }
                 )
             except (TypeError, ValueError, IndexError):
                 continue
-
-        self._data[u'tests'][self._test_id][u'telemetry-show-run'][dut] = \
-            copy.copy(
+        self._data[u'tests'][self._test_id][u'telemetry-show-run']\
+            [f"dut{self._telemetry_msg_counter}"] = copy.copy(
                 {
-                    u"host": dut,
-                    u"socket": u"",
+                    u"host": host,
+                    u"socket": sock,
                     u"runtime": runtime
                 }
             )
@@ -1122,38 +1121,36 @@ class ExecutionChecker(ResultVisitor):
         else:
             test_result[u"msg"] = test.message
 
-        if u"PERFTEST" in tags:
+        if u"PERFTEST" in tags and u"TREX" not in tags:
             # Replace info about cores (e.g. -1c-) with the info about threads
             # and cores (e.g. -1t1c-) in the long test case names and in the
             # test case names if necessary.
-            groups = re.search(self.REGEX_TC_NAME_OLD, self._test_id)
-            if not groups:
-                tag_count = 0
-                tag_tc = str()
-                for tag in test_result[u"tags"]:
-                    groups = re.search(self.REGEX_TC_TAG, tag)
-                    if groups:
-                        tag_count += 1
-                        tag_tc = tag
-
-                if tag_count == 1:
-                    self._test_id = re.sub(
-                        self.REGEX_TC_NAME_NEW, f"-{tag_tc.lower()}-",
-                        self._test_id, count=1
-                    )
-                    test_result[u"name"] = re.sub(
-                        self.REGEX_TC_NAME_NEW, f"-{tag_tc.lower()}-",
-                        test_result["name"], count=1
-                    )
-                else:
-                    test_result[u"status"] = u"FAIL"
-                    self._data[u"tests"][self._test_id] = test_result
-                    logging.debug(
-                        f"The test {self._test_id} has no or more than one "
-                        f"multi-threading tags.\n"
-                        f"Tags: {test_result[u'tags']}"
-                    )
-                    return
+            tag_count = 0
+            tag_tc = str()
+            for tag in test_result[u"tags"]:
+                groups = re.search(self.REGEX_TC_TAG, tag)
+                if groups:
+                    tag_count += 1
+                    tag_tc = tag
+
+            if tag_count == 1:
+                self._test_id = re.sub(
+                    self.REGEX_TC_NAME_NEW, f"-{tag_tc.lower()}-",
+                    self._test_id, count=1
+                )
+                test_result[u"name"] = re.sub(
+                    self.REGEX_TC_NAME_NEW, f"-{tag_tc.lower()}-",
+                    test_result["name"], count=1
+                )
+            else:
+                test_result[u"status"] = u"FAIL"
+                self._data[u"tests"][self._test_id] = test_result
+                logging.debug(
+                    f"The test {self._test_id} has no or more than one "
+                    f"multi-threading tags.\n"
+                    f"Tags: {test_result[u'tags']}"
+                )
+                return
 
         if u"DEVICETEST" in tags:
             test_result[u"type"] = u"DEVICETEST"
@@ -1341,9 +1338,6 @@ class ExecutionChecker(ResultVisitor):
         elif setup_kw.name.count(u"Install Dpdk Framework On All Duts") and \
                 not self._version:
             self._msg_type = u"dpdk-version"
-        elif setup_kw.name.count(u"Set Global Variable") \
-                and not self._timestamp:
-            self._msg_type = u"timestamp"
         elif setup_kw.name.count(u"Setup Framework") and not self._testbed:
             self._msg_type = u"testbed"
         else:
@@ -1530,6 +1524,15 @@ class InputData:
         )
         result.visit(checker)
 
+        checker.data[u"metadata"][u"tests_total"] = \
+            result.statistics.total.all.total
+        checker.data[u"metadata"][u"tests_passed"] = \
+            result.statistics.total.all.passed
+        checker.data[u"metadata"][u"tests_failed"] = \
+            result.statistics.total.all.failed
+        checker.data[u"metadata"][u"elapsedtime"] = result.suite.elapsedtime
+        checker.data[u"metadata"][u"generated"] = result.suite.endtime[:14]
+
         return checker.data
 
     def _download_and_parse_build(self, job, build, repeat, pid=10000):