Archives pour la catégorie Intégration logicielle

De la qualité naît la satiété

Les techniques de néo-management en vogue depuis les années 80 cherchent à tout prix à faire du personnel une ressource comme les autres. C’est-à-dire que les travailleurs doivent être aussi souples et interchangeables qu’une gomme ou un boulon. Dans le domaine du développement logiciel, une méthode pour arriver à cet objectif discutable est de focaliser le travail des développeurs non plus sur le produit demandé par le client, mais sur l’outil de production qui permettra effectivement de satisfaire le client mais aussi les prochains, et à moins cher que si cet outil n’existait pas (mais facturé autant, bien entendu) Ainsi, on n’a besoin de moins en moins d’experts techniques et de plus en plus de travailleurs moins qualifiés pour un produit de qualité équivalente. C’est le progrès, et bien logique. Un compilateur ne fait ni plus ni moins que ça : il génère du code assembleur que peu maîtrisent à partir d’un langage plus facile d’accès, et donc pour lequel on trouvera plus de main d’oeuvre moins essentielle.

L’intéressant là-dedans, est de voir la communication associée du middle management (Petits Chefs en français) pour justifier des dépassements financiers ou le génie dont a su faire preuve l’entreprise. Enfin, plutôt dont ils ont su faire preuve, quand on les écoute. La métrique fondamentale, c’est le nombre de lignes de code générées.  Plus il y en a, mieux c’est. Forcément : l’investissement dans le coût de développement de l’outil de génération est d’autant mieux amorti qu’on s’en sert beaucoup. Et cela rend encore plus judicieux l’investissement initial. Toutes les lignes que l’on génère, c’est autant de lignes que l’on n’a pas à écrire à la main, donc de développeurs à payer. Générer des lignes, c’est améliorer la productivité des équipes.

Tout ceci est complètement vrai, toutes choses étant égales par ailleurs. Ce qui n’est bien entendu pas le cas ici. On oublie (volontairement) au moins une chose : la qualité du code généré n’est pas la même. Pire, elle n’est pas contrôlée sur le long terme. L’architecte a prévu un schéma de génération, qui se défend totalement lors des premiers usages de l’outil. Plus le projet avance, plus il y a de choses à faire entrer dans le générateur, et donc il en sort de plus en plus de code. Peut-être que le schéma de génération initial ne s’applique plus quand on génère trois fois plus de code qu’initialement prévu ? Tout le monde s’en moque. Je dirais même qu’il ne vaudrait mieux pas que ça se sache. Ça fait déjà quatre mois qu’on dit générer 85% du code, on va pas faire s’effondrer cette métrique en dépensant des sous qui plus est ! Et l’équipe serait mécaniquement moins productive. Non, non et non, le schéma de génération, aussi mauvais soit-il devenu, ne doit pas être amélioré.

Aussi malhonnêtes soient-ils, je n’ai jamais vu aucun Petit Chef demander à ce que l’on dégrade encore plus le schéma de génération pour générer 200 lignes quand on en générait 100. Pourtant cette stratégie ferait clairement leur beurre. Mais sont-ils simplement capables d’avoir cette (une ?) idée ?

Tags:

Patience menée à bout se tourne en fureur

Ha ! la douce joie de l’informatique embarquée ! S’il est une chose qui constitue indéniablement un régal de fin gourmet, c’est bien la phase de test d’un projet d’informatique embarquée, comprenez ici « un logiciel approximatif qui tourne sur du matériel obsolète ». Le test est le moment d’assister à nouveau à une bonne pièce de théâtre, un classique parmi les classiques, dont vous connaissez tous les enchaînements, mais pour autant, on ne s’en lasse pas. Allez savoir ? Peut-être que cette fois, le jeu des acteurs sera légèrement différent, l’interprétation des didascalies plus libre ?

Plantons le décor pour ceux qui n’ont jamais vu la pièce : un gros projet industriel, avec au moins une soixantaine de développeurs. Le matériel est une boîte en laiton avec des circuits en graphène et un processeur quantique multicore de l’entre-deux guerres, on ne va pas pouvoir en acheter beaucoup. Comme il va falloir faire plein de tests mensongers rapidement, on ne va pas attendre que les soixante développeurs aient accès à ce Graal technologique. C’est parti pour faire des tests sur simulateur ! Il est bien entendu hors de question d’acheter autant de licences (hors de prix) du simulateur du matériel exotique sur lequel devra tourner ce nouveau projet. Le Régent fait l’aumône au Chef de quelques piècettes pour en installer cinq sur des postes dédiés. Cinq moyens de test non représentatifs, c’est toujours moins cher qu’un matériel cible de toute façon non encore stabilisé.

Acte I : Jusqu’ici, tout va bien

Par le jeu des indisponibilités synchronisées des documents de spécification, peu de développeurs avancent, et les rares qui ont réussi à coder quelque chose ne se bousculent pas pour tester. Il faut les comprendre : au début, il ne s’agit pas tant de tester leur code sur le simulateur que de déverminer l’environnement de test multi-paradigme ultra-bancal.

Cependant, doucement mais sûrement, chacun décide de cacher sa flemmardise derrière son impossibilité à avoir accès au moyen de test. C’est bien la seule raison valable pour ne corriger aucun des bogues détectés jusqu’ici (et comment, d’ailleurs ?)

Acte II : Organisons le chaos, ou l’explosion nucléaire

Qu’à cela ne tienne, le processus-roi vient à notre rescousse ! Une bonne âme (autrement dénomée Couillon Sidéral par tout le reste de l’équipe) va être désignée volontaire pour produire une planification hebdomadaire. Chacun mél-bombera sa boîte à lettres de son besoin pour la semaine suivante, de préférence en huit exemplaires successifs contradictoires, et, grâce à un tableur de qualité (autrement appelé Boulier Numérique) le Couillon Sidéral tentera de répondre au mieux au besoin de tous.

Comme l’entreprise est ouverte de 8h du matin à 20h le soir, le Couillon Sidéral décide d’occuper toute cette plage horaire pour organiser l’accès aux moyens de test, et là, magie ! la demande de chacun est satisfaite. Tous les bogues vont pouvoir être corrigés rapidement, et le client satisfait. Le Chef est félicité, le Régent augmenté.

Acte III : Vers l’infini et au-delà, où la sonde anale est bien en place

De façon assez étonnante, et malgré cette planification exemplaire, le projet continue de prendre du retard, et les bogues ne sont toujours pas corrigés. Quelques voix se font entendre pour réclamer de travailler le samedi, ou en horaires étendus, comprendre à partir de 6h du matin et jusqu’à 22h le soir. La réponse est cinglante : « Tant que tous les créneaux bancs ne seront pas alloués, il est hors de question d’envisager de telles extrêmités ». Méphisto, le chef des sous-traitants, qui a tout à gagner à facturer du travail durant des horaires farfelus, car mieux rémunérés, adopte la stratégie du pire et réclame deux fois plus de créneaux banc qu’auparavant, sans consulter ses équipes.

Le Couillon Sidéral se trouve bien embêté : il doit faire correspondre une demande de dix bancs pour cinq disponibles. Profondément juste, il adopte une belle règle de trois, qui va pousser tous les développeurs à sur-évaluer leurs demandes pour espérer obtenir ce qu’ils auraient demandé en temps normal. Bientôt le Couillon Sidéral doit gérer quinze bancs virtuels, puis vingt, etc. Le Régent refuse obstinément d’acheter de nouvelles licences pour des moyens de test supplémentaires. Mais le projet n’avance toujours pas.

Le Chef adapte alors sa réponse aux demandes incessantes de travail en horaires étendus/décalés/esclavagistes : « Tant que tous les créneaux bancs ne seront pas occupés, il est hors de question d’envisager de telles extrêmités ». Car le Chef a bien constaté que les bancs de test ne sont occupés que de 10h à 11h30, après le café et avant le repas, puis de 14h30 à 16h. Il semblerait que les développeurs aient aussi d’autres problèmes, certains parlent même d’une hypothétique vie sociale, ce qui est regrettable, intolérable, et fort dommageable pour le projet. Le Chef est dé-félicité. Le Régent récupère son bureau pour y faire installer un buste à sa gloire offert par la Direction Financière.

Acte IV : La débâcle

Méphisto motive ses équipes en leur faisant miroiter des bons-cadeaux Régali et des perspectives d’évolution de carrière insoutenables. Les plus jeunes développeurs se font avoir, mais respectent leur engagement en arrivant à 9h45 et en repartant à 16h03 ; qui sait combien vaut leur âme en bons-cadeaux ?

Dénouement

La démotivation est patente, le projet est fichu, mais officiellement ce n’est la faute de personne :

  • Le Chef a alerté depuis longtemps sa hiérarchie sur l’inadéquation entre les 800 bancs de test nécessaires pour ses 60 développeurs et les 5 malheureuses licences qu’il avait à disposition. Les données collectées par le Couillon Sidéral sont sans appel ;
  • Le Régent a brillament réussi à tenir les coûts, il est donc bombardé auprès du Roi pour déployer plus largement tout l’éventail de ses compétences ;
  • Les développeurs ont montré leur bonne foi en proposant de s’immoler par le feu en offrande à Râ si ça pouvait faire avancer le projet.

Méphisto, lui, propose de nouvelles missions à ses développeurs à 250 km de là. Ils n’ont qu’à faire comme lui ; s’acheter une nouvelle voiture. Malheureusement, Régali n’en fait pas.

Tags: ,

Trois points d’appuis suffisent à un bon équilibre

L’entropie est une notion sympathique. Il y en a partout, puisque la nature a horreur du vide. C’est donc tout naturellement qu’on en trouve plein la boîte crânienne des architectes, qui manquent systématiquement une occasion de se taire. Petit cas concret.

Un logiciel a été commandé par le client, il va falloir le développer. Ce logiciel fera plein de choses magiques et intéressantes. La révolution est en marche, la singularité à portée de vue. Parmi toutes les activités de ce logiciel, il est en une particulièrement épineuse. Il va remplir des traces dans un format cryptique, par exemple les résultats de son auto-analyse. Oui, les logiciels fiables savent dire si tout se barre en sucette et qu’ils doivent être remplacés par la nouvelle génération. Sac-à-papier ! il va également falloir fournir un analyseur de traces alors ? Ça se complique méchamment.

Hé ! oui, ça se complique : ce n’est plus un logiciel qu’il faut fournir, mais deux. Et puis surtout, il va falloir trouver un moyen pour forcer le pinpin qui devra se servir de tout ça à utiliser l’analyseur de traces qui correspond au logiciel qui tourne. Imaginez, s’il cherche à lire les traces produites par la version B avec l’analyseur de la version A, ou le contraire … Il risque de détecter des erreurs qui n’en sont pas, nous pourrir en réunion, et on passera trop de temps à chercher des problèmes qui n’en sont pas. Non, vraiment, il faut garantir que l’analyse des traces soit consistante.

Aujourd’hui, c’est jour de chance. L’architecte a déjà pensé à tout. On va introduire des numéros de version dans les binaires, et modifier l’analyseur pour que la première chose qu’il fasse soit de comparer son numéro de version avec celle du logiciel qui a produit les traces, comme ça, ni une, ni deux, si c’est pas pareil, il refuse de travailler, et fini les soucis. À cette fascinante idée j’opposerai deux arguments :

  1. Un bon numéro de version doit être unique. Il devrait donc être généré automagiquement, sinon il risque de mal vieillir. Et non, il ne faut pas juste un nouveau numéro à chaque livraison, mais bien à chaque production, sinon je ne sais pas trop comment les testeurs peuvent travailler. Ah ! tiens : subtilement, ce que l’on imaginait comme une activité pour le gestionnaire de configuration vient de vous échoir, là, pour vous, intégrateur ;
  2. Est-ce que le client va vraiment se contenter d’un analyseur de traces muet ? Je suis d’accord, mieux vaut se taire que de dire n’importe quoi (non, même là, il n’a pas compris), mais pour autant on ne rend pas plus service. Pire, du point de vue du client, on ne respecte pas le contrat : on devait faire une analyse qu’on ne conduit pas de toute évidence avec notre outil muet.

Au final, j’ai proposé une solution alternative : et si on s’assurait plutôt de la rétrocompatibilité des traces ? C’est-à-dire que les traces de la version B n’auraient pas rien à voir avec les traces de la version A, mais seraient un sur-ensemble ? Et le tout stocké dans un format ultra-novateur, du genre (identifiant, valeur) ? Au pire, si l’identifiant est inconnu de l’analyseur, il afficherait la donnée binaire brute, histoire de mettre la puce à l’oreille.

Allez comprendre pourquoi, cette solution trop simple a déplu. Je m’en fiche, je n’assure pas le S.A.V., bonne chance à eux.

Qui ne peut pas dormir trouve son lit mal fait

Les réjouissances continuent. De Jean-Pierre Liégois, jeune lecteur du Var (ou presque) :

Hier soir, plantage de l’appli au démarrage. Après investigation au debugger, un S/T explique que c’est la fonction d’initialisation de la RAM à 0 qui plante.
Du coup ca matin, tout le monde sur le pont pour vérifier la gestion de la RAM, la taille utilisée, regénérer l’exe pour être sûr qu’il n’ y a pas des décalages d’adresse ou truc du même genre … Impossible de résoudre le problème.
Dans l’après-midi, on retourne sur le banc pour refaire un coup de debugger, et la, surprise, le plantage n’est pas du tout sur la fonction indiquée la veille mais bien plus loin dans l’appli, sur une ligne qui, oh surprise encore, a été modifiée dans un correctif !!!
Conclusion : quand un S/T vous dit que le problème est là, surtout ne pas regarder là …

Là encore, rien que le pain quotidien du développement logiciel de logiciels embarqués. Le logiciel n’arrête pas de grossir, il y a forcément un moment où les constantes de dimensionnement appliquées depuis toujours ne conviennent plus : nécessité de faire grossir tel ou tel segment mémoire, de revoir les options du compilateur pour espérer gagner de la place, etc. Ce genre de choses est d’autant plus réjouissant que l’on sait que ça va arriver, tôt ou tard. Et pourtant, il n’y a jamais personne pour préparer la copie, car c’est autant de sous d’économisés tant que les limites ne sont pas atteintes. Par contre, une fois atteintes, la balance financière est rarement gagnante quand il s’agit de revenir à la normale. Mais passons.

À votre petit niveau d’intégrateur, que pouvez-vous faire dans le cas décrit plus haut ? Et bien avant tout, vous méfier ! Alors comme ça, d’un coup, la gestion de la mémoire est bancale parce qu’on a rajouté une condition dans le code ? Moi-même je ne compte plus les remarques du genre « ha non mais le problème est dans la libc » ou bien « c’est le compilateur qui doit être buggé ». Il faut avouer qu’il est difficile de lutter contre ce genre d’argument souvent invérifiable, d’autant plus si les outils en question sont connus et reconnus pour être particulièrement obsolètes et truffés de (non-)fonctionnalités amusantes. Sans compter les messages amusants que peuvent produire un débordement de pile … Tout de même, ce genre d’alerte doit effectivement vous inquiéter, mais ce n’est pas le message premier le plus inquiétant !

Il n’y a donc pas trente-six solutions : reprendre l’analyse du problème avec le porteur de mauvaise nouvelle. Avant de sortir la grosse artillerie des experts techniques qui, bien que roués à cet exercice, seront d’autant plus amers que le problème incriminé sera tout sauf avéré.

Les paroles s’envolent les écrits restent

Je ne résiste pas à poursuivre l’analyse de tranches de vie que je reçois :

Hier matin, nouvelle génération : Ca plante toujours à la compilation. Conclusion : quand y a un mec qui dit dans son mail de mise- à-disposition des entrées « attention j’ai modifié le nom d’un fichier, faut mettre à jour les scripts » c’est pas pour faire chier, c’est bien parce qu’il faut mettre à jour les scripts.

C’est bien plus court que la fois précédente, et pourtant c’est toujours aussi riche en enseignements. Sur chaque projet, il ya un processus plus ou moins officiel de livraison : méls, bordereau de livraison, etc. Ils permettent deux choses :

  1. À celui qui le rédige, de vérifier qu’il n’oublie rien avant de passer le relais ;
  2. À celui qui le reçoit, de prendre connaissance d’informations complémentaires éventuelles en plus des informations habituelles qui permettent d’adresser le travail quotidien.

Du coup, négliger cet acte de livraison, par l’un ou l’autre des parties, est nécessairement source de soucis.

Deuxième point, plus directement destiné à l’intégrateur : les index de production, c’est la lie ! Quel est le but premier d’un index de production ? Lister les fichiers qui seront pris en compte dans l’exécutable final. À l’origine, l’intention est louable : ça donne l’illusion de maîtriser son périmètre de production. Je dis illusion parce que ça ne fait pas tout : identifier un nom de fichier ne permet pas d’en donner la version. Et puis surtout, avec le temps, un index de production, ça sert aussi à plein d’autres choses. Ça sert à filtrer le contenu du système de fichiers. Ça sert à ranger proprement ce qui ne l’est effectivement pas dans le système de fichier. Ça sert à cacher ce qui ne devrait pas être visible de tous. Ça sert d’excuse quand ce n’est pas à jour. Un vrai cache-misère. D’autant plus que par construction un index de production est obsolète et un frein à la productivité. Une surcouche inutile à l’encontre de la logique, qui fait bien souvent dire « mais il est là mon fichier, vas-y, compile, [propos ordurier exclusivement destiné au sélectionneur de l'Équipe de France, donc censuré]« 

Quel outil doit être le garant du contour de la production, c’est-à-dire la liste des fichiers et leurs versions ? Il y a un piège, il faut deux outils :

  1. Le gestionnaire de version de code source, qui permet toujours de retrouver un certain état global du projet à partir d’un identifiant approprié pour peu qu’il ait été posé ;
  2. La chaîne de production, basée sur des règles simples, comme par exemple : tout fichier dans SRC est compilé, et tout entête trouvé dans le répertoire INC est public.

Utilisez les outils pour ce qu’ils sont sensés faire, et tout de suite, ça ira mieux.