fix(tests): prevent behave-parallel multiprocessing deadlock on btrfs/overlayfs #9826

Merged
HAL9000 merged 2 commits from fix/nox-parallel-hang-btrfs into master 2026-04-17 07:31:00 +00:00
+46 -2
View File
@@ -23,6 +23,7 @@ import argparse
import io
import multiprocessing
import os
import subprocess
import sys
import time
import traceback
@@ -32,6 +33,50 @@ from typing import Any
DEFAULT_FEATURE_ROOT = "features/"
def _is_btrfs_or_overlayfs() -> bool:
fs_targets = {"btrfs", "overlay"}
try:
result = subprocess.run(
["stat", "-f", "-c", "%T", "."],
check=True,
capture_output=True,
text=True,
)
except (OSError, subprocess.SubprocessError):
pass
else:
fs_type = result.stdout.strip().lower()
return fs_type in fs_targets
try:
current_path = os.path.realpath(".")
best_match_len = -1
best_fs_type: str | None = None
with open("/proc/mounts", encoding="utf-8") as mounts:
for line in mounts:
parts = line.split()
if len(parts) < 3:
continue
mount_point = parts[1].replace("\\040", " ")
mount_real = os.path.realpath(mount_point)
if not mount_real:
continue
if (
current_path == mount_real
or current_path.startswith(mount_real.rstrip("/") + "/")
) and len(mount_real) > best_match_len:
best_match_len = len(mount_real)
best_fs_type = parts[2].lower()
if best_fs_type:
return best_fs_type in fs_targets
except OSError:
pass
return False
# Type alias for summary dictionaries
Summary = dict[str, Any]
@@ -321,8 +366,6 @@ def main(argv: list[str] | None = None) -> None:
# Pass-through --help / --version to behave
if any(flag in remaining for flag in ("-h", "--help", "--version")):
import subprocess
code = subprocess.run(
[sys.executable, "-m", "behave", *other_args, *feature_args]
).returncode
@@ -348,6 +391,7 @@ def main(argv: list[str] | None = None) -> None:
or coverage_mode
or len(feature_paths) == 1
or len(feature_paths) <= 2
or _is_btrfs_or_overlayfs()
):
# ---- sequential in-process mode ----
_, total = _run_features_inprocess(feature_paths, other_args)