device-crash-test: Remove problematic language

Replace "whitelist" in the device-crash-test script with
"rule list".

I'm using "rule list" instead of "allow list" or "pass list"
because the list is not used only for expected/allowed errors.
It also contain rules specifying which errors shouldn't be
ignored and/or should be fatal.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210202191207.4103973-1-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Eduardo Habkost 2021-02-02 14:12:07 -05:00
parent 623972ceae
commit 1a14d4e16a
1 changed files with 48 additions and 48 deletions

View File

@ -41,18 +41,18 @@ logger = logging.getLogger('device-crash-test')
dbg = logger.debug dbg = logger.debug
# Purposes of the following whitelist: # Purposes of the following rule list:
# * Avoiding verbose log messages when we find known non-fatal # * Avoiding verbose log messages when we find known non-fatal
# (exitcode=1) errors # (exitcode=1) errors
# * Avoiding fatal errors when we find known crashes # * Avoiding fatal errors when we find known crashes
# * Skipping machines/devices that are known not to work out of # * Skipping machines/devices that are known not to work out of
# the box, when running in --quick mode # the box, when running in --quick mode
# #
# Keeping the whitelist updated is desirable, but not required, # Keeping the rule list updated is desirable, but not required,
# because unexpected cases where QEMU exits with exitcode=1 will # because unexpected cases where QEMU exits with exitcode=1 will
# just trigger a INFO message. # just trigger a INFO message.
# Valid whitelist entry keys: # Valid error rule keys:
# * accel: regexp, full match only # * accel: regexp, full match only
# * machine: regexp, full match only # * machine: regexp, full match only
# * device: regexp, full match only # * device: regexp, full match only
@ -62,7 +62,7 @@ dbg = logger.debug
# * expected: if True, QEMU is expected to always fail every time # * expected: if True, QEMU is expected to always fail every time
# when testing the corresponding test case # when testing the corresponding test case
# * loglevel: log level of log output when there's a match. # * loglevel: log level of log output when there's a match.
ERROR_WHITELIST = [ ERROR_RULE_LIST = [
# Machines that won't work out of the box: # Machines that won't work out of the box:
# MACHINE | ERROR MESSAGE # MACHINE | ERROR MESSAGE
{'machine':'niagara', 'expected':True}, # Unable to load a firmware for -M niagara {'machine':'niagara', 'expected':True}, # Unable to load a firmware for -M niagara
@ -186,65 +186,65 @@ ERROR_WHITELIST = [
] ]
def whitelistTestCaseMatch(wl, t): def errorRuleTestCaseMatch(rule, t):
"""Check if a test case specification can match a whitelist entry """Check if a test case specification can match a error rule
This only checks if a whitelist entry is a candidate match This only checks if a error rule is a candidate match
for a given test case, it won't check if the test case for a given test case, it won't check if the test case
results/output match the entry. See whitelistResultMatch(). results/output match the rule. See ruleListResultMatch().
""" """
return (('machine' not in wl or return (('machine' not in rule or
'machine' not in t or 'machine' not in t or
re.match(wl['machine'] + '$', t['machine'])) and re.match(rule['machine'] + '$', t['machine'])) and
('accel' not in wl or ('accel' not in rule or
'accel' not in t or 'accel' not in t or
re.match(wl['accel'] + '$', t['accel'])) and re.match(rule['accel'] + '$', t['accel'])) and
('device' not in wl or ('device' not in rule or
'device' not in t or 'device' not in t or
re.match(wl['device'] + '$', t['device']))) re.match(rule['device'] + '$', t['device'])))
def whitelistCandidates(t): def ruleListCandidates(t):
"""Generate the list of candidates that can match a test case""" """Generate the list of candidates that can match a test case"""
for i, wl in enumerate(ERROR_WHITELIST): for i, rule in enumerate(ERROR_RULE_LIST):
if whitelistTestCaseMatch(wl, t): if errorRuleTestCaseMatch(rule, t):
yield (i, wl) yield (i, rule)
def findExpectedResult(t): def findExpectedResult(t):
"""Check if there's an expected=True whitelist entry for a test case """Check if there's an expected=True error rule for a test case
Returns (i, wl) tuple, where i is the index in Returns (i, rule) tuple, where i is the index in
ERROR_WHITELIST and wl is the whitelist entry itself. ERROR_RULE_LIST and rule is the error rule itself.
""" """
for i, wl in whitelistCandidates(t): for i, rule in ruleListCandidates(t):
if wl.get('expected'): if rule.get('expected'):
return (i, wl) return (i, rule)
def whitelistResultMatch(wl, r): def ruleListResultMatch(rule, r):
"""Check if test case results/output match a whitelist entry """Check if test case results/output match a error rule
It is valid to call this function only if It is valid to call this function only if
whitelistTestCaseMatch() is True for the entry (e.g. on errorRuleTestCaseMatch() is True for the rule (e.g. on
entries returned by whitelistCandidates()) rules returned by ruleListCandidates())
""" """
assert whitelistTestCaseMatch(wl, r['testcase']) assert errorRuleTestCaseMatch(rule, r['testcase'])
return ((wl.get('exitcode', 1) is None or return ((rule.get('exitcode', 1) is None or
r['exitcode'] == wl.get('exitcode', 1)) and r['exitcode'] == rule.get('exitcode', 1)) and
('log' not in wl or ('log' not in rule or
re.search(wl['log'], r['log'], re.MULTILINE))) re.search(rule['log'], r['log'], re.MULTILINE)))
def checkResultWhitelist(r): def checkResultRuleList(r):
"""Look up whitelist entry for a given test case result """Look up error rule for a given test case result
Returns (i, wl) tuple, where i is the index in Returns (i, rule) tuple, where i is the index in
ERROR_WHITELIST and wl is the whitelist entry itself. ERROR_RULE_LIST and rule is the error rule itself.
""" """
for i, wl in whitelistCandidates(r['testcase']): for i, rule in ruleListCandidates(r['testcase']):
if whitelistResultMatch(wl, r): if ruleListResultMatch(rule, r):
return i, wl return i, rule
raise Exception("this should never happen") raise Exception("this should never happen")
@ -543,12 +543,12 @@ def main():
break break
if f: if f:
i, wl = checkResultWhitelist(f) i, rule = checkResultRuleList(f)
dbg("testcase: %r, whitelist match: %r", t, wl) dbg("testcase: %r, rule list match: %r", t, rule)
wl_stats.setdefault(i, []).append(f) wl_stats.setdefault(i, []).append(f)
level = wl.get('loglevel', logging.DEBUG) level = rule.get('loglevel', logging.DEBUG)
logFailure(f, level) logFailure(f, level)
if wl.get('fatal') or (args.strict and level >= logging.WARN): if rule.get('fatal') or (args.strict and level >= logging.WARN):
fatal_failures.append(f) fatal_failures.append(f)
else: else:
dbg("success: %s", formatTestCase(t)) dbg("success: %s", formatTestCase(t))
@ -560,10 +560,10 @@ def main():
logger.info("Skipped %d test cases", skipped) logger.info("Skipped %d test cases", skipped)
if args.debug: if args.debug:
stats = sorted([(len(wl_stats.get(i, [])), wl) for i, wl in stats = sorted([(len(wl_stats.get(i, [])), rule) for i, rule in
enumerate(ERROR_WHITELIST)], key=lambda x: x[0]) enumerate(ERROR_RULE_LIST)], key=lambda x: x[0])
for count, wl in stats: for count, rule in stats:
dbg("whitelist entry stats: %d: %r", count, wl) dbg("error rule stats: %d: %r", count, rule)
if fatal_failures: if fatal_failures:
for f in fatal_failures: for f in fatal_failures: