infra: generate summary.json file for python coverage runs (#9650)

Fixes: https://github.com/google/oss-fuzz/issues/9441

Signed-off-by: David Korczynski <david@adalogics.com>

---------

Signed-off-by: David Korczynski <david@adalogics.com>
Co-authored-by: jonathanmetzman <31354670+jonathanmetzman@users.noreply.github.com>
This commit is contained in:
DavidKorczynski 2023-02-13 19:37:59 +00:00 committed by GitHub
parent 57638caa86
commit 3d2ec74dba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 3 deletions

View File

@ -333,16 +333,18 @@ elif [[ $FUZZING_LANGUAGE == "python" ]]; then
cd $PYCOVDIR
python3 /usr/local/bin/python_coverage_runner_help.py combine .coverage_*
python3 /usr/local/bin/python_coverage_runner_help.py html
# Produce all_cov file used by fuzz introspector.
python3 /usr/local/bin/python_coverage_runner_help.py json -o ${TEXTCOV_REPORT_DIR}/all_cov.json
# Generate .json with similar format to llvm-cov output.
python3 /usr/local/bin/python_coverage_runner_help.py \
convert-to-summary-json ${TEXTCOV_REPORT_DIR}/all_cov.json $SUMMARY_FILE
# Copy coverage date out
cp htmlcov/status.json ${TEXTCOV_REPORT_DIR}/html_status.json
mv htmlcov/* $REPORT_PLATFORM_DIR/
mv .coverage_* $REPORT_PLATFORM_DIR/
# Create an empty summary file for now
echo "{}" >> $SUMMARY_FILE
elif [[ $FUZZING_LANGUAGE == "jvm" ]]; then
# From this point on the script does not tolerate any errors.

View File

@ -19,6 +19,7 @@ paths that match local files. This is needed for html report creation.
"""
import os
import re
import json
import sys
from coverage.cmdline import main as coverage_main
from coverage.data import CoverageData
@ -59,6 +60,40 @@ def translate_coverage(all_file_paths):
covdata_post_translation.write()
def convert_coveragepy_cov_to_summary_json(src, dst):
"""
Converts a json file produced by coveragepy into a summary.json file
similary to llvm-cov output. `src` is the source coveragepy json file,
`dst` is the destination json file, which will be overwritten.
"""
dst_dict = {'data': {'files': {}}}
with open(src, "r") as src_f:
src_json = json.loads(src_f.read())
if 'files' in src_json:
for elem in src_json.get('files'):
if 'summary' not in src_json['files'][elem]:
continue
src_dict = src_json['files'][elem]['summary']
count = src_dict['covered_lines'] + src_dict['missing_lines']
covered = src_dict['covered_lines']
notcovered = src_dict['missing_lines']
percent = src_dict['percent_covered']
dst_dict['data']['files'][elem] = {
'summary': {
'lines': {
'count': count,
'covered': covered,
'notcovered': notcovered,
'percent': percent
}
}
}
with open(dst, 'w') as dst_f:
dst_f.write(json.dumps(dst_dict))
def main():
"""
Main handler.
@ -73,6 +108,10 @@ def main():
all_file_paths.append(abs_file_path)
print('Done with path walk')
translate_coverage(all_file_paths)
elif sys.argv[1] == 'convert-to-summary-json':
src = sys.argv[2]
dst = sys.argv[3]
convert_coveragepy_cov_to_summary_json(src, dst)
else:
# Pass commands into coverage package
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])