Minor improvements to check tools

- Better handling of unusual macro for PVS-Studio
- Fail the analysis if Cppcheck exited with an internal error
This commit is contained in:
Valerii Koval
2022-04-27 20:45:21 +03:00
parent 285f19e132
commit e69fd5e682
3 changed files with 94 additions and 2 deletions

View File

@ -49,6 +49,7 @@ class CppcheckCheckTool(CheckToolBase):
for msg in (
"No C or C++ source files found",
"unrecognized command line option",
"there was an internal error",
)
):
self._bad_input = True

View File

@ -53,7 +53,15 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
)
def tool_output_filter(self, line): # pylint: disable=arguments-differ
if "license was not entered" in line.lower():
if any(
[
err_msg in line.lower()
for err_msg in (
"license was not entered",
"license information is incorrect",
)
]
):
self._bad_input = True
return line
@ -193,7 +201,7 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
'"%s"' % self._tmp_preprocessed_file,
]
cmd.extend([f for f in flags if f])
cmd.extend(["-D%s" % d for d in self.cpp_defines])
cmd.extend(['"-D%s"' % d.replace('"', '\\"') for d in self.cpp_defines])
cmd.append('@"%s"' % self._tmp_cmd_file)
# Explicitly specify C++ as the language used in .ino files

View File

@ -15,6 +15,7 @@
# pylint: disable=redefined-outer-name
import json
import sys
from os.path import isfile, join
import pytest
@ -121,6 +122,56 @@ def test_check_tool_defines_passed(clirunner, check_dir):
assert "__GNUC__" in output
def test_check_tool_complex_defines_handled(
clirunner, validate_cliresult, tmpdir_factory
):
project_dir = tmpdir_factory.mktemp("project_dir")
project_dir.join("platformio.ini").write(
DEFAULT_CONFIG
+ R"""
check_tool = cppcheck, clangtidy, pvs-studio
build_flags =
-DEXTERNAL_INCLUDE_FILE=\"test.h\"
"-DDEFINE_WITH_SPACE="Hello World!""
"""
)
src_dir = project_dir.mkdir("src")
src_dir.join("test.h").write(
"""
#ifndef TEST_H
#define TEST_H
#define ARBITRARY_CONST_VALUE 10
#endif
"""
)
src_dir.join("main.c").write(
PVS_STUDIO_FREE_LICENSE_HEADER
+ """
#if !defined(EXTERNAL_INCLUDE_FILE)
#error "EXTERNAL_INCLUDE_FILE is not declared!"
#else
#include EXTERNAL_INCLUDE_FILE
#endif
int main()
{
/* Index out of bounds */
int arr[ARBITRARY_CONST_VALUE];
for(int i=0; i < ARBITRARY_CONST_VALUE+1; i++) {
arr[i] = 0; /* High */
}
return 0;
}
"""
)
default_result = clirunner.invoke(cmd_check, ["--project-dir", str(project_dir)])
validate_cliresult(default_result)
def test_check_language_standard_definition_passed(clirunner, tmpdir):
config = DEFAULT_CONFIG + "\nbuild_flags = -std=c++17"
tmpdir.join("platformio.ini").write(config)
@ -466,6 +517,38 @@ def test_check_pvs_studio_fails_without_license(clirunner, tmpdir):
assert "license was not entered" in verbose_result.output.lower()
@pytest.mark.skipif(
sys.platform != "win32",
reason="For some reason the error message is different on Windows",
)
def test_check_pvs_studio_fails_broken_license(clirunner, tmpdir):
config = (
DEFAULT_CONFIG
+ """
check_tool = pvs-studio
check_flags = --lic-file=./pvs-studio.lic
"""
)
tmpdir.join("platformio.ini").write(config)
tmpdir.mkdir("src").join("main.c").write(TEST_CODE)
tmpdir.join("pvs-studio.lic").write(
"""
TEST
TEST-TEST-TEST-TEST
"""
)
default_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
verbose_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir), "-v"])
assert default_result.exit_code != 0
assert "failed to perform check" in default_result.output.lower()
assert verbose_result.exit_code != 0
assert "license information is incorrect" in verbose_result.output.lower()
def test_check_embedded_platform_all_tools(clirunner, validate_cliresult, tmpdir):
config = """
[env:test]