Configurer ClickHouse pour les tests d'intégration dans gitlab-ci

Nous avions un service sur golang, un sujet séparé kafka, clickhouse, gitlab-ci et une ligne de paiement en baisse, une clé ssh pourrie et c'est tout, avec une saison de vacances, de terribles pluies dans la ville, un ordinateur portable cassé, des alertes la nuit et une vente chaude . Non pas que tout cela ait été nécessaire pour cet article, mais une fois que vous montrez la vie quotidienne typique du testeur, allez dans votre intention jusqu'à la fin. La seule chose qui me dérangeait était p0. Dans le monde, il n'y a rien de plus désespéré, sombre et déprimé que le testeur qui l'a manqué sur la prod. Mais je savais que très bientôt je m'y plongerais.

Pourquoi tout ça?


Il existe un ensemble commun de services - le service lui-même qui fait quelque chose - et une base de données dans laquelle ces résultats sont écrits. parfois, cela se produit directement, c'est-à-dire «service - base». Dans mon cas, l'enregistrement se fait par un intermédiaire, c'est-à-dire «service - file d'attente - base».

Au total, il y a plusieurs éléments, et la frontière de ces éléments - la sortie de l'un et l'entrée de l'autre - c'est l'endroit où les problèmes apparaissent. Ils ne peuvent tout simplement pas ne pas y apparaître.

Un exemple frappant: dans le service, le champ de prix est traité comme float32, dans la base de données, il est configuré en décimal (18, 5), nous alimentons la valeur maximale de float32 en tant que scénario de test à partir de la sortie du service dans la base de données - oh, la base de données ne répond pas. Ou un exemple plus triste - la base de données ne plante pas, mais il n'y a pas d'erreur dans les journaux de données de la base de données. c'est juste que la base de données ne se déverse plus. Ou l'enregistrement passe, mais avec perte de données ou avec distorsion: le champ quitte le service en float64 et est enregistré en float32.

Ou, au cours du cycle de vie du service, ils ont décidé qu'il fallait changer le type de tel ou tel domaine. Le champ est implanté depuis longtemps sur le prod, mais ici il faut le modifier. Et bien sûr, nous l'avons changé en un seul endroit. Hoba, quelque chose s'est mal passé.

Défi


Je ne veux pas garder une trace de tous ces changements. Je veux qu'il ne tombe pas. Je veux que l'enregistrement aille bien.

Sortie: tests d'intégration!

Mise en œuvre et difficultés


Où rompre?


Il existe un environnement de développement: terriblement instable et est généralement utilisé par les développeurs comme sandbox. Il y a le chaos et l'anarchie caractéristiques d'un backend dur.

Il y a un environnement de test ou qa-stand: il est mieux réglé, même les devops le regardent, mais jusqu'à ce que vous les frappiez, rien ne se passera. et cet environnement est souvent mis à jour. et encore plus souvent, quelque chose y est cassé.

Et il y a une prod - le saint des saints: il vaut mieux ne pas y conduire quelque chose comme ça. les tests d'intégration suggèrent la possibilité d'un bogue qu'ils doivent trouver avant qu'il n'atteigne le prod.

Alors, que faire de l'environnement quand il est instable ou au combat? C'est vrai, créez le vôtre!

Que faire de la base?


La base de données peut être lancée de plusieurs manières.

Comme nous l'avons vu ci-dessus, nous ne nous connecterons pas à la base réelle de tel ou tel environnement.

Tout d'abord, vous pouvez augmenter le serveur cricket clickhouse avec les paramètres nécessaires, y déployer le sql nécessaire et communiquer avec lui via clickhouse-client. Lors de la première tentative réussie de mettre une base similaire, ci était triste. les tests ont clignoté, le serveur n'est pas sorti et a continué à fonctionner. Disons simplement, cela reste un mystère pour moi pourquoi cela a même commencé. (elle-même, je n'y suis pour rien). Je ne recommande pas cette option.

Une option pratique prête à l'emploi est l'utilisation d'une image docker .
Téléchargez la version souhaitée sur votre voiture. Clickhouse a besoin de config.xml avec des paramètres pour démarrer. Plus de détails ici
Pour l'image de clic réutilisée, vous devez créer le dockerfile correct. Nous y indiquons que nous voulons copier config.xl dans le dossier, nous ancrons les autres configurations requises. Assurez-vous de copier les scripts pour déployer votre base.

Puisque nous accéderons à l'image de l'extérieur, nous devons ouvrir les ports par lesquels nous communiquerons avec la clickhouse. Cliquez sur fonctionne sur 8123 sur http et sur 9000 sur tcp.

Nous obtenons le dockerfile suivant:

From yandex/clickhouse-server Expose 8123 Expose 9000 Add config.xml /etc/clickhouse-server/config.xml Add my_init_script.sql /docker-entrypoint-initdb.d/ 

Comment jeter une image en ci?


Pour travailler d'une manière ou d'une autre avec l'image docker dans ci, vous devez l'appeler d'une manière ou d'une autre.

Vous pouvez valider et exécuter l'image dans votre référentiel et exécuter docker run avec les paramètres nécessaires dans le cadre de l'exécution des tests. Seulement ici, l'image docker du clic pèse moins de 350 Mo. il est indécent de conserver ces fichiers dans git.

De plus, si la même image Docker est nécessaire sur différents projets (par exemple, différents services sont écrits dans la même base de données), d'autant plus que vous ne devez pas le faire. Vous pouvez utiliser le stockage d'images de registre Docker
Nous pensons que dans notre projet, il existe déjà et est utilisé. Par conséquent, connectez-vous, récupérez l'image docker et poussez-la là.

 docker build -t my_clickhouse_image . docker login my_registry_path.domain.com docker push my_clickhouse_image 

Allumé et notre image a volé dans le registre. Assurez-vous de spécifier l'étiquette lors de l'assemblage!

La base est prête.

En savoir plus sur le registre ici

Que faire avec ci?


Comment lancer à la fois votre service et votre base de données en une seule étape?

Tout dépend de la façon dont nous commençons et utilisons le service. Si vous travaillez avec le service comme avec une image docker, et que l'ensemble du .gitlab-ci.yml ne fonctionne qu'avec eux, alors tout est simple.
Il y a un dind errant - docker-in-docker . Il est indiqué comme le service principal ci fonctionne et vous permet d'utiliser pleinement le docker et de ne pas forcer du tout.

Nous pompons la dernière image, ajoutons l'étape de test requise aux étapes et décrivons notre séquence d'actions.

 image: docker:stable services: - docker:dind stages: - build … - test-click ... - test - release … test-click: variables: VERY_IMPORTANT_VARIABLE: “its value” before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker pull My_Service_Image - docker pull My_ClickHouse_Image - docker run -FLAGS My_ClickHouse_Image - docker run My_Service_Image /path/to/tests 

Le docker officiel docker déclare qu'il n'est pas recommandé d'utiliser dind , mais si vous en avez vraiment besoin ...

Dans mon projet, le service doit être testé via le lancement du binaire. C'est là que la magie commence.
Pour ce faire, utilisez la base de données en tant que service. La documentation officielle de gitlab-ci cite l'utilisation d'un conteneur avec une base comme exemple du cas d'utilisation le plus courant pour un conteneur docker en ci. Même des exemples de paramètres mysql, postress et redis sont fournis. Mais nous ne cherchons pas de moyens simples, nous avons besoin d'un clickhouse.

Connectez la base! Assurez-vous de spécifier un alias. s'il n'est pas spécifié, la base se verra attribuer un nom aléatoire et une ip aléatoire. Autrement dit, il ne sera pas clair exactement comment y accéder. Il n'y aura pas un tel problème avec l'alias - dans le code de test, l'appel ressemblera, par exemple, à http://my_alias_name:8123 .

Pour les tests, une image de la base de données est toujours requise, que nous avons soigneusement insérée dans le registre. Pour télécharger l'image, vous devez vous connecter à Docker et tirer Docker, seul ci ne sait pas ce qu'est Docker - vous devez l'installer.

Le code résultant de l'étape dans gitlab-ci.yml:

 Integration tests: Services: - name: my_clickhouse:latest alias: clicktest Stage: tests Variables: Variables_for_my_service: “value” Before_script: - curl -ssl https://get.docker.com/ | sh - docker login -u gitlab-ci-token -p $ci_build_token my_registry_path.domain.com Script: - ./bin/my_service & - go test -v ./tests -tags=integration Dependencies: - build 

Bénéfice


  • J'ai un tas de base de service.
  • Dans le cadre de l'autotest, il est facile d'accéder à la base de données - simplement par alias.
  • Je réinitialise les enregistrements et les paramètres de la base de données dans le cadre du test de configuration, appelle le service, il écrit dans la base de données, je me tourne vers la base de données, je vois que la base de données n'est pas tombée, je vois ce qui est arrivé, je valide. lancer plus de tests.
  • Vous ne pouvez pas tester avec des stylos!

Résultats


Il semblerait que quelques lignes de configuration dans gitlab-ci. Construire une image docker est facile. Exécuter localement localement est simple. J'ai obtenu l'intégration avec les premiers tests qui ont trouvé des problèmes en une journée. Mais les tentatives de lancement à ci se sont transformées en une semaine de douleur et de désespoir. Et maintenant, dans les semaines de douleur et de désespoir des développeurs qui doivent réparer tout ce qu'ils ont programmé là-bas.

Qu'avons-nous réussi à faire?


  • Nous avons mis en place un container avec clickhouse.
  • Nous avons commencé le conteneur dans un stockage local.
  • Nous avons appris à tirer cette image à l'étape ci.
  • Je l'ai lancé dans le coureur.

Envoyez facilement des données à la base de données et accédez-y depuis le test.

L'automatisation est un moyen assez simple de se débarrasser de la routine d'intégration de perçage manuel.

Ce qui est important de faire attention: assurez-vous que les types d'entrée de la base correspondent aux types de sortie du lien précédent. (et documentation , le cas échéant ).

Source: https://habr.com/ru/post/fr459860/


All Articles