File: run_coverage.py

package info (click to toggle)
python-azure 20250603%2Bgit-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 851,724 kB
  • sloc: python: 7,362,925; ansic: 804; javascript: 287; makefile: 195; sh: 145; xml: 109
file content (77 lines) | stat: -rw-r--r-- 3,287 bytes parent folder | download
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
76
77
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)