Issues / #1935

#1935 8 tests in tools/test_setup_*.py depend on the host: unmocked HEAD to GitHub (2) and unmocked /proc/cpuinfo read (6)

open · @gputier · 0 comentários · No GitHub

Setup & installAMD / HIPNVIDIA / CUDAModels & quantsWindowsLinux

Descrição

## Context

On v0.1.42 (61b3fb5d), `pytest tools/test_setup_amd.py tools/test_setup_choices.py tools/test_setup_engine_hash.py` in a clean `python:3.12-slim` container (`pip install -r requirements.txt pytest jsonschema`) gives 8 failed, 107 passed, with or without network. On a Windows machine with internet, the same tests are green. They lean on the host: the `WIN` branch of `cpu_info()` never reads `/proc/cpuinfo`, and the published release only ships the Windows asset. Same family as #414 (host state leaking into `test_setup_choices`).

I checked this by replacing `setup.cpu_info` (6 tests) and `urllib.request.urlopen` (2 tests) in a container with no network. All 8 turn green, so nothing else is missing (cmake and ninja come from requirements.txt, and the tests already mock `cmake_build` and `install_build_tools`).

## The 2 tests that call the real network

- `tools/test_setup_engine_hash.py:309` `WhatARefusalDoesToTheCaller::test_updating_keeps_the_installed_engine_instead_of_stopping` (fails at `:316`)
- `tools/test_setup_engine_hash.py:325` `WhatARefusalDoesToTheCaller::test_a_first_install_stops_because_there_is_nothing_to_fall_back_to` (`SystemExit` not raised at `:327`)

Cause: the tests mock `download` and `engine_digest`, but `get_prebuilt()` first sends a real `HEAD` (`setup.py:2997`, `urllib.request.urlopen(req, timeout=60)`) to `releases/download/v<version>/`, then `releases/latest/download/`. On any non-Windows host the asset is `strata-linux-x64.zip` (`setup.py:180`), which no release publishes (404). Offline, it is a DNS error. Either way, `setup.py:3003` returns `None` ("compiling instead") before `download` is reached, so the path under test (`verify_engine_archive`, `engine_refused`) never runs.

Proposed fix: patch `urllib.request.urlopen` in the test helper (`:304`) and in the `:325` test, for example `mock.patch.object(setup.urllib.request, "urlopen", return_value=mock.MagicMock())`, next to the existing patches of `download` and `engine_digest`.

## The 6 that read the real /proc/cpuinfo

- `tools/test_setup_amd.py:156` `GpuLists::test_build_for_every_arch`
- `tools/test_setup_choices.py:354` `HipVision::test_the_cpu_encoder_is_built_once`
- `tools/test_setup_choices.py:365` `HipVision::test_without_images_nothing_changes`
- `tools/test_setup_choices.py:527` `CudaVision::test_the_encoder_is_built_native` (gpu and cpu subtests)
- `tools/test_setup_choices.py:588` `HostCompilers::test_the_defs_reach_cmake`

Cause: `build_engine()` (`setup.py:3401`) and `build_engine_hip()` (`setup.py:2643`) call `cpu_floor(cpu_info()[1])`, and none of these tests mock `cpu_info`. On Linux, `cpu_info()` runs `re.search(r"^flags\s*:\s*(.*)$", txt, re.M).group(1)` (`setup.py:720`). On aarch64, the file has a `Features` line instead of `flags`, and some x86 containers under emulation have neither. `re.search` then returns `None`, and the `AttributeError` is not caught: the `try` only catches `OSError` (`setup.py:725`). Result: `AttributeError: 'NoneType' object has no attribute 'group'`.

Proposed fix, two parts:
- Tests: `mock.patch.object(setup, "cpu_info", lambda: ("test CPU", True, False))` in the shared setup of these classes, so the result does not depend on the machine.
- Product (separate from the tests, and it matters on its own): make `cpu_info()` survive a `/proc/cpuinfo` without `flags` (catch `AttributeError` too, or read `Features` on ARM). As it is, `setup.py` raises on any Linux ARM host, which is not just a test problem.

No site

Links install, modelos, releases.