validate:launcher: Allow referencing known issue by exiting signal names

This commit is contained in:
Thibault Saunier 2019-03-17 14:39:38 -03:00 committed by Thibault Saunier
parent 7dbdb84ca8
commit a77825ecbc

View file

@ -69,6 +69,7 @@ EXITING_SIGNALS = dict([(-getattr(signal, s), s) for s in [
'SIGQUIT', 'SIGILL', 'SIGABRT', 'SIGFPE', 'SIGSEGV', 'SIGBUS', 'SIGSYS', 'SIGQUIT', 'SIGILL', 'SIGABRT', 'SIGFPE', 'SIGSEGV', 'SIGBUS', 'SIGSYS',
'SIGTRAP', 'SIGXCPU', 'SIGXFSZ', 'SIGIOT'] if hasattr(signal, s)]) 'SIGTRAP', 'SIGXCPU', 'SIGXFSZ', 'SIGIOT'] if hasattr(signal, s)])
EXITING_SIGNALS.update({139: "SIGSEGV"}) EXITING_SIGNALS.update({139: "SIGSEGV"})
EXITING_SIGNALS.update({(v, k) for k, v in EXITING_SIGNALS.items()})
class Test(Loggable): class Test(Loggable):
@ -123,8 +124,25 @@ class Test(Loggable):
self.clean() self.clean()
def _generate_known_issues(self):
return ''
def generate_known_issues(self): def generate_known_issues(self):
return None res = '%s"%s": [' % (" " * 4, self.classname)
retcode = self.process.returncode if self.process else 0
if retcode != 0:
signame = EXITING_SIGNALS.get(retcode)
val = "'" + signame + "'" if signame else retcode
res += """\n {
'bug': 'FIXME - REPORT A BUG in https://gitlab.freedesktop.org/gstreamer/ ? (or remove this line)',
'%s': %s,
'sometimes': True,
},""" % ("signame" if signame else "returncode", val)
res += self._generate_known_issues()
res += "\n%s],\n" % (" " * 4)
return res
def clean(self): def clean(self):
self.kill_subprocess() self.kill_subprocess()
@ -872,17 +890,9 @@ class GstValidateTest(Test):
return ret, expected_failures, expected_retcode return ret, expected_failures, expected_retcode
def check_expected_timeout(self, expected_timeout): def check_expected_traceback(self, expected_failure):
msg = "Expected timeout happened. " msg = None
result = Result.PASSED expected_symbols = expected_failure.get('stacktrace_symbols')
message = expected_timeout.get('message')
if message:
if not re.findall(message, self.message):
result = Result.FAILED
msg = "Expected timeout message: %s got %s " % (
message, self.message)
expected_symbols = expected_timeout.get('stacktrace_symbols')
if expected_symbols: if expected_symbols:
trace_gatherer = BackTraceGenerator.get_default() trace_gatherer = BackTraceGenerator.get_default()
stack_trace = trace_gatherer.get_trace(self) stack_trace = trace_gatherer.get_trace(self)
@ -894,11 +904,29 @@ class GstValidateTest(Test):
not_found_symbols = [s for s in expected_symbols not_found_symbols = [s for s in expected_symbols
if s not in stack_trace] if s not in stack_trace]
if not_found_symbols: if not_found_symbols:
result = Result.TIMEOUT msg = " Expected symbols '%s' not found in stack trace " % (
msg = "Expected symbols '%s' not found in stack trace " % (
not_found_symbols) not_found_symbols)
return msg, False
else: else:
msg += "No stack trace available, could not verify symbols " msg += " No stack trace available, could not verify symbols "
return msg, True
def check_expected_timeout(self, expected_timeout):
msg = "Expected timeout happened. "
result = Result.PASSED
message = expected_timeout.get('message')
if message:
if not re.findall(message, self.message):
result = Result.FAILED
msg = "Expected timeout message: %s got %s " % (
message, self.message)
stack_msg, stack_res = self.check_expected_traceback(expected_timeout)
if not stack_res:
result = Result.TIMEOUT
msg += stack_msg
return result, msg return result, msg
@ -915,20 +943,30 @@ class GstValidateTest(Test):
self.debug("%s returncode: %s", self, self.process.returncode) self.debug("%s returncode: %s", self, self.process.returncode)
self.criticals, not_found_expected_failures, expected_returncode = self.check_reported_issues() self.criticals, not_found_expected_failures, expected_returncode = self.check_reported_issues()
expected_timeout = None expected_timeout = None
expected_signal = None
for i, f in enumerate(not_found_expected_failures): for i, f in enumerate(not_found_expected_failures):
if len(f) == 1 and f.get("returncode"): returncode = f.get('returncode', [])
returncode = f['returncode'] if not isinstance(returncode, list):
if not isinstance(expected_returncode, list): returncode = [returncode]
returncode = [expected_returncode]
if f.get('signame'):
signames = f['signame']
if not isinstance(signames, list):
signames = [signames]
returncode = [EXITING_SIGNALS[signame] for signame in signames]
if returncode:
if 'sometimes' in f: if 'sometimes' in f:
returncode.append(0) returncode.append(0)
expected_returncode = returncode
expected_signal = f
elif f.get("timeout"): elif f.get("timeout"):
expected_timeout = f expected_timeout = f
not_found_expected_failures = [f for f in not_found_expected_failures not_found_expected_failures = [f for f in not_found_expected_failures
if not f.get('returncode')] if not f.get('returncode') and not f.get('signame')]
msg = "" msg = ""
result = Result.PASSED result = Result.PASSED
@ -944,10 +982,15 @@ class GstValidateTest(Test):
else: else:
return return
elif self.process.returncode in EXITING_SIGNALS: elif self.process.returncode in EXITING_SIGNALS:
result = Result.FAILED msg = "Application exited with signal %s" % (EXITING_SIGNALS[self.process.returncode])
msg = "Application exited with signal %s" % ( if self.process.returncode not in expected_returncode:
EXITING_SIGNALS[self.process.returncode] result = Result.FAILED
) else:
if expected_signal:
stack_msg, stack_res = self.check_expected_traceback(expected_signal)
if not stack_res:
msg += stack_msg
result = Result.FAILED
self.add_stack_trace_to_logfile() self.add_stack_trace_to_logfile()
elif self.process.returncode == VALGRIND_ERROR_CODE: elif self.process.returncode == VALGRIND_ERROR_CODE:
msg = "Valgrind reported errors " msg = "Valgrind reported errors "
@ -968,19 +1011,18 @@ class GstValidateTest(Test):
if not f.get('sometimes', True)] if not f.get('sometimes', True)]
if mandatory_failures: if mandatory_failures:
msg += "(Expected errors not found: %s) " % mandatory_failures msg += " (Expected errors not found: %s) " % mandatory_failures
result = Result.FAILED result = Result.FAILED
elif self.expected_failures: elif self.expected_failures:
msg += '%s(Expected errors occured: %s)%s' % (Colors.OKBLUE, msg += ' %s(Expected errors occured: %s)%s' % (Colors.OKBLUE,
self.expected_failures, self.expected_failures,
Colors.ENDC) Colors.ENDC)
self.set_result(result, msg.strip()) self.set_result(result, msg.strip())
def generate_known_issues(self): def _generate_known_issues(self):
if not self.criticals and self.result != Result.TIMEOUT: res = ""
return None self.criticals = self.criticals or []
res = '%s"%s": [' % (" " * 4, self.classname)
if self.result == Result.TIMEOUT: if self.result == Result.TIMEOUT:
res += """ { res += """ {
'bug': 'FIXME - REPORT A BUG in https://gitlab.freedesktop.org/gstreamer/ ? (or remove this line)', 'bug': 'FIXME - REPORT A BUG in https://gitlab.freedesktop.org/gstreamer/ ? (or remove this line)',
@ -996,13 +1038,14 @@ class GstValidateTest(Test):
for key, value in report.items(): for key, value in report.items():
if key == "type": if key == "type":
continue continue
if value is None:
continue
res += '\n%s%s"%s": "%s",' % ( res += '\n%s%s"%s": "%s",' % (
" " * 12, "# " if key == "details" else "", " " * 12, "# " if key == "details" else "",
key, value.replace('\n', '\\n')) key, value.replace('\n', '\\n'))
res += "\n%s}," % (" " * 8) res += "\n%s}," % (" " * 8)
res += "\n%s],\n" % (" " * 4)
return res return res
def get_valgrind_suppressions(self): def get_valgrind_suppressions(self):
@ -1857,21 +1900,24 @@ class _TestsLauncher(Loggable):
if self.options.forever: if self.options.forever:
r = 1 r = 1
while True: while True:
printc("Running iteration %d" % r, title=True) printc("-> Iteration %d" % r, end='')
if not self._run_tests(): if not self._run_tests():
break break
r += 1 r += 1
self.clean_tests() self.clean_tests()
printc("OK", Colors.OKGREEN)
return False return False
elif self.options.n_runs: elif self.options.n_runs:
res = True res = True
for r in range(self.options.n_runs): for r in range(self.options.n_runs):
t = "Running iteration %d" % r printc("-> Iteration %d" % r)
print("%s\n%s\n%s\n" % ("=" * len(t), t, "=" * len(t)))
if not self._run_tests(): if not self._run_tests():
res = False res = False
printc("ERROR", Colors.FAIL)
else:
printc("OK", Colors.OKGREEN)
self.clean_tests() self.clean_tests()
return res return res
@ -1880,7 +1926,7 @@ class _TestsLauncher(Loggable):
finally: finally:
all_known_issues = "" all_known_issues = ""
for test in self.tests: for test in self.tests:
if test.result != Result.PASSED: if test.result not in [Result.PASSED, Result.NOT_RUN]:
known_issues = test.generate_known_issues() known_issues = test.generate_known_issues()
if known_issues: if known_issues:
all_known_issues += known_issues all_known_issues += known_issues