问题 / #414

#414 test_setup_choices fails on a host with a real CUDA install: find_nvcc()'s /usr/local/cuda* glob is not mocked

closed · @rwkeyes · 3 评论 · 去 GitHub 看

Setup & installAMD / HIPNVIDIA / CUDA

说明

**What happens.** `tools/test_setup_choices.py::ExperimentalSm60.test_find_nvcc_below` errors on any machine that has a CUDA toolkit installed:

```
ERROR: test_find_nvcc_below (test_setup_choices.ExperimentalSm60)
Traceback (most recent call last):
  File "tools/test_setup_choices.py", line 132, in test_find_nvcc_below
    self.assertEqual(setup.find_nvcc(), (str(new), (13, 0)))
  File "setup.py", line 604, in find_nvcc
    v = re.search(r"release (\d+)\.(\d+)", out([c, "--version"]))
  File "tools/test_setup_choices.py", line 131, in <lambda>
    mock.patch.object(setup, "out", lambda cmd: versions[cmd[0]]):
KeyError: '/usr/local/cuda-13.2/bin/nvcc'
```

Reproduced on two hosts, each failing on **its own** toolkit path — CUDA 13.2 at `/usr/local/cuda-13.2` (plus `/usr/bin/nvcc`), and CUDA 12.8 at `/usr/local/cuda-12.8`:

```
KeyError: '/usr/local/cuda-12.8/bin/nvcc'
```

Seen from `python -m unittest discover -s tools -p 'test_*.py'` on 0.1.32 (`c499bd1`), on both a HIP/gfx1100 box and a CUDA 12.8 box.

**Why.** The test mocks `WIN`, `shutil.which`, `CUDA_PATH` and `setup.out`, but `find_nvcc()` also enumerates the *real* filesystem:

```python
cands += [str(p / "bin" / "nvcc") for p in sorted(Path("/usr/local").glob("cuda*"), reverse=True)]
cands += [str(p / "bin" / "nvcc") for p in sorted(Path("/opt").glob("cuda*"), reverse=True)]   # Arch (#46)
```

Those real candidates are appended to the mocked ones. They are normally **newer** than the test's fake `13.0`, so they win the loop, and the mocked `out()` has no entry for them → `KeyError`.

**Confirmation.** Faking the glob out — returning nothing for `cuda*` — makes the test pass unchanged:

```python
real = pathlib.Path.glob
pathlib.Path.glob = lambda self, pat, **k: iter(()) if "cuda" in str(pat) else real(self, pat, **k)
# -> failures=0 errors=0
```

So the cause is the unmocked glob and nothing about the host.

**Suggested fix.** Mock the cuda-root enumeration as well (`mock.patch.object(Path, "glob", ...)`), or make the roots injectable so the test can point `find_nvcc()` at its temp directory.

**This is not a product bug** — `find_nvcc()` does exactly what it should, and the engine/setup path is unaffected. It is test hermeticity only, and it is invisible on a machine without CUDA installed, which is presumably why CI does not catch it.

本站相关内容

相关页面的快捷入口。