Skip to content

Commit

Permalink
Merge pull request Ericsson#4245 from bruntib/query_checkers_script
Browse files Browse the repository at this point in the history
[script] Script for querying all reports
  • Loading branch information
cservakt authored Aug 9, 2024
2 parents f7e9d53 + 591495c commit 22cada3
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
55 changes: 55 additions & 0 deletions scripts/result_listing/compare_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -------------------------------------------------------------------------
#
# 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 __sorted_results(result_file):
return json.load(result_file).sort(
key=lambda report: report['bugHash'] + str(report['reportId']))

def __print_missing(needles, haystack, haystack_name):
for needle in needles:
if needle not in haystack:
print(f"Report not found in {haystack_name}:")
print(json.dumps(needle, indent=4))
return True
return False

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 = __sorted_results(args.result1)
result2 = __sorted_results(args.result2)

found_missing = False
found_missing |= __print_missing(result1, result2, "result2")
found_missing |= __print_missing(result2, result1, "result1")

args.result1.close()
args.result2.close()

return 1 if found_missing else 0

if __name__ == '__main__':
sys.exit(main())
128 changes: 128 additions & 0 deletions scripts/result_listing/query_all_reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# -------------------------------------------------------------------------
#
# 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 dump_products(args: argparse.Namespace):
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))


def main():
args = parse_args()

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

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

dump_products(args)

return 0


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

0 comments on commit 22cada3

Please sign in to comment.