Skip to content

Commit 5179211

Browse files
committed
[script] Script for querying all reports
This script can query all reports for all products from a CodeChecker server.
1 parent 5c6b81e commit 5179211

File tree

2 files changed

+181
-0
lines changed

2 files changed

+181
-0
lines changed
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
import argparse
10+
import json
11+
import sys
12+
13+
def main():
14+
parser = argparse.ArgumentParser(
15+
description="Compares two CodeChecker results. The results should be "
16+
"generated by 'CodeChecker cmd results' command.")
17+
18+
parser.add_argument(
19+
"result1",
20+
type=argparse.FileType("r"),
21+
help="Path of the first result.")
22+
23+
parser.add_argument(
24+
"result2",
25+
type=argparse.FileType("r"),
26+
help="Path of the second result.")
27+
28+
args = parser.parse_args()
29+
30+
result1 = json.load(args.result1)
31+
result2 = json.load(args.result2)
32+
33+
result1.sort(key=lambda report: report['bugHash'] + str(report['reportId']))
34+
result2.sort(key=lambda report: report['bugHash'] + str(report['reportId']))
35+
36+
found_mismatch = False
37+
38+
for report in result1:
39+
if report not in result2:
40+
print("Report not found in result2:")
41+
print(json.dumps(report, indent=4))
42+
found_mismatch = True
43+
44+
for report in result2:
45+
if report not in result1:
46+
print("Report not found in result1:")
47+
print(json.dumps(report, indent=4))
48+
found_mismatch = True
49+
50+
args.result1.close()
51+
args.result2.close()
52+
53+
return 1 if found_mismatch else 0
54+
55+
if __name__ == '__main__':
56+
sys.exit(main())
57+
+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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+
import argparse
9+
import functools
10+
import json
11+
import os
12+
import subprocess
13+
import sys
14+
from multiprocess import Pool
15+
from pathlib import Path
16+
from typing import List, Tuple
17+
18+
19+
def parse_args():
20+
"""
21+
Initialize global variables based on command line arguments. These
22+
variables are global because get_results() uses them. That function is used
23+
as a callback which doesn't get this info as parameters.
24+
"""
25+
parser = argparse.ArgumentParser(
26+
description="Fetch all reports of products")
27+
28+
parser.add_argument(
29+
'--url',
30+
default='localhost:8001',
31+
help='URL of a CodeChecker server.')
32+
33+
parser.add_argument(
34+
'--output',
35+
required=True,
36+
help='Output folder for generated JSON files.')
37+
38+
parser.add_argument(
39+
'-j', '--jobs',
40+
default=1,
41+
type=int,
42+
help='Get reports in this many parallel jobs.')
43+
44+
parser.add_argument(
45+
'--products',
46+
nargs='+',
47+
help='List of products to fetch reports for. By default, all products '
48+
'are fetched.')
49+
50+
return parser.parse_args()
51+
52+
53+
def __get_keys_from_list(out) -> List[str]:
54+
"""
55+
Get all keys from a JSON list.
56+
"""
57+
return map(lambda prod: next(iter(prod.keys())), json.loads(out))
58+
59+
60+
def result_getter(args: argparse.Namespace):
61+
def get_results(product_run: Tuple[str, str]):
62+
product, run = product_run
63+
print(product, run)
64+
65+
out, _ = subprocess.Popen([
66+
'CodeChecker', 'cmd', 'results', run,
67+
'-o', 'json',
68+
'--url', f'{args.url}/{product}'],
69+
stdout=subprocess.PIPE,
70+
stderr=subprocess.PIPE).communicate()
71+
72+
reports = sorted(
73+
json.loads(out), key=lambda report: report['reportId'])
74+
75+
run = run.replace('/', '_')
76+
with open(Path(args.output) / f'{product}_{run}.json', 'w',
77+
encoding='utf-8') as f:
78+
json.dump(reports, f)
79+
80+
return get_results
81+
82+
83+
def get_all_products(url: str) -> List[str]:
84+
"""
85+
Get all products from a CodeChecker server.
86+
87+
:param url: URL of a CodeChecker server.
88+
:return: List of product names.
89+
"""
90+
out, _ = subprocess.Popen(
91+
['CodeChecker', 'cmd', 'products', 'list', '-o', 'json', '--url', url],
92+
stdout=subprocess.PIPE,
93+
stderr=subprocess.DEVNULL).communicate()
94+
95+
return __get_keys_from_list(out)
96+
97+
98+
def main():
99+
args = parse_args()
100+
101+
os.makedirs(args.output, exist_ok=True)
102+
103+
if not args.products:
104+
args.products = get_all_products(args.url)
105+
106+
for product in args.products:
107+
f = functools.partial(lambda p, r: (p, r), product)
108+
with subprocess.Popen([
109+
'CodeChecker', 'cmd', 'runs',
110+
'--url', f'{args.url}/{product}',
111+
'-o', 'json'],
112+
stdout=subprocess.PIPE,
113+
stderr=subprocess.PIPE
114+
) as proc:
115+
runs = list(__get_keys_from_list(proc.stdout.read()))
116+
117+
with Pool(args.jobs) as p:
118+
p.map(result_getter(args), map(f, runs))
119+
120+
return 0
121+
122+
123+
if __name__ == '__main__':
124+
sys.exit(main())

0 commit comments

Comments
 (0)