blob: 2c30f9ab736db58a325801d76d18f332b40aee22 [file] [log] [blame]
Anas Nashif3ae52622019-04-06 09:08:09 -04001# SPDX-License-Identifier: Apache-2.0
Anas Nashif576be982017-12-23 20:20:27 -05002import re
3from collections import OrderedDict
4
Anas Nashif47f16652020-04-11 09:57:43 -04005result_re = re.compile(".*(PASS|FAIL|SKIP) - (test_)?(.*)")
Andy Rossaa2b8a12019-03-06 09:45:30 -08006
Anas Nashif576be982017-12-23 20:20:27 -05007class Harness:
Anas Nashiff29087e2019-01-25 09:37:38 -05008 GCOV_START = "GCOV_COVERAGE_DUMP_START"
9 GCOV_END = "GCOV_COVERAGE_DUMP_END"
Andrew Boie81ef42d2019-07-16 15:29:46 -070010 FAULT = "ZEPHYR FATAL ERROR"
Anas Nashif83fc06a2019-06-22 11:04:10 -040011 RUN_PASSED = "PROJECT EXECUTION SUCCESSFUL"
12 RUN_FAILED = "PROJECT EXECUTION FAILED"
Anas Nashiff29087e2019-01-25 09:37:38 -050013
Anas Nashif576be982017-12-23 20:20:27 -050014 def __init__(self):
15 self.state = None
16 self.type = None
17 self.regex = []
18 self.matches = OrderedDict()
19 self.ordered = True
20 self.repeat = 1
Anas Nashife0a6a0b2018-02-15 20:07:24 -060021 self.tests = {}
Anas Nashif61e21632018-04-08 13:30:16 -050022 self.id = None
Anas Nashifb20c4842018-06-05 21:36:20 -050023 self.fail_on_fault = True
Anas Nashif77837e82018-08-29 10:05:27 -040024 self.fault = False
Anas Nashiff29087e2019-01-25 09:37:38 -050025 self.capture_coverage = False
Andy Ross5efdd6a2019-06-18 11:57:21 -070026 self.next_pattern = 0
Anas Nashif83fc06a2019-06-22 11:04:10 -040027 self.record = None
28 self.recording = []
29 self.fieldnames = []
Anas Nashif8b425fa2020-08-31 11:50:51 -040030 self.ztest = False
Anas Nashif576be982017-12-23 20:20:27 -050031
32 def configure(self, instance):
Anas Nashif83fc06a2019-06-22 11:04:10 -040033 config = instance.testcase.harness_config
34 self.id = instance.testcase.id
35 if "ignore_faults" in instance.testcase.tags:
Anas Nashifb20c4842018-06-05 21:36:20 -050036 self.fail_on_fault = False
37
Anas Nashif576be982017-12-23 20:20:27 -050038 if config:
39 self.type = config.get('type', None)
Ulf Magnusson0d39a102019-09-06 11:13:19 +020040 self.regex = config.get('regex', [])
Anas Nashif576be982017-12-23 20:20:27 -050041 self.repeat = config.get('repeat', 1)
42 self.ordered = config.get('ordered', True)
Anas Nashif83fc06a2019-06-22 11:04:10 -040043 self.record = config.get('record', {})
44
45 def process_test(self, line):
46
47 if self.RUN_PASSED in line:
48 if self.fault:
49 self.state = "failed"
50 else:
51 self.state = "passed"
52
53 if self.RUN_FAILED in line:
54 self.state = "failed"
55
56 if self.fail_on_fault:
57 if self.FAULT == line:
58 self.fault = True
59
60 if self.GCOV_START in line:
61 self.capture_coverage = True
62 elif self.GCOV_END in line:
63 self.capture_coverage = False
Anas Nashif576be982017-12-23 20:20:27 -050064
65class Console(Harness):
66
Andy Rossaa2b8a12019-03-06 09:45:30 -080067 def configure(self, instance):
68 super(Console, self).configure(instance)
69 if self.type == "one_line":
70 self.pattern = re.compile(self.regex[0])
71 elif self.type == "multi_line":
72 self.patterns = []
73 for r in self.regex:
74 self.patterns.append(re.compile(r))
75
Anas Nashif576be982017-12-23 20:20:27 -050076 def handle(self, line):
77 if self.type == "one_line":
Andy Rossaa2b8a12019-03-06 09:45:30 -080078 if self.pattern.search(line):
Anas Nashif576be982017-12-23 20:20:27 -050079 self.state = "passed"
Andy Ross5efdd6a2019-06-18 11:57:21 -070080 elif self.type == "multi_line" and self.ordered:
81 if (self.next_pattern < len(self.patterns) and
82 self.patterns[self.next_pattern].search(line)):
83 self.next_pattern += 1
84 if self.next_pattern >= len(self.patterns):
85 self.state = "passed"
86 elif self.type == "multi_line" and not self.ordered:
Andy Rossaa2b8a12019-03-06 09:45:30 -080087 for i, pattern in enumerate(self.patterns):
88 r = self.regex[i]
Anas Nashif39caff52018-01-24 09:54:08 +053089 if pattern.search(line) and not r in self.matches:
Anas Nashif576be982017-12-23 20:20:27 -050090 self.matches[r] = line
Anas Nashif576be982017-12-23 20:20:27 -050091 if len(self.matches) == len(self.regex):
Ulf Magnussonea4d1d62019-09-02 11:48:44 +020092 self.state = "passed"
Anas Nashiff29087e2019-01-25 09:37:38 -050093
94 if self.fail_on_fault:
Andrew Boie81ef42d2019-07-16 15:29:46 -070095 if self.FAULT in line:
96 self.fault = True
Anas Nashiff29087e2019-01-25 09:37:38 -050097
98 if self.GCOV_START in line:
99 self.capture_coverage = True
100 elif self.GCOV_END in line:
101 self.capture_coverage = False
Anas Nashif576be982017-12-23 20:20:27 -0500102
Anas Nashif83fc06a2019-06-22 11:04:10 -0400103
104 if self.record:
105 pattern = re.compile(self.record.get("regex", ""))
106 match = pattern.search(line)
107 if match:
108 csv = []
109 if not self.fieldnames:
110 for k,v in match.groupdict().items():
111 self.fieldnames.append(k)
112
113 for k,v in match.groupdict().items():
114 csv.append(v.strip())
115 self.recording.append(csv)
116
Anas Nashiff16e92c2019-03-31 16:58:12 -0400117 if self.state == "passed":
118 self.tests[self.id] = "PASS"
119 else:
120 self.tests[self.id] = "FAIL"
121
Anas Nashif83fc06a2019-06-22 11:04:10 -0400122 self.process_test(line)
Andy Rossaa2b8a12019-03-06 09:45:30 -0800123
Anas Nashif576be982017-12-23 20:20:27 -0500124class Test(Harness):
125 RUN_PASSED = "PROJECT EXECUTION SUCCESSFUL"
126 RUN_FAILED = "PROJECT EXECUTION FAILED"
127
128 def handle(self, line):
Andy Rossaa2b8a12019-03-06 09:45:30 -0800129 match = result_re.match(line)
Anas Nashifa4dd49b2019-12-04 16:48:49 -0500130 if match and match.group(2):
Anas Nashif61e21632018-04-08 13:30:16 -0500131 name = "{}.{}".format(self.id, match.group(3))
132 self.tests[name] = match.group(1)
Anas Nashif8b425fa2020-08-31 11:50:51 -0400133 self.ztest = True
Anas Nashife0a6a0b2018-02-15 20:07:24 -0600134
Anas Nashif576be982017-12-23 20:20:27 -0500135 if self.RUN_PASSED in line:
Anas Nashif77837e82018-08-29 10:05:27 -0400136 if self.fault:
137 self.state = "failed"
138 else:
139 self.state = "passed"
Anas Nashif576be982017-12-23 20:20:27 -0500140
141 if self.RUN_FAILED in line:
142 self.state = "failed"
Anas Nashifb20c4842018-06-05 21:36:20 -0500143
144 if self.fail_on_fault:
Andrew Boie81ef42d2019-07-16 15:29:46 -0700145 if self.FAULT in line:
146 self.fault = True
Anas Nashifb20c4842018-06-05 21:36:20 -0500147
Anas Nashif8b425fa2020-08-31 11:50:51 -0400148 if not self.ztest and self.state:
149 if self.state == "passed":
150 self.tests[self.id] = "PASS"
151 else:
152 self.tests[self.id] = "FAIL"
Anas Nashifadb6a892020-06-09 09:37:01 -0400153
Anas Nashiff29087e2019-01-25 09:37:38 -0500154 if self.GCOV_START in line:
155 self.capture_coverage = True
156 elif self.GCOV_END in line:
157 self.capture_coverage = False
Anas Nashif83fc06a2019-06-22 11:04:10 -0400158
159 self.process_test(line)
Anas Nashifce8c12e2020-05-21 09:11:40 -0400160
161class Ztest(Test):
162 pass