Le process de Continuous Delivery (livraison continue) répond à plusieurs objectifs. L'un de ses objectifs est de s'assurer que l'application réponde bien aux besoins des utilisateurs. Un autre est de configurer le logiciel selon l'environnement. Pour cela, on peut utiliser un logiciel de gestion de configuration. L'objectif global est bien sûr d'amener l'application en production à condition que les tests aient été réussis.

Nous allons donc aborder ici les points clés du Continuous Delivery, à savoir l'automatisation de la préparation et de la mise à jour des différents environnements (développement, test, staging et production), l'automatisation de l'exécution des tests d'acceptance et des tests non fonctionnels et enfin la définition d'une politique de nommage des versions (versioning).


Les environnements

Tout d'abord, parlons environnement et infrastructure.

D'une manière générale, vous allez avoir besoin de quatre environnements : un pour le développement, un pour les tests d'intégration et exploratoires, un pour les tests finaux et un pour la production.

Là, on commence à comprendre tout l'intérêt des technologies du type Docker.

L'environnement de développement contient la dernière version du code source. En général, il y a un serveur partagé par l'ensemble des développeurs. C'est donc sur cet environnement que le code des différents développeurs est intégré (commit). C'est aussi sur cet environnement que les tests unitaires sont exécutés.

Une fois le code développé, il faut le tester. Cela se fait dans l'environnement de test. Cet environnement doit donc se rapprocher le plus possible de l'environnement de production et doit donc être fiable. Les testeurs vont exécuter des tests fonctionnels (d'intégration avec les systèmes externes et tests exploratoires).

Une fois l'application testée, elle est considérée comme release candidate. La release peut être stockée dans le repository d'artefacts. Autrement dit, c'est potentiellement une version qui va aller en production. Cette application est testée dans l'environnement de staging. Cet environnement doit donc, en toute logique, se rapprocher le plus possible de l'environnement de production, y compris la localisation en plusieurs endroits. Les tests d'acceptance (UAT) et les tests non fonctionnels sont exécutés dans cet environnement.

Une fois la release candidate testée et validée, elle va être déployée dans l'environnement de production. C'est celui qui est utilisé par l'utilisateur final.

Il existe à ce jour des outils très performants pour prendre en charge le déploiement, y compris la mise en oeuvre de cluster : Ansible, Docker, Docker Compose, Docker Swarm, Kubernetes, ...

Un petit mot sur les performances des sites Web : les temps de réponse diffèrent selon l'emplacement géographique. Une solution peut donc de déployer l'application Web dans différents endroits physiques. Il suffit alors d'utiliser un load balancer géographique pour choisir le serveur à utiliser.

Le passage d'un environnement à l'autre se fait de la manière suivante :

  • Le déploiement du code dans l'environnement de développement peut se faire par exemple lors de chaque commit.
  • Le déploiement dans l'environnement de test peut éventuellement se faire en même temps, mais il peut aussi se faire manuellement.
  • Le déploiement en environnement de staging se fait une fois les tests menés en environnement de test sont réussis.
  • Le déploiement en environnement de production se fait logiquement une fois les tests d'acceptance et les non fonctionnels réussis.

Les tests non fonctionnels

Il existe de nombreux types de tests non fonctionnels. Le choix des tests change selon votre projet.

Certains peuvent être exécutés dans le process de Continuous Delivery, d'autres en dehors.

Les tests intégrés dans le Continuous Delivery peuvent ainsi être exécutés de manière réellement continue dans la chaîne, tandis que les autres peuvent être exécutés la nuit (nightly build) et analysés hebdomadairement pour analyser la tendance.

Les tests non fonctionnels intégrés dans le Continuous Delivery

Lest tests de performance mesurent la measure la réactivité et la stabilité du système. Les tests de performance comprennent :

  • les tests de montée en charge,
  • les tests de stress,
  • les tests d'évolutivité.

L'unité de mesure est le temps RTT (round-trip time). La release candidate est rejetée si le RTT est supérieur à une valeur maximale.

Les tests de montée en charge vérifient le bon fonctionnement de l'application lorsqu'il y a de nombreux accès concurrents. Concrètement, on simule un certain nombre d'utilisateurs en utilisant plusieurs machines et on vérifie la latence, c'est-à-dire le temps de réponse. La release candidate est rejetée si la latence dépasse une valeur maximale.

Les tests de stress (ou tests de capacité) permettent de déterminer le nombre d'utilisateurs concurrents que le système peut supporter sans dépasser une latence maximale, c'est-à-dire un temps de réponse. Ce nombre d'utilisateur concurrents maximum est utile pour se préparer aux périodes de pic d'usage du système. Ce test étant long, il est en général lancé hors process du Continuous Delivery, à la demande donc.

Les tests de sécurité permettent de tester la sécurité proprement dite et la protection des données. Ils comprennent deux types de tests : les tests de sécurité fonctionnels (comme le test de l'authentification, les autorisations, les rôles, ...) et les tests de sécurité non fonctionnels (comme la protection contre l'injection SQL). Ces tests peuvent figurer dans le process de Continuous Delivery, mais peuvent aussi être exécutés de manière exploratoire.

Les tests non fonctionnels non intégrés dans le Continuous Delivery

Les tests d'évolutivité permettent d'étudier la variation de la latence quand on ajouter des serveurs. Ils permettent d'identifier les limites du système. Tout comme les tests de stress, ils sont longs et devraient donc être lancés hors process du Continuous Delivery.

Les tests d'endurance (ou tests de longétivité) permettent de vérifier que les performances du système ne s'écroulent pas avec le temps à cause de fuites mémoire ou de problèmes de stabilité. Ce test devrait lui aussi être exécuté hors Continuous Delivery.

Les tests de maintenabilité permettent de s'assurer que le code est maintenable, par exemple en utilisant l'analyse statique ou le taux de couverture de test. Ces tests peuvent déjà être exécutés lors des commits par exemple, mais devraient être intégrés dans le Continuous Delivery.

Les tests de reprise (recovery) permettent de déterminer le temps pour remettre en état opérationnel un système après une panne logicielle ou matérielle.

Les tests d'internationalisation permettent de vérifier que l'application s'adapte à la langue et à la culture étrangère des utilisateurs (textes, format de saisie des données, devise, ...).

Les tests d'usability peuvent être exécutés avant d'arriver dans l'environnement de production. Mais idéalement, une release beta pourrait être transmise à certains utilisateurs. Cette release pourrait être modifiée pour intégrer les feedbacks de ces utilisateurs. Cela suppose par contre un délai de génération de release beta très rapide. Les efforts de test peuvent alors être limités.

La politique de versioning

Il existe plusieurs politiques possibles de versioning des applications. Les plus simples sont d'utiliser un numéro séquentiel ou un nom basé sur la date et heure (timestamp) de la build.

La méthode préconisée est d'utiliser un versioning sémantique. Ce format prend la forme "x.y.z", avec :

  • "x" est le numéro de version majeure
  • "y" est le numéro de version mineur
  • "z" est le numéro de build

Si seule la version mineur change, alors l'application doit être rétrocompatible; mais si la version majeure change, ce n'est pas nécessaire.


 

Le Continuous Delivery (CD) se situe après le Continuous Integration (CI). Si le Continuous Integration est la partie la première mise en place, le Continus Delivery n'en reste pas moins capital. Il existe aujourd'hui de nombreux outils pour automatiser les tâches : Docker, Docker Swarm, Docker Compose, Kubernetes, Ansible, ... Jenkins permet de définir des pipelines qui vont automatiser ces tâches via des scripts et d'utiliser les outils tels que Docker ou Ansible.

 


Pensées pour mieux produire

Soyez prévenu dès que mon livre "Pensées pour mieux produire" sera disponible à la vente !

DevOps, Agile, Scrum, Kanban, XP, SAFe, LeSS, Lean Startup, Lean UX, Design Thinking, Craftmanship, Management 3.0, ...

 

Bruno Delb

Agile Coach and DevOps, with an experience in the Medical Device software domain, Management 3.0, Agile games and development (especially on mobile) are my passion.

Search

Ads