mirror of
https://git.yoctoproject.org/poky
synced 2026-06-01 00:59:48 +00:00
oeqa/logparser: Reform the ptest results parser
Now we have a dedicated ptest parser, merge in the remaining ptest specific pieces to further clarify and simplify the code, moving to a point where we can consider extending/enhancing it. (From OE-Core rev: 05991bb5bc8018275d03fdeecee3d5a757840c7c) (From OE-Core rev: e514c34195a7e1b2b7a1916ebd8c8ef631c60a01) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
@@ -1,50 +1,16 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import pprint
|
import pprint
|
||||||
|
import re
|
||||||
|
|
||||||
from oeqa.runtime.case import OERuntimeTestCase
|
from oeqa.runtime.case import OERuntimeTestCase
|
||||||
from oeqa.core.decorator.depends import OETestDepends
|
from oeqa.core.decorator.depends import OETestDepends
|
||||||
from oeqa.core.decorator.oeid import OETestID
|
from oeqa.core.decorator.oeid import OETestID
|
||||||
from oeqa.core.decorator.data import skipIfNotFeature
|
from oeqa.core.decorator.data import skipIfNotFeature
|
||||||
from oeqa.runtime.decorator.package import OEHasPackage
|
from oeqa.runtime.decorator.package import OEHasPackage
|
||||||
from oeqa.utils.logparser import PtestParser, Result
|
from oeqa.utils.logparser import PtestParser
|
||||||
|
|
||||||
class PtestRunnerTest(OERuntimeTestCase):
|
class PtestRunnerTest(OERuntimeTestCase):
|
||||||
|
|
||||||
# a ptest log parser
|
|
||||||
def parse_ptest(self, logfile):
|
|
||||||
parser = PtestParser()
|
|
||||||
result = Result()
|
|
||||||
|
|
||||||
with open(logfile, errors='replace') as f:
|
|
||||||
for line in f:
|
|
||||||
result_tuple = parser.parse_line(line)
|
|
||||||
if not result_tuple:
|
|
||||||
continue
|
|
||||||
line_type, category, status, name = result_tuple
|
|
||||||
|
|
||||||
if line_type == 'section' and status == 'begin':
|
|
||||||
current_section = name
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line_type == 'section' and status == 'end':
|
|
||||||
current_section = None
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line_type == 'test' and status == 'pass':
|
|
||||||
result.store(current_section, name, status)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line_type == 'test' and status == 'fail':
|
|
||||||
result.store(current_section, name, status)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line_type == 'test' and status == 'skip':
|
|
||||||
result.store(current_section, name, status)
|
|
||||||
continue
|
|
||||||
|
|
||||||
result.sort_tests()
|
|
||||||
return result
|
|
||||||
|
|
||||||
@OETestID(1600)
|
@OETestID(1600)
|
||||||
@skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES')
|
@skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES')
|
||||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||||
@@ -83,7 +49,7 @@ class PtestRunnerTest(OERuntimeTestCase):
|
|||||||
extras['ptestresult.rawlogs'] = {'log': output}
|
extras['ptestresult.rawlogs'] = {'log': output}
|
||||||
|
|
||||||
# Parse and save results
|
# Parse and save results
|
||||||
parse_result = self.parse_ptest(ptest_runner_log)
|
parse_result = PtestParser().parse(ptest_runner_log)
|
||||||
parse_result.log_as_files(ptest_log_dir, test_status = ['pass','fail', 'skip'])
|
parse_result.log_as_files(ptest_log_dir, test_status = ['pass','fail', 'skip'])
|
||||||
if os.path.exists(ptest_log_dir_link):
|
if os.path.exists(ptest_log_dir_link):
|
||||||
# Remove the old link to create a new one
|
# Remove the old link to create a new one
|
||||||
|
|||||||
@@ -7,32 +7,40 @@ from . import ftools
|
|||||||
|
|
||||||
# A parser that can be used to identify weather a line is a test result or a section statement.
|
# A parser that can be used to identify weather a line is a test result or a section statement.
|
||||||
class PtestParser(object):
|
class PtestParser(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.results = Result()
|
||||||
|
|
||||||
self.test_regex = {}
|
def parse(self, logfile):
|
||||||
self.test_regex['pass'] = re.compile(r"^PASS:(.+)")
|
test_regex = {}
|
||||||
self.test_regex['fail'] = re.compile(r"^FAIL:(.+)")
|
test_regex['pass'] = re.compile(r"^PASS:(.+)")
|
||||||
self.test_regex['skip'] = re.compile(r"^SKIP:(.+)")
|
test_regex['fail'] = re.compile(r"^FAIL:(.+)")
|
||||||
|
test_regex['skip'] = re.compile(r"^SKIP:(.+)")
|
||||||
|
|
||||||
self.section_regex = {}
|
section_regex = {}
|
||||||
self.section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
|
section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
|
||||||
self.section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
|
section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
|
||||||
|
|
||||||
# Parse a line and return a tuple containing the type of result (test/section) and its category, status and name
|
with open(logfile, errors='replace') as f:
|
||||||
def parse_line(self, line):
|
for line in f:
|
||||||
|
result = section_regex['begin'].search(line)
|
||||||
|
if result:
|
||||||
|
current_section = result.group(1)
|
||||||
|
continue
|
||||||
|
|
||||||
for test_status, status_regex in test_status_list.items():
|
result = section_regex['end'].search(line)
|
||||||
test_name = status_regex.search(line)
|
if result:
|
||||||
if test_name:
|
if current_section != result.group(1):
|
||||||
return ['test', test_category, test_status, test_name.group(1)]
|
bb.warn("Ptest log section mismatch %s vs. %s" % (current_section, result.group(1)))
|
||||||
|
current_section = None
|
||||||
|
continue
|
||||||
|
|
||||||
for section_status, status_regex in section_status_list.items():
|
for t in test_regex:
|
||||||
section_name = status_regex.search(line)
|
result = test_regex[t].search(line)
|
||||||
if section_name:
|
if result:
|
||||||
return ['section', section_category, section_status, section_name.group(1)]
|
self.results.store(current_section, result.group(1), t)
|
||||||
return None
|
|
||||||
|
|
||||||
|
self.results.sort_tests()
|
||||||
|
return self.results
|
||||||
|
|
||||||
class Result(object):
|
class Result(object):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user