Scénarios de bout en bout de la téléphonie
Cette page donne l'état des 31 scénarios de bout en bout de la téléphonie Navin (ADR-0173, tâche t-211ee738). Les tests tournent avec les vrais moteurs, sans root ni conteneur : Asterisk 20.6.0, Kamailio 5.7.4 (fichier aussi vérifié par Kamailio 6.0.8), RTPengine, SIPp 3.7.2, PostgreSQL (pgserver), SeaweedFS, et le vrai code du Control Plane : compilation, publication par AMI vers Asterisk et par JSONRPC vers Kamailio, routes /v1/telephony.
Statuts : exécuté (le test passe ici), bloqué (impossible ici, la raison est donnée).
Banc de test
Le Navin Manager rend les services asterisk, kamailio et rtpengine de son catalogue
(tests/telephony/render_stack.py, lancé avec l'interpréteur du Manager). tests/telephony/e2e_stack.py démarre
les moteurs, parle AMI, ARI et JSONRPC, lance SIPp et fournit un appelant Python (RTP PCMU et DTMF RFC 4733, que
SIPp ne sait pas émettre sans droits) et un client SIP sur WebSocket sécurisé. Adresses de bouclage : Kamailio
127.0.0.21:5060, Asterisk 127.0.0.1, postes du tenant A 127.0.0.6, du tenant B 127.0.0.7, opérateurs 127.0.0.5
(trunk principal) et 127.0.0.15 (trunk de secours).
Préparation unique : ln -s en_US_f_Allison /tmp/toolchains/asterisk/usr/share/asterisk/sounds/en (le paquet
Debian des sons crée ce lien dans son postinst, qu'une extraction saute ; sans lui les annonces du SVI, de la
messagerie et du code de conférence échouent). Le test échoue avec cette commande si le lien manque.
Commandes
services/control-plane/.venv/bin/python -m pytest services/control-plane/tests/test_telephony_e2e_edge.py -q -p no:cacheprovider
services/control-plane/.venv/bin/python -m pytest services/control-plane/tests/test_telephony_e2e.py -q -p no:cacheprovider
services/control-plane/.venv/bin/python -m pytest services/control-plane/tests/test_telephony_e2e_dedicated.py -q -p no:cacheprovider
services/control-plane/.venv/bin/python -m pytest services/control-plane/tests/test_telephony_ha_real.py -q -p no:cacheprovider
Résultats du 3 novembre 2026, après correction des anomalies 3, 7, 8 et 9 : edge 6 passés ; e2e 21 passés ; dedicated 2 passés ; ha_real 7 passés (tests de tel-ha). 29 scénarios exécutés, 2 bloqués (S30, S31).
Matrice
| N° | Scénario | Statut | Preuve ou raison |
|---|---|---|---|
| S01 | Asterisk single rendu par le Manager, modules chargés | exécuté | test_telephony_e2e_edge.py::test_s01_*, test_telephony_e2e.py::test_s01_* |
| S02 | Pool Asterisk de 2 nœuds | exécuté (tel-ha) | test_telephony_ha_real.py::test_1_both_asterisk_nodes_are_probed_up, test_2_calls_of_one_tenant_land_on_the_same_node |
| S03 | Kamailio vérifié par le vrai binaire | exécuté | test_telephony_e2e_edge.py::test_s03_* (5.7.4 et 6.0.8, JSONRPC en HTTPS avec la CA de test) |
| S04 | RTPengine démarre et répond au ping ng | exécuté | test_telephony_e2e_edge.py::test_s04_* |
| S05 | Modèle mutualisé : deux tenants publiés et relus | exécuté | test_telephony_e2e.py::test_s05_* (GetConfig, endpoints, tables Kamailio) |
| S06 | Modèle dédié | exécuté | test_telephony_e2e_dedicated.py::test_s06_* (un seul tenant sur son pool, appel entre deux postes) |
| S07 | Enregistrement via Kamailio, Path conservé | exécuté | test_telephony_e2e.py::test_s07_* (Path de la périphérie lu par AMI PJSIPShowContacts, mauvais mot de passe refusé) |
| S08 | Appel interne entre deux postes | exécuté | test_telephony_e2e.py::test_s08_* |
| S09 | Isolation des tenants | exécuté | test_telephony_e2e.py::test_s09_* (aucun contexte de B ne cite A, appel de B vers A refusé, identifiants de B refusés sur le domaine de A) |
| S10 | DID entrant d'un opérateur autorisé | exécuté | test_telephony_e2e.py::test_s10_* |
| S11 | DID inconnu (404), hôte hors trunk_hosts refusé | exécuté | test_telephony_e2e.py::test_s11_*, test_telephony_e2e_edge.py::test_s11_* |
| S12 | SVI : DTMF vers une file, délai, choix invalide | exécuté | test_telephony_e2e.py::test_s12_* (option 1 vers la file, choix invalide vers 1001) ; sortie sur délai prouvée par test_s14_* |
| S13 | File servie par un poste membre | exécuté | test_telephony_e2e.py::test_s13_* |
| S14 | Messagerie sur non-réponse, compteur AMI | exécuté | test_telephony_e2e.py::test_s14_* (MailboxCount, fichier msg0000 dans INBOX) |
| S15 | Conférence, code PIN | exécuté | test_telephony_e2e.py::test_s15_* (deux appelants admis, mauvais code refusé) |
| S16 | Enregistrement, stockage objet, URL signée | exécuté | test_telephony_e2e.py::test_s16_s17_* : fichier MixMonitor listé par ARI, rangé dans SeaweedFS (indexé par media.sweep, voir l'anomalie 8), URL signée de 300 s, signature falsifiée refusée, autre tenant refusé |
| S17 | CDR et historique depuis Cdr et CEL | exécuté | test_telephony_e2e.py::test_s16_s17_* (flux AMI de tel-calls : appel entrant, ANSWERED, poste 1002) |
| S18 | Appel national par trunk, bascule | exécuté | test_telephony_e2e.py::test_s18_* (numéro présenté du trunk, 503 du principal puis trunk de secours) |
| S19 | International refusé sans permission | exécuté | test_telephony_e2e.py::test_s19_* |
| S20 | Préfixe surtaxé bloqué par le quota | exécuté | test_telephony_e2e.py::test_s20_* |
| S21 | Durée maximale d'appel | exécuté | test_telephony_e2e.py::test_s21_* (BYE d'Asterisk après 60 s) |
| S22 | Limite CPS par tenant (pipelimit) | exécuté | test_telephony_e2e.py::test_s22_* (rafale au-delà de la limite du tenant refusée en 503, après la correction de l'anomalie 7) |
| S23 | Appels simultanés par tenant | exécuté | test_telephony_e2e.py::test_s23_* (486 « Tenant call limit ») |
| S24 | Anti-flood (pike) | exécuté | test_telephony_e2e_edge.py::test_s24_* |
| S25 | Anti-bruteforce (ipban) | exécuté | test_telephony_e2e_edge.py::test_s25_* |
| S26 | Versions : v2 puis retour à v1 | exécuté | test_telephony_e2e_dedicated.py::test_s26_* (fichiers du nœud égaux à ceux de v1) |
| S27 | Panne et drain d'un nœud | exécuté (tel-ha) | test_telephony_ha_real.py::test_3_4_5_loss_of_a_node_and_its_return, test_6_drain_of_a_node, test_6b_drain_with_the_disabled_state_holds ; le drain de Navin Enterprise envoie l'état d (désactivé, ni choisi ni sondé), car l'état i était remis actif par les sondes OPTIONS après 15 s |
| S28 | WebRTC : identifiants éphémères, REGISTER en WSS | exécuté | test_telephony_e2e.py::test_s28_* (identifiants du Control Plane acceptés en WSS, mauvais identifiants refusés, après la correction de l'anomalie 9 ; le média n'est pas testé) |
| S29 | Webhook call.ended et blocage fraude | exécuté | call.ended prouvé par test_s16_s17_* ; test_s29_* : blocage écrit dans tenant_blocks et appel du poste bloqué refusé, après la correction de l'anomalie 3 |
| S30 | Appel LiveKit SIP vers un agent vocal | bloqué | livekit/sip ne publie aucun binaire (releases GitHub vides, tags jusqu'à v1.22.0), seulement une image de conteneur ; la compilation demande libopus, libopusfile et libsoxr (paquets système, root) ; pas de moteur de conteneur ici. Prouvé ailleurs : services/voice-agent/tests/test_registration_real.py, test_telephony_calls.py::test_livekit_webhook_and_voice_worker_contract (faux serveur Twirp) |
| S31 | Transfert d'un appel IA vers un humain | bloqué | même raison que S30 ; TransferSIPParticipant prouvé contre un faux serveur Twirp dans test_telephony_calls.py |
Anomalies trouvées
- Publication AMI impossible sur un vrai Asterisk (UpdateConfig n'ajoute rien à une catégorie gabarit). Corrigé par tel-sipfix : AOR sans gabarit.
- Postes identifiés comme
navin-kamailio: REGISTER refusé en 403. Corrigé par tel-sipfix : en-têteX-Navin-Endpoint,endpoint_identifier_order = header,ip,username,anonymous. - Table
tenant_blocksabsente du Kamailio rendu :htable.setsrépond « HTTP 500 », un blocage fraude n'atteint pas la périphérie. Corrigé : table déclarée (répliquée par DMQ en ha) et vérifiée dansroute[FROM_PHONE], 403 pour un tenant ou un poste bloqué ;route[FRAUD_BLOCK]refuse aussi en 403 les appels des opérateurs vers un tenant bloqué et ceux de son PBX vers un opérateur (UUID deX-Navin-Tenantramené au tid), avant tout relais ; supprimer la clé rétablit les appels (navin-manager/server/tests/test_kamailio_real.py::test_fraud_blocks_refuse_the_calls_of_the_tenant_until_lifted, Kamailio 5.7.4 et 6.0.8). rewrite_contact = yesderrière Kamailio : le contact devenait l'adresse de la périphérie. Corrigé par tel-sipfix.- Route préchargée vers la périphérie (Path) refusée par
route[FROM_INTERNAL](loose_routevaut faux pour une requête initiale). Corrigé par tel-sipfix. - Doublon
navin-rejectentre le Manager et le compilateur. Corrigé par tel-sipfix. pl_check(...) < 0dansroute[LIMITS]n'est jamais vrai : la limite CPS ne refuse rien (8 INVITE en rafale pour une limite de 3, tous relayés). Corrigé :if (!pl_check(...)), un code négatif valant faux.apps = alldanscel.conf.j2: Asterisk 20 n'accepte plusall, aucun événement CEL APP_START n'est émis, l'enregistrement n'est pas annoncé à l'ingestion. Corrigé : liste explicite des applications (mixmonitor, queue, dial, playback, background, voicemail, confbridge, stasis). Le test S16 passe toujours parmedia.sweep; l'annonce par APP_START n'est pas encore prouvée par un test.- Mot de passe WebRTC signé en HMAC-SHA1 par le Control Plane alors que le Manager règle
sha_algorithmsur SHA256 par défaut : REGISTER refusé. Corrigé : réglageEAI_TELEPHONY_EPHEMERAL_ALGORITHM(sha256 par défaut), à aligner sur le paramètreephemeral_algorithmdu service kamailio. - Les écoutes TLS de Kamailio refusent les poignées de main pendant les premières secondes : le banc attend une réponse JSONRPC avant de commencer.