Skip to content

Commit

Permalink
[GUI] New "Analysis statistics" tab to show all enabled checkers and …
Browse files Browse the repository at this point in the history
…their statistics

It is a new feature based on Ericsson#4089. The new Analysis statitics tab on the Statistics page is able to list all enabled checkers for runs that are selected (or for all runs if no run selected) in the report filter. The table lists all checkers that were enabled in at least one of runs according to the latest analysis. It also shows checker severity, status, number of closed and outstanding reports.

Status can inform the user that the specific checker was "Enabled in all" runs or "Enabled in all runs except these" where "runs" and "these" words are links to list appropriate runs.

Closed and outstanding report counts depend on review and detection status. These statistics represent the number of closed and outstanding reports that belong to runs that were created with new DB schema.
  • Loading branch information
cservakt committed Mar 8, 2024
1 parent fa1d14f commit 9da5f39
Show file tree
Hide file tree
Showing 23 changed files with 800 additions and 27 deletions.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/js/codechecker-api-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codechecker-api",
"version": "6.55.0",
"version": "6.56.0",
"description": "Generated node.js compatible API stubs for CodeChecker server.",
"main": "lib",
"homepage": "https://github.com/Ericsson/codechecker",
Expand Down
Binary file modified web/api/py/codechecker_api/dist/codechecker_api.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/py/codechecker_api/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
with open('README.md', encoding='utf-8', errors="ignore") as f:
long_description = f.read()

api_version = '6.55.0'
api_version = '6.56.0'

setup(
name='codechecker_api',
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/py/codechecker_api_shared/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
with open('README.md', encoding='utf-8', errors="ignore") as f:
long_description = f.read()

api_version = '6.55.0'
api_version = '6.56.0'

setup(
name='codechecker_api_shared',
Expand Down
2 changes: 1 addition & 1 deletion web/codechecker_web/shared/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# The newest supported minor version (value) for each supported major version
# (key) in this particular build.
SUPPORTED_VERSIONS = {
6: 55
6: 56
}

# Used by the client to automatically identify the latest major and minor
Expand Down
185 changes: 183 additions & 2 deletions web/server/codechecker_server/api/report_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import sqlalchemy
from sqlalchemy.sql.expression import or_, and_, not_, func, \
asc, desc, union_all, select, bindparam, literal_column
asc, desc, union_all, select, bindparam, literal_column, case
from sqlalchemy.orm import contains_eager

import codechecker_api_shared
Expand All @@ -42,7 +42,8 @@
ReviewStatusRuleFilter, ReviewStatusRuleSortMode, \
ReviewStatusRuleSortType, RunData, RunFilter, RunHistoryData, \
RunReportCount, RunSortType, RunTagCount, \
SourceComponentData, SourceFileData, SortMode, SortType
SourceComponentData, SourceFileData, SortMode, SortType, \
ReviewStatus as API_ReviewStatus, DetectionStatus, CheckerInfo

from codechecker_common import util
from codechecker_common.logger import get_logger
Expand All @@ -58,6 +59,7 @@
from ..database.database import conv, DBSession, escape_like
from ..database.run_db_model import \
AnalysisInfo, AnalysisInfoChecker as DB_AnalysisInfoChecker, \
AnalysisInfoChecker, \
AnalyzerStatistic, \
BugPathEvent, BugReportPoint, \
CleanupPlan, CleanupPlanReportHash, Checker, Comment, \
Expand Down Expand Up @@ -2861,6 +2863,185 @@ def getCheckerCounts(self, run_ids, report_filter, cmp_data, limit,
results.append(checker_count)
return results

@exc_to_thrift_reqfail
@timeit
def getCheckerInfo(self, run_ids, report_filter):
self.__require_view()
with DBSession(self._Session) as session:
# filter_expression, join_tables = process_report_filter(
# session, run_ids, report_filter)

max_run_histories = session.query(
RunHistory.run_id,
func.max(RunHistory.id).label('max_run_history_id'),
) \
.filter(RunHistory.run_id.in_(run_ids) if run_ids else True) \
.group_by(RunHistory.run_id)

subquery = (
session.query(
func.group_concat(Run.id.distinct()).label("run_id")
if report_filter.isUnique
else Run.id.label("run_id"),
Checker.id.label("checker_id"),
Checker.checker_name,
Checker.analyzer_name,
Checker.severity,
Report.bug_id,
Report.detection_status,
Report.review_status,
)
.join(RunHistory)
.join(AnalysisInfo, RunHistory.analysis_info)
.join(AnalysisInfoChecker, (
(AnalysisInfo.id == AnalysisInfoChecker.analysis_info_id)
& (AnalysisInfoChecker.enabled.is_(True))))
.join(Checker, AnalysisInfoChecker.checker_id == Checker.id)
.outerjoin(Report, ((Checker.id == Report.checker_id)
& (Run.id == Report.run_id)))
.filter(RunHistory.id == max_run_histories.subquery()
.c.max_run_history_id)
)

if report_filter.isUnique:
subquery = subquery.group_by(
Checker.id,
Checker.checker_name,
Checker.analyzer_name,
Checker.severity,
Report.bug_id,
Report.detection_status,
Report.review_status
)

subquery = subquery.subquery()

query = (
session.query(
subquery.c.checker_id,
subquery.c.checker_name,
subquery.c.analyzer_name,
subquery.c.severity,
subquery.c.run_id,
case(
[
(
subquery.c.detection_status.in_(list(map(
detection_status_str,
(DetectionStatus.OFF,
DetectionStatus.UNAVAILABLE)
))),
False
)
],
else_=True
).label("isEnabled"),
case(
[
(
and_(
subquery.c.detection_status.in_(list(map(
detection_status_str,
(DetectionStatus.NEW,
DetectionStatus.UNRESOLVED,
DetectionStatus.REOPENED)
))),
subquery.c.review_status.in_(list(map(
review_status_str,
(API_ReviewStatus.UNREVIEWED,
API_ReviewStatus.CONFIRMED))))
),
True
)
],
else_=False
).label("isOpened"),
func.count(subquery.c.bug_id)
)
.group_by(
subquery.c.checker_id,
subquery.c.checker_name,
subquery.c.analyzer_name,
subquery.c.severity,
subquery.c.run_id,
case(
[
(
subquery.c.detection_status.in_(list(map(
detection_status_str,
(DetectionStatus.OFF,
DetectionStatus.UNAVAILABLE)
))),
False
)
],
else_=True
),
case(
[
(
and_(
subquery.c.detection_status.in_(list(map(
detection_status_str,
(DetectionStatus.NEW,
DetectionStatus.UNRESOLVED,
DetectionStatus.REOPENED)
))),
subquery.c.review_status.in_(list(map(
review_status_str,
(API_ReviewStatus.UNREVIEWED,
API_ReviewStatus.CONFIRMED))))
),
True
)
],
else_=False
)
)
)

checker_stats = {}
for checker_id, \
checker_name, \
analyzer_name, \
severity, \
run_ids, \
is_enabled, \
is_opened, \
cnt \
in query.all():
checker_stat = checker_stats[checker_id] \
if checker_id in checker_stats \
else CheckerInfo(
checkerName=checker_name,
analyzerName=analyzer_name,
enabled=[],
disabled=[runId for runId, _
in max_run_histories.all()],
severity=severity,
closed=0,
outstanding=0
)

if is_enabled:
for r in (run_ids.split(",")
if type(run_ids) is str
else [run_ids]):
run_id = int(r)
if run_id not in checker_stat.enabled:
checker_stat.enabled.append(run_id)
if run_id in checker_stat.disabled:
checker_stat.disabled.remove(run_id)

if is_enabled and is_opened:
checker_stat.outstanding += cnt
else:
checker_stat.closed += cnt

checker_stats[checker_id] = checker_stat

return checker_stats

@exc_to_thrift_reqfail
@timeit
def getAnalyzerNameCounts(self, run_ids, report_filter, cmp_data, limit,
Expand Down
12 changes: 6 additions & 6 deletions web/server/vue-cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/server/vue-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"dependencies": {
"@mdi/font": "^6.5.95",
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.55.0.tgz",
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.56.0.tgz",
"chart.js": "^2.9.4",
"chartjs-plugin-datalabels": "^0.7.0",
"codemirror": "^5.65.0",
Expand Down
Loading

0 comments on commit 9da5f39

Please sign in to comment.