- if alert["type"] == "failed-tests":
- text = ""
- html = "<html><body>"
- for item in alert["include"]:
- file_name = "{path}/{name}".format(
- path=self._path_failed_tests, name=item)
- try:
- with open("{0}.txt".format(file_name), 'r') as txt_file:
- text += "{0}:\n\n".format(
- item.replace("failed-tests-", ""))
- text += txt_file.read() + "\n" * 2
- except IOError:
- logging.error("Not possible to read the file '{0}.txt'.".
- format(file_name))
- try:
- with open("{0}.rst".format(file_name), 'r') as rst_file:
- html += "<h2>{0}:</h2>".format(
- item.replace("failed-tests-", ""))
- html += rst_file.readlines()[2].\
- replace("../trending", alert.get("url", ""))
- html += "<br>" * 3
- except IOError:
- logging.error("Not possible to read the file '{0}.rst'.".
- format(file_name))
- html += "</body></html>"
- else:
- raise AlertingError("Alert of type '{0}' is not implemented.".
- format(alert["type"]))
- return text, html
-
- def _generate_files_for_jenkins(self, alert):
+ directory = self.configs[alert[u"way"]][u"output-dir"]
+ failed_tests = defaultdict(dict)
+ file_path = f"{directory}/{test_set}.txt"
+ version = u""
+ try:
+ with open(file_path, u'r') as f_txt:
+ for idx, line in enumerate(f_txt):
+ if idx == 0:
+ build = line[:-1]
+ continue
+ if idx == 1:
+ version = line[:-1]
+ continue
+ if idx == 2:
+ passed = line[:-1]
+ continue
+ if idx == 3:
+ failed = line[:-1]
+ continue
+ if idx == 4:
+ minutes = int(line[:-1]) // 60000
+ duration = f"{(minutes // 60):02d}:{(minutes % 60):02d}"
+ continue
+ try:
+ line, error_msg = line[:-1].split(u'###', maxsplit=1)
+ test = line.split(u'-')
+ name = u'-'.join(test[3:-1])
+ if len(error_msg) > 128:
+ if u";" in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u';', 1)[0]}..."
+ elif u":" in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u':', 1)[0]}..."
+ elif u"." in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u'.', 1)[0]}..."
+ elif u"?" in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u'?', 1)[0]}..."
+ elif u"!" in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u'!', 1)[0]}..."
+ elif u"," in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u',', 1)[0]}..."
+ elif u" " in error_msg[128:256]:
+ error_msg = \
+ f"{error_msg[:128]}" \
+ f"{error_msg[128:].split(u' ', 1)[0]}..."
+ else:
+ error_msg = error_msg[:128]
+
+ except ValueError:
+ continue
+
+ for e_msg in self.error_msgs:
+ if SequenceMatcher(None, e_msg,
+ error_msg).ratio() > 0.5:
+ error_msg = e_msg
+ break
+ if error_msg not in self.error_msgs:
+ self.error_msgs.append(error_msg)
+
+ error_msg_index = self.error_msgs.index(error_msg)
+
+ if failed_tests.get(name, {}).get(error_msg_index) is None:
+ failed_tests[name][error_msg_index] = \
+ dict(nics=list(),
+ framesizes=list(),
+ cores=list())
+
+ if test[0] not in \
+ failed_tests[name][error_msg_index][u"nics"]:
+ failed_tests[name][error_msg_index][u"nics"].\
+ append(test[0])
+ if test[1] not in \
+ failed_tests[name][error_msg_index][u"framesizes"]:
+ failed_tests[name][error_msg_index][u"framesizes"].\
+ append(test[1])
+ check_core = test[2] + f"[{str(error_msg_index)}]"
+ if check_core not in \
+ failed_tests[name][error_msg_index][u"cores"]:
+ failed_tests[name][error_msg_index][u"cores"].\
+ append(test[2] + "[" + str(error_msg_index) + "]")
+
+ except IOError:
+ logging.error(f"No such file or directory: {file_path}")
+ return None, None, None, None, None, None
+ if sort:
+ sorted_failed_tests = OrderedDict()
+ for key in sorted(failed_tests.keys()):
+ sorted_failed_tests[key] = failed_tests[key]
+ return build, version, passed, failed, duration, sorted_failed_tests
+
+ return build, version, passed, failed, duration, failed_tests
+
+ def _list_gressions(self, alert, idx, header, re_pro):
+ """Create a file with regressions or progressions for the test set
+ specified by idx.
+
+ :param alert: Files are created for this alert.
+ :param idx: Index of the test set as it is specified in the
+ specification file.
+ :param header: The header of the list of [re|pro]gressions.
+ :param re_pro: 'regressions' or 'progressions'.
+ :type alert: dict
+ :type idx: int
+ :type header: str
+ :type re_pro: str
+ """
+
+ if re_pro not in (u"regressions", u"progressions"):
+ return
+
+ in_file = (
+ f"{self.configs[alert[u'way']][u'output-dir']}/"
+ f"{re_pro}-{alert[u'urls'][idx].split(u'/')[-1]}.txt"
+ )
+ out_file = (
+ f"{self.configs[alert[u'way']][u'output-dir']}/"
+ f"trending-{re_pro}.txt"
+ )
+
+ try:
+ with open(in_file, u'r') as txt_file:
+ file_content = txt_file.read()
+ with open(out_file, u'a+') as reg_file:
+ reg_file.write(header)
+ if file_content:
+ reg_file.write(file_content)
+ else:
+ reg_file.write(f"No {re_pro}")
+ except IOError as err:
+ logging.warning(repr(err))
+
+ def _generate_email_body(self, alert):