mirror of https://github.com/google/oss-fuzz.git
[java][coverage] Make sure filenames is a string and not a list. (#6928)
* single quotes * [java][coverage] Make sure filenames is a string and not a list. Fixes: https://github.com/google/oss-fuzz/issues/6913 * fmt
This commit is contained in:
parent
de1ccb4623
commit
18a5b07b6b
|
@ -25,17 +25,17 @@ import xml.etree.ElementTree as ET
|
||||||
def convert(xml):
|
def convert(xml):
|
||||||
"""Turns a JaCoCo XML report into an llvm-cov JSON summary."""
|
"""Turns a JaCoCo XML report into an llvm-cov JSON summary."""
|
||||||
summary = {
|
summary = {
|
||||||
"type": "oss-fuzz.java.coverage.json.export",
|
'type': 'oss-fuzz.java.coverage.json.export',
|
||||||
"version": "1.0.0",
|
'version': '1.0.0',
|
||||||
"data": [{
|
'data': [{
|
||||||
"totals": {},
|
'totals': {},
|
||||||
"files": [],
|
'files': [],
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
report = ET.fromstring(xml)
|
report = ET.fromstring(xml)
|
||||||
totals = make_element_summary(report)
|
totals = make_element_summary(report)
|
||||||
summary["data"][0]["totals"] = totals
|
summary['data'][0]['totals'] = totals
|
||||||
|
|
||||||
# Since Java compilation does not track source file location, we match
|
# Since Java compilation does not track source file location, we match
|
||||||
# coverage info to source files via the full class name, e.g. we search for
|
# coverage info to source files via the full class name, e.g. we search for
|
||||||
|
@ -46,21 +46,23 @@ def convert(xml):
|
||||||
# way.
|
# way.
|
||||||
src_files = list_src_files()
|
src_files = list_src_files()
|
||||||
|
|
||||||
for class_element in report.findall("./package/class"):
|
for class_element in report.findall('./package/class'):
|
||||||
class_name = class_element.attrib["name"]
|
class_name = class_element.attrib['name']
|
||||||
package_name = os.path.dirname(class_name)
|
package_name = os.path.dirname(class_name)
|
||||||
if "sourcefilename" not in class_element.attrib:
|
if 'sourcefilename' not in class_element.attrib:
|
||||||
continue
|
continue
|
||||||
basename = class_element.attrib["sourcefilename"]
|
basename = class_element.attrib['sourcefilename']
|
||||||
# This path is "foo/Bar.java" for the class element
|
# This path is 'foo/Bar.java' for the class element
|
||||||
# <class name="foo/Bar" sourcefilename="Bar.java">.
|
# <class name="foo/Bar" sourcefilename="Bar.java">.
|
||||||
canonical_path = os.path.join(package_name, basename)
|
canonical_path = os.path.join(package_name, basename)
|
||||||
|
|
||||||
class_summary = make_element_summary(class_element)
|
class_summary = make_element_summary(class_element)
|
||||||
summary["data"][0]["files"].append({
|
src_files = relative_to_src_path(src_files, canonical_path)
|
||||||
"filename": relative_to_src_path(src_files, canonical_path),
|
for src_file in src_files:
|
||||||
"summary": class_summary,
|
summary['data'][0]['files'].append({
|
||||||
})
|
'filename': src_file,
|
||||||
|
'summary': class_summary,
|
||||||
|
})
|
||||||
|
|
||||||
return json.dumps(summary)
|
return json.dumps(summary)
|
||||||
|
|
||||||
|
@ -68,12 +70,12 @@ def convert(xml):
|
||||||
def list_src_files():
|
def list_src_files():
|
||||||
"""Returns a map from basename to full path for all files in $OUT/$SRC."""
|
"""Returns a map from basename to full path for all files in $OUT/$SRC."""
|
||||||
filename_to_paths = {}
|
filename_to_paths = {}
|
||||||
out_path = os.environ["OUT"] + "/"
|
out_path = os.environ['OUT'] + '/'
|
||||||
src_path = os.environ["SRC"]
|
src_path = os.environ['SRC']
|
||||||
src_in_out = out_path + src_path
|
src_in_out = out_path + src_path
|
||||||
for dirpath, _, filenames in os.walk(src_in_out):
|
for dirpath, _, filenames in os.walk(src_in_out):
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
full_path = dirpath + "/" + filename
|
full_path = dirpath + '/' + filename
|
||||||
# Map /out//src/... to /src/...
|
# Map /out//src/... to /src/...
|
||||||
src_path = full_path[len(out_path):]
|
src_path = full_path[len(out_path):]
|
||||||
filename_to_paths.setdefault(filename, []).append(src_path)
|
filename_to_paths.setdefault(filename, []).append(src_path)
|
||||||
|
@ -95,11 +97,11 @@ def make_element_summary(element):
|
||||||
"""Returns a coverage summary for an element in the XML report."""
|
"""Returns a coverage summary for an element in the XML report."""
|
||||||
summary = {}
|
summary = {}
|
||||||
|
|
||||||
function_counter = element.find("./counter[@type='METHOD']")
|
function_counter = element.find('./counter[@type=\'METHOD\']')
|
||||||
summary["functions"] = make_counter_summary(function_counter)
|
summary['functions'] = make_counter_summary(function_counter)
|
||||||
|
|
||||||
line_counter = element.find("./counter[@type='LINE']")
|
line_counter = element.find('./counter[@type=\'LINE\']')
|
||||||
summary["lines"] = make_counter_summary(line_counter)
|
summary['lines'] = make_counter_summary(line_counter)
|
||||||
|
|
||||||
# JaCoCo tracks branch coverage, which counts the covered control-flow edges
|
# JaCoCo tracks branch coverage, which counts the covered control-flow edges
|
||||||
# between llvm-cov's regions instead of the covered regions themselves. For
|
# between llvm-cov's regions instead of the covered regions themselves. For
|
||||||
|
@ -109,12 +111,12 @@ def make_element_summary(element):
|
||||||
# coverage. Since this would give incorrect results for CI Fuzz purposes, we
|
# coverage. Since this would give incorrect results for CI Fuzz purposes, we
|
||||||
# increase the regions counter by 1 if there is any amount of instruction
|
# increase the regions counter by 1 if there is any amount of instruction
|
||||||
# coverage.
|
# coverage.
|
||||||
instruction_counter = element.find("./counter[@type='INSTRUCTION']")
|
instruction_counter = element.find('./counter[@type=\'INSTRUCTION\']')
|
||||||
has_some_coverage = instruction_counter is not None and int(
|
has_some_coverage = instruction_counter is not None and int(
|
||||||
instruction_counter.attrib["covered"]) > 0
|
instruction_counter.attrib["covered"]) > 0
|
||||||
branch_covered_adjustment = 1 if has_some_coverage else 0
|
branch_covered_adjustment = 1 if has_some_coverage else 0
|
||||||
region_counter = element.find("./counter[@type='BRANCH']")
|
region_counter = element.find('./counter[@type=\'BRANCH\']')
|
||||||
summary["regions"] = make_counter_summary(
|
summary['regions'] = make_counter_summary(
|
||||||
region_counter, covered_adjustment=branch_covered_adjustment)
|
region_counter, covered_adjustment=branch_covered_adjustment)
|
||||||
|
|
||||||
return summary
|
return summary
|
||||||
|
@ -126,15 +128,15 @@ def make_counter_summary(counter_element, covered_adjustment=0):
|
||||||
covered = covered_adjustment
|
covered = covered_adjustment
|
||||||
missed = 0
|
missed = 0
|
||||||
if counter_element is not None:
|
if counter_element is not None:
|
||||||
covered += int(counter_element.attrib["covered"])
|
covered += int(counter_element.attrib['covered'])
|
||||||
missed += int(counter_element.attrib["missed"])
|
missed += int(counter_element.attrib['missed'])
|
||||||
summary["covered"] = covered
|
summary['covered'] = covered
|
||||||
summary["notcovered"] = missed
|
summary['notcovered'] = missed
|
||||||
summary["count"] = summary["covered"] + summary["notcovered"]
|
summary['count'] = summary['covered'] + summary['notcovered']
|
||||||
if summary["count"] != 0:
|
if summary['count'] != 0:
|
||||||
summary["percent"] = (100.0 * summary["covered"]) / summary["count"]
|
summary['percent'] = (100.0 * summary['covered']) / summary['count']
|
||||||
else:
|
else:
|
||||||
summary["percent"] = 0
|
summary['percent'] = 0
|
||||||
return summary
|
return summary
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,5 +156,5 @@ def main():
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
Loading…
Reference in New Issue