diff options
| -rw-r--r-- | meta/lib/oeqa/runtime/cases/ptest.py | 4 | ||||
| -rw-r--r-- | meta/lib/oeqa/utils/logparser.py | 40 |
2 files changed, 37 insertions, 7 deletions
diff --git a/meta/lib/oeqa/runtime/cases/ptest.py b/meta/lib/oeqa/runtime/cases/ptest.py index ae54a01669..3cfd7af7e2 100644 --- a/meta/lib/oeqa/runtime/cases/ptest.py +++ b/meta/lib/oeqa/runtime/cases/ptest.py | |||
| @@ -49,13 +49,15 @@ class PtestRunnerTest(OERuntimeTestCase): | |||
| 49 | extras['ptestresult.rawlogs'] = {'log': output} | 49 | extras['ptestresult.rawlogs'] = {'log': output} |
| 50 | 50 | ||
| 51 | # Parse and save results | 51 | # Parse and save results |
| 52 | parse_result = PtestParser().parse(ptest_runner_log) | 52 | parse_result, sections = PtestParser().parse(ptest_runner_log) |
| 53 | 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']) |
| 54 | if os.path.exists(ptest_log_dir_link): | 54 | if os.path.exists(ptest_log_dir_link): |
| 55 | # Remove the old link to create a new one | 55 | # Remove the old link to create a new one |
| 56 | os.remove(ptest_log_dir_link) | 56 | os.remove(ptest_log_dir_link) |
| 57 | os.symlink(os.path.basename(ptest_log_dir), ptest_log_dir_link) | 57 | os.symlink(os.path.basename(ptest_log_dir), ptest_log_dir_link) |
| 58 | 58 | ||
| 59 | extras['ptestresult.sections'] = sections | ||
| 60 | |||
| 59 | trans = str.maketrans("()", "__") | 61 | trans = str.maketrans("()", "__") |
| 60 | resmap = {'pass': 'PASSED', 'skip': 'SKIPPED', 'fail': 'FAILED'} | 62 | resmap = {'pass': 'PASSED', 'skip': 'SKIPPED', 'fail': 'FAILED'} |
| 61 | for section in parse_result.result_dict: | 63 | for section in parse_result.result_dict: |
diff --git a/meta/lib/oeqa/utils/logparser.py b/meta/lib/oeqa/utils/logparser.py index f8d1c03630..dddea14fc9 100644 --- a/meta/lib/oeqa/utils/logparser.py +++ b/meta/lib/oeqa/utils/logparser.py | |||
| @@ -9,6 +9,7 @@ from . import ftools | |||
| 9 | class PtestParser(object): | 9 | class PtestParser(object): |
| 10 | def __init__(self): | 10 | def __init__(self): |
| 11 | self.results = Result() | 11 | self.results = Result() |
| 12 | self.sections = {} | ||
| 12 | 13 | ||
| 13 | def parse(self, logfile): | 14 | def parse(self, logfile): |
| 14 | test_regex = {} | 15 | test_regex = {} |
| @@ -19,28 +20,55 @@ class PtestParser(object): | |||
| 19 | section_regex = {} | 20 | section_regex = {} |
| 20 | section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest") | 21 | section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest") |
| 21 | section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest") | 22 | section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest") |
| 23 | section_regex['duration'] = re.compile(r"^DURATION: (.+)") | ||
| 24 | section_regex['exitcode'] = re.compile(r"^ERROR: Exit status is (.+)") | ||
| 25 | section_regex['timeout'] = re.compile(r"^TIMEOUT: .*/(.+)/ptest") | ||
| 26 | |||
| 27 | def newsection(): | ||
| 28 | return { 'name': "No-section", 'log': "" } | ||
| 29 | |||
| 30 | current_section = newsection() | ||
| 22 | 31 | ||
| 23 | with open(logfile, errors='replace') as f: | 32 | with open(logfile, errors='replace') as f: |
| 24 | for line in f: | 33 | for line in f: |
| 25 | result = section_regex['begin'].search(line) | 34 | result = section_regex['begin'].search(line) |
| 26 | if result: | 35 | if result: |
| 27 | current_section = result.group(1) | 36 | current_section['name'] = result.group(1) |
| 28 | continue | 37 | continue |
| 29 | 38 | ||
| 30 | result = section_regex['end'].search(line) | 39 | result = section_regex['end'].search(line) |
| 31 | if result: | 40 | if result: |
| 32 | if current_section != result.group(1): | 41 | if current_section['name'] != result.group(1): |
| 33 | bb.warn("Ptest log section mismatch %s vs. %s" % (current_section, result.group(1))) | 42 | bb.warn("Ptest END log section mismatch %s vs. %s" % (current_section['name'], result.group(1))) |
| 34 | current_section = None | 43 | if current_section['name'] in self.sections: |
| 44 | bb.warn("Ptest duplicate section for %s" % (current_section['name'])) | ||
| 45 | self.sections[current_section['name']] = current_section | ||
| 46 | del self.sections[current_section['name']]['name'] | ||
| 47 | current_section = newsection() | ||
| 48 | continue | ||
| 49 | |||
| 50 | result = section_regex['timeout'].search(line) | ||
| 51 | if result: | ||
| 52 | if current_section['name'] != result.group(1): | ||
| 53 | bb.warn("Ptest TIMEOUT log section mismatch %s vs. %s" % (current_section['name'], result.group(1))) | ||
| 54 | current_section['timeout'] = True | ||
| 35 | continue | 55 | continue |
| 36 | 56 | ||
| 57 | for t in ['duration', 'exitcode']: | ||
| 58 | result = section_regex[t].search(line) | ||
| 59 | if result: | ||
| 60 | current_section[t] = result.group(1) | ||
| 61 | continue | ||
| 62 | |||
| 63 | current_section['log'] = current_section['log'] + line | ||
| 64 | |||
| 37 | for t in test_regex: | 65 | for t in test_regex: |
| 38 | result = test_regex[t].search(line) | 66 | result = test_regex[t].search(line) |
| 39 | if result: | 67 | if result: |
| 40 | self.results.store(current_section, result.group(1), t) | 68 | self.results.store(current_section['name'], result.group(1), t) |
| 41 | 69 | ||
| 42 | self.results.sort_tests() | 70 | self.results.sort_tests() |
| 43 | return self.results | 71 | return self.results, self.sections |
| 44 | 72 | ||
| 45 | class Result(object): | 73 | class Result(object): |
| 46 | 74 | ||
