-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
Copy pathrun_coverage.py
77 lines (62 loc) · 3.21 KB
/
run_coverage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import coverage
import argparse
import os
import json
import datetime
import logging
from typing import Optional
from ci_tools.parsing import ParsedSetup, get_config_setting
from ci_tools.variables import in_ci
from ci_tools.environment_exclusions import is_check_enabled
from ci_tools.functions import get_total_coverage
logging.basicConfig(level=logging.INFO)
coveragerc_file = os.path.join(os.path.dirname(__file__), "..", "..", ".coveragerc")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Check coverage for a package."
)
parser.add_argument(
"-t",
"--target",
dest="target_package",
help="The target package directory on disk. This script looks for a .coverage file under <target_package> directory.",
required=True,
)
parser.add_argument(
"-r",
"--root",
dest="repo_root",
help="The root of the directory. Source paths are relative to this.",
required=True,
)
args = parser.parse_args()
pkg_details = ParsedSetup.from_path(args.target_package)
possible_coverage_file = os.path.join(args.target_package, ".coverage")
if os.path.exists(possible_coverage_file):
total_coverage = get_total_coverage(possible_coverage_file, coveragerc_file, pkg_details.name, args.repo_root)
if total_coverage is not None:
# log the metric for reporting before doing anything else
if in_ci():
metric_obj = {}
metric_obj["value"] = total_coverage / 100
metric_obj["name"] = "test_coverage_ratio"
metric_obj["labels"] = { "package": pkg_details.name, "repo": "Azure/azure-sdk-for-python" }
metric_obj["timestamp"] = datetime.datetime.now(datetime.timezone.utc).isoformat()
# normally we logging.info anywhere we need to output, but these logmetric statements
# need to be the sole value on the line, as the logmetric log parsing doesn't allow prefixes
# before the 'logmetric' start string.
print(f'logmetric: {json.dumps(metric_obj)}')
# todo: add relative coverage comparison after we generate eng/coverages.json file in main
# when we add that, we will call the config setting relative_cov to check if this is enabled
# there, we will only ever compare the baseline % against the generated %
# as a fallback, we can always check the absolute coverage % against the config setting
# if the config setting is not set, we will not enforce any coverage
if is_check_enabled(args.target_package, "absolute_cov", False):
logging.info("Coverage enforcement is enabled for this package.")
# if this threshold is not set in config setting, the default will be very high
cov_threshold = get_config_setting(args.target_package, "absolute_cov_percent", 95.0)
if total_coverage < float(cov_threshold):
logging.error(
f"Coverage for {pkg_details.name} is below the threshold of {cov_threshold:.2f}% (actual: {total_coverage:.2f}%)"
)
exit(1)