A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 4, 03:45 UTC
[CI][Bugfix] Surface subprocess output in spawn_new_process_for_each_test (#41943)
Signed-off-by: haosdent <haosdent@gmail.com>
haosdent committed
May 8, 2026 at 16:39 UTC
160858cba47aa5999b57ef9445b9dfa946a09458
1 file changed
+18
-5
tests/utils.py
+18
-5
@@ -1511,6 +1511,16 @@ def fork_new_process_for_each_test(func: Callable[_P, None]) -> Callable[_P, Non
1511
return wrapper
1512
1513
1514
+def _format_subprocess_exit(returncode: int) -> str:
1515
+ """Render a subprocess exit code, naming the signal for negative codes."""
1516
+ if returncode >= 0:
1517
+ return f"exit code {returncode}"
1518
+ try:
1519
+ return f"killed by {signal.Signals(-returncode).name} ({returncode})"
1520
+ except ValueError:
1521
+ return f"exit code {returncode}"
1522
+
1523
+
1524
# Set on the spawn-child interpreter so the wrapper short-circuits when the
1525
# child resolves `module.qualname` back to its own decorated form, instead of
1526
# launching another subprocess.
@@ -1531,6 +1541,12 @@ def spawn_new_process_for_each_test(f: Callable[_P, None]) -> Callable[_P, None]
1541
``vllm.compilation.counter.compilation_counter``) into stale clones in
1542
the child, so increments performed by the production code in the child
1543
would never be observable to the test.
1544
+
1545
+ The child inherits the parent's stdout/stderr so its output (engine
1546
+ cores, NCCL, CUDA, ...) reaches the test runner live; the Python-level
1547
+ traceback is serialized to ``tb_file`` for structured re-raising. A
1548
+ native crash leaves ``tb_file`` empty — the diagnostic is then only in
1549
+ the inherited subprocess output.
1550
"""
1551
1552
@functools.wraps(f)
@@ -1581,23 +1597,20 @@ def spawn_new_process_for_each_test(f: Callable[_P, None]) -> Callable[_P, None]
1597
result = subprocess.run(
1598
[sys.executable, "-c", child_script],
1599
input=payload,
1584
- capture_output=True,
1600
env=env,
1601
)
1602
1603
if result.returncode != 0:
1589
- # Prefer the child's traceback file; fall back to stderr if
1590
- # the child crashed before its except handler ran.
1604
try:
1605
with open(tb_file) as fp:
1606
tb = fp.read()
1607
except OSError:
1608
tb = ""
1609
if not tb:
1597
- tb = result.stderr.decode()
1610
+ tb = "<no Python traceback; see subprocess output above>"
1611
raise RuntimeError(
1612
f"Test subprocess '{f.__name__}' failed "
1600
- f"(exit code {result.returncode}):\n{tb}"
1613
+ f"({_format_subprocess_exit(result.returncode)}):\n{tb}"
1614
)
1615
finally:
1616
with contextlib.suppress(OSError):