Tous ceux qui administrent un ensemble de machines, et particulièrement des serveurs, savent à quel point le disque dur en est un élément critique, et qu'il est important de s'assurer de sa fiabilité. Il est pourtant encore difficile à l'heure actuelle d'avoir une idée précise de la fiabilité d'un disque dur, mais aussi de la fiabilité des couches logicielles qui y donnent accès, notamment le noyau, le modèle d'entrées-sortie et le système de fichier. C'est de l'ensemble de ces besoins qu'est né le projet Rugg.

La manière dont une application interagit avec le disque dur est très variable : qu'il s'agisse d'un serveur de base de données (tel que Postgresql) ou d'un serveur Web (tel que Apache), le comportement de la combinason disque/os/filesystem variera en conséquence. Il est donc important de pouvoir simuler de manière précise le comportement d'une application particulière, de manière à voir si des problèmes se manifestent, et dans un second temps, d'apprécier la performance de cette combinaison.

Rugg est donc parti avec ces objectifs en tête. Initialement constitué d'une API Python relativement simple, Rugg a rapidement évolué vers un langage de domaine, pour simplifier et rendre plus concise l'écriture de scénarios. En effet, dans Rugg, si l'on veut tester une zone de 100Go sur son disque dur, il suffit d'exécuter la ligne suivante :

$ rugg 'zone 100Go, subdivide in 2 : fill with same text, ensure same'

Et l'on peut ainsi s'assurer que la zone de 100Go testée n'est pas endommagée. Bien sûr, ce test est relativement basique, et marchera probablement chez tout le monde. Cela dit, nous avons réussi à trouver un bug important dans le module XFS pour Linux en exécutant le scénario suivant sur un serveur SuSE Linux, doté de 500Go d'espace disque en RAID:

zone 500Gb, subdivide 100 | fill same text, ensure same, blank | fill same binary, ensure same

Ce scénario alloue une zone de 500Go, et lance 100 threads qui vont écrire les mêmes données sur des portions de cette zone. Les données sont ensuite vérifiées, puis on efface le tout, et on recommence en remplissant avec les mêmes données binaires, encore vérifiées. Le serveur n'a pas résisté à ce traitement.

D'une manière générale, Rugg m'a permis de montrer l'intérêt de développer un langage de domaine plutôt que de créer une API (pour le langage Python, déjà très concis). Voici en particulier des raisons que je trouve intéressantes :

En ce qui concerne le design du langage, j'ai vraiment essayé de donner une place importante à la compacité, mais aussi à la possibilité de vérifier au maximum la cohérence d'un scénario, ce qui est rendu possible par l'utilisation d'un système de type (qui assure donc un typage statique du programme).

En tant que langage, Rugg est qualifiable de fonctionnel pur, dans le sens où le passage de valeurs se fait par paramètres, et où aucune valeur n'est directement modifiée (elles sont immuables). Les opérations de Rugg agissent comme des producteurs et des consommateurs de valeurs, ayant pour effet de bord d'agir sur le système de fichiers.

Il y a donc là un paradoxe intéressante : alors que Rugg est purement fonctionnel au niveau de son langage, son fonctionnement interne est entièrement basé sur les effets de bords. En d'autres termes, on décrit un scénario à l'aide de constructs de nature purement fonctionnelle, pour décrire un processus dont l'exécution même est l'effet de bord du programme. C'est, il me semble, essentiellement parce que Rugg est un langage déclaratif, de nature descriptive - par opposition à une nature impérative.

Voilà, je pense que pour certains il y a eu quelques passages un peu trop "jargonesques", mais peut-être que la prochaine que vous aurez à tester un disque dur ou votre serveur, vous penserez à donner un "petit coup de Rugg" !