feat(multimodal): 完成阶段F运行管理与收尾验收
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from app.errors import ApiError
|
||||
from app.local_models import components, runtime
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolate(monkeypatch, tmp_path):
|
||||
monkeypatch.setattr(components, 'ROOT', tmp_path / 'cuda')
|
||||
monkeypatch.setattr(components, 'state', {'status': 'unchecked', 'stage': '', 'cuda_available': None})
|
||||
monkeypatch.setattr(components, 'task', None)
|
||||
|
||||
|
||||
def test_status_checks_without_installing_and_detects_existing_cuda(monkeypatch):
|
||||
python = components.ROOT / 'Scripts/python.exe'
|
||||
python.parent.mkdir(parents=True)
|
||||
python.touch()
|
||||
calls = []
|
||||
async def execute(args, timeout):
|
||||
calls.append(args)
|
||||
return [json.dumps({'torch': '2.9.1+cu128', 'cuda_available': True})]
|
||||
monkeypatch.setattr(components, 'execute', execute)
|
||||
async def scenario():
|
||||
assert (await components.status())['status'] == 'checking'
|
||||
await components.task
|
||||
assert (await components.status())['status'] == 'installed'
|
||||
assert len(calls) == 1 and calls[0][0] == str(python)
|
||||
assert components.ready()
|
||||
asyncio.run(scenario())
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != 'nt', reason='Windows installer')
|
||||
def test_install_deduplicates_and_failure_can_retry(monkeypatch):
|
||||
monkeypatch.setattr(components.shutil, 'which', lambda name: 'uv.exe')
|
||||
async def scenario():
|
||||
entered, release = asyncio.Event(), asyncio.Event()
|
||||
calls = []
|
||||
async def execute(args, timeout):
|
||||
calls.append(args)
|
||||
entered.set()
|
||||
await release.wait()
|
||||
raise RuntimeError('private exception')
|
||||
monkeypatch.setattr(components, 'execute', execute)
|
||||
await components.install()
|
||||
await entered.wait()
|
||||
first = components.task
|
||||
await components.install()
|
||||
assert first is components.task
|
||||
release.set()
|
||||
await first
|
||||
assert components.state['status'] == 'failed'
|
||||
assert 'private exception' not in str(components.state)
|
||||
await components.install()
|
||||
await components.task
|
||||
assert len(calls) == 2 and '-RuntimeDirectory' in calls[0]
|
||||
assert not components.ready()
|
||||
asyncio.run(scenario())
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != 'nt', reason='Windows installer')
|
||||
def test_install_refuses_active_inference(monkeypatch):
|
||||
monkeypatch.setattr(runtime.runtime, 'active', {1: 'bekko'})
|
||||
async def scenario():
|
||||
with pytest.raises(ApiError) as exc:
|
||||
await components.install()
|
||||
assert exc.value.code == 'MODEL_IN_USE'
|
||||
asyncio.run(scenario())
|
||||
|
||||
|
||||
def test_interpreter_keeps_cpu_default_and_respects_explicit_override(monkeypatch):
|
||||
monkeypatch.delenv('APP_MODEL_PYTHON', raising=False)
|
||||
python = components.ROOT / 'Scripts/python.exe'
|
||||
python.parent.mkdir(parents=True)
|
||||
python.touch()
|
||||
(components.ROOT / 'ready.json').write_text('{}')
|
||||
monkeypatch.setattr(runtime, 'configuration', lambda: runtime.RuntimeConfig(device='cpu'))
|
||||
assert runtime.interpreter() != python
|
||||
monkeypatch.setattr(runtime, 'configuration', lambda: runtime.RuntimeConfig(device='cuda'))
|
||||
assert runtime.interpreter() == python
|
||||
monkeypatch.setenv('APP_MODEL_PYTHON', 'explicit-python.exe')
|
||||
assert str(runtime.interpreter()) == 'explicit-python.exe'
|
||||
Reference in New Issue
Block a user