X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Ftools%2Fpresentation%2Finput_data_parser.py;h=8feb057e28e69cf65238742402791e42ca174c2c;hp=fe6213628b468a83e4d9dfdecaf381764550b589;hb=3e06f8130ec9df4b6cc0241156be6744b47955ca;hpb=c7cd008e11e76e22b8cebf5397b2b149251cbb4c diff --git a/resources/tools/presentation/input_data_parser.py b/resources/tools/presentation/input_data_parser.py index fe6213628b..8feb057e28 100644 --- a/resources/tools/presentation/input_data_parser.py +++ b/resources/tools/presentation/input_data_parser.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. +# Copyright (c) 2019 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -33,6 +33,7 @@ from os import remove from os.path import join from datetime import datetime as dt from datetime import timedelta +from json import loads from jumpavg.AvgStdevMetadataFactory import AvgStdevMetadataFactory from input_data_files import download_and_unzip_data_file @@ -78,7 +79,7 @@ class ExecutionChecker(ResultVisitor): "parent": "Name of the parent of the test", "doc": "Test documentation", "msg": "Test message", - "vat-history": "DUT1 and DUT2 VAT History", + "conf-history": "DUT1 and DUT2 VAT History", "show-run": "Show Run", "tags": ["tag 1", "tag 2", "tag n"], "type": "NDRPDR", @@ -198,7 +199,7 @@ class ExecutionChecker(ResultVisitor): } }, "lossTolerance": "lossTolerance", # Only type: "PDR" - "vat-history": "DUT1 and DUT2 VAT History" + "conf-history": "DUT1 and DUT2 VAT History" "show-run": "Show Run" }, "ID" { @@ -235,7 +236,7 @@ class ExecutionChecker(ResultVisitor): "doc": "Test documentation" "msg": "Test message" "tags": ["tag 1", "tag 2", "tag n"], - "vat-history": "DUT1 and DUT2 VAT History" + "conf-history": "DUT1 and DUT2 VAT History" "show-run": "Show Run" "status": "PASS" | "FAIL" }, @@ -251,6 +252,9 @@ class ExecutionChecker(ResultVisitor): # TODO: Remove when definitely no NDRPDRDISC tests are used: REGEX_RATE = re.compile(r'^[\D\d]*FINAL_RATE:\s(\d+\.\d+)\s(\w+)') + REGEX_PLR_RATE = re.compile(r'PLRsearch lower bound::\s(\d+.\d+).*\n' + r'PLRsearch upper bound::\s(\d+.\d+)') + REGEX_NDRPDR_RATE = re.compile(r'NDR_LOWER:\s(\d+.\d+).*\n.*\n' r'NDR_UPPER:\s(\d+.\d+).*\n' r'PDR_LOWER:\s(\d+.\d+).*\n.*\n' @@ -275,7 +279,8 @@ class ExecutionChecker(ResultVisitor): REGEX_TOLERANCE = re.compile(r'^[\D\d]*LOSS_ACCEPTANCE:\s(\d*\.\d*)\s' r'[\D\d]*') - REGEX_VERSION_VPP = re.compile(r"(return STDOUT Version:\s*)(.*)") + REGEX_VERSION_VPP = re.compile(r"(return STDOUT Version:\s*|" + r"VPP Version:\s*)(.*)") REGEX_VERSION_DPDK = re.compile(r"(return STDOUT testpmd)([\d\D\n]*)" r"(RTE Version: 'DPDK )(.*)(')") @@ -318,6 +323,9 @@ class ExecutionChecker(ResultVisitor): # Timestamp self._timestamp = None + # Testbed. The testbed is identified by TG node IP address. + self._testbed = None + # Mapping of TCs long names self._mapping = mapping @@ -329,7 +337,7 @@ class ExecutionChecker(ResultVisitor): # 1 - VAT History of DUT1 # 2 - VAT History of DUT2 self._lookup_kw_nr = 0 - self._vat_history_lookup_nr = 0 + self._conf_history_lookup_nr = 0 # Number of Show Running messages found # 0 - no message @@ -358,7 +366,9 @@ class ExecutionChecker(ResultVisitor): "vpp-version": self._get_vpp_version, "dpdk-version": self._get_dpdk_version, "teardown-vat-history": self._get_vat_history, - "test-show-runtime": self._get_show_run + "teardown-papi-history": self._get_papi_history, + "test-show-runtime": self._get_show_run, + "testbed": self._get_testbed } @property @@ -370,6 +380,28 @@ class ExecutionChecker(ResultVisitor): """ return self._data + def _get_testbed(self, msg): + """Called when extraction of testbed IP is required. + The testbed is identified by TG node IP address. + + :param msg: Message to process. + :type msg: Message + :returns: Nothing. + """ + + if msg.message.count("Arguments:"): + message = str(msg.message).replace(' ', '').replace('\n', '').\ + replace("'", '"').replace('b"', '"').\ + replace("honeycom", "honeycomb") + message = loads(message[11:-1]) + try: + self._testbed = message["TG"]["host"] + except (KeyError, ValueError): + pass + finally: + self._data["metadata"]["testbed"] = self._testbed + self._msg_type = None + def _get_vpp_version(self, msg): """Called when extraction of VPP version is required. @@ -378,7 +410,9 @@ class ExecutionChecker(ResultVisitor): :returns: Nothing. """ - if msg.message.count("return STDOUT Version:"): + if msg.message.count("return STDOUT Version:") or \ + msg.message.count("VPP Version:") or \ + msg.message.count("VPP version:"): self._version = str(re.search(self.REGEX_VERSION_VPP, msg.message). group(2)) self._data["metadata"]["version"] = self._version @@ -422,9 +456,9 @@ class ExecutionChecker(ResultVisitor): :returns: Nothing. """ if msg.message.count("VAT command history:"): - self._vat_history_lookup_nr += 1 - if self._vat_history_lookup_nr == 1: - self._data["tests"][self._test_ID]["vat-history"] = str() + self._conf_history_lookup_nr += 1 + if self._conf_history_lookup_nr == 1: + self._data["tests"][self._test_ID]["conf-history"] = str() else: self._msg_type = None text = re.sub("[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} " @@ -432,9 +466,31 @@ class ExecutionChecker(ResultVisitor): replace("\n\n", "\n").replace('\n', ' |br| ').\ replace('\r', '').replace('"', "'") - self._data["tests"][self._test_ID]["vat-history"] += " |br| " - self._data["tests"][self._test_ID]["vat-history"] += \ - "**DUT" + str(self._vat_history_lookup_nr) + ":** " + text + self._data["tests"][self._test_ID]["conf-history"] += " |br| " + self._data["tests"][self._test_ID]["conf-history"] += \ + "**DUT" + str(self._conf_history_lookup_nr) + ":** " + text + + def _get_papi_history(self, msg): + """Called when extraction of PAPI command history is required. + + :param msg: Message to process. + :type msg: Message + :returns: Nothing. + """ + if msg.message.count("PAPI command history:"): + self._conf_history_lookup_nr += 1 + if self._conf_history_lookup_nr == 1: + self._data["tests"][self._test_ID]["conf-history"] = str() + else: + self._msg_type = None + text = re.sub("[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} " + "PAPI command history:", "", msg.message, count=1). \ + replace("\n\n", "\n").replace('\n', ' |br| ').\ + replace('\r', '').replace('"', "'") + + self._data["tests"][self._test_ID]["conf-history"] += " |br| " + self._data["tests"][self._test_ID]["conf-history"] += \ + "**DUT" + str(self._conf_history_lookup_nr) + ":** " + text def _get_show_run(self, msg): """Called when extraction of VPP operational data (output of CLI command @@ -538,6 +594,33 @@ class ExecutionChecker(ResultVisitor): return throughput, status + def _get_plr_throughput(self, msg): + """Get PLRsearch lower bound and PLRsearch upper bound from the test + message. + + :param msg: The test message to be parsed. + :type msg: str + :returns: Parsed data as a dict and the status (PASS/FAIL). + :rtype: tuple(dict, str) + """ + + throughput = { + "LOWER": -1.0, + "UPPER": -1.0 + } + status = "FAIL" + groups = re.search(self.REGEX_PLR_RATE, msg) + + if groups is not None: + try: + throughput["LOWER"] = float(groups.group(1)) + throughput["UPPER"] = float(groups.group(2)) + status = "PASS" + except (IndexError, ValueError): + pass + + return throughput, status + def _get_ndrpdr_latency(self, msg): """Get LATENCY from the test message. @@ -710,6 +793,7 @@ class ExecutionChecker(ResultVisitor): if test.status == "PASS" and ("NDRPDRDISC" in tags or "NDRPDR" in tags or + "SOAK" in tags or "TCP" in tags or "MRR" in tags or "BMRR" in tags): @@ -721,6 +805,8 @@ class ExecutionChecker(ResultVisitor): test_result["type"] = "PDR" elif "NDRPDR" in tags: test_result["type"] = "NDRPDR" + elif "SOAK" in tags: + test_result["type"] = "SOAK" elif "TCP" in tags: test_result["type"] = "TCP" elif "MRR" in tags: @@ -761,6 +847,10 @@ class ExecutionChecker(ResultVisitor): test_result["latency"], test_result["status"] = \ self._get_ndrpdr_latency(test.message) + elif test_result["type"] in ("SOAK", ): + test_result["throughput"], test_result["status"] = \ + self._get_plr_throughput(test.message) + elif test_result["type"] in ("TCP", ): groups = re.search(self.REGEX_TCP, test.message) test_result["result"] = int(groups.group(2)) @@ -901,6 +991,8 @@ class ExecutionChecker(ResultVisitor): elif setup_kw.name.count("Setup performance global Variables") \ and not self._timestamp: self._msg_type = "timestamp" + elif setup_kw.name.count("Setup Framework") and not self._testbed: + self._msg_type = "testbed" else: return setup_kw.messages.visit(self) @@ -937,9 +1029,13 @@ class ExecutionChecker(ResultVisitor): """ if teardown_kw.name.count("Show Vat History On All Duts"): - self._vat_history_lookup_nr = 0 + self._conf_history_lookup_nr = 0 self._msg_type = "teardown-vat-history" teardown_kw.messages.visit(self) + elif teardown_kw.name.count("Show Papi History On All Duts"): + self._conf_history_lookup_nr = 0 + self._msg_type = "teardown-papi-history" + teardown_kw.messages.visit(self) def end_teardown_kw(self, teardown_kw): """Called when keyword ends. Default implementation does nothing.