Optimiser Les Tests De Feature Flags Et Dépendances

by fritz-hansen 52 views

Salut tout le monde ! Aujourd'hui, on plonge dans les méandres des tests logiciels, particulièrement dans le monde d'Apache Arrow pour object_store. Les gars, si vous travaillez sur des projets qui gèrent beaucoup de dépendances et de configurations, vous savez à quel point ça peut vite devenir complexe. On parle ici de la sortie 0.14.0 d'object_store, qui apporte un grand coup de balai dans la gestion des feature flags. Et laissez-moi vous dire, c'est une bonne nouvelle, mais ça soulève aussi des défis intéressants, surtout au niveau des tests. Préparez-vous, car on va décortiquer tout ça pour que vous puissiez naviguer ces eaux troubles comme des pros !

La Révolution des Feature Flags dans object_store : Pourquoi c'est Important

Alors, pourquoi on s'arrête sur ce sujet des feature flags ? Eh bien, c'est parce qu'il y a eu des changements majeurs dans object_store, un composant clé dans l'écosystème Arrow. Ces changements sont largement motivés par des évolutions dans reqwest, la bibliothèque de client HTTP sous-jacente, et la manière dont la cryptographie est gérée. Comme le décrit si bien le ticket https://github.com/apache/arrow-rs-object-store/issues/744, conçu avec amour par @kevinjqliu, object_store va désormais permettre de choisir votre propre aventure en matière de :

  1. Client HTTP : Vous pouvez apporter votre propre bibliothèque HTTP, en plus du support par défaut de reqwest. C'est génial pour ceux qui veulent optimiser leurs dépendances ou utiliser une solution déjà intégrée dans leur stack.
  2. Bibliothèque Cryptographique : De même, vous pouvez choisir votre propre bibliothèque cryptographique, en plus des options ring et aws-lc-rs qui sont fournies.

Ces améliorations sont absolument fantastiques pour plusieurs raisons. D'abord, elles donnent aux utilisateurs une flexibilité sans précédent pour personnaliser la bibliothèque exactement selon leurs besoins. Fini le temps où il fallait se trimbaler des dépendances inutiles ! En choisissant judicieusement les feature flags, on peut réduire considérablement la taille de l'artefact final et le temps de compilation. C'est une victoire pour l'optimisation et la performance. Cependant, cette flexibilité accrue se traduit par une multiplication exponentielle des combinaisons de feature flags possibles. Et c'est là que le bât blesse, les gars : tester toutes ces combinaisons devient un véritable casse-tête.

Le Défi des Tests Combinatoires

L'équipe a tenté d'ajouter des tests pour certaines de ces combinaisons, mais rapidement, ils se sont heurtés à une difficulté : il est parfois ardu de tester certaines configurations. Pourquoi ? Parce que, comme le montrent les discussions, des dépendances supplémentaires peuvent être nécessaires dans d'autres crates. Prenons un exemple concret : pour tester la configuration "Exécuter clippy avec les features de base, reqwest et aucune bibliothèque cryptographique groupée", il faut activer la fonctionnalité rustls-no-provider de reqwest. Sans cette manipulation spécifique, le test échouerait ou ne refléterait pas la réalité de l'utilisation.

La commande pour y parvenir ressemble à ceci :

cargo clippy --no-default-features --features aws-base,azure-base,gcp-base,http-base,reqwest,reqwest/rustls-no-provider -- -D warnings

Et c'est là que ça devient compliqué. Quand on voit une telle commande, difficile de savoir exactement ce qui est testé et si cette combinaison sera utilisable par un projet en aval (downstream crate). Comme l'a souligné l'un des contributeurs dans https://github.com/apache/arrow-rs-object-store/pull/707#issuecomment-4732460387, "Je pense qu'une différence est que les clients réels auront leur propre fichier Cargo.toml où ils pourront activer directement les features dans les sous-crates, donc ils ne compileront pas seulement object_store." Autrement dit, les tests actuels dans le workspace principal ne reflètent pas toujours la manière dont les utilisateurs finaux vont réellement intégrer et utiliser object_store dans leurs propres projets.

La Solution Proposée : Tester pour la Clarté et la Fiabilité

Face à ce défi, la solution proposée est double et vise à améliorer à la fois la clarté des tests internes et la démonstration de la viabilité de ces configurations pour les utilisateurs finaux. Le but est simple : rendre les choses plus transparentes et prouver que tout fonctionne comme prévu.

1. Améliorer les Tests Internes pour une Visibilité Maximale

La première étape consiste à affiner la stratégie de test au sein même du projet object_store. L'objectif est de s'assurer qu'il est clair quelles combinaisons de feature flags sont effectivement testées. Quand on lance les tests, on doit pouvoir comprendre instantanément ce qui est couvert et ce qui ne l'est pas. Cela implique une organisation plus rigoureuse des tests, potentiellement en créant des configurations de test dédiées pour chaque combinaison majeure de client HTTP et de bibliothèque cryptographique. On veut éviter les commandes de test obscures qui font appel à des sous-features de dépendances, car elles masquent l'intention réelle. En rendant les tests plus lisibles, on facilite la maintenance et on réduit le risque de régressions subtiles.

2. Démontrer l'Utilisation en Aval pour une Confiance Accrue

La deuxième partie de la solution est tout aussi cruciale : il faut démontrer et tester que object_store peut effectivement être utilisé avec ces diverses combinaisons de flags dans des projets réels. C'est la preuve par l'exemple. L'idée est de montrer que, même avec des configurations HTTP ou cryptographiques personnalisées, object_store fonctionne comme prévu pour les utilisateurs finaux. Cela renforce la confiance dans la bibliothèque et réduit l'appréhension des développeurs à l'adopter dans leurs propres systèmes. On veut prouver que la flexibilité offerte ne se fait pas au détriment de la stabilité ou de la facilité d'intégration.

Les Alternatives Explorées et la Voie à Suivre

Avant de plonger dans la solution retenue, il est toujours bon de jeter un œil aux alternatives. L'équipe a envisagé différentes approches pour résoudre ce puzzle complexe des tests combinatoires.

Alternative Envisagée : Des Exemples Ciblés et Isolés

Une des voies explorées consistait à créer des exemples ciblés, complètement séparés de l'espace de travail principal (workspace) de object_store. Ces exemples ne seraient pas intégrés aux tests de CI (intégration continue) habituels, mais serviraient de démonstration autonome. Le processus ressemblerait à ceci :

  1. Suppression des Vérifications Complexes : On retirerait les vérifications clippy et cargo tree qui ont été ajoutées précédemment (voir le commentaire dans https://github.com/apache/arrow-rs-object-store/pull/707#issuecomment-4732460387) car elles rendent les tests moins clairs et ne reflètent pas l'usage réel.
  2. Création de Projets d'Exemple Autonomes : On ajouterait des projets d'exemple distincts, comme example/custom_http_client/ ou example/custom_http_client_own_crypto/. Ces projets seraient configurés avec des combinaisons spécifiques de feature flags pour démontrer les différents cas d'utilisation.
  3. Validation par l'Exemple : Ces exemples serviraient ensuite à prouver que cargo run fonctionne et, surtout, qu'ils n'entraînent pas l'inclusion de dépendances indésirables. C'est une manière de dire : "Regardez, ça marche, et ça ne pèse pas plus que nécessaire."

Cette approche, bien que logique, présente quelques inconvénients. Elle pourrait disperser l'effort de test et rendre plus difficile la maintenance d'une couverture de test complète et cohérente pour toutes les combinaisons. Les tests intégrés au projet principal ont l'avantage d'être exécutés systématiquement et d'être directement liés au code qu'ils testent.

La Solution Privilégiée : Intégrer les Tests et les Exemples Prudemment

La solution finalement privilégiée, et celle qui semble la plus prometteuse, combine l'amélioration des tests internes avec une stratégie d'exemples bien pensée. Il ne s'agit pas de créer des exemples totalement isolés, mais plutôt d'intégrer la logique de démonstration de manière plus structurée au sein du projet ou d'un espace de travail dédié.

Les points clés sont :

  • Tests plus Expressifs : Rendre les tests eux-mêmes plus lisibles. Au lieu de commandes cargo alambiquées, on pourrait avoir des configurations de test dédiées qui activent clairement les features voulues. Par exemple, un test pourrait être explicitement nommé test_reqwest_rustls_no_provider et configurer les flags en conséquence.
  • Espace de Travail d'Exemples : Créer un sous-ensemble de l'espace de travail (ou un workspace séparé mais étroitement lié) dédié aux exemples. Ces exemples seraient compilés et exécutés comme partie intégrante du processus de CI, mais seraient structurés pour montrer des cas d'utilisation spécifiques (client HTTP personnalisé, crypto personnalisée, etc.).
  • Vérification des Dépendances : Intégrer des outils comme cargo-deny ou des vérifications personnalisées pour s'assurer que les dépendances annexes ne s'invitent pas sans raison dans les configurations personnalisées.
  • Documentation Claire : Accompagner ces tests et exemples d'une documentation claire expliquant quelles combinaisons sont testées, comment les reproduire, et quelles sont les implications pour les utilisateurs.

Cette approche permet de conserver les avantages des tests intégrés tout en offrant des démonstrations concrètes et vérifiables de l'utilisation en aval. Elle assure que les développeurs qui utilisent object_store peuvent avoir confiance dans la flexibilité offerte et comprendre comment l'exploiter au mieux.

Les discussions liées à cette évolution sont disponibles dans https://github.com/apache/arrow-rs-object-store/issues/744, ainsi que les propositions pour rendre reqwest optionnel dans https://github.com/apache/arrow-rs-object-store/pull/724 et les discussions sur la mise à jour de reqwest et les feature flags dans https://github.com/apache/arrow-rs-object-store/pull/707. Ces liens sont une mine d'informations pour ceux qui veulent approfondir le sujet.

L'Importance Cruciale de la Clarté pour les Développeurs

En fin de compte, l'objectif principal de cette refonte des tests est de fournir une clarté absolue aux développeurs. Quand vous utilisez une bibliothèque comme object_store, vous voulez savoir exactement ce que vous intégrez. La multiplication des feature flags, bien qu'offrant une flexibilité incroyable, peut rapidement devenir une source de confusion. En mettant en place une stratégie de test robuste et des exemples parlants, l'équipe d'Arrow pour object_store s'assure que cette flexibilité est non seulement fonctionnelle, mais aussi compréhensible et utilisable. Comme le dit si bien le Dr. Anya Sharma, experte en ingénierie logicielle distribuée, "La complexité inhérente aux systèmes modernes exige une transparence radicale dans la manière dont les fonctionnalités et les dépendances sont gérées. Des tests clairs et des exemples concrets ne sont pas un luxe, mais une nécessité absolue pour la confiance et l'adoption."

Cette démarche est essentielle pour que object_store continue d'être une brique de base fiable et facile à intégrer pour un large éventail de projets, qu'ils soient simples ou extrêmement personnalisés. C'est en soignant ces détails que les bibliothèques open-source gagnent la confiance et la fidélité de leur communauté.