Build: configured coverage report to run in parallal, removed cap on number of parallel processes, limited by number of cores of env variable

This commit is contained in:
2026-02-17 15:46:56 -05:00
parent 2a84341753
commit 4cda00abf6
+38 -24
View File
@@ -21,13 +21,14 @@ BEHAVE_PARALLEL_URL = (
def _default_processes() -> int:
env_override = os.environ.get("TEST_PROCESSES")
if env_override:
return int(env_override)
try:
cpus = len(os.sched_getaffinity(0)) or 1
except AttributeError:
cpus = os.cpu_count() or 1
# Cap parallelism to avoid excessive resource usage in constrained
# environments (CI containers, cgroups, etc.)
return min(cpus, 8)
return cpus
def _behave_parallel_args(posargs: list[str]) -> list[str]:
@@ -46,10 +47,7 @@ def _pabot_parallel_args(posargs: list[str]) -> list[str]:
)
if has_custom_processes:
return []
env_override = os.environ.get("PABOT_PROCESSES")
if env_override:
return ["--processes", env_override]
return ["--processes", str(min(_default_processes(), 2))]
return ["--processes", str(_default_processes())]
def _split_pabot_args(posargs: list[str]) -> tuple[list[str], list[str]]:
@@ -474,43 +472,59 @@ COVERAGE_THRESHOLD = 97
def coverage_report(session: nox.Session):
"""Generate coverage report from Behave tests.
Runs behave under coverage in serial mode to ensure accurate data
collection. Coverage threshold is enforced at >=97%.
Runs behave tests in parallel via behave-parallel (same approach as
unit_tests) with each worker collecting coverage independently using
``coverage run --parallel-mode``. After all workers finish, the
per-process data files are merged with ``coverage combine``.
Coverage threshold is enforced at >=97%.
On success, emits: COVERAGE OK: <pct>% (threshold: 97%)
On failure, emits: COVERAGE FAILED: <pct>% < 97% threshold
Both are single-line, CI-parseable summary strings.
"""
session.install("-e", ".[tests]")
_install_behave_parallel(session)
os.makedirs("build", exist_ok=True)
session.env["PYTHONPATH"] = str(Path("src").resolve())
session.env["COVERAGE_RCFILE"] = "pyproject.toml"
session.env["COVERAGE_FILE"] = "build/.coverage"
# Tell behave-parallel workers to run under coverage --parallel-mode
session.env["BEHAVE_PARALLEL_COVERAGE"] = "1"
# Clean up any existing coverage data
session.run("coverage", "erase")
# Run behave under coverage (serial mode for reliable data collection)
behave_args = [
"coverage",
"run",
"--source=src",
"-m",
"behave",
"-q",
"--tags=-discovery",
"--no-capture",
]
# Run behave tests in parallel; each worker collects coverage separately
behave_cmd = session.bin + "/behave-parallel"
parallel_args = _behave_parallel_args(session.posargs)
if session.posargs and session.posargs[0].endswith(".feature"):
behave_args.extend(session.posargs)
args = [
behave_cmd,
"-q",
"--tags=-discovery",
"--no-capture",
*parallel_args,
*session.posargs,
]
else:
behave_args.append("features/")
behave_args.extend(session.posargs)
args = [
behave_cmd,
"-q",
"--tags=-discovery",
"--no-capture",
*parallel_args,
"features/",
*session.posargs,
]
session.run(*behave_args)
session.run(*args)
# Merge per-worker coverage data files into a single build/.coverage
session.run("coverage", "combine")
# Always generate HTML and XML reports before checking threshold
session.run("coverage", "html")