Skip to content

Commit 98bd13c

Browse files
authored
Merge pull request #4450 from bruntib/typed_annotations
[feat] Introduce chronological order for dynamic reports
2 parents e405f2b + c0fa99e commit 98bd13c

File tree

16 files changed

+95
-40
lines changed

16 files changed

+95
-40
lines changed

docs/analyzer/user_guide.md

+11-3
Original file line numberDiff line numberDiff line change
@@ -1779,9 +1779,15 @@ name.
17791779

17801780
`.plist` files can be extended with a `report-annotation` section shown in the
17811781
following example. Report annotations are custom labels that can be attached to
1782-
a report. CodeChecker supports the usage of `testcase` and `timestamp`
1783-
annotations. `timestamp` can be used for ordering and `testcase` can be used
1784-
for filtering reports in the CodeChecker GUI.
1782+
a report. CodeChecker supports the usage of `testcase`, `timestamp` and
1783+
`chronological_order` annotations. `timestamp` and `chronological_order` can be
1784+
used for ordering and `testcase` can be used for filtering reports in the
1785+
CodeChecker GUI. These are typed annotations and CodeChecker is validating
1786+
these types:
1787+
1788+
- `timestamp`: Date-time format
1789+
- `chronological_order`: Integer
1790+
- `testcase`: String
17851791

17861792
<pre>
17871793
&lt;dict&gt;
@@ -1804,6 +1810,8 @@ for filtering reports in the CodeChecker GUI.
18041810
&lt;string&gt;yhegalkoei&lt;/string&gt;
18051811
&lt;key&gt;timestamp&lt;/key&gt;
18061812
&lt;string&gt;1970-04-26T17:27:55&lt;/string&gt;
1813+
&lt;key&gt;chronological_order&lt;/key&gt;
1814+
&lt;integer&gt;42&lt;/integer&gt;
18071815
&lt;/dict&gt;</b>
18081816
&lt;key&gt;path&lt;/key&gt;
18091817
&lt;array&gt;
Binary file not shown.
Binary file not shown.

web/api/js/codechecker-api-node/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codechecker-api",
3-
"version": "6.60.0",
3+
"version": "6.61.0",
44
"description": "Generated node.js compatible API stubs for CodeChecker server.",
55
"main": "lib",
66
"homepage": "https://github.com/Ericsson/codechecker",
Binary file not shown.

web/api/py/codechecker_api/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
with open('README.md', encoding='utf-8', errors="ignore") as f:
99
long_description = f.read()
1010

11-
api_version = '6.60.0'
11+
api_version = '6.61.0'
1212

1313
setup(
1414
name='codechecker_api',
Binary file not shown.

web/api/py/codechecker_api_shared/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
with open('README.md', encoding='utf-8', errors="ignore") as f:
99
long_description = f.read()
1010

11-
api_version = '6.60.0'
11+
api_version = '6.61.0'
1212

1313
setup(
1414
name='codechecker_api_shared',

web/api/report_server.thrift

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ enum SortType {
8282
DETECTION_STATUS,
8383
BUG_PATH_LENGTH,
8484
TIMESTAMP,
85-
TESTCASE
85+
TESTCASE,
86+
CHRONOLOGICAL_ORDER
8687
}
8788

8889
enum RunSortType {

web/codechecker_web/shared/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# The newest supported minor version (value) for each supported major version
2121
# (key) in this particular build.
2222
SUPPORTED_VERSIONS = {
23-
6: 60
23+
6: 61
2424
}
2525

2626
# Used by the client to automatically identify the latest major and minor

web/server/codechecker_server/api/mass_store_run.py

+7-20
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
Run, RunLock, RunHistory
4949
from ..metadata import checker_is_unavailable, MetadataInfoParser
5050

51+
from .report_annotations import report_annotation_types
5152
from .report_server import ThriftRequestHandler
5253
from .thrift_enum_helper import report_extended_data_type_str
5354

@@ -1160,39 +1161,25 @@ def __validate_and_add_report_annotations(
11601161
doesn't match then an exception is thrown. In case of proper format the
11611162
annotation is added to the database.
11621163
"""
1163-
allowed_types = {
1164-
"datetime": {
1165-
"func": datetime.fromisoformat,
1166-
"display": "date-time in ISO format"
1167-
},
1168-
"string": {
1169-
"func": str,
1170-
"display": "string"
1171-
}
1172-
}
1173-
1174-
allowed_annotations = {
1175-
"timestamp": allowed_types["datetime"],
1176-
"testsuite": allowed_types["string"],
1177-
"testcase": allowed_types["string"]
1178-
}
1179-
11801164
for key, value in report_annotation.items():
11811165
try:
1182-
allowed_annotations[key]["func"](value)
1166+
# String conversion is for normalizing the format. For example,
1167+
# "2000-01-01T10:20" timestamp will be stored as
1168+
# "2000-01-01 10:20".
1169+
value = str(report_annotation_types[key]["func"](value))
11831170
session.add(ReportAnnotations(report_id, key, value))
11841171
except KeyError:
11851172
# pylint: disable=raise-missing-from
11861173
raise codechecker_api_shared.ttypes.RequestFailed(
11871174
codechecker_api_shared.ttypes.ErrorCode.REPORT_FORMAT,
11881175
f"'{key}' is not an allowed report annotation.",
1189-
allowed_annotations.keys())
1176+
report_annotation_types.keys())
11901177
except ValueError:
11911178
# pylint: disable=raise-missing-from
11921179
raise codechecker_api_shared.ttypes.RequestFailed(
11931180
codechecker_api_shared.ttypes.ErrorCode.REPORT_FORMAT,
11941181
f"'{value}' has wrong format. '{key}' annotations must be "
1195-
f"'{allowed_annotations[key]['display']}'.")
1182+
f"'{report_annotation_types[key]['display']}'.")
11961183

11971184
def __get_report_limit_for_product(self):
11981185
with DBSession(self.__config_database) as session:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# -------------------------------------------------------------------------
2+
#
3+
# Part of the CodeChecker project, under the Apache License v2.0 with
4+
# LLVM Exceptions. See LICENSE for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# -------------------------------------------------------------------------
8+
9+
from datetime import datetime
10+
import sqlalchemy
11+
12+
13+
__allowed_types = {
14+
"datetime": {
15+
"func": datetime.fromisoformat,
16+
"display": "date-time in ISO format",
17+
# TODO: SQLite has limited datetime support
18+
"db": sqlalchemy.types.String
19+
},
20+
"string": {
21+
"func": str,
22+
"display": "string",
23+
"db": sqlalchemy.types.String
24+
},
25+
"integer": {
26+
"func": int,
27+
"display": "integer",
28+
"db": sqlalchemy.types.Integer
29+
}
30+
}
31+
32+
33+
report_annotation_types = {
34+
"timestamp": __allowed_types["datetime"],
35+
"testcase": __allowed_types["string"],
36+
"chronological_order": __allowed_types["integer"]
37+
}

web/server/codechecker_server/api/report_server.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
from .thrift_enum_helper import detection_status_enum, \
7373
detection_status_str, report_status_enum, \
7474
review_status_enum, review_status_str, report_extended_data_type_enum
75+
from .report_annotations import report_annotation_types
7576

7677
# These names are inherited from Thrift stubs.
7778
# pylint: disable=invalid-name
@@ -1024,7 +1025,9 @@ def get_sort_map(sort_types, is_unique=False):
10241025
SortType.REVIEW_STATUS: [(Report.review_status, 'rw_status')],
10251026
SortType.DETECTION_STATUS: [(Report.detection_status, 'dt_status')],
10261027
SortType.TIMESTAMP: [('annotation_timestamp', 'annotation_timestamp')],
1027-
SortType.TESTCASE: [('annotation_testcase', 'annotation_testcase')]}
1028+
SortType.TESTCASE: [('annotation_testcase', 'annotation_testcase')],
1029+
SortType.CHRONOLOGICAL_ORDER: [('annotation_chronological_order',
1030+
'annotation_chronological_order')]}
10281031

10291032
if is_unique:
10301033
sort_type_map[SortType.FILENAME] = [(File.filename, 'filename')]
@@ -1959,7 +1962,9 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
19591962
for col in annotation_keys:
19601963
annotation_cols[col] = func.max(sqlalchemy.case([(
19611964
ReportAnnotations.key == col,
1962-
ReportAnnotations.value)])).label(f"annotation_{col}")
1965+
cast(ReportAnnotations.value,
1966+
report_annotation_types[col]["db"]))])) \
1967+
.label(f"annotation_{col}")
19631968

19641969
if report_filter.isUnique:
19651970
# A report annotation filter cannot be set in WHERE clause if
@@ -2143,7 +2148,7 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
21432148
for row in query_result:
21442149
report, filepath = row[0], row[1]
21452150
annotations = {
2146-
k: v for k, v in zip(annotation_keys, row[2:])
2151+
k: str(v) for k, v in zip(annotation_keys, row[2:])
21472152
if v is not None}
21482153

21492154
review_data = create_review_data(

web/server/vue-cli/package-lock.json

+6-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/server/vue-cli/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"dependencies": {
2929
"@mdi/font": "^6.5.95",
30-
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.60.0.tgz",
30+
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.61.0.tgz",
3131
"chart.js": "^2.9.4",
3232
"chartjs-plugin-datalabels": "^0.7.0",
3333
"codemirror": "^5.65.0",

web/server/vue-cli/src/views/Reports.vue

+19-1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ export default {
276276
align: "center",
277277
sortable: true
278278
},
279+
{
280+
text: "Chronological order",
281+
value: "chronological-order",
282+
align: "center",
283+
sortable: true
284+
},
279285
{
280286
text: "Testcase",
281287
value: "testcase",
@@ -287,6 +293,7 @@ export default {
287293
sameReports: {},
288294
hasTimeStamp: true,
289295
hasTestCase : true,
296+
hasChronologicalOrder: true,
290297
selected: [],
291298
namespace: namespace,
292299
pagination: {
@@ -337,6 +344,10 @@ export default {
337344
return this.hasTestCase;
338345
}
339346
347+
if (header.value === "chronological-order") {
348+
return this.hasChronologicalOrder;
349+
}
350+
340351
return true;
341352
});
342353
},
@@ -365,7 +376,8 @@ export default {
365376
"$id": id,
366377
"sameReports": report.sameReports,
367378
"timestamp": report.annotations["timestamp"],
368-
"testcase": report.annotations["testcase"]
379+
"testcase": report.annotations["testcase"],
380+
"chronological-order": report.annotations["chronological-order"]
369381
};
370382
});
371383
}
@@ -388,6 +400,9 @@ export default {
388400
389401
this.hasTestCase =
390402
this.formattedReports.some(report => report.testcase);
403+
404+
this.hasChronologicalOrder =
405+
this.formattedReports.some(report => report["chronological-order"]);
391406
}
392407
}
393408
},
@@ -426,6 +441,9 @@ export default {
426441
case "testcase":
427442
type = SortType.TESTCASE;
428443
break;
444+
case "chronological-order":
445+
type = SortType.CHRONOLOGICAL_ORDER;
446+
break;
429447
default:
430448
type = SortType.SEVERITY;
431449
}

0 commit comments

Comments
 (0)