masters-thesis/op-summarizer/opsummarizer.py
Erki df8e5c5d09
All checks were successful
continuous-integration/drone/push Build is passing
Add unit testing for expected output
2021-03-10 01:12:47 +02:00

84 lines
2.7 KiB
Python

import json
from dataclasses import asdict
from typing import Dict, List
from gcovreader import GCovFile
from opfinderreader import OperationLogReader, UniqueOperation
class OpSummarizer:
def __init__(self, gcov_path: str, opfinder_path: str) -> None:
self.gcov = GCovFile(gcov_path)
self.ops = OperationLogReader(opfinder_path)
self.gcov.read()
self.ops.read()
def count_operations(self, file: str) -> Dict[UniqueOperation, int]:
if file not in self.gcov.files or file not in self.ops.files:
raise RuntimeError(f"File {file} not in both parsers.")
op_counter: Dict[UniqueOperation, int] = {}
for gcov_line in self.gcov.files[file]:
op_lines = self.ops.get_lines(file, gcov_line.line_number)
for op_log in op_lines:
# TODO: revise this. Need a special case for for-loop clauses
# or branching in general.
if op_log.branch_number != gcov_line.branch_number:
continue
unique_op = op_log.entry
if unique_op in op_counter:
op_counter[unique_op] += gcov_line.count
else:
op_counter[unique_op] = gcov_line.count
return op_counter
@staticmethod
def operation_count_to_json_dict(unique_ops: Dict[UniqueOperation, int]) -> List[Dict]:
out = []
for uo, uo_count in unique_ops.items():
d = asdict(uo)
d["count"] = uo_count
out.append(d)
return out
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Merges gcovr and op-finder outputs.")
parser.add_argument("files", metavar="FILES", type=str, nargs="+",
help="The files to accumulate.")
parser.add_argument("--gcov", type=str, default="./data/gcov.json",
help="The gcovr json file to use.")
parser.add_argument("--finder", type=str, default="./data/opfinder.json",
help="The op-finder json file to use.")
parser.add_argument("--output", type=str, default=None, required=False,
help="The file to output the data to.")
args = parser.parse_args()
summarizer = OpSummarizer(args.gcov, args.finder)
total_count = {}
for file_name in args.files:
ops = summarizer.count_operations(file_name)
total_count[file_name] = summarizer.operation_count_to_json_dict(ops)
print(f"Unique operations for file {file_name}:")
for uop, count in ops.items():
print(f"\t{count}: {uop}")
print("---------")
if args.output:
with open(args.output, "w") as outfile:
json.dump(total_count, outfile)