mirror of
https://github.com/commaai/panda.git
synced 2026-06-14 08:04:25 +08:00
The new misra_failfast.py wrapper patches misra.py's reportError to sys.exit(1) on the first real violation, handling cppcheck's inline and macro suppressions to avoid false positives on clean code. Also removes sampling (all 12 tests run in ~38s with xdist) and adds board/crypto and board/certs to ignored mutation paths since they're only included from bootstub.c. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Wrapper around cppcheck's misra.py that exits on first violation.
|
|
|
|
Used by mutation tests to fail fast — we only need to know if ANY
|
|
violation exists, not enumerate them all. This saves ~10s per test
|
|
by killing the 54MB XML dump parsing early.
|
|
"""
|
|
import sys
|
|
|
|
# cppcheck prepends its addons/ dir to sys.path, so these are directly importable
|
|
import cppcheckdata
|
|
import misra
|
|
|
|
_original_reportError = misra.MisraChecker.reportError
|
|
|
|
def _failfast_reportError(self, location, num1, num2):
|
|
ruleNum = num1 * 100 + num2
|
|
|
|
# misra's own suppression checks
|
|
if self.isRuleGloballySuppressed(ruleNum):
|
|
return
|
|
if self.settings.verify:
|
|
return _original_reportError(self, location, num1, num2)
|
|
if self.isRuleSuppressed(location.file, location.linenr, ruleNum):
|
|
return _original_reportError(self, location, num1, num2)
|
|
|
|
errorId = 'misra-c2012-%d.%d' % (num1, num2)
|
|
|
|
# cppcheck's own suppression checks (file-pattern, line, block).
|
|
# with --cli these are normally applied AFTER the addon, so we check here.
|
|
if cppcheckdata.is_suppressed(location, '', errorId):
|
|
return _original_reportError(self, location, num1, num2)
|
|
|
|
# cppcheck-suppress-macro: suppresses a rule for all expansions of a macro.
|
|
# is_suppressed doesn't handle type="macro", so check manually.
|
|
if getattr(location, 'macroName', None):
|
|
for s in cppcheckdata.current_dumpfile_suppressions:
|
|
if s.suppressionType == 'macro' and s.errorId == errorId:
|
|
return _original_reportError(self, location, num1, num2)
|
|
|
|
# real violation — report it then bail out
|
|
_original_reportError(self, location, num1, num2)
|
|
sys.exit(1)
|
|
|
|
misra.MisraChecker.reportError = _failfast_reportError
|
|
misra.main()
|