Skip to content

Commit

Permalink
[script] Script for querying all reports
Browse files Browse the repository at this point in the history
This script can query all reports for all products from a CodeChecker
server.
  • Loading branch information
bruntib committed Jul 31, 2024
1 parent 5c6b81e commit 4920f98
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
53 changes: 53 additions & 0 deletions scripts/compare_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

import argparse
import json
import sys

def main():
parser = argparse.ArgumentParser(
description="Compares two CodeChecker results. The results should be "
"generated by 'CodeChecker cmd results' command.")

parser.add_argument(
"result1",
type=argparse.FileType("r"),
help="Path of the first result.")

parser.add_argument(
"result2",
type=argparse.FileType("r"),
help="Path of the second result.")

args = parser.parse_args()

result1 = json.load(args.result1)
result2 = json.load(args.result2)

result1.sort(key=lambda report: report['bugHash'] + str(report['reportId']))
result2.sort(key=lambda report: report['bugHash'] + str(report['reportId']))

found_mismatch = False

for report in result1:
if report not in result2:
print("Report not found in result2:")
print(json.dumps(report, indent=4))
found_mismatch = True

for report in result2:
if report not in result1:
print("Report not found in result1:")
print(json.dumps(report, indent=4))
found_mismatch = True

return 1 if found_mismatch else 0

if __name__ == '__main__':
sys.exit(main())
124 changes: 124 additions & 0 deletions scripts/query_all_reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
import argparse
import functools
import json
import os
import subprocess
import sys
from multiprocess import Pool
from pathlib import Path
from typing import List, Tuple


def parse_args():
"""
Initialize global variables based on command line arguments. These
variables are global because get_results() uses them. That function is used
as a callback which doesn't get this info as parameters.
"""
parser = argparse.ArgumentParser(
description="Fetch all reports of products")

parser.add_argument(
'--url',
default='localhost:8001',
help='URL of a CodeChecker server.')

parser.add_argument(
'--output',
required=True,
help='Output folder for generated JSON files.')

parser.add_argument(
'-j', '--jobs',
default=1,
type=int,
help='Get reports in this many parallel jobs.')

parser.add_argument(
'--products',
nargs='+',
help='List of products to fetch reports for. By default, all products '
'are fetched.')

return parser.parse_args()


def __get_keys_from_list(out) -> List[str]:
"""
Get all keys from a JSON list.
"""
return map(lambda prod: next(iter(prod.keys())), json.loads(out))


def result_getter(args: argparse.Namespace):
def get_results(product_run: Tuple[str, str]):
product, run = product_run
print(product, run)

out, _ = subprocess.Popen([
'CodeChecker', 'cmd', 'results', run,
'-o', 'json',
'--url', f'{args.url}/{product}'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()

reports = sorted(
json.loads(out), key=lambda report: report['reportId'])

run = run.replace('/', '_')
with open(Path(args.output) / f'{product}_{run}.json', 'w',
encoding='utf-8') as f:
json.dump(reports, f)

return get_results


def get_all_products(url: str) -> List[str]:
"""
Get all products from a CodeChecker server.
:param url: URL of a CodeChecker server.
:return: List of product names.
"""
out, _ = subprocess.Popen(
['CodeChecker', 'cmd', 'products', 'list', '-o', 'json', '--url', url],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL).communicate()

return __get_keys_from_list(out)


def main():
args = parse_args()

os.makedirs(args.output, exist_ok=True)

if not args.products:
args.products = get_all_products(args.url)

for product in args.products:
f = functools.partial(lambda p, r: (p, r), product)
with subprocess.Popen([
'CodeChecker', 'cmd', 'runs',
'--url', f'{args.url}/{product}',
'-o', 'json'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) as proc:
runs = list(__get_keys_from_list(proc.stdout.read()))

with Pool(args.jobs) as p:
p.map(result_getter(args), map(f, runs))

return 0


if __name__ == '__main__':
sys.exit(main())

0 comments on commit 4920f98

Please sign in to comment.