openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

81 lines
2.4 KiB

#!/usr/bin/env python3
import os
import glob
import pytest
import shutil
import subprocess
import tempfile
import random
HERE = os.path.abspath(os.path.dirname(__file__))
ROOT = os.path.join(HERE, "../../")
IGNORED_PATHS = (
'board/obj',
'board/jungle',
'board/stm32h7/inc',
'board/stm32f4/inc',
'board/fake_stm.h',
# bootstub only files
'board/flasher.h',
'board/bootstub.c',
'board/bootstub_declarations.h',
'board/stm32h7/llflash.h',
'board/stm32f4/llflash.h',
)
mutations = [
# default
(None, None, False),
# F4 only
("board/stm32f4/llbxcan.h", "s/1U/1/g", True),
# H7 only
("board/stm32h7/llfdcan.h", "s/return ret;/if (true) { return ret; } else { return false; }/g", True),
]
patterns = [
# misra-c2012-13.3
"$a void test(int tmp) { int tmp2 = tmp++ + 2; if (tmp2) {;}}",
# misra-c2012-13.4
"$a int test(int x, int y) { return (x=2) && (y=2); }",
# misra-c2012-13.5
"$a void test(int tmp) { if (true && tmp++) {;} }",
# misra-c2012-13.6
"$a void test(int tmp) { if (sizeof(tmp++)) {;} }",
# misra-c2012-14.1
"$a void test(float len) { for (float j = 0; j < len; j++) {;} }",
# misra-c2012-14.4
"$a void test(int len) { if (len - 8) {;} }",
# misra-c2012-16.4
r"$a void test(int temp) {switch (temp) { case 1: ; }}\n",
# misra-c2012-17.8
"$a void test(int cnt) { for (cnt=0;;cnt++) {;} }",
# misra-c2012-20.4
r"$a #define auto 1\n",
# misra-c2012-20.5
r"$a #define TEST 1\n#undef TEST\n",
]
all_files = glob.glob('board/**', root_dir=ROOT, recursive=True)
files = [f for f in all_files if f.endswith(('.c', '.h')) and not f.startswith(IGNORED_PATHS)]
assert len(files) > 70, all(d in files for d in ('board/main.c', 'board/stm32f4/llbxcan.h', 'board/stm32h7/llfdcan.h'))
for p in patterns:
mutations.append((random.choice(files), p, True))
@pytest.mark.parametrize("fn, patch, should_fail", mutations)
def test_misra_mutation(fn, patch, should_fail):
with tempfile.TemporaryDirectory() as tmp:
shutil.copytree(ROOT, tmp + "/panda", dirs_exist_ok=True)
shutil.copytree(ROOT + "../opendbc", tmp + "/opendbc", dirs_exist_ok=True)
# apply patch
if fn is not None:
r = os.system(f"cd {tmp}/panda && sed -i '{patch}' {fn}")
assert r == 0
# run test
r = subprocess.run("SKIP_TABLES_DIFF=1 panda/tests/misra/test_misra.sh", cwd=tmp, shell=True)
failed = r.returncode != 0
assert failed == should_fail