From: Vallari Agrawal Date: Thu, 16 Jun 2022 11:17:33 +0000 (+0530) Subject: orch/run: Read logs line by line X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ae01aa825a259eb69857865bf66e06a3f1cb4ee9;p=teuthology.git orch/run: Read logs line by line And include test name in UnitTestError Signed-off-by: Vallari Agrawal --- diff --git a/teuthology/exceptions.py b/teuthology/exceptions.py index c02eed4f6..c45885a41 100644 --- a/teuthology/exceptions.py +++ b/teuthology/exceptions.py @@ -211,20 +211,23 @@ class UnitTestError(Exception): """ Exception thrown on unit test failure """ - def __init__(self, command, exitstatus, node=None, label=None, message=""): + def __init__(self, command, exitstatus, node=None, label=None, test=None, message=None): self.command = command self.exitstatus = exitstatus self.node = node self.label = label + self.test = test self.message = message def __str__(self): prefix = "Unit test failed" + if self.test: + prefix = "{failed_test} test failed".format(failed_test=self.test) if self.label: prefix += " ({label})".format(label=self.label) if self.node: prefix += " on {node}".format(node=self.node) - return "{prefix} with status {status}: {message}".format( + return "{prefix} with status {status}: '{message}'".format( prefix=prefix, status=self.exitstatus, message=self.message, diff --git a/teuthology/orchestra/run.py b/teuthology/orchestra/run.py index eab28ed49..196c093af 100644 --- a/teuthology/orchestra/run.py +++ b/teuthology/orchestra/run.py @@ -183,13 +183,13 @@ class RemoteProcess(object): raise CommandCrashedError(command=self.command) if self.returncode != 0: if self.scan_tests_errors: - error = ErrorScanner(self.scan_tests_errors).scan() + test, error = ErrorScanner().scan(test_names=self.scan_tests_errors) if error: raise UnitTestError( command=self.command, exitstatus=self.returncode, node=self.hostname, label=self.label, - message=error, - ) + test=test, message=error, + ) raise CommandFailedError( command=self.command, exitstatus=self.returncode, node=self.hostname, label=self.label @@ -238,32 +238,35 @@ class ErrorScanner(object): Scan for unit tests errors in teuthology.log """ __flag__ = 0 - def __init__(self, test_names=[]): + def scan(self, test_names=[]): self.test_names = test_names - - def scan(self): logfile = self.__logfile__ if not logfile or not self.test_names: - return None - + return None, None + ERROR_PATTERN = { "nose": r"ERROR:\s", "gtest": r"\[\s\sFAILED\s\s\]", } - logs = [] - with open(logfile, 'r') as f: - logs = f.readlines() + error_test = None + error_msg = None - for line_number in range(len(logs) - 1, ErrorScanner.__flag__, -1): - line = logs[line_number] + f = open(logfile, 'r') + f.seek(ErrorScanner.__flag__ + 1) + while f: + line = f.readline() for test in self.test_names: pattern = ERROR_PATTERN[test] error = re.search(pattern, line) if error: - ErrorScanner.__flag__ = line_number - return line[error.start():].strip() - ErrorScanner.__flag__ = len(logs) - 1 - return None + error_test = test + error_msg = line[error.start():].strip() + break + if error_msg: + break + ErrorScanner.__flag__ = f.tell() + f.close() + return error_test, error_msg @property def __logfile__(self):