Skip to content

Commit

Permalink
Merge pull request #142 from melexis/polyspace-checker
Browse files Browse the repository at this point in the history
Implement Polyspace checker
  • Loading branch information
JasperCraeghs authored Jul 5, 2024
2 parents 534c3f5 + c38bbc6 commit 2831527
Show file tree
Hide file tree
Showing 24 changed files with 2,946 additions and 175 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bin/
include/
local/
pip-selfcheck.json
pyvenv.cfg

# Spyder project settings
.spyderproject
Expand All @@ -98,3 +99,6 @@ pip-selfcheck.json

# Offline version file
src/mlx/warnings/__version__.py

# plantuml generation
src/*.plantuml
114 changes: 111 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,64 @@ input file. When this setting is missing, the default value ``true`` is used.
.. |--xunit report.xml| replace:: ``--xunit report.xml``
.. _`--xunit report.xml`: https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#xunit-compatible-result-file

Parse for Polyspace Failures
----------------------------

The Polyspace checker requires as input a TSV file exported by Polyspace.
You can find instructions on exporting TSV files in the Polyspace documentation.

Exporting Polyspace Results
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following commands instruct Polyspace to export the results as a TSV file:

.. code-block:: bash
polyspace-results-export -format csv -results-dir <resultsFolder> <export_options>
# or
polyspace-results-export -format csv -host <hostName> -run-id <runID> <export_options> <polyspace_access_options>
The csv format outputs tab-separated values (TSV).
Each result in the TSV format consists of tab-separated information in columns.
Starting from Polyspace version R2024a these columns are available:
ID, Family, Group, Color, New, Check, Information, Function, File, Status, Severity, Comment, Key, Line and Col.
In previous versions of Polyspace the Line and Col column are not available yet.

This file is required when you enable Polyspace in the configuration file.

Configuration
^^^^^^^^^^^^^

Polyspace checking can only be enabled with a configuration file,
and it cannot be used together with other checkers enabled.
In this case, only the Polyspace checker will run.

When you enable Polyspace checking in the configuration file,
the checks consist of a key that represents the "family" column of the TSV file.
For example, "run-time check" is the family of Code Prover and "defect" is the family of Bug Finder.
The value of that key is a list, which contains the name of the column to check as a key and
the value of that column to check together with ``min`` and ``max`` values.

Example Checks
^^^^^^^^^^^^^^

In case of Code Prover, you might want to check the ``color`` column on ``red`` or ``orange`` issues.
In case of Bug Finder, you might want to check the ``information`` column on ``impact: high``, ``impact: medium``, or even ``impact: low``.
Other issues, such as "Global variable", can also be handled.
You can specify any column and value you want to check in the configuration file.

Running the mlx-warnings plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following commands demonstrate how to run the mlx-warnings plugin with the TSV file:

.. code-block:: bash
# basic Polyspace checker
mlx-warnings --config <configuration_file> <tsv_file>
# Polyspace checker with code quality export
mlx-warnings --code-quality path/to/code_quality.json --config <configuration_file> <tsv_file>
----------------------------------
Configuration File to Pass Options
----------------------------------
Expand Down Expand Up @@ -341,6 +399,20 @@ The values for 'min' and 'max' can be set with environment variables via a
"max": 0
}
]
},
"polyspace": {
"enabled": false,
"cq_description_template": "$PRODUCT $family: $check",
"exclude": [
".+\\tdummy_function\\(\\)\\tdummy_file_name\\.c\\t"
],
"run-time check": [
{
"color": "red",
"min": 0,
"max": 0
}
]
}
}
Expand Down Expand Up @@ -392,6 +464,30 @@ An example configuration for the sphinx checker is given below:
}
}
You can define regular expressions to exclude certain Polyspace results, i.e. specific rows of the TSV file,
when they match against the string that represents the row. This string is a concatenation of the values
of all cells in the row, separated by a tab character (`\t`).
Note: backslashes need to be escaped in JSON syntax.

.. code-block:: json
{
"polyspace": {
"enabled": true,
"cq_description_template": "$PRODUCT $family: $check",
"exclude": [
".+\\tdummy_function\\(\\)\\tdummy_file_name\\.c\\t"
],
"run-time check": [
{
"color": "red",
"min": 0,
"max": 0
}
]
}
}
Exclude Sphinx Deprecation Warnings
-----------------------------------

Expand All @@ -411,16 +507,28 @@ Code Quality Report
-------------------

Use ``-C, --code-quality`` to let the plugin generate `a Code Quality report`_ for GitLab CI. All counted
Sphinx, Doxygen and XMLRunner will be included. Other checker types are not supported by this feature. The report is
Sphinx, Doxygen, XMLRunner and Polyspace warnings/errors/failures will be included. Other checker types are not yet supported by this feature. The report is
a JSON file that implements `a subset of the Code Climate spec`_. Define this file `as a codequality report artifact`_
of the CI job.

If a warning doesn't contain a path, ``"cq_default_path"`` from the `configuration file to pass options`_ will be used.
If not configured, ``.gitlab-ci.yml`` will be used as a fallback path.

You can customize the description with ``"cq_description_template"``, see `configuration file to pass options`_.
Its value should be a template for Python's |string.Template|_. The template should contain ``$description`` and has
access to all environment variables, e.g. ``$HOME``.
Its value should be a template for Python's |string.Template|_. The template has access to all environment variables,
e.g. ``$HOME``, and other variables that depend on the checker type:

Polyspace
Any field of a Polyspace defect can be included by using the corresponding
`column title <Exporting Polyspace Results_>`_ in lowercase as the variable name.
The default template is ``Polyspace: $check``.

Other
The template should contain ``$description``, which is the default.

The Polyspace checker generates the fingerprint (a unique identifier) for each row in the TSV file that is exported as finding.
Specific columns (``new``, ``status``, ``severity``, ``comment``, and ``key``) are excluded as they might contain transient information.
The remaining values in the row are hashed using a MD5 function to create the fingerprint.

=======================
Issues and New Features
Expand Down
191 changes: 150 additions & 41 deletions docs/design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,166 @@ Software Design
Class Diagram
=============

.. uml generated by `pyreverse mlx.warnings --filter ALL -o plantuml`
.. uml::

@startuml
class WarningsPlugin {
#checkerList : WarningsChecker
+__init__(sphinx=False, doxygen=False, junit=False, verbose=False)
@startuml classes
set namespaceSeparator none
class "CoverityChecker" as mlx.warnings.regex_checker.CoverityChecker {
CLASSIFICATION : str
count
name : str
pattern
check(content)
}

class WarningsChecker {
#min_count = 0
#max_count = 0
#count = 0
#verbose = False

#{abstract} __init__(name, verbose=False)
+set_limits(min_count=0, max_count=0,
+{abstract}check(content)
+get_count()
class "DoxyChecker" as mlx.warnings.regex_checker.DoxyChecker {
name : str
pattern
}

class RegexChecker {
#{abstract} __init__(name, regex, verbose=False)
+check(content)
class "JUnitChecker" as mlx.warnings.junit_checker.JUnitChecker {
count
name : str
_check_testcase(testcase)
check(content)
prepare_tree(root_input)
}

class SphinxChecker {
#{static} String name
#{static} String regex
+__init__(verbose=False)
class "PolyspaceChecker" as mlx.warnings.polyspace_checker.PolyspaceChecker {
_cq_description_template : Template
checkers : list
count : int
counted_warnings
cq_default_path
cq_description_template
maximum
minimum
name : str
__init__(verbose)
check(content)
parse_config(config)
return_check_limits()
return_count()
}

class DoxyChecker {
#{static} String name
#{static} String regex
+__init__(verbose=False)
class "PolyspaceFamilyChecker" as mlx.warnings.polyspace_checker.PolyspaceFamilyChecker {
_cq_description_template
check_value
code_quality_severity : dict
column_name
count
cq_description_template
cq_findings : list
family_value
__init__(family_value, column_name, check_value)
add_code_quality_finding(row)
check(content)
return_count()
}

class JUnitChecker {
#{static} String name
+__init__(verbose=False)
+check(content)
class "RegexChecker" as mlx.warnings.regex_checker.RegexChecker {
SEVERITY_MAP : dict
count
name : str
pattern : NoneType
add_code_quality_finding(match)
check(content)
}

WarningsPlugin o-- WarningsChecker
WarningsChecker <|-- RegexChecker
RegexChecker <|-- SphinxChecker
RegexChecker <|-- DoxyChecker
WarningsChecker <|-- JUnitChecker

class "RobotChecker" as mlx.warnings.robot_checker.RobotChecker {
checkers : list
count : int
counted_warnings
maximum
minimum
name : str
check(content)
parse_config(config)
return_check_limits()
return_count()
}
class "RobotSuiteChecker" as mlx.warnings.robot_checker.RobotSuiteChecker {
check_suite_name : bool
is_valid_suite_name : bool
name
__init__(name, check_suite_name)
_check_testcase(testcase)
check(content)
return_count()
}
class "SphinxChecker" as mlx.warnings.regex_checker.SphinxChecker {
name : str
pattern
sphinx_deprecation_regex : str
sphinx_deprecation_regex_in_match : str
include_sphinx_deprecation()
}
class "WarningsChecker" as mlx.warnings.warnings_checker.WarningsChecker {
_counted_warnings : list
_cq_description_template : Template
_maximum : int
_minimum : int
count : int
counted_warnings
cq_default_path : str
cq_description_template
cq_enabled : bool
cq_findings : list
exclude_patterns : list
include_patterns : list
maximum
minimum
name : str
verbose : bool
__init__(verbose)
_is_excluded(content)
_return_error_code()
_search_patterns(content, patterns)
add_patterns(regexes, pattern_container)
{abstract}check(content)
parse_config(config)
print_when_verbose(message)
return_check_limits()
return_count()
}
class "<color:red>WarningsConfigError</color>" as mlx.warnings.exceptions.WarningsConfigError {
}
class "WarningsPlugin" as mlx.warnings.warnings.WarningsPlugin {
_maximum : int
_minimum : int
activated_checkers : dict
count : int
cq_enabled : bool
printout : bool
public_checkers : list
verbose : bool
__init__(verbose, config_file, cq_enabled)
activate_checker(checker)
activate_checker_name(name)
check(content)
check_logfile(file)
config_parser(config)
configure_maximum(maximum)
configure_minimum(minimum)
get_checker(name)
return_check_limits(name)
return_count(name)
toggle_printout(printout)
write_code_quality_report(out_file)
write_counted_warnings(out_file)
}
class "XMLRunnerChecker" as mlx.warnings.regex_checker.XMLRunnerChecker {
name : str
pattern
}
mlx.warnings.junit_checker.JUnitChecker --|> mlx.warnings.warnings_checker.WarningsChecker
mlx.warnings.polyspace_checker.PolyspaceChecker --|> mlx.warnings.warnings_checker.WarningsChecker
mlx.warnings.polyspace_checker.PolyspaceFamilyChecker --|> mlx.warnings.warnings_checker.WarningsChecker
mlx.warnings.regex_checker.CoverityChecker --|> mlx.warnings.regex_checker.RegexChecker
mlx.warnings.regex_checker.DoxyChecker --|> mlx.warnings.regex_checker.RegexChecker
mlx.warnings.regex_checker.RegexChecker --|> mlx.warnings.warnings_checker.WarningsChecker
mlx.warnings.regex_checker.SphinxChecker --|> mlx.warnings.regex_checker.RegexChecker
mlx.warnings.regex_checker.XMLRunnerChecker --|> mlx.warnings.regex_checker.RegexChecker
mlx.warnings.robot_checker.RobotChecker --|> mlx.warnings.warnings_checker.WarningsChecker
mlx.warnings.robot_checker.RobotSuiteChecker --|> mlx.warnings.junit_checker.JUnitChecker
@enduml


String Handling
===============

Expand Down
3 changes: 3 additions & 0 deletions src/mlx/warnings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
'CoverityChecker',
'DoxyChecker',
'JUnitChecker',
'PolyspaceChecker',
'PolyspaceFamilyChecker',
'RobotChecker',
'RobotSuiteChecker',
'SphinxChecker',
Expand All @@ -21,5 +23,6 @@
from .junit_checker import JUnitChecker
from .regex_checker import CoverityChecker, DoxyChecker, SphinxChecker, XMLRunnerChecker
from .robot_checker import RobotChecker, RobotSuiteChecker
from .polyspace_checker import PolyspaceChecker, PolyspaceFamilyChecker
from .warnings import WarningsPlugin, warnings_wrapper
from .warnings_checker import WarningsChecker
Loading

0 comments on commit 2831527

Please sign in to comment.