summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/utils
diff options
context:
space:
mode:
authorRoss Burton <ross.burton@arm.com>2023-07-20 16:51:50 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-07-21 11:52:26 +0100
commitb398c7653ec6272178dd6403dfcadf475f677bf5 (patch)
tree03500f603fb1ce3c115530cd868eade0d716bac6 /meta/lib/oeqa/utils
parentaceb924845e0a77c878c3aea2941e2d3548b5a61 (diff)
downloadpoky-b398c7653ec6272178dd6403dfcadf475f677bf5.tar.gz
oeqa/ltp: rewrote LTP testcase and parser
The LTP test reporting appears to be a little fragile so I tried to make it more reliable. Primarily this is done by not passing -p to runltp, which results in machine-readable logfiles instead of human-readable. These are easier to parse and have more context in, so we can also report correctly skipped tests. (From OE-Core rev: d585c6062fcf452e7288f6f8fb540fd92cbf5ea2) Signed-off-by: Ross Burton <ross.burton@arm.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa/utils')
-rw-r--r--meta/lib/oeqa/utils/logparser.py62
1 files changed, 40 insertions, 22 deletions
diff --git a/meta/lib/oeqa/utils/logparser.py b/meta/lib/oeqa/utils/logparser.py
index 8054acc853..496d9e0c90 100644
--- a/meta/lib/oeqa/utils/logparser.py
+++ b/meta/lib/oeqa/utils/logparser.py
@@ -4,7 +4,7 @@
4# SPDX-License-Identifier: MIT 4# SPDX-License-Identifier: MIT
5# 5#
6 6
7import sys 7import enum
8import os 8import os
9import re 9import re
10 10
@@ -106,30 +106,48 @@ class PtestParser(object):
106 f.write(status + ": " + test_name + "\n") 106 f.write(status + ": " + test_name + "\n")
107 107
108 108
109# ltp log parsing 109class LtpParser:
110class LtpParser(object): 110 """
111 def __init__(self): 111 Parse the machine-readable LTP log output into a ptest-friendly data structure.
112 self.results = {} 112 """
113 self.section = {'duration': "", 'log': ""}
114
115 def parse(self, logfile): 113 def parse(self, logfile):
116 test_regex = {} 114 results = {}
117 test_regex['PASSED'] = re.compile(r"PASS") 115 # Aaccumulate the duration here but as the log rounds quick tests down
118 test_regex['FAILED'] = re.compile(r"FAIL") 116 # to 0 seconds this is very much a lower bound. The caller can replace
119 test_regex['SKIPPED'] = re.compile(r"SKIP") 117 # the value.
120 118 section = {"duration": 0, "log": ""}
121 with open(logfile, errors='replace') as f: 119
120 class LtpExitCode(enum.IntEnum):
121 # Exit codes as defined in ltp/include/tst_res_flags.h
122 TPASS = 0 # Test passed flag
123 TFAIL = 1 # Test failed flag
124 TBROK = 2 # Test broken flag
125 TWARN = 4 # Test warning flag
126 TINFO = 16 # Test information flag
127 TCONF = 32 # Test not appropriate for configuration flag
128
129 with open(logfile, errors="replace") as f:
130 # Lines look like this:
131 # tag=cfs_bandwidth01 stime=1689762564 dur=0 exit=exited stat=32 core=no cu=0 cs=0
122 for line in f: 132 for line in f:
123 for t in test_regex: 133 if not line.startswith("tag="):
124 result = test_regex[t].search(line) 134 continue
125 if result:
126 self.results[line.split()[0].strip()] = t
127
128 for test in self.results:
129 result = self.results[test]
130 self.section['log'] = self.section['log'] + ("%s: %s\n" % (result.strip()[:-2], test.strip()))
131 135
132 return self.results, self.section 136 values = dict(s.split("=") for s in line.strip().split())
137
138 section["duration"] += int(values["dur"])
139 exitcode = int(values["stat"])
140 if values["exit"] == "exited" and exitcode == LtpExitCode.TCONF:
141 # Exited normally with the "invalid configuration" code
142 results[values["tag"]] = "SKIPPED"
143 elif exitcode == LtpExitCode.TPASS:
144 # Successful exit
145 results[values["tag"]] = "PASSED"
146 else:
147 # Other exit
148 results[values["tag"]] = "FAILED"
149
150 return results, section
133 151
134 152
135# ltp Compliance log parsing 153# ltp Compliance log parsing