Skip to content

Commit

Permalink
Merge pull request Ericsson#3693 from dkrupp/suppression_fix
Browse files Browse the repository at this point in the history
Import the suppressions per report
  • Loading branch information
bruntib authored Jul 6, 2022
2 parents d5cc62e + 1176d8f commit ad0a7ff
Show file tree
Hide file tree
Showing 10 changed files with 530 additions and 409 deletions.
623 changes: 343 additions & 280 deletions docs/web/user_guide.md

Large diffs are not rendered by default.

49 changes: 37 additions & 12 deletions web/server/codechecker_server/api/report_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1843,10 +1843,11 @@ def getReportDetails(self, reportId):
def _setReviewStatus(self, session, report_hash, status,
message, date=None):
"""
This function sets the review status of the given report. This is the
implementation of changeReviewStatus(), but it is also extended with
a session parameter which represents a database transaction. This is
needed because during storage a specific session object has to be used.
This function sets the review status of all the reports of a
given hash. This is the implementation of addReviewStatusRule(),
but it is also extended with a session parameter which represents a
database transaction. This is needed because during storage a specific
session object has to be used.
"""
review_status = session.query(ReviewStatus).get(report_hash)
if review_status is None:
Expand Down Expand Up @@ -1958,21 +1959,40 @@ def isReviewStatusChangeDisabled(self):
@timeit
def changeReviewStatus(self, report_id, status, message):
"""
Change review status of the bug by report id.
Change the review status of a report by report id.
"""
self.__require_permission([permissions.PRODUCT_ACCESS,
permissions.PRODUCT_STORE])

if self.isReviewStatusChangeDisabled():
msg = "Review status change is disabled!"
raise codechecker_api_shared.ttypes.RequestFailed(
codechecker_api_shared.ttypes.ErrorCode.GENERAL, msg)

with DBSession(self._Session) as session:
report = session.query(Report).get(report_id)
if report:
self._setReviewStatus(
session, report.bug_id, status, message)
# False positive and intentional reports are considered closed,
# so their "fix date" is set. The reports are reopened when
# they become unreviewed or confirmed again.
# Don't change "fix date" for closed
# report which remain closed.
if status in ["false_positive", "intentional"]:
if report.detection_status in [
"unresolved", "new", "reopened"]\
and report.review_status not in [
"false_positive", "intentional"]:
session.query(Report).filter(
Report.id == report_id).update(
{"fixed_at": datetime.now()})
elif report.detection_status in [
"unresolved", "new", "reopened"]\
and report.review_status in [
"false_positive", "intentional"]:
session.query(Report).filter(
Report.id == report_id).update({"fixed_at": None})

session.query(Report).filter(Report.id == report_id).update({
'review_status': review_status_str(status),
'review_status_author': self._get_username(),
'review_status_message': bytes(message, 'utf-8'),
'review_status_date': datetime.now()
})
else:
raise codechecker_api_shared.ttypes.RequestFailed(
codechecker_api_shared.ttypes.ErrorCode.DATABASE,
Expand Down Expand Up @@ -2061,6 +2081,11 @@ def addReviewStatusRule(self, report_hash, review_status, message):
self.__require_permission([permissions.PRODUCT_ACCESS,
permissions.PRODUCT_STORE])

if self.isReviewStatusChangeDisabled():
msg = "Review status change is disabled!"
raise codechecker_api_shared.ttypes.RequestFailed(
codechecker_api_shared.ttypes.ErrorCode.GENERAL, msg)

with DBSession(self._Session) as session:
self._setReviewStatus(
session, report_hash, review_status, message)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 77 additions & 60 deletions web/server/vue-cli/src/assets/userguide/userguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,63 @@ on GitHub</a>
Table of Contents
=================

* [Products](#products)
* [Managing products](#managing-products)
* [Add new product](#add-new-product)
* [Disable review status change](#disable-review-status-change)
* [Confidentiality classification](#confidentiality-classification)
* [Edit product configuration](#edit-product-configuration)
* [Remove a product](#remove-a-product)
* [Managing permissions](#managing-permissions)
* [Notification banner](#notification-banner)
* [Runs and history events](#runs-and-history-events)
* [Runs](#runs)
* [Show description](#show-description)
* [Show check command](#show-check-command)
* [Show analyzer statistics](#show-analyzer-statistics)
* [Filter runs](#filter-runs)
* [Compare runs](#compare-runs)
* [Sorting runs](#sorting-runs)
* [Delete runs](#delete-runs)
* [Run history](#run-history)
* [Compare run history events](#compare-run-history-events)
* [Filter run history events](#filter-run-history-events)
* [Reports](#reports)
* [Review status](#review-status)
* [Detection status](#detection-status)
* [Severity levels](#severity-levels)
* [Filtering reports](#filtering-reports)
* [Date filters](#date-filters)
* [Regex based filters](#regex-based-filters)
* [Report count](#report-count)
* [Remove filtered reports](#remove-filtered-reports)
* [Clear report filters](#clear-report-filters)
* [Unique reports](#unique-reports)
* [Compare mode](#compare-mode)
* [Compare two different runs](#compare-runs)
* [Compare two different tagged versions of the same](#compare-tags)
* [Manage source components](#manage-source-components)
* [Report details](#report-details)
* [Report navigation tree](#report-navigation-tree)
* [Button pane](#button-pane)
* [Report info](#report-info)
* [Show documentation](#show-documentation)
* [Change review status](#change-review-status)
* [Same reports](#same-reports)
* [Bug path view](#bug-path-view)
* [Comment](#comment)
* [Statistics](#statistics)
* [Statistics pages](#statistics-pages)
* [Product overview](#product-overview)
* [Checker statistics](#checker-statistics)
* [Severity statistics](#severity-statistics)
* [Component statistics](#component-statistics)
* [Filtering statistics](#filtering-statistics)
* [Uniqueing checker statistics](#checker-statistics-uniqueing)
- [WEB GUI User Guide](#web-gui-user-guide)
- [Table of Contents](#table-of-contents)
- [Products](#products)
- [Managing products](#managing-products)
- [Add new product](#add-new-product)
- [Disable review status change](#disable-review-status-change)
- [Confidentiality classification](#confidentiality-classification)
- [Edit product configuration](#edit-product-configuration)
- [Remove a product](#remove-a-product)
- [Managing permissions](#managing-permissions)
- [Notification banner](#notification-banner)
- [Runs and history events](#runs-and-history-events)
- [Runs](#runs)
- [Show description](#show-description)
- [Show check command](#show-check-command)
- [Show analyzer statistics](#show-analyzer-statistics)
- [Filter runs](#filter-runs)
- [Compare runs](#compare-runs)
- [Sorting runs](#sorting-runs)
- [Delete runs](#delete-runs)
- [Run history](#run-history)
- [Compare run history events](#compare-run-history-events)
- [Filter run history events](#filter-run-history-events)
- [Reports](#reports)
- [Review status](#review-status)
- [Detection status](#detection-status)
- [Severity levels](#severity-levels)
- [Filtering reports](#filtering-reports)
- [Date filters](#date-filters)
- [Regex based filters](#regex-based-filters)
- [Report count](#report-count)
- [Remove filtered reports](#remove-filtered-reports)
- [Clear report filters](#clear-report-filters)
- [Unique reports](#unique-reports)
- [Compare mode](#compare-mode)
- [Compare two different runs](#compare-two-different-runs)
- [Compare two different tagged versions of the same](#compare-two-different-tagged-versions-of-the-same)
- [Manage source components](#manage-source-components)
- [Manage cleanup plans](#manage-cleanup-plans)
- [Assign reports to cleanup plans](#assign-reports-to-cleanup-plans)
- [Report details](#report-details)
- [Report Navigation Tree](#report-navigation-tree)
- [Button pane](#button-pane)
- [Report info](#report-info)
- [Show documentation](#show-documentation)
- [Change review status](#change-review-status)
- [Same reports](#same-reports)
- [Bug path view](#bug-path-view)
- [Comment](#comment)
- [Statistics](#statistics)
- [Statistics pages](#statistics-pages)
- [Product overview](#product-overview)
- [Checker statistics](#checker-statistics)
- [Severity statistics](#severity-statistics)
- [Component statistics](#component-statistics)
- [Filtering statistics](#filtering-statistics)
- [Uniqueing checker statistics](#uniqueing-checker-statistics)

# Products
The product system allows a single CodeChecker server to serve multiple
Expand All @@ -93,7 +97,7 @@ In the product list table you can see the following information:
belongs to.
- `Description`: short description of the product.
- `Administrator names`: product admins have the right to allow access for
individual people or LDAP groups.
individual people or LDAP groups.
- `Number of runs`: number of runs in the product.
- `Latest store to the product`: date of the latest run storage.
- `Run store in progress`: show run names if a storage is in progress.
Expand Down Expand Up @@ -400,18 +404,31 @@ This report is a bug but we don't want to fix it.
![Review statuses](images/reports/review_statuses.png)


Review statuses are connected to
[report hashes](https://github.com/Ericsson/codechecker/blob/master/docs/analyzer/report_identification.md).
If the same report can be found in multiple runs it will have the same review
status.

It can be changed on the [GUI](#userguide-change-review-status) or by using
Review status can be set on the [GUI](#userguide-change-review-status) or by using
[source code comments ](https://github.com/Ericsson/codechecker/blob/master/docs/analyzer/user_guide.md#source-code-comments)
(*codechecker_false_positive*, *codechecker_confirmed*, etc.)

Review status set in source comments are applied on the individual report instances, while
review status set in the GUI are added as Review Status Rules connected to
[report hashes](https://github.com/Ericsson/codechecker/blob/master/docs/analyzer/report_identification.md).

So when you chang the review status of a report in the GUI,
it will change the review status in all reports with the same hash
in all runs. Reports stored in the future with the same hash will also get the same review status.

So once you set the review status in the GUI,
there is no need to set the same review status again in other runs.



**Note**: source code comment is stronger and can overwrite the value in the
database.

Review status values added in the WEB GUI are stored as Review Status Rules
and can be managed in the Configuration/ReviewStatusRules tab.
![Review Status Rules](images/review_status_rules/review_status.rules.png)


## Detection status
The detection status is the state of a bug report in a run.

Expand Down
7 changes: 4 additions & 3 deletions web/tests/functional/db_cleanup/test_db_cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ def test_garbage_file_collection(self):
success = self._cc_client.addComment(report_id, comment)
self.assertTrue(success)

# Change review status.
success = self._cc_client.changeReviewStatus(
report_id, ReviewStatus.CONFIRMED, 'Real bug')
# Change review status with a review status rule.
success = self._cc_client.addReviewStatusRule(
report.bugHash, ReviewStatus.CONFIRMED,
'Real bug')
self.assertTrue(success)

# Remove the first storage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ def guiSuppressAllHashes(self, checker_name):
[project_orig_run.runId], 500, 0, None, report_filter, None, False)

for report in reports:
self._cc_client.changeReviewStatus(
report.reportId,
self._cc_client.addReviewStatusRule(
report.bugHash,
ReviewStatus.FALSE_POSITIVE,
"not a bug")

Expand Down
70 changes: 34 additions & 36 deletions web/tests/functional/report_viewer_api/test_report_counting.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,8 @@ def test_run1_all_review_status(self):

# Set report status of all reports to unreviewed.
for report in reports:
self._cc_client.changeReviewStatus(report.reportId,
ReviewStatus.UNREVIEWED,
'')
self._cc_client.addReviewStatusRule(report.bugHash,
ReviewStatus.UNREVIEWED, '')

review_status = defaultdict(int)
review_status[ReviewStatus.UNREVIEWED] = len(reports)
Expand All @@ -398,9 +397,9 @@ def test_run1_all_review_status(self):
start_range = i * 5
end_range = (i + 1) * 5
for report in unique_reports[start_range:end_range]:
self._cc_client.changeReviewStatus(report[0],
status,
'comment')
self._cc_client.addReviewStatusRule(report[1],
status,
'comment')
review_status[status] += \
reporthash_reports_count[report[1]]

Expand All @@ -422,38 +421,37 @@ def test_run1_run2_all_review_status(self):
None,
None)

report_ids = [x.reportId for x
in self._cc_client.getRunResults([runid],
report_count,
0,
[],
None,
None,
False)]
report_hashes = [x.bugHash for x
in self._cc_client.getRunResults([runid],
report_count, 0,
[],
None,
None,
False)]

# Set report status of all reports to unreviewed.
for rid in report_ids:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.UNREVIEWED,
'')

for rid in report_ids[:5]:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.UNREVIEWED,
'comment')
for rid in report_ids[5:10]:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.CONFIRMED,
'comment')

for rid in report_ids[10:15]:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.FALSE_POSITIVE,
'comment')
for rid in report_ids[15:20]:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.INTENTIONAL,
'comment')
for rid in report_hashes:
self._cc_client.addReviewStatusRule(rid,
ReviewStatus.UNREVIEWED,
'')

for rid in report_hashes[:5]:
self._cc_client.addReviewStatusRule(rid,
ReviewStatus.UNREVIEWED,
'comment')
for rid in report_hashes[5:10]:
self._cc_client.addReviewStatusRule(rid,
ReviewStatus.CONFIRMED,
'comment')

for rid in report_hashes[10:15]:
self._cc_client.addReviewStatusRule(rid,
ReviewStatus.FALSE_POSITIVE,
'comment')
for rid in report_hashes[15:20]:
self._cc_client.addReviewStatusRule(rid,
ReviewStatus.INTENTIONAL,
'comment')

rv_counts_1 = self._cc_client.getReviewStatusCounts([self._runids[0]],
None,
Expand Down
10 changes: 4 additions & 6 deletions web/tests/functional/report_viewer_api/test_report_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,11 @@ def test_filter_review_status(self):
None,
False)

report_ids = [r.reportId for r in run_results]

# Set all review statuses in case some other tests changed them.
for rid in report_ids:
self._cc_client.changeReviewStatus(rid,
ReviewStatus.CONFIRMED,
'')
for r in run_results:
self._cc_client.addReviewStatusRule(r.bugHash,
ReviewStatus.CONFIRMED,
'')

for level in severity_test_data:
for review_status, test_result_count in level.items():
Expand Down
5 changes: 3 additions & 2 deletions web/tests/functional/suppress/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ def setup_package():
if ret:
sys.exit(1)
print("Analyzing the test project was successful.")
test_project_name_dup = test_project_name + "_duplicate"
ret = codechecker.store(codechecker_cfg, test_project_name_dup)

codechecker_cfg['run_names'] = [test_project_name]

codechecker_cfg['run_names'] = [test_project_name, test_project_name_dup]
test_config['codechecker_cfg'] = codechecker_cfg

env.export_test_cfg(TEST_WORKSPACE, test_config)
Expand Down
Loading

0 comments on commit ad0a7ff

Please sign in to comment.