cppcheck/addons/test/test-misra.py

178 lines
6.2 KiB
Python
Raw Normal View History

# Running the test with Python 2:
# Be sure to install pytest version 4.6.4 (newer should also work)
# Command in cppcheck directory:
# python -m pytest addons/test/test-misra.py
#
# Running the test with Python 3:
# Command in cppcheck directory:
# PYTHONPATH=./addons python3 -m pytest addons/test/test-misra.py
import os
import pytest
import re
import sys
import tempfile
from .util import dump_create, dump_remove, convert_json_output
TEST_SOURCE_FILES = ['./addons/test/misra/misra-test.c']
def remove_misra_config(s:str):
ret = ''
for line in s.splitlines():
if '[misra-config]' not in line:
ret += line + '\n'
return ret
@pytest.fixture(scope="function")
def checker():
from addons.misra import MisraChecker, MisraSettings, get_args_parser
parser = get_args_parser()
args = parser.parse_args([])
settings = MisraSettings(args)
return MisraChecker(settings)
@pytest.fixture
def test_files():
for f in TEST_SOURCE_FILES:
dump_create(f)
yield
for f in TEST_SOURCE_FILES:
dump_remove(f)
def test_loadRuleTexts_structure(checker):
checker.loadRuleTexts("./addons/test/misra/misra_rules_structure.txt")
assert(checker.ruleTexts.get(101, None) is None)
assert(checker.ruleTexts[102].text == "Rule text.")
assert(checker.ruleTexts.get(103, None) is None)
def test_loadRuleTexts_empty_lines(checker):
checker.loadRuleTexts("./addons/test/misra/misra_rules_empty_lines.txt")
assert(len(checker.ruleTexts) == 3)
assert(len(checker.ruleTexts[102].text) == len("Rule text."))
def test_loadRuleTexts_mutiple_lines(checker):
checker.loadRuleTexts("./addons/test/misra/misra_rules_multiple_lines.txt")
assert(checker.ruleTexts[101].text == "Multiple lines text.")
assert(checker.ruleTexts[102].text == "Multiple lines text.")
assert(checker.ruleTexts[103].text == "Multiple lines text.")
assert(checker.ruleTexts[104].text == "Should")
assert(checker.ruleTexts[105].text == "Should")
assert(checker.ruleTexts[106].text == "Can contain empty lines.")
def test_verifyRuleTexts(checker, capsys):
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.verifyRuleTexts()
captured = capsys.readouterr().out
assert("21.3" not in captured)
assert("1.3" in captured)
def test_rules_misra_severity(checker):
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
assert(checker.ruleTexts[1004].misra_severity == 'Mandatory')
assert(checker.ruleTexts[401].misra_severity == 'Required')
assert(checker.ruleTexts[1505].misra_severity == 'Advisory')
assert(checker.ruleTexts[2104].misra_severity == '')
def test_json_out(checker, capsys, test_files):
sys.argv.append("--cli")
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.parseDump("./addons/test/misra/misra-test.c.dump")
captured = capsys.readouterr()
captured = captured.out.splitlines()
sys.argv.remove("--cli")
json_output = convert_json_output(captured)
assert("Mandatory" in json_output['c2012-10.4'][0]['extra'])
assert("Required" in json_output['c2012-21.3'][0]['extra'])
assert("Advisory" in json_output['c2012-20.1'][0]['extra'])
def test_rules_cppcheck_severity(checker, capsys, test_files):
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.parseDump("./addons/test/misra/misra-test.c.dump")
captured = capsys.readouterr().err
assert("(error)" not in remove_misra_config(captured))
assert("(warning)" not in captured)
assert("(style)" in captured)
def test_rules_cppcheck_severity_custom(checker, capsys, test_files):
2020-06-08 15:58:17 +02:00
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.setSeverity("custom-severity")
checker.parseDump("./addons/test/misra/misra-test.c.dump")
captured = capsys.readouterr().err
assert("(error)" not in remove_misra_config(captured))
2020-06-08 15:58:17 +02:00
assert("(warning)" not in captured)
assert("(style)" not in captured)
assert("(custom-severity)" in captured)
def test_rules_suppression(checker, capsys):
test_sources = ["addons/test/misra/misra-suppressions1-test.c",
"addons/test/misra/misra-suppressions2-test.c"]
for src in test_sources:
re_suppressed= r"\[%s\:[0-9]+\]" % src
dump_remove(src)
dump_create(src, "--suppressions-list=addons/test/misra/suppressions.txt")
checker.parseDump(src + ".dump")
captured = capsys.readouterr().err
found = re.search(re_suppressed, captured)
2020-11-11 20:28:26 +01:00
assert found is None, 'Unexptected output:\n' + captured
dump_remove(src)
def test_arguments_regression():
args_ok = ["-generate-table",
"--rule-texts=./addons/test/assets/misra_rules_multiple_lines.txt",
"--verify-rule-texts",
"-t=foo", "--template=foo",
"--suppress-rules=15.1",
"--quiet",
"--cli",
"--no-summary",
"--show-suppressed-rules",
2020-06-08 15:58:17 +02:00
"-P=src/", "--file-prefix=src/",
"--severity=misra-warning"]
# Arguments with expected SystemExit
args_exit = ["--non-exists", "--non-exists-param=42", "-h", "--help"]
from addons.misra import get_args_parser
# sys.argv contains all pytest arguments - so clear all existing arguments first and restore afterwards
sys_argv_old = sys.argv
sys.argv = [sys.argv[0]]
try:
for arg in args_exit:
sys.argv.append(arg)
with pytest.raises(SystemExit):
parser = get_args_parser()
parser.parse_args()
sys.argv.remove(arg)
for arg in args_ok:
sys.argv.append(arg)
try:
parser = get_args_parser()
parser.parse_args()
except SystemExit:
pytest.fail("Unexpected SystemExit with '%s'" % arg)
sys.argv.remove(arg)
finally:
sys.argv = sys_argv_old
def test_read_ctu_info_line(checker):
assert checker.read_ctu_info_line('{') is None
assert checker.read_ctu_info_line('{"summary":"123"}') is None
assert checker.read_ctu_info_line('{"data":123}') is None
assert checker.read_ctu_info_line('{"summary":"123","data":123}') is not None