mardi 14 mai 2013

Niveaux de Gravité d'une Erreur : Peuvent-ils (doivent-ils) être standardisés ?

Traduction d'un article de Conrad Weisert "Error Severity Levels".

Contexte: les conventions du système d'exploitation

Je viens de lire une longue discussion sur Linked-In sur les niveaux de gravité d'erreur dans un programme, et j'ai été frappé par le sentiment d'une redécouverte des techniques que nous utilisions il y a déjà quelques décennies. Je ne connais pas de livre traitant cette question de manière approfondie, alors permettez-moi d'essayer de commencer. D'abord étudions un peu l'histoire:

1959 : Système d'exploitation de second génération (709-7090)
Le système d'exploitation SHARE (SHARE Operating System - SOS) introduit la notion de niveaux de gravité. Une expression de contrôle d'un batch pouvait spécifier :

- GOIF : Execute uniquement si aucune erreur ou avertissement n'a eu lieu,
- GO : Execute si aucune erreur sérieuse a eu lieu,
- GOGOGO1 : Execute quoi qu'il en soit.

Certains programmes SOS n'observèrent pas ces conventions et certaines installations 709-7090 n'utilisaient pas SOS, mais cette convention inspira les fonctionnalités plus générales des systèmes suivant.

SOS etablit aussi la notion d'interception d'évènements anormaux sous le contrôle du programme, ce qui amena à la gestion des conditions de PL/I, qui à son tour inspira le traitement des exceptions des langages de programmation de la famille C d'aujourd'hui.

1965 : Système d'exploitation de troisième génération
OS/360 systématisa la notion de code de condition applicables à des travaux par lot (batch jobs) de plusieurs étape. Des conventions pour des niveaux de gravité numériques étaient observées par tous les processus système et programmes utilisateurs. Chaque étape d'un job fixait un code retour qui des étapes suivantes peuvent tester avec le Job Control Language (JCL):

00 Aucune erreur n'a eu lieu.
04 Une condition de niveau d'avertissement (trivial) a eu lieu, continuez le traitement,
08 Une erreur sérieuse a eu lieu, supprimez les étapes suivantes dans ce job,
12 Une erreur fatale a eu lieu, terminez l'exécution de ce job immédiatement !

Les codes et ces actions étaient, bien sûr, uniquement des conventions. Vous pouviez mettre en place un job pour faire tout ce que vous vouliez pour n'importe quelle valeur de retour, tant que le programme ne faisait pas ABEND.2


Conventions de programmation

Certaines applications ont étendu les conventions OS/360, en particulier dans le cas des programmes de traitement des transactions. Notre propre entreprise et plusieurs de nos clients ont adopté les conventions suivantes et ont développé une sous-routine standard pour émettre des messages d'erreur de diagnostic, d'abord en PL/I, plus tard en COBOL, et finalement, avec les adaptations nécessaires, en C++ et Java:

1. Lorsqu'il rencontre une erreur, le programme fait un
    CALL SYSERR (lvl, msg);
où le texte de msg suivait la convention demandant à commencer par un identifiant3 qui contenait le nom de la routine d'exécution de l'appel, et le code lvl était un équivalent symbolique d'un des codes conventionnels de retour de JCL.

2. À la fin du programme, une routine de sortie fixait le code de retour OS à la valeur la plus élevée rencontrée pendant l'exécution.

3. Une limite, que le programme pouvait outrepasser, définissait le nombre maximum d'erreurs autorisées pendant l'exécution. Lorsque ce nombre est dépassé, le programme prend fin. Cette fonction est utile pour empêcher un programme hors-contrôle de générer des centaines de pages de sortie incohérentes (par exemple si l'on a accidentellement fourni un programme source à un autre programme attendant un fichier de transactions).

Il y avait d'autres fonctionnalités, mais vous voyez l'idée. Les programmeurs appréciaient l'aide de cette routine, et elle est toujours utilisé dans presque tous les programmes développés dans ces organisations.4

D'autres améliorations évidentes étaient nécessaires pour supporter les programmes multi-thread. Quand une sous-tâche devrait être autorisée à terminer la tâche principale et comment?

D'autres idées?


Faites-nous savoir si vous avez développé ou si vous connaissez une meilleure façon de gérer les erreurs découvertes par les programmes, les messages de diagnostic, et les niveaux de gravité. Quels standard, le cas échéant, seriez-vous prêt à utiliser?

 

1—Dave Farber de Bell Telephone Laboratories appelait ce niveau "GO DAMMIT!" a une conférence SHARE.
2-ABnormal END (fin anormale) : l'action la plus radicale quand une continuation du traitement pourrait causer des dégâts considérables. (En fait, les versions suivantes de l'OS supportaient l'exécution conditionnelle d'étape même si une ABEND a eu lieu, mais les programmeurs prudents évitaient ça).
3-Dans certains langages de programmation cet identifiant peut être généré automatiquement, mais dans la plupart des languages, c'était juste une convention que les programmeurs étaient tenus de se conformer. Cela évitait aux utilisateurs la frustration ressentie lorsqu'ils reçoivent un message mystérieux de, disons, Windows®, indiquant que "le programme spécifié ne peux pas ...".
4- Si vous souhaitez une copie nous contacter à cweisert@acm.org et dites nous pour quel langage et environnement vous en avez besoin.

samedi 16 mars 2013

Linux : Jenkins en tant que service lancé au démarrage, stoppé à l'arrêt de la machine

Voici mon script de gestion d'un service Jenkins sous linux (debian) pour maitriser entièrement mon serveur d'intégration local.

Tout d'abord, j'ai créé un utilisateur cijenkins dans un groupe ciserver. Ensuite j'ai créé un répertoire /var/run/jenkins pour recevoir le fichier jenkins.pid contenant le pid du process de jenkins. Ce pid servira au script du service de savoir quel process terminer. Bien sûr, faites un petit chown cijenkins:ciserver /var/run/jenkins

Ensuite j'ai aussi créé le répertoire /var/log/jenkins qui recevra le fichier de log en cours jenkins.log. De même, faites un petit chown cijenkins:ciserver /var/log/jenkins J'ai ensuite créé le fichier /etc/init.d/jenkins (avec un petit chmod 755 dessus) :

#! /bin/sh
# /etc/init.d/jenkins
#

# Some things that run always
touch /var/lock/jenkins

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting script jenkins "
    start-stop-daemon -b --start --oknodo --user cijenkins --group ciserver --pidfile /var/run/jenkins/jenkins.pid --chuid cijenkins:ciserver --make-pidfile --exec /bin/bash -- -c "exec /usr/bin/java -jar /opt/jenkins-1.505.war &>> /var/log/jenkins/jenkins.log"
    ;;
  stop)
    echo "Stopping script jenkins"
    start-stop-daemon --stop --oknodo --user cijenkins --group ciserver --name java --pidfile /var/run/jenkins/jenkins.pid --retry=TERM/30/KILL/5
    ;;
  *)
    echo "Usage: /etc/init.d/jenkins {start|stop}"
    exit 1
    ;;
esac

exit 0

Comme on le voit dans ce script on peut démarrer ou arrêter le service jenkins par l'option start ou stop. Le script permet d'écrire la sortie standard vers le fichier de log ainsi que de démarrer le service avec un utilisateur différent (ce script est lancé par root).

Si vous souhaitez lancer ce script au démarrage et à l'arrêt de votre PC il faut créer les liens dans le système d'initialisation de linux : update-rc.d jenkins defaults Plus de détail dans cet article.

Ensuite, vous pouvez vous amuser à configurer votre jenkins pour prendre en charge vos développements, notamment les développements python.

vendredi 15 février 2013

Scene.org Awards, c'est fini...

Un message laconique nous informe de la fin des Scene.org Awards, récompensant les meilleures démos :
The Scene.org Awards project has found its conclusion at Assembly in 2012 and is not continued any further. The past ten years have been an amazing time for the Demoscene, and we sincerely hope that the Scene.org Awards have done their part in recognizing and honoring the unparalleled talent that we have in the community. A big thank you to everyone who's been part of this - keep on demoing!
Scene.org fourni le plus grand répertoire de fichiers de la scène démo. Fondé en 1996, le site héberge environ 600 GB of données liées à la démoscene et est sponsorisé entre autre par Pixar (excusez du peu !). Heureusement toutes ces données restent accessibles en tant qu'archive. Une page se tourne, peut-être que l'époque de la scène démo est définitivement fermée...




samedi 22 décembre 2012

Emacs et Python : flymake pour vérifier le votre code en arrière plan avec pylint, pep8 et pyflakes

Cet article fait suite au premier article sur le sujet Emacs et Python : mon environnement de développement avec virtualenv.

Flymake va permettre de vérifier en arrière plan la validité de votre code ainsi que le respect de bonne pratiques. Les outils réalisant cette analyse sont pylint, pep8 et pyflakes. Flymake fait partie de la distribution standard de emacs et va appeler ces outils pour mettre en exergue les éventuelles erreurs dans votre code.


Tout d'abord, installez pylint, pep8 et pyflakes en utilisant l'outil d'installation pip (cet outil est installé par défaut à la création de votre environnement virtuel virtualenv) : dans une fenêtre shell (ou DOS) activez votre environnement virtuel python si ce n'est pas déjà fait et faites:
pip install pylint
pip install pep8
pip install pyflakes
Ces trois outils vont être appelés par un script shell (ou batch sous windows) unique : pycheckers (ou pycheckers.bat sous windows). C'est celui-ci qui sera appelé par flymakes.

Sous linux, créez un script pycheckers avec les droits d'exécution :
#!/bin/sh
cd /
filename=`readlink -f $*`
pylint -f parseable -r n $filename
pep8 $filename
pyflakes $filename
Sous windows, créez un batch pycheckers.bat :
@@echo off
pylint -f parseable -r n -i y %* | sed -r "s/\\/\//g"
pep8 %*
pyflakes %* | sed -r "s/\\/\//g"
exit /b 0
L'appel à l'outil sed permet de remettre d'aplomb les / du chemin complet des fichiers analysés pour que Flymake n'est pas de problème pour faire correspondre les erreurs aux fichiers ouverts dans Emacs. Sous linux, copiez pycheckers sous monenv/bin , sous windows copiez pycheckers.bat dans monenv\Scripts. Dans votre .emacs, mettre la configuration flymake suivante:
(when (load "flymake" t)
  (defun flymake-pyflakes-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-with-folder-structure))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "pycheckers"  (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pyflakes-init flymake-simple-cleanup)))

(add-hook 'python-mode-hook 'flymake-mode)
Relancez votre Emacs à partir d'un shell où votre environnement python a été activé : sous linux : nohup emacs > /dev/null 2>&1 et sous windows: start /B emacs

Et voilà, lors de l'édition de programme python (.py) flymake-mode sera automatiquement démarré et fera appel à pycheckers à chaque fois que vous aurez modifié votre code source. Flymake surlignera les lignes où des erreurs ont été reportées par les outils pylint, pep8 et pyflakes. Lisez la documentation flymake pour connaitre l'ensemble de ce qui peut être fait avec cet outil.

mercredi 5 décembre 2012

Emacs et Python : mon environnement de développement sous Windows et Linux avec virtualenv

J'ai passé du temps à peaufiner mon environnement de développement Python sous Emacs, histoire d'être le plus productif possible. Je vais essayer de résumer dans ce billet et les suivants l'ensemble des actions à mener pour configurer Emacs et avoir à disposition l'ensemble des fonctionnalités qu'on est en droit d'attendre d'un IDE moderne. J'ai testé cette configuration sous linux et windows ce qui n'est pas rien car, parfois, la configuration est bien différente. Tout d'abord, voici en gros l'architecture logicielle de cette solution de développement :

- Emacs 23 ou 24 : votre éditeur de texte préféré
- Python 2.6 ou 2.7 mais pas python 3 (et oui, je n'ai pas eu encore le temps de comparer les différentes opérations à mener pour être aussi compatible python 3)
- virtualenv : un outil pour définir des environnements python séparés, très pratique pour avoir des configurations différentes entre les projets
- pylint, pep8 et pyflakes : outils python que nous utiliserons pour faire de l'analyse statique du code en arrière plan dans Emacs via flymake.
- rope, ropemode, ropemacs et pymacs : outils python de refactoring, utilisés aussi pour faire de la "completion" (compléter automatiquement lors de la frappe)
- gnuwin32 : c'est la majorité des outils GNU compilés nativement pour windows. Ils serviront sous windows à corriger certains petits problèmes.
- auto-complete : mode emacs pour compléter les termes lors de la frappe,
- flymake : pour faire de l'analyse statique en arrière plan du code en cours de frappe,
- eldoc : mode emacs pour avoir dans le minibuffer, la signature de la fonction en cours de frappe.


Installation d'emacs

Télécharger la dernière version de Emacs 24 ou 23 et dézipper la : sous windows, prendre la version binaire; sous linux : prendre les sources et recompiler.

Pour information, sous debian, il y a une version emacs 23 qui marche très bien, installez là directement via le "gestionnaire de paquet Synaptic".

S'assurer que l'exécutable "emacs" est dans le PATH et que vous pouvez l'appeler directement à partir de votre invite shell.


Installation de python

Téléchargez python 2.6 ou 2.7 et installez le.

Sous windows, pas la peine de mettre ensuite le répertoire python dans le PATH (on utilisera virtualenv pour "activer" une certaine version de python)


Sous windows : installation de gnuwin32

Gnuwin32 est un ensemble d'outils GNU compilés nativement pour Windows. Ces outils vont nous rendre la vie plus facile sous Windows, car de part sa nature, Emacs s'intègre bien mieux à son environnement quand quelques outils GNU de base sont disponibles.

Téléchargez l'outil de téléchargement des outils gnuwin32 puis avec cet outil, installez tous les outils gnuwin32, puis mettre le répertoire /bin dans la variable PATH.


Installation d'un environnement virtualenv

Télécharger la dernière version de virtualenv.py puis créez votre nouvel environnement virtualenv avec l'instruction suivante :

python ./virtualenv.py monenv

Cela crée un répertoire monenv correspondant à votre environnement virtuel python. A l'intérieur ont été recopié les exécutables python (le même python qui a été utilisé dans la commande précédente) ainsi qu'un sous ensemble de la bibliothèque standard nécessaire pour initier l'environnement virtuel. Il faut ensuite "activer" votre environnement virtuel en invoquant la commande suivante: sous linux :

. ./monenv/bin/activate

sous windows :

.\monenv\Scripts\activate

Vous pouvez voir que votre environnement virtuel est activé sur votre invite de commande qui a du changer d'aspect et doit maintenant indiquer entre parenthèse le nom de l'environnement virtuel actif.

Faites un which python (même sous windows, grâce à gnuwin32 !) pour voir que vous utilisez bien le python (ou python.exe) de votre environnement virtuel et pas le python global. Il est à noter qu'on ne retrouve pas toutes les libraries standard python dans monenv/lib (monenv\Lib sous windows), et lors de l'exécution de python, le répertoire des librairies standards de l'installation globale se retrouve aussi dans le sys.path python, comme le prouve ces quelques lignes :

(monenv) F:\jrx\src\jrxemacs>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib\\site-packages\\setuptools-0.6c11-py2.7.egg', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib\\site-packages\\pip-1.2.1-py2.7.egg', 'C:\\WINDOWS\\system32\\python27.zip', 'F:\\jrx\\src\\virtualenvs\\monenv\\DLLs', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib\\plat-win', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib\\lib-tk', 'F:\\jrx\\src\\virtualenvs\\monenv\\Scripts', 'c:\\soft\\python-2.7\\Lib', 'c:\\soft\\python-2.7\\DLLs', 'c:\\soft\\python-2.7\\Lib\\lib-tk', 'F:\\jrx\\src\\virtualenvs\\monenv', 'F:\\jrx\\src\\virtualenvs\\monenv\\lib\\site-packages']
>>>

L'intérêt de virtualenv vient aussi du fait que les outils pip et easy_install sont installés automatiquement dès la création de l'environnement virtuel.

Voilà, nous avons ici les bases de l'installation Emacs et Python pour développer. Reste à configurer Emacs pour fonctionner avec Python. Dans un prochain billet, nous verrons comment outiller cet environnement pour faire fonctionner la superbe librairie flymake de Emacs et avoir de l'analyse statique de votre code en temps réel!