2019-06-17 21:17:29 +02:00
|
|
|
# python -m pytest addons/test/test-misra.py
|
2019-06-25 00:42:13 +02:00
|
|
|
import json
|
2019-06-17 21:17:29 +02:00
|
|
|
import pytest
|
2019-07-16 22:32:41 +02:00
|
|
|
import re
|
2019-06-19 21:57:28 +02:00
|
|
|
import sys
|
|
|
|
try:
|
|
|
|
from cStringIO import StringIO
|
|
|
|
except ImportError:
|
|
|
|
from io import StringIO
|
2019-06-23 14:08:05 +02:00
|
|
|
import subprocess
|
2019-06-19 21:57:28 +02:00
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
TEST_SOURCE_FILES = ['./addons/test/misra-test.c']
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
def dump_create(fpath, *argv):
|
|
|
|
cmd = ["./cppcheck", "--dump", "--quiet", fpath] + list(argv)
|
|
|
|
p = subprocess.Popen(cmd)
|
|
|
|
p.communicate()
|
|
|
|
if p.returncode != 0:
|
|
|
|
raise OSError("cppcheck returns error code: %d" % p.returncode)
|
|
|
|
subprocess.Popen(["sync"])
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
def dump_remove(fpath):
|
|
|
|
subprocess.Popen(["rm", "-f", fpath + ".dump"])
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
def setup_module(module):
|
|
|
|
for f in TEST_SOURCE_FILES:
|
2019-07-16 22:32:41 +02:00
|
|
|
dump_create(f)
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
def teardown_module(module):
|
|
|
|
for f in TEST_SOURCE_FILES:
|
2019-07-16 22:32:41 +02:00
|
|
|
dump_remove(f)
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
@pytest.fixture(scope="function")
|
2019-06-17 21:17:29 +02:00
|
|
|
def checker():
|
|
|
|
from addons.misra import MisraChecker, MisraSettings, get_args
|
|
|
|
args = get_args()
|
|
|
|
settings = MisraSettings(args)
|
|
|
|
return MisraChecker(settings)
|
|
|
|
|
|
|
|
|
|
|
|
def test_loadRuleTexts_structure(checker):
|
|
|
|
checker.loadRuleTexts("./addons/test/assets/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/assets/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/assets/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 == "Should")
|
|
|
|
|
2019-06-19 21:57:28 +02:00
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
def test_verifyRuleTexts(checker, capsys):
|
2019-06-19 21:57:28 +02:00
|
|
|
checker.loadRuleTexts("./addons/test/assets/misra_rules_dummy.txt")
|
2019-07-16 22:32:41 +02:00
|
|
|
checker.verifyRuleTexts()
|
|
|
|
captured = capsys.readouterr().out
|
2019-06-19 21:57:28 +02:00
|
|
|
assert("21.3" not in captured)
|
|
|
|
assert("1.3" in captured)
|
2019-06-23 14:08:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_rules_misra_severity(checker):
|
|
|
|
checker.loadRuleTexts("./addons/test/assets/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 == '')
|
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
def test_json_out(checker, capsys):
|
2019-06-25 00:42:13 +02:00
|
|
|
sys.argv.append("--cli")
|
|
|
|
checker.loadRuleTexts("./addons/test/assets/misra_rules_dummy.txt")
|
2019-07-16 22:32:41 +02:00
|
|
|
checker.parseDump("./addons/test/misra-test.c.dump")
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
captured = captured.out.splitlines()
|
2019-06-25 00:42:13 +02:00
|
|
|
sys.argv.remove("--cli")
|
|
|
|
json_output = {}
|
2019-07-16 22:32:41 +02:00
|
|
|
for line in captured:
|
2019-06-25 00:42:13 +02:00
|
|
|
try:
|
|
|
|
json_line = json.loads(line)
|
|
|
|
json_output[json_line['errorId']] = json_line
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
assert("Mandatory" in json_output['c2012-10.4']['extra'])
|
|
|
|
assert("Required" in json_output['c2012-21.3']['extra'])
|
|
|
|
assert("Advisory" in json_output['c2012-20.1']['extra'])
|
|
|
|
|
|
|
|
|
2019-07-16 22:32:41 +02:00
|
|
|
def test_rules_cppcheck_severity(checker, capsys):
|
2019-06-23 14:08:05 +02:00
|
|
|
checker.loadRuleTexts("./addons/test/assets/misra_rules_dummy.txt")
|
2019-07-16 22:32:41 +02:00
|
|
|
checker.parseDump("./addons/test/misra-test.c.dump")
|
|
|
|
captured = capsys.readouterr().err
|
2019-06-23 14:08:05 +02:00
|
|
|
assert("(error)" not in captured)
|
|
|
|
assert("(warning)" not in captured)
|
|
|
|
assert("(style)" in captured)
|
2019-07-16 22:32:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_rules_suppression(checker, capsys):
|
|
|
|
test_sources = ["addons/test/misra-suppressions1-test.c",
|
|
|
|
"addons/test/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/suppressions.txt")
|
|
|
|
checker.parseDump(src + ".dump")
|
|
|
|
captured = capsys.readouterr().err
|
|
|
|
found = re.search(re_suppressed, captured)
|
|
|
|
assert(found is None)
|
|
|
|
dump_remove(src)
|