blob: 32fde14a7def76e973dffbc3de27eb4469b74a23 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
2
3import sys
4import os
5import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -05006
7# A parser that can be used to identify weather a line is a test result or a section statement.
Andrew Geissler99467da2019-02-25 18:54:23 -06008class PtestParser(object):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05009 def __init__(self):
Andrew Geissler99467da2019-02-25 18:54:23 -060010 self.results = {}
11 self.sections = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012
Andrew Geissler99467da2019-02-25 18:54:23 -060013 def parse(self, logfile):
14 test_regex = {}
15 test_regex['PASSED'] = re.compile(r"^PASS:(.+)")
16 test_regex['FAILED'] = re.compile(r"^FAIL:(.+)")
17 test_regex['SKIPPED'] = re.compile(r"^SKIP:(.+)")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050018
Andrew Geissler99467da2019-02-25 18:54:23 -060019 section_regex = {}
20 section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
21 section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
22 section_regex['duration'] = re.compile(r"^DURATION: (.+)")
23 section_regex['exitcode'] = re.compile(r"^ERROR: Exit status is (.+)")
24 section_regex['timeout'] = re.compile(r"^TIMEOUT: .*/(.+)/ptest")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050025
Andrew Geissler99467da2019-02-25 18:54:23 -060026 def newsection():
27 return { 'name': "No-section", 'log': "" }
28
29 current_section = newsection()
30
31 with open(logfile, errors='replace') as f:
32 for line in f:
33 result = section_regex['begin'].search(line)
34 if result:
35 current_section['name'] = result.group(1)
36 continue
37
38 result = section_regex['end'].search(line)
39 if result:
40 if current_section['name'] != result.group(1):
41 bb.warn("Ptest END log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
42 if current_section['name'] in self.sections:
43 bb.warn("Ptest duplicate section for %s" % (current_section['name']))
44 self.sections[current_section['name']] = current_section
45 del self.sections[current_section['name']]['name']
46 current_section = newsection()
47 continue
48
49 result = section_regex['timeout'].search(line)
50 if result:
51 if current_section['name'] != result.group(1):
52 bb.warn("Ptest TIMEOUT log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
53 current_section['timeout'] = True
54 continue
55
56 for t in ['duration', 'exitcode']:
57 result = section_regex[t].search(line)
58 if result:
59 current_section[t] = result.group(1)
60 continue
61
62 current_section['log'] = current_section['log'] + line
63
64 for t in test_regex:
65 result = test_regex[t].search(line)
66 if result:
67 if current_section['name'] not in self.results:
68 self.results[current_section['name']] = {}
69 self.results[current_section['name']][result.group(1)] = t
70
71 return self.results, self.sections
Patrick Williamsc124f4f2015-09-15 14:41:29 -050072
73 # Log the results as files. The file name is the section name and the contents are the tests in that section.
Andrew Geissler99467da2019-02-25 18:54:23 -060074 def results_as_files(self, target_dir):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 if not os.path.exists(target_dir):
76 raise Exception("Target directory does not exist: %s" % target_dir)
77
Andrew Geissler99467da2019-02-25 18:54:23 -060078 for section in self.results:
79 prefix = 'No-section'
Brad Bishopd7bf8c12018-02-25 22:55:05 -050080 if section:
Andrew Geissler99467da2019-02-25 18:54:23 -060081 prefix = section
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082 section_file = os.path.join(target_dir, prefix)
83 # purge the file contents if it exists
Andrew Geissler99467da2019-02-25 18:54:23 -060084 with open(section_file, 'w') as f:
85 for test_name in sorted(self.results[section]):
86 status = self.results[section][test_name]
87 f.write(status + ": " + test_name + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050088