diff --git a/experimental/c-cpp/post-process.py b/experimental/c-cpp/post-process.py index e42c9ba9d2..67eec1c3bf 100644 --- a/experimental/c-cpp/post-process.py +++ b/experimental/c-cpp/post-process.py @@ -13,11 +13,11 @@ # limitations under the License. """Post process results by from-scratch OSS-Fuzz generation.""" +import argparse import json import logging import os -import sys -from typing import Any, Optional +from typing import Any, Dict, List, Optional import constants @@ -156,12 +156,14 @@ def read_session_project_report(project_folder_out): } -def analyse_project_session(oss_fuzz_dir: str, project_folder_out: str) -> None: +def analyse_project_session(oss_fuzz_dir: str, + project_folder_out: str, + to_print: bool = False) -> List[Dict[str, Any]]: """Interprets the results for a auto-gen session.""" logger.info('Analysing: %s', project_folder_out) project_report = read_session_project_report(project_folder_out) if not project_report: - return + return [] total_outcomes = extract_results_from_generated_samples( oss_fuzz_dir, project_folder_out) @@ -169,17 +171,19 @@ def analyse_project_session(oss_fuzz_dir: str, project_folder_out: str) -> None: sorted_outcomes = sorted(total_outcomes, key=lambda x: x['cov_history'][-1], reverse=True) - logger.info('Results: %s', project_report['project']) - logger.info('- Language: %s', project_report['language']) - logger.info('- Functions from Fuzz Introspector: %s', - project_report['total-functions']) - logger.info('- Harnesses generated: %d', len(total_outcomes)) - for harness_result in sorted_outcomes: - logger.info('%s :: %d :: %d :: [asan errors: %d] :: coverage: %f ', - harness_result['target'], harness_result['cov_history'][0], - harness_result['cov_history'][-1], - len(harness_result['addr_san']), - harness_result['line_coverage']) + if to_print: + logger.info('Results: %s', project_report['project']) + logger.info('- Language: %s', project_report['language']) + logger.info('- Functions from Fuzz Introspector: %s', + project_report['total-functions']) + logger.info('- Harnesses generated: %d', len(total_outcomes)) + for harness_result in sorted_outcomes: + logger.info('%s :: %d :: %d :: [asan errors: %d] :: coverage: %f ', + harness_result['target'], harness_result['cov_history'][0], + harness_result['cov_history'][-1], + len(harness_result['addr_san']), + harness_result['line_coverage']) + return sorted_outcomes def analyse_oss_fuzz_build(oss_fuzz_dir: str) -> None: @@ -193,7 +197,55 @@ def analyse_oss_fuzz_build(oss_fuzz_dir: str) -> None: if not os.path.isdir(project_folder_out): continue - analyse_project_session(oss_fuzz_dir, project_folder_out) + analyse_project_session(oss_fuzz_dir, project_folder_out, True) + + +def get_top_projects(oss_fuzz_dir: str) -> List[Dict[str, Any]]: + """Gets the top project for each auto-generated project.""" + sorted_project_folders = get_oss_fuzz_generated_projects(oss_fuzz_dir) + + top_projects = [] + for target_project in sorted_project_folders: + project_folder_out = os.path.join(oss_fuzz_out_dir(oss_fuzz_dir), + target_project) + if not os.path.isdir(project_folder_out): + continue + + sorted_projects = analyse_project_session(oss_fuzz_dir, project_folder_out) + if sorted_projects: + top_projects.append(sorted_projects[0]) + + for top_project in top_projects: + logger.info('%s :: %d :: %d :: [asan errors: %d] :: coverage: %f ', + top_project['target'], + top_project['cov_history'][0], top_project['cov_history'][-1], + len(top_project['addr_san']), top_project['line_coverage']) + return top_projects + + +def parse_args() -> argparse.Namespace: + """Parses commandline arguments.""" + parser = argparse.ArgumentParser() + + subparsers = parser.add_subparsers(dest='command') + print_parser = subparsers.add_parser( + 'print', + help='prints results of auto-gen to stdout', + ) + print_parser.add_argument('--oss-fuzz-dir', + type=str, + help='OSS-Fuzz directory with generated results', + required=True) + top_finder = subparsers.add_parser( + 'top-projects', + help='prints status of top projects', + ) + top_finder.add_argument('--oss-fuzz-dir', + type=str, + help='OSS-Fuzz directory with generated results', + required=True) + args = parser.parse_args() + return args def setup_logging() -> None: @@ -204,7 +256,11 @@ def setup_logging() -> None: def main() -> None: """Entrypoint""" setup_logging() - analyse_oss_fuzz_build(sys.argv[1]) + args = parse_args() + if args.command == 'print': + analyse_oss_fuzz_build(args.oss_fuzz_dir) + elif args.command == 'top-projects': + get_top_projects(args.oss_fuzz_dir) if __name__ == '__main__':