mercredi 3 octobre 2012

Mise en place selenium

Ces derniers temps, on m'a demandé de mettre en place de scénario de surveillance sur une application typiquement horrible : code HTML horrible, Internet Explorer only etc.

Bref, j'ai donc commencé à vouloir faire ça en cucumber mais je me suis rapidement frotté à des problèmes mon cher concombre masqué refusant catégoriquement mes noms de formulaires fantaisiste (il faut dire qu'on trouve des dollars ('$') dedans ...).

Bien triste, j'ai commencé à chercher quelque chose d'autre qui pourrait répondre à mon besoin et je suis tombé sur selenium (http://seleniumhq.org/) et son IDE (qui est une simple extension à installer dans firefox).

J'ai commencé à faire joujou avec l'IDE et - malgré un rendu HTML catastrophique - j'ai réussi à faire un scénario de test avec Firefox.

En trifouillant un peu, j'ai vu qu'il existait un serveur selenium (un process java) et qu'il pouvait tourner dans un serveur X virtuel. Devant tant de beauté, j'ai donc commencé à mettre ça en place :D.

Pré-requis python

Comme par la suite je vais générer des scripts au format python, nous allons devoir installer la librairie python permettant de communiquer avec selenium. Ici, rien de bien compliqué, un coup de apt-get pour installer le nécessaire :

apt-get install python-pip python-dev build-essential

Maintenant que nous avons pip, nous pouvons procéder à l'installation de la librairie selenium :

pip install -U selenium

Passons maintenant à la suite (et y'a du monde !)

X11 Virtual frame buffer (miam !)

Ce cher Xvfb ! Toujours un petit moment émouvant quand je le croise ! Pour le lancer, il faut simplement utiliser la ligne de commande suivante :

DISPLAY=:1 Xvfb :1 -screen 0 1024x768x24

Bien penser à le rendre utilisable depuis n'importe où avec la commande xhost :

DISPLAY=:1 xhost +

ATTENTION : L'utilisation de xhost + va rendre le serveur X visible depuis l'extérieur !!! Il est conseillé de mettre en place un parefeu pour bloquer les accès externes.

L'installation se fait avec un apt-get install xvfb (et x11-server-utils pour disposer de l'utilitaire xhost)

Installation de Firefox

Par la suite, nous utiliserons firefox pour faire nos tests. Donc rien de bien fameux si ce n'est un apt-get install firefox (à remplacer par iceweasel si vous êtes sur Debian).

Mise en place de Selenium

On arrive enfin au coeur du sujet. Selenium est un serveur qui s'appuie sur un jar java pour se lancer. Donc de manière logique, il va vous falloir un java fonctionnel. Je vous passe les détails, vous faîtes comme vous voulez.

Récupérer ensuite la dernière version de selenium serveur sous la forme d'un JAR. Vous pouvez ensuite le lancer avec la ligne de commande suivante :

export DISPLAY=:1
java -Djava.security.egd=file:/dev/./urandom \
     -jar /path/to/jar/selenium-server-standalone-2.25.0.jar \
     -browserSessionReuse

A noter la présence de l'option -browserSessionReuse qui permet d'éviter de relancer le navigateur à chaque lancement de scénario et l'option biscornu java.security.egd qui permet de passer du device aléatoire /dev/random (qui est lent) à /dev/urandom qui lui n'utilise pas l'entropie du système pour fonctionner mais un générateur de nombre aléatoire.

Test de notre premier scénario

À l'aide de l'IDE selenium, nous avons enregistré notre scénario. Nous allons maintenant exporter ce dernier au format Python 2 / unittest / Remote Control. Voici ce à quoi ça devrait ressembler :

from selenium import selenium
import unittest, time, re

class sites(unittest.TestCase):
    def setUp(self):
        self.verificationErrors = []
        self.selenium = selenium("localhost", 4444, "*chrome", "http://monsite/")
        self.selenium.start()
    
    def test_sites(self):
        sel = self.selenium
        sel.open("/ma_page")
        sel.type("id=un_champ", "une_valeur")
        sel.type("id=un_autre_champ", "une_autre_valeur")
        sel.click("id=id_d_un_lien")
        sel.wait_for_page_to_load("30000")
    
    def tearDown(self):
        self.selenium.stop()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()
Lançons maintenant ce beau script depuis la machine faisant tourner selenium :

python mon_scenario.py
.
----------------------------------------------------------------------
Ran 1 test in 4.051s
OK

Magnifique non ? Tout à fait mais ça ne vous dit pas ce que vous allez en faire dans votre nagios.

(Des)intégrations dans nagios/Shinken

Comment ça, vous voulez le script qui analyse la sortie de tout ça et l'insert directement dans nagios ? Je vous trouve un peu exigeant quand même !

Bon, si vous insistez ... Il faut récupérer le script check_selenium.pl et lancer ensuite la sonde de la manière suivante :

/emplacement/scripts/check_selenium.pl --script \
      /emplacement/de/mon/scenario.py  \
      --label "Le test de ma super application"

De là, vous devriez obtenir la sortie suivante :

Selenium test OK (Le test de ma super application)|time=3.180s test_count=1

Elle est pas belle la vie ?