studio: fix tests turning main CI red/flaky (kill-process, install overrides, UI re-login) (#6419)
* studio: set _stats_logger in kill-process test backend #6377 added a self._stats_logger cleanup step to _kill_process's finally block. test_kill_process_records_timestamp_on_actual_kill (added in #6400) builds the backend via __new__, which bypasses __init__ where _stats_logger is set, so once both landed on main the test raised AttributeError: 'LlamaCppBackend' object has no attribute '_stats_logger'. Set _stats_logger on the hand-built backend, mirroring __init__, so the kill path's finally has the attribute it expects. * test: assert torchao override step on normal Linux, not overrides.txt #6400 moved the torchao dependency override from a fixed pin in overrides.txt to a torch-matched spec installed via --force-reinstall (_select_torchao_spec), and turned overrides.txt into a comment-only pointer. It updated the Windows variant (test_windows_only_includes_overrides) to check for --reinstall, but left test_normal_linux_includes_overrides asserting overrides.txt is installed, which no longer happens. Check for the override step (--reinstall) instead, matching the Windows test. * test(ui): tolerate ERR_ABORTED on /login re-login in shutdown step The Shutdown step re-logs in after a CLI password rotation that revoked the prior token. The SPA auth guard can client-side-redirect mid-navigation against the stale token, aborting page.goto("/login") with net::ERR_ABORTED. It is a race (passes on main most of the time). Resolve on domcontentloaded and tolerate the abort, relying on the password-field wait that follows to confirm we reached /login, matching the wait_until used by the other navigations in this file.
This commit is contained in:
parent
6c02af8618
commit
79b57fe038
3 changed files with 19 additions and 5 deletions
|
|
@ -281,6 +281,7 @@ def test_kill_process_records_timestamp_on_actual_kill():
|
|||
backend = LlamaCppBackend.__new__(LlamaCppBackend)
|
||||
backend._process = None
|
||||
backend._healthy = False
|
||||
backend._stats_logger = None # _kill_process stops it in finally
|
||||
backend._stdout_thread = None
|
||||
backend._llama_log_fh = None
|
||||
backend._last_kill_monotonic = 0.0
|
||||
|
|
|
|||
|
|
@ -471,11 +471,15 @@ class TestInstallPythonStackSubprocessMock:
|
|||
# -- Normal Linux path (NO_TORCH=False, IS_MACOS=False, IS_WINDOWS=False) --
|
||||
|
||||
def test_normal_linux_includes_overrides(self):
|
||||
"""Normal Linux: overrides.txt IS called."""
|
||||
"""Normal Linux: the torchao override step IS called.
|
||||
|
||||
The override step installs a torch-matched torchao spec via
|
||||
--force-reinstall (uv: --reinstall), not overrides.txt directly.
|
||||
"""
|
||||
cmds = self._capture_install(no_torch = False, is_macos = False, is_windows = False)
|
||||
assert self._cmds_contain_file(
|
||||
cmds, "overrides.txt"
|
||||
), "overrides.txt should be called on normal Linux"
|
||||
assert any(
|
||||
"--reinstall" in cmd for cmd in cmds
|
||||
), "torchao override step (--reinstall) should be called on normal Linux"
|
||||
|
||||
def test_normal_linux_includes_triton(self):
|
||||
"""Normal Linux: triton-kernels.txt IS called."""
|
||||
|
|
|
|||
|
|
@ -1430,7 +1430,16 @@ with sync_playwright() as p:
|
|||
# Re-login through the UI with NEW2 so the browser has a valid
|
||||
# access token for the /api/shutdown call (the previous one
|
||||
# was invalidated by the CLI rotation above).
|
||||
page.goto(f"{BASE}/login")
|
||||
# The CLI rotation left a stale token, so the SPA auth guard can
|
||||
# client-side-redirect mid-navigation and abort this goto with
|
||||
# net::ERR_ABORTED. Resolve on domcontentloaded and tolerate the
|
||||
# abort; the password-field wait below confirms we reached /login.
|
||||
try:
|
||||
page.goto(f"{BASE}/login", wait_until = "domcontentloaded", timeout = 60_000)
|
||||
except Exception as exc:
|
||||
if "ERR_ABORTED" not in str(exc):
|
||||
raise
|
||||
info(f"goto /login aborted ({exc!r}); password-field wait will confirm /login")
|
||||
pw_field = page.locator("#password")
|
||||
pw_field.wait_for(state = "visible", timeout = 60_000)
|
||||
pw_field.fill(NEW2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue