blob: b31214b1c728da56c0cdc4fb9060256cdb3b7b52 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
Brad Bishopc342db32019-05-15 21:57:59 -04002#
3# SPDX-License-Identifier: MIT
4#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005
6import sys
7import os
8import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -05009
10# 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 -060011class PtestParser(object):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012 def __init__(self):
Andrew Geissler99467da2019-02-25 18:54:23 -060013 self.results = {}
14 self.sections = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015
Andrew Geissler99467da2019-02-25 18:54:23 -060016 def parse(self, logfile):
17 test_regex = {}
18 test_regex['PASSED'] = re.compile(r"^PASS:(.+)")
Brad Bishopf3fd2882019-06-21 08:06:37 -040019 test_regex['FAILED'] = re.compile(r"^FAIL:([^(]+)")
Andrew Geissler99467da2019-02-25 18:54:23 -060020 test_regex['SKIPPED'] = re.compile(r"^SKIP:(.+)")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021
Andrew Geissler99467da2019-02-25 18:54:23 -060022 section_regex = {}
23 section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
24 section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
25 section_regex['duration'] = re.compile(r"^DURATION: (.+)")
26 section_regex['exitcode'] = re.compile(r"^ERROR: Exit status is (.+)")
27 section_regex['timeout'] = re.compile(r"^TIMEOUT: .*/(.+)/ptest")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028
Andrew Geissler99467da2019-02-25 18:54:23 -060029 def newsection():
30 return { 'name': "No-section", 'log': "" }
31
32 current_section = newsection()
33
34 with open(logfile, errors='replace') as f:
35 for line in f:
36 result = section_regex['begin'].search(line)
37 if result:
38 current_section['name'] = result.group(1)
39 continue
40
41 result = section_regex['end'].search(line)
42 if result:
43 if current_section['name'] != result.group(1):
44 bb.warn("Ptest END log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
45 if current_section['name'] in self.sections:
46 bb.warn("Ptest duplicate section for %s" % (current_section['name']))
47 self.sections[current_section['name']] = current_section
48 del self.sections[current_section['name']]['name']
49 current_section = newsection()
50 continue
51
52 result = section_regex['timeout'].search(line)
53 if result:
54 if current_section['name'] != result.group(1):
55 bb.warn("Ptest TIMEOUT log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
56 current_section['timeout'] = True
57 continue
58
59 for t in ['duration', 'exitcode']:
60 result = section_regex[t].search(line)
61 if result:
62 current_section[t] = result.group(1)
63 continue
64
65 current_section['log'] = current_section['log'] + line
66
67 for t in test_regex:
68 result = test_regex[t].search(line)
69 if result:
70 if current_section['name'] not in self.results:
71 self.results[current_section['name']] = {}
Brad Bishopf3fd2882019-06-21 08:06:37 -040072 self.results[current_section['name']][result.group(1).strip()] = t
Andrew Geissler99467da2019-02-25 18:54:23 -060073
74 return self.results, self.sections
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075
76 # 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 -060077 def results_as_files(self, target_dir):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078 if not os.path.exists(target_dir):
79 raise Exception("Target directory does not exist: %s" % target_dir)
80
Andrew Geissler99467da2019-02-25 18:54:23 -060081 for section in self.results:
82 prefix = 'No-section'
Brad Bishopd7bf8c12018-02-25 22:55:05 -050083 if section:
Andrew Geissler99467da2019-02-25 18:54:23 -060084 prefix = section
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085 section_file = os.path.join(target_dir, prefix)
86 # purge the file contents if it exists
Andrew Geissler99467da2019-02-25 18:54:23 -060087 with open(section_file, 'w') as f:
88 for test_name in sorted(self.results[section]):
89 status = self.results[section][test_name]
90 f.write(status + ": " + test_name + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050091
Brad Bishopc342db32019-05-15 21:57:59 -040092
93# ltp log parsing
94class LtpParser(object):
95 def __init__(self):
96 self.results = {}
97 self.section = {'duration': "", 'log': ""}
98
99 def parse(self, logfile):
100 test_regex = {}
101 test_regex['PASSED'] = re.compile(r"PASS")
102 test_regex['FAILED'] = re.compile(r"FAIL")
103 test_regex['SKIPPED'] = re.compile(r"SKIP")
104
105 with open(logfile, errors='replace') as f:
106 for line in f:
107 for t in test_regex:
108 result = test_regex[t].search(line)
109 if result:
110 self.results[line.split()[0].strip()] = t
111
112 for test in self.results:
113 result = self.results[test]
114 self.section['log'] = self.section['log'] + ("%s: %s\n" % (result.strip()[:-2], test.strip()))
115
116 return self.results, self.section
117
118
119# ltp Compliance log parsing
120class LtpComplianceParser(object):
121 def __init__(self):
122 self.results = {}
123 self.section = {'duration': "", 'log': ""}
124
125 def parse(self, logfile):
126 test_regex = {}
127 test_regex['PASSED'] = re.compile(r"^PASS")
128 test_regex['FAILED'] = re.compile(r"^FAIL")
129 test_regex['SKIPPED'] = re.compile(r"(?:UNTESTED)|(?:UNSUPPORTED)")
130
131 section_regex = {}
132 section_regex['test'] = re.compile(r"^Testing")
133
134 with open(logfile, errors='replace') as f:
135 for line in f:
136 result = section_regex['test'].search(line)
137 if result:
138 self.name = ""
139 self.name = line.split()[1].strip()
140 self.results[self.name] = "PASSED"
141 failed = 0
142
143 failed_result = test_regex['FAILED'].search(line)
144 if failed_result:
145 failed = line.split()[1].strip()
146 if int(failed) > 0:
147 self.results[self.name] = "FAILED"
148
149 for test in self.results:
150 result = self.results[test]
151 self.section['log'] = self.section['log'] + ("%s: %s\n" % (result.strip()[:-2], test.strip()))
152
153 return self.results, self.section