SERVER-103036: Code Coverage and Coveralls cleanup (#34309)

GitOrigin-RevId: d252fab64461be455d8192e8a0eb683e567f4bb0
This commit is contained in:
Steve McClure 2025-04-02 09:02:38 -04:00 committed by MongoDB Bot
parent 197bbfb335
commit dc89f1d50d
2 changed files with 15 additions and 59 deletions

View File

@ -21,7 +21,6 @@ buildvariants:
${coverage_bazel_tags} ${coverage_bazel_tags}
large_distro_name: amazon2023.3-arm64-large large_distro_name: amazon2023.3-arm64-large
resmoke_jobs_factor: 0.5 # Avoid starting too many mongod's resmoke_jobs_factor: 0.5 # Avoid starting too many mongod's
# Mixing --cache and --gcov doesn't work correctly yet. See SERVER-11084
exec_timeout_secs: 32400 # 9 hour timeout exec_timeout_secs: 32400 # 9 hour timeout
timeout_secs: 18000 # 5 hour idle timeout timeout_secs: 18000 # 5 hour idle timeout
gcov_tool: /opt/mongodbtoolchain/v5/bin/gcov gcov_tool: /opt/mongodbtoolchain/v5/bin/gcov
@ -32,11 +31,11 @@ buildvariants:
gcov_environment: GCOV_PREFIX=$(pwd)/.. GCOV_PREFIX_STRIP=3 gcov_environment: GCOV_PREFIX=$(pwd)/.. GCOV_PREFIX_STRIP=3
compile_variant: *AL2023-arm64-coverage compile_variant: *AL2023-arm64-coverage
tasks: tasks:
# These are carefully and explicitly curated. Do not add more tests/tasks without consulting with DevProd.
# unittests
- name: compile_and_package_serial_no_unittests_TG - name: compile_and_package_serial_no_unittests_TG
distros: distros:
- amazon2023.3-arm64-large - amazon2023.3-arm64-large
# These are carefully and explicitly curated. Do not add more tests/tasks without consulting with DevProd.
# unittests
- name: bazel_coverage - name: bazel_coverage
# jstests # jstests
- name: jsCore - name: jsCore
@ -70,7 +69,6 @@ buildvariants:
${coverage_bazel_tags} ${coverage_bazel_tags}
large_distro_name: rhel93-medium large_distro_name: rhel93-medium
resmoke_jobs_factor: 0.5 # Avoid starting too many mongod's resmoke_jobs_factor: 0.5 # Avoid starting too many mongod's
# Mixing --cache and --gcov doesn't work correctly yet. See SERVER-11084
exec_timeout_secs: 32400 # 9 hour timeout exec_timeout_secs: 32400 # 9 hour timeout
timeout_secs: 18000 # 5 hour idle timeout timeout_secs: 18000 # 5 hour idle timeout
gcov_tool: /opt/mongodbtoolchain/v5/bin/gcov gcov_tool: /opt/mongodbtoolchain/v5/bin/gcov
@ -81,11 +79,11 @@ buildvariants:
gcov_environment: GCOV_PREFIX=$(pwd)/.. GCOV_PREFIX_STRIP=3 gcov_environment: GCOV_PREFIX=$(pwd)/.. GCOV_PREFIX_STRIP=3
compile_variant: *rhel-93-64-bit-coverage compile_variant: *rhel-93-64-bit-coverage
tasks: tasks:
# These are carefully and explicitly curated. Do not add more tests/tasks without consulting with DevProd.
# unittests
- name: compile_and_package_serial_no_unittests_TG - name: compile_and_package_serial_no_unittests_TG
distros: distros:
- rhel93-large - rhel93-large
# These are carefully and explicitly curated. Do not add more tests/tasks without consulting with DevProd.
# unittests
- name: bazel_coverage - name: bazel_coverage
distros: distros:
- rhel93-large - rhel93-large

View File

@ -1,22 +1,17 @@
import glob import glob
import hashlib
import os import os
import platform import platform
import subprocess import subprocess
import sys import sys
import tarfile
from urllib.request import urlretrieve
import requests import requests
import retry import retry
from buildscripts.util.expansions import get_expansion from buildscripts.util.expansions import get_expansion
# This script is used to gather code coverage data from the build and post it to coveralls.
@retry.retry(tries=3, delay=5) # It is run as part of the Evergreen build process.
def retry_download(url: str, file: str): # It is not intended to be run directly.
print(f"Attempting to download {file} from {url}")
urlretrieve(url, file)
@retry.retry(tries=3, delay=5) @retry.retry(tries=3, delay=5)
@ -35,38 +30,6 @@ def retry_coveralls_post(coveralls_report: str):
raise RuntimeError(f"Error while sending coveralls report: {response.status_code}") raise RuntimeError(f"Error while sending coveralls report: {response.status_code}")
def download_coveralls_reporter(arch: str) -> str:
if arch == "arm64" or arch == "aarch64":
url = "https://github.com/coverallsapp/coverage-reporter/releases/download/v0.6.15/coveralls-linux-aarch64.tar.gz"
sha = "47653fa86b8eaae30b16c5d3f37fbeda30d8708153a261df2cdc9cb67e6c48e0"
else:
url = "https://github.com/coverallsapp/coverage-reporter/releases/download/v0.6.15/coveralls-linux-x86_64.tar.gz"
sha = "59b159a93ae44a649fe7ef8f10d906c146057c4f81acb4f448d441b9ff4dadb3"
print(f"Downloading coveralls from {url}")
tar_location = "coveralls.tar.gz"
retry_download(url, tar_location)
with tarfile.open(tar_location, "r:gz") as tar:
tar.extractall()
os.remove(tar_location)
if not os.path.exists("coveralls"):
raise RuntimeError(
"Coveralls was successfully downloaded but the binary was not found in the expected location."
)
sha256_hash = hashlib.sha256()
with open("coveralls", "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
calculated_sha = sha256_hash.hexdigest()
if calculated_sha != sha:
raise RuntimeError(
f"Downloaded file from {url} calculated sha ({calculated_sha}) did not match expected sha ({sha})"
)
return os.path.abspath("coveralls")
def get_bazel_coverage_report_file() -> str: def get_bazel_coverage_report_file() -> str:
BAZEL_BINARY = "bazel" # simplified since we already restrict which platforms can run coverage BAZEL_BINARY = "bazel" # simplified since we already restrict which platforms can run coverage
proc = subprocess.run([BAZEL_BINARY, "info", "output_path"], check=True, capture_output=True) proc = subprocess.run([BAZEL_BINARY, "info", "output_path"], check=True, capture_output=True)
@ -94,12 +57,12 @@ def main():
arch = platform.uname().machine.lower() arch = platform.uname().machine.lower()
print(f"Detected arch: {arch}") print(f"Detected arch: {arch}")
if arch in disallowed_arches: if arch in disallowed_arches:
print("Code coverage not supported on this architecture") raise RuntimeError(f"Code coverage not supported on architecture '{arch}'.")
return 1
if not os.path.exists(".git"): if not os.path.exists(".git"):
print("No git repo found in working directory. Code coverage needs git repo to function.") raise RuntimeError(
return 1 "No git repo found in working directory. Code coverage needs git repo to function."
)
coveralls_token = get_expansion("coveralls_token") coveralls_token = get_expansion("coveralls_token")
assert coveralls_token is not None, "Coveralls token was not found" assert coveralls_token is not None, "Coveralls token was not found"
@ -112,13 +75,11 @@ def main():
bazel_coverage_report_location = get_bazel_coverage_report_file() bazel_coverage_report_location = get_bazel_coverage_report_file()
if os.path.exists(bazel_coverage_report_location): if os.path.exists(bazel_coverage_report_location):
print("Found bazel coverage report.") print("Found bazel coverage report.")
coveralls_reporter_location = download_coveralls_reporter(arch)
version_id = get_expansion("version_id") version_id = get_expansion("version_id")
task_id = get_expansion("task_id") task_id = get_expansion("task_id")
args = [ args = [
coveralls_reporter_location, "coveralls",
"report", "report",
bazel_coverage_report_location, bazel_coverage_report_location,
"--service-name=travis-ci", "--service-name=travis-ci",
@ -157,8 +118,7 @@ def main():
os.rename(old_path, new_path) os.rename(old_path, new_path)
if not has_bazel_gcno: if not has_bazel_gcno:
print("No gcno files were found. Something went wrong.") raise RuntimeError("Neither bazel coverage nor gcno files were found.")
return 1
my_env = os.environ.copy() my_env = os.environ.copy()
my_env["COVERALLS_REPO_TOKEN"] = coveralls_token my_env["COVERALLS_REPO_TOKEN"] = coveralls_token
@ -221,12 +181,10 @@ def main():
) )
print(process.stdout) print(process.stdout)
if process.returncode != 0: if process.returncode != 0:
print(f"gcovr failed with code: {process.returncode}") raise RuntimeError(f"gcovr failed with code: {process.returncode}")
return 1
if not os.path.exists(coveralls_report): if not os.path.exists(coveralls_report):
print("Could not find coveralls json report") raise RuntimeError(f"Could not find coveralls json report at {coveralls_report}")
return 1
retry_coveralls_post(coveralls_report) retry_coveralls_post(coveralls_report)
return 0 return 0