Installation d’Autobahn|Testsuite sous Xubuntu

L’année dernière, dans le cadre du travail, j’ai fait une implémentation de la partie client du protocole WebSocket, décrit par la RFC 6455, pour une utilisation dans un environnement Java embarqué contraint. Au début, j’utilisais un petit serveur, écrit en Java SE,  pour avoir quelques tests simples. Quand mon implémentation à commencer à devenir mature, j’ai cherché comment tester de manière un peu plus complète ma bibliothèque et j’ai trouvé Autobahn|Testsuite. C’est une test suite automatique, écrite en Python 2 et elle est plutôt réputée pour ce protocole, à en juger par la liste affirmée des utilisateurs. Elle est en tout cas, elle est suffisamment réputée pour qu’Oracle fasse un article quand leur implémentation de référence de WebSocket en Java a atteint pour la première fois un score de 100 %. J’ai remis en branle cette test suite cette semaine car je vais me resservir de cette bibliothèque pour un nouveau projet.

Le site officiel donne une procédure d’installation qui est en apparence simple mais j’ai rencontré plusieurs problèmes en l’installant sous Xubutu. J’écris cet article pour retracer les problèmes et les solutions.

La première étape est d’installer les dépendance décrites. Python 2.7 est installé par défaut, il me suffit donc d’installer les modules pip et Twisted :

sudo apt-get install python-pip
sudo apt-get install python-twisted

On peut ensuite passer à l’installation de la test suite en elle-même. Je vous conseille de demander les droits root pour éviter des erreurs telles que error: could not create '/usr/local/lib/python2.7/dist-packages/autobahntestsuite': Permission denied. Dans le terminal :

sudo pip install autobahntestsuite>

Après des téléchargements et un peu de défilement dans la console, vous rencontrerez sans doute une erreur comme celle-ci :

wsaccel/utf8validator.c:8:22: fatal error: pyconfig.h: No such file or directory

 #include "pyconfig.h"

                      ^

compilation terminated.

error: command 'i686-linux-gnu-gcc' failed with exit status 1

Pour que l’installation réussisse, j’ai dû installé quelques paquets supplémentaires :

sudo apt-get install python-dev
sudo apt-get install libffi-dev
sudo apt-get install libssl-dev

L’installation est maintenant terminée ! Il n’y a plus qu’à lancer le test d’installation, qui vérifie que tout s’est bien installé :

$ wstest --help
Traceback (most recent call last):
  File "/usr/local/bin/wstest", line 5, in 
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2749, in 
    working_set = WorkingSet._build_master()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 444, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 725, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 628, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: characteristic>=14.0.0
$ echo $?
1

Caramba ! Encore raté ! Python ne possède pas le module characteristic ou alors il en possède une version trop ancienne. pip est la solution pour installer des modules Python :

sudo pip install characteristic

Histoire de vous faire gagner du temps, je vous annonce qu’il manque aussi d’autres modules, installez-les avant de retenter wtest :

sudo pip install pyasn1-modules
sudo pip install cryptography
sudo pip install unittest2

Finalement :

$ wstest --help && echo $?
Usage: wstest [options]
Options:
  -d, --debug            Debug output [default: off].
  -a, --autobahnversion  Print version information for Autobahn and
                         AutobahnTestSuite.
  -m, --mode=            Test mode, one of: echoserver, echoclient,
                         broadcastclient, broadcastserver, fuzzingserver,
                         fuzzingclient, testeeserver, testeeclient, massconnect,
                         serializer [required]
  -t, --testset=         Run a test set from an import test spec.
  -s, --spec=            Test specification file [required in some modes].
  -o, --outfile=         Output filename for modes that generate testdata.
  -w, --wsuri=           WebSocket URI [required in some modes].
  -u, --webport=         Web port for running an embedded HTTP Web server;
                         defaults to 8080; set to 0 to disable. [optionally used
                         in some modes: fuzzingserver, echoserver,
                         broadcastserver, wsperfmaster]. [default: 8080]
  -i, --ident=           Testee client identifier [optional for client testees].
  -k, --key=             Server private key file for secure WebSocket (WSS)
                         [required in server modes for WSS].
  -c, --cert=            Server certificate file for secure WebSocket (WSS)
                         [required in server modes for WSS].
      --version          Display Twisted version and exit.
      --help             Display this help and exit.

0

\o/

Quand j’avais réussi à faire fonctionner wtest au travail, l’aventure n’était pas vraiment terminée. J’avais fait cela sur mon PC avec Internet mais je souhaitais monter un serveur de tests sur le réseau privé non relié à Internet… Il y avait une solution !

pip install --download . autobahntestsuite

Cette commande permet de télécharger toutes les dépendances nécessaires (y compris les récalcitrants pyasn1-modules et autre characteristic…) dans le dossier courant. On peut ensuite déplacer ce dossier sur le PC non connecté à Internet et lancer une installation hors-ligne. En effet, pip est capable d’installer à partir de dépendances qu’il cherche dans le dossier précisé plutôt que d’aller les chercher dans ses dépôts habituels :

pip install --no-index --find-links="/path/to/downloaded/dependencies" packagename

Dans mon cas, les dépendances n’étaient pas super bien gérées. J’ai eu des erreurs tels que distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse('enum34') que j’ai corrigé en installant manuellement enum34 et cffi. Ces dépendances avaient pourtant bien été téléchargées mais l’installation du module autobahntestsuite n’arrivait pas à les installer toute seule.

Maintenant que tout est installé, on va quand même essayé de faire un vrai test du protocole, non ? Vous trouverez des détails sur l’utilisation de wtest sur cette page dédiée. Pour faire simple, je vais lancer un serveur de tests et je vais y connecter mon navigateur pour quel score il obtient. Le serveur se lance avec la commande suivante :

$ wstest -m fuzzingserver
Auto-generating spec file 'fuzzingserver.json'
Loading spec from /home/pgradot/fuzzingserver.json

Using Twisted reactor class 
Using UTF8 Validator class 
Using XOR Masker classes 

Autobahn WebSockets 0.7.2/0.10.9 Fuzzing Server (Port 9001)
Ok, will run 521 test cases for any clients connecting
Cases = ['1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.
...
'13.7.16', '13.7.17', '13.7.18']

La commande ne rend pas la main tant que le serveur tourne. J’ai tronqué (avec ...) la liste des 521 test cases qui sont en attente de clients. Il suffit ensuite de lancer Firefox et d’aller à l’adresse http://localhost:8080 :

autobahn start test

Vous l’aurez deviner, il suffit de cliquer sur Test your browser pour lancer le test :

autobahn test running

On voit le compteur de tests exécutés se mettre à jour sur la page. Dans le terminal, on peut voir les traces d’exécution du serveur. En voici un extrait :

Running test case ID 12.5.11 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60352
Running test case ID 12.5.12 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60353
Running test case ID 12.5.13 for agent Firefox/40.0-20100101 from peer tcp4:127.0.0.1:60354

Quand les tests sont terminés, il faut cliquer sur le bouton Update Reports (Manual) pour mettre à jour les résultats, retourner à la page précédente et afficher les résultats des tests locaux :

autobahn results

Cette version 40 de Firefox ne fait pas un score de 100 %, certains tests sur les trames de fermeture de connexion sont à « fail« . Il affiche tout de même de très bons résultats 🙂

Bons tests !

Une Réponse

  1. Pingback: OpenShift et DIY, PHP7, WebSockets, Ratchet - Context is king...

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.