Wir hatten einen Service für Golang, ein separates Thema, Kafka, Clickhouse, Gitlab-CI und eine fallende Gewinnlinie, einen faulen SSH-Schlüssel und das alles, zusammen mit einer Ferienzeit, schrecklichen Regenfällen in der Stadt, einem kaputten Laptop, nächtlichen Warnungen und einem heißen Verkauf . Nicht, dass dies alles für diesen Artikel notwendig gewesen wäre, aber wenn Sie den typischen Alltag des Testers zeigen, gehen Sie in Ihrer Absicht bis zum Ende. Das einzige, was mich störte, war p0. Auf der Welt gibt es nichts Verzweifelteres, Düstereres und Deprimierteres als den Tester, der es auf dem Stoß verpasst hat. Aber ich wusste, dass ich mich ziemlich bald darauf einlassen würde.
Warum das alles?
Es gibt ein gemeinsames Bündel von Diensten - den Dienst selbst, der etwas tut - und eine Datenbank, in die diese Ergebnisse geschrieben werden. manchmal geschieht dies direkt, dh "Service - Basis". In meinem Fall erfolgt die Aufzeichnung über einen Vermittler, dh "Service - Warteschlange - Basis".
Insgesamt gibt es mehrere Elemente, und die Grenze dieser Elemente - die Ausgabe des einen und die Eingabe des anderen - ist der Ort, an dem Probleme auftreten. Sie können dort einfach nicht erscheinen.
Ein anschauliches Beispiel: Im Service wird das Preisfeld als float32 verarbeitet, in der Datenbank als Dezimalzahl (18, 5) konfiguriert, geben wir den Maximalwert von float32 als Testfall aus der Ausgabe des Service an die Datenbank weiter - oh, die Datenbank antwortet nicht. Oder ein traurigeres Beispiel: Die Datenbank stürzt nicht ab, aber es gibt keinen Fehler in den Datenprotokollen in der Datenbank. Es ist nur so, dass die Datenbank nicht mehr fließt. Oder die Aufzeichnung wird durchgeführt, jedoch mit Datenverlust oder mit Verzerrung: Das Feld verlässt den Dienst als float64 und wird als float32 aufgezeichnet.
Oder sie haben im Verlauf des Lebenszyklus entschieden, dass der Typ dieses oder jenes Feldes geändert werden muss. Das Feld ist seit langem auf dem Produkt implementiert, aber hier muss es bearbeitet werden. Und natürlich haben wir es nur an einer Stelle geändert. Hoba, wieder ist etwas schief gelaufen.
Herausforderung
Ich möchte nicht alle diese Änderungen verfolgen. Ich möchte, dass es nicht fällt. Ich möchte, dass die Aufnahme richtig läuft.
Beenden: Integrationstests!
Umsetzung und Schwierigkeiten
Wo soll man brechen?
Es gibt eine Entwicklungsumgebung: schrecklich instabil und wird normalerweise von Entwicklern als Sandbox verwendet. Es gibt Chaos und Anarchie, die für ein hartes Backend charakteristisch sind.
Es gibt eine Testumgebung oder einen Qa-Stand: Es ist besser abgestimmt, sogar Entwickler sehen es sich an, aber bis Sie sie treten, wird nichts passieren. und diese Umgebung wird oft aktualisiert. und noch öfter ist dort etwas kaputt.
Und es gibt einen Stoß - das Allerheiligste: Es ist besser, so etwas nicht darauf zu fahren. Integrationstests deuten auf die Möglichkeit eines Fehlers hin, den sie finden müssen, bevor er zum Produkt gelangt.
Was tun mit der Umgebung, wenn sie entweder instabil ist oder kämpft? Das ist richtig, erstellen Sie Ihre eigenen!
Was tun mit der Basis?
Die Datenbank kann auf verschiedene Arten gestartet werden.
Wie wir oben besprochen haben, werden wir uns nicht mit der realen Basis dieser oder jener Umgebung verbinden.
Zunächst können Sie den
Cruttle- Clickhouse-Server mit den erforderlichen Einstellungen anheben, die erforderliche SQL darauf ausrollen und über den Clickhouse-Client mit ihm kommunizieren. Beim ersten erfolgreichen Versuch, eine ähnliche Basis zu schaffen, war ci traurig. Die Tests blitzten, der Server ging nicht aus und arbeitete weiter. Sagen wir einfach, es bleibt mir immer noch ein Rätsel, warum es überhaupt angefangen hat. (es selbst, ich habe nichts damit zu tun). Ich empfehle diese Option nicht.
Eine praktische Option ist die Verwendung eines
Docker-Images .
Laden Sie die gewünschte Version in Ihr Auto herunter. Clickhouse benötigt config.xml mit Einstellungen zum Starten. Weitere Details
hierFür das wiederverwendete Klickbild müssen Sie die richtige Docker-Datei erstellen. Wir geben darin an, dass wir config.xl in den Ordner kopieren möchten, wir docken die anderen erforderlichen Konfigurationen an. Stellen Sie sicher, dass Sie die Skripte kopieren, um Ihre Basis bereitzustellen.
Da wir von außen auf das Bild zugreifen, müssen wir die Ports öffnen, über die wir mit dem Clickhouse kommunizieren. Klicken Sie auf 8123 auf http und auf 9000 auf tcp.
Wir erhalten die folgende Docker-Datei:
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/
Wie wirft man ein Bild in ci?
Um irgendwie mit dem Docker-Image in ci zu arbeiten, müssen Sie es dort irgendwie aufrufen.
Sie können das Image in Ihrem Repository festschreiben und ausführen und Docker Run mit den erforderlichen Parametern ausführen, um die Tests auszuführen. Nur hier wiegt das Docker-Image des Klicks weniger als 350mb. Es ist unanständig, solche Dateien in Git zu halten.
Wenn für verschiedene Projekte dasselbe Docker-Image benötigt wird (z. B. werden unterschiedliche Dienste in dieselbe Datenbank geschrieben), sollten Sie dies umso mehr nicht tun. Sie können den
Dock-Registrierungs- Image-Speicher verwenden
Wir glauben, dass es in unserem Projekt bereits existiert und verwendet wird. Melden Sie sich daher an, sammeln Sie das Docker-Image und verschieben Sie es dorthin.
docker build -t my_clickhouse_image . docker login my_registry_path.domain.com docker push my_clickhouse_image
Aussteigen und unser Bild flog in die Registrierung. Stellen Sie sicher, dass Sie das Tag während der Montage angeben!
Die Basis ist fertig.
Lesen Sie hier mehr über die Registrierung
Was tun mit ci?
Wie können Sie sowohl Ihren Dienst als auch Ihre Datenbank in einem Schritt starten?
Es hängt alles davon ab, wie wir den Service starten und nutzen. Wenn Sie mit dem Dienst wie mit einem Docker-Image arbeiten und tatsächlich die gesamte .gitlab-ci.yml nur mit ihnen funktioniert, ist alles einfach.
Es gibt einen Dind Streuner -
Docker-in-Docker . Es wird angezeigt, mit dem der Hauptdienst ci zusammenarbeitet, und ermöglicht es Ihnen, den Docker vollständig zu nutzen und überhaupt nicht zu belasten.
Wir pumpen das neueste Bild aus, fügen den Phasen den erforderlichen Testschritt hinzu und beschreiben unsere Abfolge von Aktionen.
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
Der offizielle Docker Docker gibt an, dass es nicht empfohlen wird,
dind zu verwenden, aber wenn Sie wirklich ...
In meinem Projekt muss der Dienst durch den Start der Binärdatei getestet werden. Hier beginnt die Magie.
Verwenden Sie dazu die Datenbank als Dienst. In der offiziellen gitlab-ci-Dokumentation wird die Verwendung eines Containers mit Basis als
Beispiel für den häufigsten Anwendungsfall für einen Docker-Container in ci genannt. Sogar
Beispiele für MySQL-, Postress- und Redis-Einstellungen werden bereitgestellt. Aber wir suchen nicht nach einfachen Wegen, wir brauchen ein Clickhouse.
Verbinden Sie die Basis! Stellen Sie sicher, dass Sie einen Alias angeben. Wenn es nicht angegeben ist, wird der Basis ein zufälliger Name und eine zufällige IP zugewiesen. Das heißt, es wird nicht genau klar sein, wie darauf zugegriffen werden soll. Es wird kein solches Problem mit Alias geben - im
http://my_alias_name:8123
der Aufruf beispielsweise wie
http://my_alias_name:8123
.
Für Tests wird weiterhin ein Image der Datenbank benötigt, das wir sorgfältig in die Registrierung einfügen. Um das Image herunterzuladen, müssen Sie sich anmelden und Docker ziehen. Nur ci weiß nicht, was Docker ist - Sie müssen es installieren.
Der resultierende Code für den Schritt in 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
Gewinn
- Ich habe eine funktionierende Servicebasis.
- Im Rahmen des Autotests ist der Zugriff auf die Datenbank einfach - einfach per Alias.
- Ich setze die Datensätze und Einstellungen der Datenbank im Rahmen des Setup-Tests zurück, rufe den Dienst an, schreibe in die Datenbank, wende mich an die Datenbank, sehe, dass die Datenbank nicht heruntergefallen ist, sehe, was angekommen ist, validiere ich. wirf mehr Tests.
- Sie können nicht mit Stiften testen!
Ergebnisse
Es scheint, dass ein paar Zeilen Setup in Gitlab-CI. Das Erstellen eines Docker-Images ist einfach. Das lokale Ausführen ist einfach. Ich habe mich in die ersten Tests integriert, bei denen an einem Tag Probleme festgestellt wurden. Aber Versuche, es bei ci zu starten, wurden zu einer Woche voller Schmerz und Hoffnungslosigkeit. Und jetzt, in den Wochen des Schmerzes und der Hoffnungslosigkeit von Entwicklern, die alles reparieren müssen, was sie dort programmiert haben.
Was haben wir geschafft?
- Wir haben einen Container mit Clickhouse aufgestellt.
- Wir haben den Container im lokalen Lager gestartet.
- Wir haben gelernt, dieses Bild in Schritt ci zu ziehen.
- Startete es im Läufer.
Senden Sie einfach Daten an die Datenbank und greifen Sie vom Test darauf zu.
Die Automatisierung ist ein ziemlich einfacher Weg, um die Routine der manuellen Piercing-Integration loszuwerden.
Was ist wichtig zu beachten: Stellen Sie sicher, dass die Eingabetypen der Basis den Ausgabetypen des vorherigen Links entsprechen. (und
ggf. Dokumentation).