"""La fabrique choisit le moteur d'après le matériel — décision pure, testable depuis n'importe quelle machine.""" import pytest from moteur import choisir_transcripteur, nom_moteur_pour @pytest.mark.parametrize("plateforme, machine, cuda, attendu", [ ("darwin", "arm64", False, "mlx"), ("darwin", "x86_64", False, "faster-cpu"), ("win32", "AMD64", True, "faster-gpu"), ("win32", "AMD64", False, "faster-cpu"), ]) def test_la_decision_suit_le_materiel(plateforme, machine, cuda, attendu): assert nom_moteur_pour(plateforme, machine, cuda) == attendu def test_apple_silicon_prend_mlx_meme_sans_cuda(): assert nom_moteur_pour("darwin", "arm64", cuda_disponible=False) == "mlx" def test_la_fabrique_rend_un_transcripteur_complet(): t = choisir_transcripteur(nom="mlx", modele="mlx-community/whisper-medium", langue="fr", amorce="") assert callable(t.warmup) and callable(t.transcrire) def test_un_moteur_inconnu_est_refuse_clairement(): with pytest.raises(NotImplementedError) as e: choisir_transcripteur(nom="vosk", modele="x", langue="fr", amorce="") assert "vosk" in str(e.value) # --- Sonde CUDA : le nom de la bibliothèque partagée diffère par OS et par version. # Ces tests injectent une doublure de chargeur pour rester exécutables depuis # n'importe quelle machine, sans jamais dépendre d'une vraie installation CUDA. from moteur import _cuda_disponible def test_cuda_reconnue_sur_windows_via_dll_versionnee(): def charger(nom): if nom == "cudart64_12.dll": return object() raise OSError(f"introuvable : {nom}") assert _cuda_disponible(plateforme="win32", charger=charger) is True def test_cuda_absente_sur_windows_si_aucune_dll_ne_charge(): def charger(nom): raise OSError(f"introuvable : {nom}") assert _cuda_disponible(plateforme="win32", charger=charger) is False def test_cuda_reconnue_sur_linux_darwin_via_so(): def charger(nom): if nom == "libcudart.so": return object() raise OSError(f"introuvable : {nom}") assert _cuda_disponible(plateforme="linux", charger=charger) is True assert _cuda_disponible(plateforme="darwin", charger=charger) is True def test_cuda_sonde_ne_leve_jamais_meme_si_le_chargeur_explose(): def charger(nom): raise RuntimeError("chargeur casse, pas seulement OSError") assert _cuda_disponible(plateforme="win32", charger=charger) is False # --- faster-whisper : meme garantie que MLX ci-dessus — la fabrique rend un # transcripteur complet sans jamais importer faster_whisper au niveau module, # pour rester executable sur une machine qui ne l'a pas installe. def test_la_fabrique_rend_un_transcripteur_faster_cpu_complet(): t = choisir_transcripteur(nom="faster-cpu", modele="Systran/faster-whisper-small", langue="fr", amorce="") assert callable(t.warmup) and callable(t.transcrire) assert t.peripherique == "cpu" assert t.type_calcul == "int8" def test_la_fabrique_rend_un_transcripteur_faster_gpu_complet(): t = choisir_transcripteur(nom="faster-gpu", modele="Systran/faster-whisper-small", langue="fr", amorce="") assert callable(t.warmup) and callable(t.transcrire) assert t.peripherique == "cuda" assert t.type_calcul == "float16"