Skip to content

Commit 90fd042

Browse files
rparolinclaude
andcommitted
Address review follow-ups: tighter protocol, structured-error tests, isolated maps probe
- Reject `error` field on STATUS_OK payloads in parse_dynamic_lib_subprocess_payload (STATUS_OK never carries one). - Add unit tests for the structured-error round trip (subprocess emits STATUS_NOT_FOUND with {type, message}; parent re-raises with that message) and the no-message fallback. - Run the "find does not load in caller process" check in a fresh Python interpreter so test ordering / unrelated tests in the same pytest process can't taint /proc/self/maps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6f45e21 commit 90fd042

2 files changed

Lines changed: 74 additions & 8 deletions

File tree

cuda_pathfinder/cuda/pathfinder/_dynamic_libs/subprocess_protocol.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ def reject() -> NoReturn:
7272
isinstance(error, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in error.items())
7373
):
7474
reject()
75-
if status == STATUS_OK and isinstance(abs_path, str):
76-
return DynamicLibSubprocessPayload(status=STATUS_OK, abs_path=abs_path, error=error)
75+
# STATUS_OK carries a path and never an error; STATUS_NOT_FOUND has no
76+
# path but may carry a structured error from the child loader.
77+
if status == STATUS_OK and isinstance(abs_path, str) and error is None:
78+
return DynamicLibSubprocessPayload(status=STATUS_OK, abs_path=abs_path, error=None)
7779
if status == STATUS_NOT_FOUND and abs_path is None:
7880
return DynamicLibSubprocessPayload(status=STATUS_NOT_FOUND, abs_path=None, error=error)
7981
reject()

cuda_pathfinder/tests/test_find_nvidia_dynamic_lib.py

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
import json
45
import os
56
import platform
7+
import subprocess
8+
import sys
9+
import textwrap
610

711
import pytest
812
from child_load_nvidia_dynamic_lib_helper import run_load_nvidia_dynamic_lib_in_subprocess
@@ -13,10 +17,13 @@
1317
DynamicLibUnknownError,
1418
find_nvidia_dynamic_lib,
1519
)
20+
from cuda.pathfinder._dynamic_libs import find_nvidia_dynamic_lib as find_nvidia_dynamic_lib_module
1621
from cuda.pathfinder._dynamic_libs import load_nvidia_dynamic_lib as load_nvidia_dynamic_lib_module
1722
from cuda.pathfinder._dynamic_libs import supported_nvidia_libs
1823
from cuda.pathfinder._dynamic_libs.subprocess_protocol import (
24+
STATUS_NOT_FOUND,
1925
STATUS_OK,
26+
DynamicLibSubprocessPayload,
2027
parse_dynamic_lib_subprocess_payload,
2128
)
2229
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS, quote_for_shell
@@ -94,17 +101,74 @@ def test_find_matches_load_in_subprocess(info_summary_append):
94101
assert os.path.samefile(find_abs_path, load_payload.abs_path)
95102

96103

97-
def test_find_nvidia_dynamic_lib_does_not_load_in_caller_process():
98-
if IS_WINDOWS or not os.path.exists("/proc/self/maps"):
99-
pytest.skip("Requires /proc/self/maps for in-process load detection")
104+
def test_find_nvidia_dynamic_lib_propagates_subprocess_not_found_message(monkeypatch):
105+
# End-to-end of the structured-error path: the subprocess child encodes
106+
# DynamicLibNotFoundError into the JSON payload; the parent re-raises
107+
# with the original message preserved.
108+
find_nvidia_dynamic_lib.cache_clear()
109+
expected = "child loader said: cudart could not be located"
110+
111+
def fake_run(mode, libname, *, timeout, error_label):
112+
return DynamicLibSubprocessPayload(
113+
status=STATUS_NOT_FOUND,
114+
abs_path=None,
115+
error={"type": "DynamicLibNotFoundError", "message": expected},
116+
)
117+
118+
monkeypatch.setattr(find_nvidia_dynamic_lib_module, "run_dynamic_lib_subprocess", fake_run)
119+
with pytest.raises(DynamicLibNotFoundError, match=expected):
120+
find_nvidia_dynamic_lib("cudart")
100121

122+
123+
def test_find_nvidia_dynamic_lib_falls_back_when_subprocess_not_found_omits_message(monkeypatch):
101124
find_nvidia_dynamic_lib.cache_clear()
102-
libname = "cudart"
125+
126+
def fake_run(mode, libname, *, timeout, error_label):
127+
return DynamicLibSubprocessPayload(status=STATUS_NOT_FOUND, abs_path=None, error=None)
128+
129+
monkeypatch.setattr(find_nvidia_dynamic_lib_module, "run_dynamic_lib_subprocess", fake_run)
130+
with pytest.raises(DynamicLibNotFoundError, match=r"could not locate 'cudart'"):
131+
find_nvidia_dynamic_lib("cudart")
132+
133+
134+
_DOES_NOT_LOAD_PROBE = textwrap.dedent(
135+
"""
136+
import json
137+
import os
138+
import sys
139+
140+
from cuda.pathfinder import DynamicLibNotFoundError, find_nvidia_dynamic_lib
141+
142+
libname = sys.argv[1]
103143
try:
104144
find_nvidia_dynamic_lib(libname)
145+
find_status = "found"
105146
except DynamicLibNotFoundError:
106-
pytest.skip(f"{libname} not available on this host")
147+
find_status = "not-found"
107148
108149
with open("/proc/self/maps") as f:
109150
maps = f.read()
110-
assert "libcudart" not in maps, "find_nvidia_dynamic_lib must not load the library into the caller process"
151+
print(json.dumps({"find_status": find_status, "loaded": ("lib" + libname) in maps}))
152+
"""
153+
).strip()
154+
155+
156+
def test_find_nvidia_dynamic_lib_does_not_load_in_caller_process():
157+
if IS_WINDOWS or not os.path.exists("/proc/self/maps"):
158+
pytest.skip("Requires /proc/self/maps for in-process load detection")
159+
160+
libname = "cudart"
161+
# Run in a fresh interpreter so test ordering / other pathfinder tests
162+
# in the same process can't have pre-loaded the library.
163+
result = subprocess.run( # noqa: S603 - trusted argv: current interpreter + inline probe
164+
[sys.executable, "-c", _DOES_NOT_LOAD_PROBE, libname],
165+
capture_output=True,
166+
text=True,
167+
timeout=60,
168+
check=False,
169+
)
170+
assert result.returncode == 0, f"probe failed:\nstdout={result.stdout!r}\nstderr={result.stderr!r}"
171+
payload = json.loads(result.stdout.strip().splitlines()[-1])
172+
if payload["find_status"] == "not-found":
173+
pytest.skip(f"{libname} not available on this host")
174+
assert payload["loaded"] is False, "find_nvidia_dynamic_lib must not load the library into the caller process"

0 commit comments

Comments
 (0)