Skip to content

Commit a440dba

Browse files
authored
Report Coverage Number in CI (Azure#39639)
* report a single overall coverage % per package
1 parent 6618cce commit a440dba

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pythonenv*/
1818
.ptvs/
1919

2020
# Coverage report
21-
**/.coverage
21+
**/.coverage*
2222
_coverage
2323

2424
# Build results

eng/pipelines/templates/steps/build-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ steps:
155155
156156
python -m pip install coverage==7.2.5
157157
python scripts/devops_tasks/create_coverage.py
158-
displayName: Create Coverage Report
158+
displayName: Report Coverage
159159
condition: and(succeeded(), ${{ parameters.RunCoverage }})
160160
161161
- ${{ if eq('true', parameters.UseFederatedAuth) }}:

eng/tox/run_coverage.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import coverage
2+
import argparse
3+
import os
4+
import json
5+
import datetime
6+
7+
from ci_tools.parsing import ParsedSetup
8+
from ci_tools.variables import in_ci
9+
from ci_tools.environment_exclusions import is_check_enabled
10+
11+
def get_total_coverage(coverage_file: str) -> float:
12+
cov = coverage.Coverage(data_file=coverage_file)
13+
cov.load()
14+
report = cov.report()
15+
16+
return report
17+
18+
19+
if __name__ == "__main__":
20+
parser = argparse.ArgumentParser(
21+
description="Check coverage for a package."
22+
)
23+
24+
parser.add_argument(
25+
"-t",
26+
"--target",
27+
dest="target_package",
28+
help="The target package directory on disk. This script looks for a .coverage file under <target_package> directory.",
29+
required=True,
30+
)
31+
32+
args = parser.parse_args()
33+
pkg_details = ParsedSetup.from_path(args.target_package)
34+
35+
possible_coverage_file = os.path.join(args.target_package, ".coverage")
36+
37+
if os.path.exists(possible_coverage_file):
38+
total_coverage = get_total_coverage(possible_coverage_file)
39+
print(f"Total coverage for {pkg_details.name} is {total_coverage:.2f}%")
40+
41+
if in_ci():
42+
metric_obj = {}
43+
metric_obj["value"] = total_coverage / 100
44+
metric_obj["name"] = "test_coverage_ratio"
45+
metric_obj["labels"] = { "package": pkg_details.name }
46+
metric_obj["timestamp"] = datetime.datetime.now(datetime.timezone.utc).isoformat()
47+
print(f'logmetric: {json.dumps(metric_obj)}')
48+
49+
if is_check_enabled(args.target_package, "cov_enforcement", False):
50+
print("Coverage enforcement is enabled for this package.")
51+

eng/tox/tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ commands =
7373
python {repository_root}/eng/tox/create_package_and_install.py -d {envtmpdir} -p {tox_root} -w {envtmpdir}
7474
python -m pip freeze
7575
pytest {[pytest]default_args} {posargs} {tox_root}
76+
python {repository_root}/eng/tox/run_coverage.py -t {tox_root}
7677

7778

7879
[testenv:pylint]

scripts/devops_tasks/create_coverage.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def generate_coverage_xml():
5353
if os.path.exists(coverage_dir):
5454
logging.info("Generating coverage XML")
5555
commands = ["coverage", "xml", "-i"]
56-
run_check_call(commands, root_dir, always_exit = False)
56+
run_check_call(commands, root_dir, always_exit=False)
5757
else:
5858
logging.error("Coverage file is not available in {} to generate coverage XML".format(coverage_dir))
5959

@@ -72,11 +72,12 @@ def fix_coverage_xml(coverage_file):
7272
out = re.sub("\.?\.tox[\s\S\.\d]*?\.site-packages", "", out)
7373

7474
if out:
75-
with open(coverage_file, 'w') as cov_file:
75+
with open(coverage_file, "w") as cov_file:
7676
cov_file.write(out)
7777

78+
7879
if __name__ == "__main__":
79-
coverage_xml = os.path.join(root_dir, 'coverage.xml')
80+
coverage_xml = os.path.join(root_dir, "coverage.xml")
8081

8182
collect_tox_coverage_files()
8283
generate_coverage_xml()

0 commit comments

Comments
 (0)