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:
+38
-24
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user