|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | +# License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | +# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 5 | + |
| 6 | +import io |
| 7 | +import json |
| 8 | +import os |
| 9 | + |
| 10 | +import requests |
| 11 | +import structlog |
| 12 | +import zstandard |
| 13 | + |
| 14 | +from code_coverage_bot import hgmo |
| 15 | +from code_coverage_bot import utils |
| 16 | +from code_coverage_bot.phabricator import PhabricatorUploader |
| 17 | +from code_coverage_bot.secrets import secrets |
| 18 | +from code_coverage_tools.gcp import DEFAULT_FILTER |
| 19 | +from code_coverage_tools.gcp import download_report |
| 20 | +from code_coverage_tools.gcp import get_bucket |
| 21 | +from code_coverage_tools.gcp import get_name |
| 22 | +from code_coverage_tools.gcp import list_reports |
| 23 | + |
| 24 | +logger = structlog.get_logger(__name__) |
| 25 | + |
| 26 | + |
| 27 | +def generate(repo_dir: str) -> None: |
| 28 | + commit_coverage_path = "commit_coverage.json" |
| 29 | + |
| 30 | + url = f"https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.relman.code-coverage.{secrets[secrets.APP_CHANNEL]}.cron.latest/artifacts/public/{commit_coverage_path}.zst" # noqa |
| 31 | + r = requests.head(url, allow_redirects=True) |
| 32 | + if r.status_code != 404: |
| 33 | + utils.download_file(url, f"{commit_coverage_path}.zst") |
| 34 | + |
| 35 | + try: |
| 36 | + dctx = zstandard.ZstdDecompressor() |
| 37 | + with open(f"{commit_coverage_path}.zst", "rb") as zf: |
| 38 | + with dctx.stream_reader(zf) as reader: |
| 39 | + commit_coverage = json.load(reader) |
| 40 | + except FileNotFoundError: |
| 41 | + commit_coverage = {} |
| 42 | + |
| 43 | + assert ( |
| 44 | + secrets[secrets.GOOGLE_CLOUD_STORAGE] is not None |
| 45 | + ), "Missing GOOGLE_CLOUD_STORAGE secret" |
| 46 | + bucket = get_bucket(secrets[secrets.GOOGLE_CLOUD_STORAGE]) |
| 47 | + |
| 48 | + for changeset, platform, suite in list_reports(bucket, "mozilla-central"): |
| 49 | + # We are only interested in "overall" coverage, not platform or suite specific. |
| 50 | + if platform != DEFAULT_FILTER or suite != DEFAULT_FILTER: |
| 51 | + continue |
| 52 | + |
| 53 | + # We already have data for this commit. |
| 54 | + if changeset in commit_coverage: |
| 55 | + continue |
| 56 | + |
| 57 | + report_name = get_name("mozilla-central", changeset, platform, suite) |
| 58 | + assert download_report("ccov-reports", bucket, report_name) |
| 59 | + |
| 60 | + with open(os.path.join("ccov-reports", f"{report_name}.json"), "r") as f: |
| 61 | + report = json.load(f) |
| 62 | + |
| 63 | + phabricatorUploader = PhabricatorUploader(repo_dir, changeset) |
| 64 | + |
| 65 | + with hgmo.HGMO(repo_dir=repo_dir) as hgmo_server: |
| 66 | + changesets = hgmo_server.get_automation_relevance_changesets(changeset) |
| 67 | + |
| 68 | + results = phabricatorUploader.generate(report, changesets) |
| 69 | + for changeset in changesets: |
| 70 | + desc = changeset["desc"].split("\n")[0] |
| 71 | + |
| 72 | + if any(text in desc for text in ["r=merge", "a=merge"]): |
| 73 | + continue |
| 74 | + |
| 75 | + # Lookup changeset coverage from phabricator uploader |
| 76 | + coverage = results.get(changeset["node"]) |
| 77 | + if coverage is None: |
| 78 | + logger.warn("No coverage found", changeset=changeset) |
| 79 | + continue |
| 80 | + |
| 81 | + commit_coverage[changeset["node"]] = { |
| 82 | + "added": sum(c["lines_added"] for c in coverage["paths"].values()), |
| 83 | + "covered": sum(c["lines_covered"] for c in coverage["paths"].values()), |
| 84 | + "unknown": sum(c["lines_unknown"] for c in coverage["paths"].values()), |
| 85 | + } |
| 86 | + |
| 87 | + cctx = zstandard.ZstdCompressor(threads=-1) |
| 88 | + with open(f"{commit_coverage_path}.zst", "wb") as zf: |
| 89 | + with cctx.stream_writer(zf) as compressor: |
| 90 | + with io.TextIOWrapper(compressor, encoding="utf-8") as f: |
| 91 | + json.dump(commit_coverage, f) |
0 commit comments