diff options
| author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-01-29 13:24:45 +0000 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-02-25 22:27:39 +0000 |
| commit | ff0a227e4c3e949ab4dca31c60ec693b40b9ce28 (patch) | |
| tree | ee8add934f55cc826bd8c301798ca723a85075a7 | |
| parent | a18ab724da3b93e0ebca6972cdfcb1145cffad5f (diff) | |
| download | poky-ff0a227e4c3e949ab4dca31c60ec693b40b9ce28.tar.gz | |
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>
| -rw-r--r-- | meta/lib/oeqa/runtime/cases/ptest.py | 40 | ||||
| -rw-r--r-- | meta/lib/oeqa/utils/logparser.py | 58 |
2 files changed, 36 insertions, 62 deletions
diff --git a/meta/lib/oeqa/runtime/cases/ptest.py b/meta/lib/oeqa/runtime/cases/ptest.py index 1ce22a09e7..ae54a01669 100644 --- a/meta/lib/oeqa/runtime/cases/ptest.py +++ b/meta/lib/oeqa/runtime/cases/ptest.py | |||
| @@ -1,50 +1,16 @@ | |||
| 1 | import unittest | 1 | import unittest |
| 2 | import pprint | 2 | import pprint |
| 3 | import re | ||
| 3 | 4 | ||
| 4 | from oeqa.runtime.case import OERuntimeTestCase | 5 | from oeqa.runtime.case import OERuntimeTestCase |
| 5 | from oeqa.core.decorator.depends import OETestDepends | 6 | from oeqa.core.decorator.depends import OETestDepends |
| 6 | from oeqa.core.decorator.oeid import OETestID | 7 | from oeqa.core.decorator.oeid import OETestID |
| 7 | from oeqa.core.decorator.data import skipIfNotFeature | 8 | from oeqa.core.decorator.data import skipIfNotFeature |
| 8 | from oeqa.runtime.decorator.package import OEHasPackage | 9 | from oeqa.runtime.decorator.package import OEHasPackage |
| 9 | from oeqa.utils.logparser import PtestParser, Result | 10 | from oeqa.utils.logparser import PtestParser |
| 10 | 11 | ||
| 11 | class PtestRunnerTest(OERuntimeTestCase): | 12 | class PtestRunnerTest(OERuntimeTestCase): |
| 12 | 13 | ||
| 13 | # a ptest log parser | ||
| 14 | def parse_ptest(self, logfile): | ||
| 15 | parser = PtestParser() | ||
| 16 | result = Result() | ||
| 17 | |||
| 18 | with open(logfile, errors='replace') as f: | ||
| 19 | for line in f: | ||
| 20 | result_tuple = parser.parse_line(line) | ||
| 21 | if not result_tuple: | ||
| 22 | continue | ||
| 23 | line_type, category, status, name = result_tuple | ||
| 24 | |||
| 25 | if line_type == 'section' and status == 'begin': | ||
| 26 | current_section = name | ||
| 27 | continue | ||
| 28 | |||
| 29 | if line_type == 'section' and status == 'end': | ||
| 30 | current_section = None | ||
| 31 | continue | ||
| 32 | |||
| 33 | if line_type == 'test' and status == 'pass': | ||
| 34 | result.store(current_section, name, status) | ||
| 35 | continue | ||
| 36 | |||
| 37 | if line_type == 'test' and status == 'fail': | ||
| 38 | result.store(current_section, name, status) | ||
| 39 | continue | ||
| 40 | |||
| 41 | if line_type == 'test' and status == 'skip': | ||
| 42 | result.store(current_section, name, status) | ||
| 43 | continue | ||
| 44 | |||
| 45 | result.sort_tests() | ||
| 46 | return result | ||
| 47 | |||
| 48 | @OETestID(1600) | 14 | @OETestID(1600) |
| 49 | @skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES') | 15 | @skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES') |
| 50 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 16 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
| @@ -83,7 +49,7 @@ class PtestRunnerTest(OERuntimeTestCase): | |||
| 83 | extras['ptestresult.rawlogs'] = {'log': output} | 49 | extras['ptestresult.rawlogs'] = {'log': output} |
| 84 | 50 | ||
| 85 | # Parse and save results | 51 | # Parse and save results |
| 86 | parse_result = self.parse_ptest(ptest_runner_log) | 52 | parse_result = PtestParser().parse(ptest_runner_log) |
| 87 | parse_result.log_as_files(ptest_log_dir, test_status = ['pass','fail', 'skip']) | 53 | parse_result.log_as_files(ptest_log_dir, test_status = ['pass','fail', 'skip']) |
| 88 | if os.path.exists(ptest_log_dir_link): | 54 | if os.path.exists(ptest_log_dir_link): |
| 89 | # Remove the old link to create a new one | 55 | # Remove the old link to create a new one |
diff --git a/meta/lib/oeqa/utils/logparser.py b/meta/lib/oeqa/utils/logparser.py index 0807093fda..f8d1c03630 100644 --- a/meta/lib/oeqa/utils/logparser.py +++ b/meta/lib/oeqa/utils/logparser.py | |||
| @@ -7,32 +7,40 @@ from . import ftools | |||
| 7 | 7 | ||
| 8 | # A parser that can be used to identify weather a line is a test result or a section statement. | 8 | # A parser that can be used to identify weather a line is a test result or a section statement. |
| 9 | class PtestParser(object): | 9 | class PtestParser(object): |
| 10 | |||
| 11 | def __init__(self): | 10 | def __init__(self): |
| 12 | 11 | self.results = Result() | |
| 13 | self.test_regex = {} | 12 | |
| 14 | self.test_regex['pass'] = re.compile(r"^PASS:(.+)") | 13 | def parse(self, logfile): |
| 15 | self.test_regex['fail'] = re.compile(r"^FAIL:(.+)") | 14 | test_regex = {} |
| 16 | self.test_regex['skip'] = re.compile(r"^SKIP:(.+)") | 15 | test_regex['pass'] = re.compile(r"^PASS:(.+)") |
| 17 | 16 | test_regex['fail'] = re.compile(r"^FAIL:(.+)") | |
| 18 | self.section_regex = {} | 17 | test_regex['skip'] = re.compile(r"^SKIP:(.+)") |
| 19 | self.section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest") | 18 | |
| 20 | self.section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest") | 19 | section_regex = {} |
| 21 | 20 | section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest") | |
| 22 | # Parse a line and return a tuple containing the type of result (test/section) and its category, status and name | 21 | section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest") |
| 23 | def parse_line(self, line): | 22 | |
| 24 | 23 | with open(logfile, errors='replace') as f: | |
| 25 | for test_status, status_regex in test_status_list.items(): | 24 | for line in f: |
| 26 | test_name = status_regex.search(line) | 25 | result = section_regex['begin'].search(line) |
| 27 | if test_name: | 26 | if result: |
| 28 | return ['test', test_category, test_status, test_name.group(1)] | 27 | current_section = result.group(1) |
| 29 | 28 | continue | |
| 30 | for section_status, status_regex in section_status_list.items(): | 29 | |
| 31 | section_name = status_regex.search(line) | 30 | result = section_regex['end'].search(line) |
| 32 | if section_name: | 31 | if result: |
| 33 | return ['section', section_category, section_status, section_name.group(1)] | 32 | if current_section != result.group(1): |
| 34 | return None | 33 | bb.warn("Ptest log section mismatch %s vs. %s" % (current_section, result.group(1))) |
| 35 | 34 | current_section = None | |
| 35 | continue | ||
| 36 | |||
| 37 | for t in test_regex: | ||
| 38 | result = test_regex[t].search(line) | ||
| 39 | if result: | ||
| 40 | self.results.store(current_section, result.group(1), t) | ||
| 41 | |||
| 42 | self.results.sort_tests() | ||
| 43 | return self.results | ||
| 36 | 44 | ||
| 37 | class Result(object): | 45 | class Result(object): |
| 38 | 46 | ||
