ci: commit workspace changes from notebook and backend fixes (excludes test_env, Frontend)
This commit is contained in:
313
tests_notebook/diagnose_diagram.py
Normal file
313
tests_notebook/diagnose_diagram.py
Normal file
@@ -0,0 +1,313 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script de diagnostic pour identifier et corriger le problème des diagrammes vides
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import base64
|
||||
import matplotlib
|
||||
matplotlib.use('Agg') # Backend non-interactif
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
# Ajouter le répertoire parent pour importer les modules
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
def test_basic_matplotlib():
|
||||
"""Test si matplotlib fonctionne correctement."""
|
||||
print("=== TEST MATPLOTLIB DE BASE ===")
|
||||
|
||||
try:
|
||||
# Créer un graphique simple
|
||||
fig, ax = plt.subplots(figsize=(10, 6))
|
||||
x = np.linspace(0, 10, 100)
|
||||
y = np.sin(x)
|
||||
|
||||
ax.plot(x, y, 'b-', linewidth=2)
|
||||
ax.set_xlabel('X')
|
||||
ax.set_ylabel('Y')
|
||||
ax.set_title('Test Matplotlib')
|
||||
ax.grid(True)
|
||||
|
||||
# Sauvegarder
|
||||
plt.savefig('test_matplotlib.png', dpi=100, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
|
||||
# Vérifier le fichier
|
||||
if os.path.exists('test_matplotlib.png'):
|
||||
size = os.path.getsize('test_matplotlib.png')
|
||||
print(f"✅ Matplotlib fonctionne - Fichier : {size} octets")
|
||||
return True
|
||||
else:
|
||||
print("❌ Fichier non généré")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur matplotlib : {e}")
|
||||
return False
|
||||
|
||||
def test_refrigerant_loading():
|
||||
"""Test le chargement du réfrigérant R290."""
|
||||
print("\n=== TEST CHARGEMENT R290 ===")
|
||||
|
||||
try:
|
||||
from app.core.refrigerant_loader import get_refrigerant
|
||||
|
||||
refrigerant = get_refrigerant("R290")
|
||||
if refrigerant:
|
||||
print(f"✅ R290 chargé : {refrigerant.refrig_name}")
|
||||
|
||||
# Test fonctions de base
|
||||
try:
|
||||
h_l = refrigerant.hsl_px(1.0, 0) / 1000 # kJ/kg
|
||||
h_v = refrigerant.hsv_px(1.0, 1) / 1000 # kJ/kg
|
||||
T_sat = refrigerant.T_px(1.0, 0.5)
|
||||
|
||||
print(f" h_l(1 bar) : {h_l:.2f} kJ/kg")
|
||||
print(f" h_v(1 bar) : {h_v:.2f} kJ/kg")
|
||||
print(f" T_sat(1 bar) : {T_sat - 273.15:.2f} °C")
|
||||
|
||||
if h_l is not None and h_v is not None and T_sat is not None:
|
||||
print("✅ Fonctions thermodynamiques OK")
|
||||
return True
|
||||
else:
|
||||
print("❌ Valeurs None retournées")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur fonctions thermodynamiques : {e}")
|
||||
return False
|
||||
else:
|
||||
print("❌ R290 non chargé")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur chargement R290 : {e}")
|
||||
return False
|
||||
|
||||
def test_saturation_curve():
|
||||
"""Test la génération de la courbe de saturation."""
|
||||
print("\n=== TEST COURBE DE SATURATION ===")
|
||||
|
||||
try:
|
||||
from app.core.refrigerant_loader import get_refrigerant
|
||||
|
||||
refrigerant = get_refrigerant("R290")
|
||||
Hsl, Hsv, Psat, Tsat = [], [], [], []
|
||||
|
||||
# Calculer quelques points
|
||||
for p_bar in [0.5, 1.0, 2.0, 5.0, 10.0, 20.0]:
|
||||
try:
|
||||
h_l = refrigerant.hsl_px(p_bar, 0) / 1000
|
||||
h_v = refrigerant.hsv_px(p_bar, 1) / 1000
|
||||
T_sat = refrigerant.T_px(p_bar, 0.5)
|
||||
|
||||
if h_l is not None and h_v is not None and T_sat is not None:
|
||||
Hsl.append(h_l)
|
||||
Hsv.append(h_v)
|
||||
Psat.append(p_bar)
|
||||
Tsat.append(T_sat)
|
||||
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
print(f"✅ Points calculés : {len(Hsl)}")
|
||||
|
||||
if len(Hsl) > 2:
|
||||
# Créer le graphique
|
||||
fig, ax = plt.subplots(figsize=(10, 6))
|
||||
ax.plot(Hsl, Psat, 'b-', linewidth=2, label='Liquide saturé')
|
||||
ax.plot(Hsv, Psat, 'r-', linewidth=2, label='Vapeur saturée')
|
||||
ax.set_xlabel('Enthalpie [kJ/kg]')
|
||||
ax.set_ylabel('Pression [bar]')
|
||||
ax.set_title('Courbe de Saturation R290')
|
||||
ax.set_yscale('log')
|
||||
ax.grid(True, which='both', alpha=0.3)
|
||||
ax.legend()
|
||||
|
||||
plt.savefig('test_saturation.png', dpi=100, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
|
||||
if os.path.exists('test_saturation.png'):
|
||||
size = os.path.getsize('test_saturation.png')
|
||||
print(f"✅ Courbe générée - Fichier : {size} octets")
|
||||
return True
|
||||
else:
|
||||
print("❌ Fichier non généré")
|
||||
return False
|
||||
else:
|
||||
print("❌ Pas assez de points")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur courbe saturation : {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_complete_diagram():
|
||||
"""Test la génération complète du diagramme."""
|
||||
print("\n=== TEST DIAGRAMME COMPLET ===")
|
||||
|
||||
try:
|
||||
from app.core.refrigerant_loader import get_refrigerant
|
||||
from app.services.diagram_generator import DiagramGenerator
|
||||
|
||||
# Créer le générateur
|
||||
refrigerant = get_refrigerant("R290")
|
||||
diagram_gen = DiagramGenerator(refrigerant)
|
||||
|
||||
# Générer le diagramme
|
||||
fig = diagram_gen.plot_diagram(
|
||||
p_min=0.1,
|
||||
p_max=20.0,
|
||||
h_min=-100,
|
||||
h_max=600,
|
||||
include_isotherms=True,
|
||||
title="Test Complet R290"
|
||||
)
|
||||
|
||||
# Sauvegarder
|
||||
fig.savefig('test_complete.png', dpi=100, bbox_inches='tight')
|
||||
plt.close(fig)
|
||||
|
||||
if os.path.exists('test_complete.png'):
|
||||
size = os.path.getsize('test_complete.png')
|
||||
print(f"✅ Diagramme complet généré - Fichier : {size} octets")
|
||||
|
||||
# Vérifier si le fichier est valide
|
||||
if size > 1000: # Au moins 1 Ko
|
||||
print("✅ Fichier semble valide")
|
||||
return True
|
||||
else:
|
||||
print("❌ Fichier trop petit - probablement vide")
|
||||
return False
|
||||
else:
|
||||
print("❌ Fichier non généré")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur diagramme complet : {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_api_direct():
|
||||
"""Test l'API directement."""
|
||||
print("\n=== TEST API DIRECT ===")
|
||||
|
||||
try:
|
||||
import requests
|
||||
|
||||
# Charger la requête
|
||||
with open('request_r290.json', 'r') as f:
|
||||
request_data = json.load(f)
|
||||
|
||||
# Appeler l'API
|
||||
response = requests.post("http://localhost:8001/api/v1/diagrams/ph",
|
||||
json=request_data, timeout=30)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
|
||||
if 'image' in result and result['image']:
|
||||
# Décoder et sauvegarder
|
||||
image_data = base64.b64decode(result['image'])
|
||||
with open('test_api.png', 'wb') as f:
|
||||
f.write(image_data)
|
||||
|
||||
size = len(image_data)
|
||||
print(f"✅ API fonctionne - Image : {size} octets")
|
||||
|
||||
if size > 1000:
|
||||
print("✅ Image API valide")
|
||||
return True
|
||||
else:
|
||||
print("❌ Image API trop petite")
|
||||
return False
|
||||
else:
|
||||
print("❌ Pas d'image dans la réponse API")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ Erreur API : {response.status_code}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur API : {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""Fonction principale de diagnostic."""
|
||||
print("🔍 DIAGNOSTIC COMPLET - API DIAGRAMMES PH")
|
||||
print("=" * 50)
|
||||
|
||||
# Tests progressifs
|
||||
tests = [
|
||||
("Matplotlib de base", test_basic_matplotlib),
|
||||
("Chargement R290", test_refrigerant_loading),
|
||||
("Courbe de saturation", test_saturation_curve),
|
||||
("Diagramme complet", test_complete_diagram),
|
||||
("API directe", test_api_direct),
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for test_name, test_func in tests:
|
||||
print(f"\n🧪 {test_name}")
|
||||
print("-" * 30)
|
||||
|
||||
try:
|
||||
result = test_func()
|
||||
results.append((test_name, result))
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur inattendue : {e}")
|
||||
results.append((test_name, False))
|
||||
|
||||
# Rapport final
|
||||
print("\n" + "=" * 50)
|
||||
print("📊 RAPPORT FINAL")
|
||||
print("=" * 50)
|
||||
|
||||
success_count = 0
|
||||
for test_name, success in results:
|
||||
status = "✅ SUCCÈS" if success else "❌ ÉCHEC"
|
||||
print(f"{status} - {test_name}")
|
||||
if success:
|
||||
success_count += 1
|
||||
|
||||
total_tests = len(results)
|
||||
success_rate = (success_count / total_tests) * 100
|
||||
|
||||
print(f"\n📈 Résumé : {success_count}/{total_tests} tests réussis ({success_rate:.1f}%)")
|
||||
|
||||
if success_rate == 100:
|
||||
print("\n🎉 TOUS LES TESTS RÉUSSIS !")
|
||||
print("✅ Le système fonctionne parfaitement")
|
||||
elif success_rate >= 60:
|
||||
print("\n🟡 CERTAINS TESTS RÉUSSIS")
|
||||
print("⚠️ Des problèmes subsistent")
|
||||
else:
|
||||
print("\n🔴 NOMBREUX ÉCHECS")
|
||||
print("🚨 Des corrections majeures sont nécessaires")
|
||||
|
||||
# Recommandations
|
||||
print("\n💡 RECOMMANDATIONS :")
|
||||
|
||||
if not any(r[1] for r in results[:2]): # Matplotlib ou R290
|
||||
print("- Vérifier l'installation de matplotlib")
|
||||
print("- Vérifier les fichiers DLL/SO dans libs/so/")
|
||||
|
||||
if results[2][1] and not results[3][1]: # Saturation OK mais diagramme complet KO
|
||||
print("- Problème dans le service DiagramGenerator")
|
||||
print("- Vérifier les calculs d'isothermes")
|
||||
|
||||
if results[3][1] and not results[4][1]: # Diagramme local OK mais API KO
|
||||
print("- Problème dans l'endpoint API")
|
||||
print("- Vérifier les logs de l'API")
|
||||
|
||||
print("\n📁 Fichiers générés dans le répertoire courant")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
13
tests_notebook/request_r290.json
Normal file
13
tests_notebook/request_r290.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"refrigerant": "R290",
|
||||
"pressure_range": {
|
||||
"min": 0.1,
|
||||
"max": 20.0
|
||||
},
|
||||
"enthalpy_range": {
|
||||
"min": -100,
|
||||
"max": 600
|
||||
},
|
||||
"include_isotherms": true,
|
||||
"format": "png"
|
||||
}
|
||||
1
tests_notebook/test_r290_api.png
Normal file
1
tests_notebook/test_r290_api.png
Normal file
File diff suppressed because one or more lines are too long
73
tests_notebook/test_r290_diagram.py
Normal file
73
tests_notebook/test_r290_diagram.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script de test pour générer un diagramme PH R290
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Ajouter le répertoire courant pour importer les modules
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
try:
|
||||
from app.core.refrigerant_loader import get_refrigerant
|
||||
from app.services.diagram_generator import DiagramGenerator
|
||||
|
||||
print("=== GENERATION DIAGRAMME PH R290 ===")
|
||||
|
||||
# Test 1: Charger le réfrigérant R290
|
||||
print("\n1. Chargement R290...")
|
||||
refrigerant = get_refrigerant("R290")
|
||||
if refrigerant:
|
||||
print(f"R290 charge: {refrigerant.refrig_name}")
|
||||
else:
|
||||
print("Echec chargement R290")
|
||||
sys.exit(1)
|
||||
|
||||
# Test 2: Créer le générateur de diagrammes
|
||||
print("\n2. Creation generateur de diagrammes...")
|
||||
diagram_gen = DiagramGenerator(refrigerant)
|
||||
print("Generateur de diagrammes cree")
|
||||
|
||||
# Test 3: Générer le diagramme
|
||||
print("\n3. Generation du diagramme...")
|
||||
try:
|
||||
fig = diagram_gen.plot_diagram(
|
||||
p_min=0.1, # bar
|
||||
p_max=20.0, # bar
|
||||
h_min=-100, # kJ/kg
|
||||
h_max=600, # kJ/kg
|
||||
include_isotherms=True,
|
||||
title="PH Diagram for R290 (Propane)"
|
||||
)
|
||||
print("Diagramme genere avec succes!")
|
||||
|
||||
# Test 4: Sauvegarder le diagramme
|
||||
print("\n4. Sauvegarde du diagramme...")
|
||||
fig.savefig("test_r290_diagram.png", dpi=100, bbox_inches='tight')
|
||||
print("Diagramme sauvegarde dans: test_r290_diagram.png")
|
||||
|
||||
# Test 5: Exporter en base64
|
||||
print("\n5. Export en base64...")
|
||||
base64_image = diagram_gen.export_to_base64(fig)
|
||||
print(f"Image base64 generee: {len(base64_image)} caracteres")
|
||||
|
||||
# Nettoyer
|
||||
import matplotlib.pyplot as plt
|
||||
plt.close(fig)
|
||||
|
||||
print("\n=== SUCCES ===")
|
||||
print("Le diagramme R290 a ete genere avec succes!")
|
||||
print("Fichier: test_r290_diagram.png")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERREUR generation diagramme: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERREUR generale: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user