137 lines
4.1 KiB
Python
137 lines
4.1 KiB
Python
"""
|
|
Configuration pytest pour RPA Vision V3
|
|
|
|
Auteur: Dom, Alice Kiro - 15 décembre 2024
|
|
Objectif: Fiche #4 - Assurer que pytest trouve 'core' depuis n'importe où
|
|
|
|
Ce fichier garantit que:
|
|
- pytest fonctionne depuis la racine du projet
|
|
- pytest fonctionne depuis un IDE (PyCharm/VSCode)
|
|
- Les imports 'from core...' marchent partout
|
|
- Plus de problèmes PYTHONPATH
|
|
- Le GPU est vérifié avant les tests qui en ont besoin
|
|
"""
|
|
import sys
|
|
import types
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
# S'assurer que la racine du projet est dans sys.path pour que `import core...` fonctionne partout
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
# Vérification que core est accessible
|
|
try:
|
|
import core
|
|
print(f"✅ Core module accessible depuis: {core.__file__}")
|
|
except ImportError as e:
|
|
print(f"❌ Erreur import core: {e}")
|
|
print(f" ROOT path: {ROOT}")
|
|
print(f" sys.path: {sys.path[:3]}...")
|
|
|
|
|
|
# Certains tests HTTP d'agent_chat n'ont pas besoin du transport SocketIO reel.
|
|
# Le service de production garde Flask-SocketIO comme dependance, mais l'env de
|
|
# test local peut etre minimal. On fournit alors un shim strictement pytest.
|
|
try:
|
|
import flask_socketio # noqa: F401
|
|
except ModuleNotFoundError:
|
|
flask_socketio = types.ModuleType("flask_socketio")
|
|
|
|
class _FakeSocketIO:
|
|
def __init__(self, app=None, *args, **kwargs):
|
|
self.app = app
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
self.handlers = {}
|
|
self.emitted = []
|
|
|
|
def on(self, event):
|
|
def decorator(func):
|
|
self.handlers[event] = func
|
|
return func
|
|
return decorator
|
|
|
|
def emit(self, event, payload=None, **kwargs):
|
|
self.emitted.append((event, payload, kwargs))
|
|
|
|
def run(self, *args, **kwargs):
|
|
return None
|
|
|
|
def _fake_emit(*_args, **_kwargs):
|
|
return None
|
|
|
|
flask_socketio.SocketIO = _FakeSocketIO
|
|
flask_socketio.emit = _fake_emit
|
|
sys.modules["flask_socketio"] = flask_socketio
|
|
|
|
try:
|
|
import prometheus_client # noqa: F401
|
|
except ModuleNotFoundError:
|
|
prometheus_client = types.ModuleType("prometheus_client")
|
|
prometheus_client.CONTENT_TYPE_LATEST = "text/plain; version=0.0.4"
|
|
|
|
def _fake_generate_latest(*_args, **_kwargs):
|
|
return b""
|
|
|
|
class _FakeMetric:
|
|
def __init__(self, *_args, **_kwargs):
|
|
pass
|
|
|
|
def labels(self, **_kwargs):
|
|
return self
|
|
|
|
def inc(self, *_args, **_kwargs):
|
|
return None
|
|
|
|
def observe(self, *_args, **_kwargs):
|
|
return None
|
|
|
|
def set(self, *_args, **_kwargs):
|
|
return None
|
|
|
|
def info(self, *_args, **_kwargs):
|
|
return None
|
|
|
|
prometheus_client.generate_latest = _fake_generate_latest
|
|
prometheus_client.Counter = _FakeMetric
|
|
prometheus_client.Histogram = _FakeMetric
|
|
prometheus_client.Gauge = _FakeMetric
|
|
prometheus_client.Info = _FakeMetric
|
|
sys.modules["prometheus_client"] = prometheus_client
|
|
|
|
|
|
# =============================================================================
|
|
# GPU Preflight — vérification avant les tests GPU
|
|
# =============================================================================
|
|
|
|
def pytest_configure(config):
|
|
"""Enregistre le marqueur 'gpu' pour les tests nécessitant le GPU."""
|
|
config.addinivalue_line(
|
|
"markers",
|
|
"gpu: test nécessitant le GPU (skip auto si VRAM insuffisante)",
|
|
)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _gpu_preflight_check(request):
|
|
"""Skip automatiquement les tests marqués 'gpu' si la machine n'est pas prête."""
|
|
marker = request.node.get_closest_marker("gpu")
|
|
if marker is None:
|
|
return
|
|
|
|
from core.gpu.preflight import check_machine_ready
|
|
|
|
# Seuils personnalisables via le marqueur : @pytest.mark.gpu(min_vram=2000)
|
|
min_vram = marker.kwargs.get("min_vram", 1000)
|
|
max_util = marker.kwargs.get("max_util", 80)
|
|
|
|
result = check_machine_ready(
|
|
min_free_vram_mb=min_vram,
|
|
max_gpu_util_percent=max_util,
|
|
)
|
|
if not result.ready:
|
|
pytest.skip(f"GPU pas prêt : {result.reason}")
|