mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-02 02:03:54 +00:00
validate:launcher: Allow referencing known issue by exiting signal names
This commit is contained in:
parent
7dbdb84ca8
commit
a77825ecbc
1 changed files with 82 additions and 36 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue