Make the unsloth_cli studio tests pass in isolation (#7599)

* Make the unsloth_cli studio tests pass in isolation

Six tests in test_studio_run_parallel_flag.py and one in
test_studio_secure_flag.py only passed in a full-directory run. All of them
reach the in-venv branch of run(), which does `from state.tool_policy import
set_tool_policy`. That module lives under studio/backend, so it only imports
once something has put that directory on sys.path, and nothing in either file
does. They were relying on test_start.py, which calls
ensure_studio_backend_path() and leaks the sys.path entry, or on
test_studio_cloudflare_flag.py, which stubs the module.

Add a stub_tool_policy_state fixture in a new conftest and use it in the seven,
so the state comes from the test rather than from whatever ran first.

Every file in unsloth_cli/tests now passes on its own, and the suite is stable
across four pytest-randomly seeds.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Daniel Han 2026-07-29 01:33:19 -07:00 committed by GitHub
commit 5cebc46124
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 31 additions and 5 deletions

View file

@ -0,0 +1,26 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""Shared fixtures for the unsloth_cli tests."""
import sys
import types
import pytest
@pytest.fixture
def stub_tool_policy_state(monkeypatch):
"""Stub the backend's `state.tool_policy`, which run() imports in-venv.
It lives under studio/backend, so it only imports once something has put
that directory on sys.path. Tests that reach the in-venv branch of run()
used to get that for free from whichever file ran earlier and did it as a
side effect, which made them pass only in a full-directory run.
"""
state_mod = types.ModuleType("state")
tp_mod = types.ModuleType("state.tool_policy")
tp_mod.set_tool_policy = lambda *a, **k: None
state_mod.tool_policy = tp_mod
monkeypatch.setitem(sys.modules, "state", state_mod)
monkeypatch.setitem(sys.modules, "state.tool_policy", tp_mod)

View file

@ -613,7 +613,7 @@ def test_studio_default_exposes_parallel_option():
@pytest.mark.parametrize("value", [1, 4, 8, 64])
def test_in_venv_path_passes_parallel_to_run_server(monkeypatch, value):
def test_in_venv_path_passes_parallel_to_run_server(monkeypatch, value, stub_tool_policy_state):
"""In-venv path must forward --parallel to
run_server(llama_parallel_slots=N), not the old hardcoded 4."""
studio_mod = _load_run_command()
@ -706,7 +706,9 @@ def test_secure_api_only_is_refused_before_any_reexec(monkeypatch, tmp_path):
@pytest.mark.parametrize("extra,expected", [(["--api-only"], True), ([], False)])
def test_in_venv_path_passes_api_only_to_run_server(monkeypatch, extra, expected):
def test_in_venv_path_passes_api_only_to_run_server(
monkeypatch, extra, expected, stub_tool_policy_state
):
"""In-venv path must forward --api-only to run_server(api_only=...)."""
studio_mod = _load_run_command()

View file

@ -244,7 +244,7 @@ class _RunServerCaptured(SystemExit):
self.kwargs = dict(kwargs)
def test_run_in_venv_passes_secure_and_forces_host(monkeypatch, tmp_path):
def test_run_in_venv_passes_secure_and_forces_host(monkeypatch, tmp_path, stub_tool_policy_state):
import types
studio_mod = _studio()