Hallo zusammen. Heute teilen wir die letzte Teilfolge unseres Artikels , dessen Übersetzung speziell für die Studierenden des Kurses vorbereitet wurde. .

Deployment-Test
Der behandelte Teststil ist ein leistungsstarker Ansatz, der es uns ermöglicht, White-Box-Tests durchzuführen, um die internen Abläufe unseres Infrastrukturcodes zu überprüfen. Allerdings schränkt er ein wenig ein, was wir testen können. Die Tests basieren auf einem In-Memory-Deployment-Plan, der von Pulumi vor dem eigentlichen Deployment erstellt wird, weshalb das Deployment selbst nicht getestet werden kann. Für solche Fälle bietet Pulumi ein Framework für Integrationstests. Diese beiden Ansätze funktionieren hervorragend zusammen!
Das Integrations-Testframework von Pulumi ist in Go geschrieben und wird von uns verwendet, um den Großteil unseres internen Codes zu testen. Während der zuvor besprochene modulare Testansatz eher wie ein White-Box-Test ist, handelt es sich bei den Integrationstests um einen Black-Box-Test. (Es gibt auch Varianten detaillierter interner Tests.) Dieses Framework wurde entwickelt, um eine vollständige Pulumi-Anwendung zu nehmen und verschiedene Lebenszyklusoperationen wie das Bereitstellen eines neuen Stacks von Grund auf, dessen Aktualisierung mit Variationen und dessen Löschung, möglicherweise mehrere Male, durchzuführen. Wir führen diese regelmäßig durch (zum Beispiel nachts) und als Stresstests.
(Wir , um ähnliche Integrations-Testmöglichkeiten im nativen SDK der Sprachen zu integrieren. Sie können das Go-Testframework unabhängig von der Sprache verwenden, in der Ihre Pulumi-Anwendung geschrieben ist.)
Wenn Sie das Programm mit diesem Framework ausführen, können Sie Folgendes überprüfen:
- Der Code Ihres Projekts ist syntaktisch korrekt und funktioniert fehlerfrei.
- Die Konfigurationseinstellungen für den Stack und die Geheimnisse funktionieren und werden korrekt interpretiert.
- Ihr Projekt kann erfolgreich bei Ihrem gewählten Cloud-Anbieter bereitgestellt werden.
- Ihr Projekt kann erfolgreich von einem Ausgangszustand auf N weitere Zustände aktualisiert werden.
- Ihr Projekt kann erfolgreich gelöscht und von Ihrem Cloud-Anbieter entfernt werden.
Wie wir bald sehen werden, kann dieses Framework auch zur Durchführung von Runtime-Validierungen verwendet werden.
Ein einfacher Integrationstest
Um dies in der Praxis zu sehen, schauen wir uns das Repository an pulumi/examples, da unser Team und die Pulumi-Community es zur Testung ihrer eigenen Pull-Requests, Commits und nächtlichen Builds nutzen.
Nachfolgend finden Sie einen vereinfachten Test unseres :
example_test.go:
package test
import (
"os"
"path"
"testing"
"github.com/pulumi/pulumi/pkg/testing/integration"
)
func TestExamples(t *testing.T) {
awsRegion := os.Getenv("AWS_REGION")
if awsRegion == "" {
awsRegion = "us-west-1"
}
cwd, _ := os.Getwd()
integration.ProgramTest(t, &integration.ProgramTestOptions{
Quick: true,
SkipRefresh: true,
Dir: path.Join(cwd, "..", "..", "aws-js-s3-folder"),
Config: map[string]string{
"aws:region": awsRegion,
},
})
} Dieser Test durchläuft den grundlegenden Lebenszyklus der Erstellung, Änderung und Zerstörung eines Stacks für einen Ordner. aws-js-s3-folder. Es dauert etwa eine Minute, um das Ergebnis des Tests zu melden:
$ go test .
PASS
ok ... 43.993s Es gibt viele Parameter zur Anpassung des Verhaltens dieser Tests. Eine vollständige Liste der Optionen finden Sie ProgramTestOptions. Zum Beispiel können Sie den Jaeger-Endpunkt für das Tracing konfigurieren (Tracing), angeben, dass Sie beim negativen Testen mit einem Testfehler rechnen (ExpectFailure), eine Serie von "Änderungen" an dem Programm für einen sequentiellen Statuswechsel anwenden (EditDirs) und vieles mehr. Schauen wir uns an, wie wir diese verwenden können, um die Bereitstellung der Anwendung zu überprüfen.
Überprüfung der Ressourcenattribute
Die oben erwähnte Integration stellt sicher, dass unser Programm „funktioniert“ – es stürzt nicht ab. Aber was ist, wenn wir die Eigenschaften des erhaltenen Stacks überprüfen möchten? Zum Beispiel, ob bestimmte Arten von Ressourcen vorbereitet wurden (oder nicht) und ob sie bestimmte Attribute haben.
Parameter ExtraRuntimeValidation für ProgramTestOptions ermöglicht es uns, den nach der Bereitstellung (post-deployment state) von Pulumi festgehaltenen Zustand zu sehen, damit wir zusätzliche Überprüfungen durchführen können. Dazu gehört ein vollständiger Snapshot des Endzustandes des Stacks, einschließlich der Konfiguration, exportierter Ausgabewerte, aller Ressourcen und ihrer Eigenschaftswerte sowie aller Abhängigkeiten zwischen den Ressourcen.
Um ein einfaches Beispiel dafür zu sehen, überprüfen wir, ob unser Programm einen S3 Bucket:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// wie zuvor...
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
var foundBuckets int
for _, res := range stack.Deployment.Resources {
if res.Type == "aws:s3/bucket:Bucket" {
foundBuckets++
}
}
assert.Equal(t, 1, foundBuckets, "Es wurde erwartet, einen einzelnen AWS S3 Bucket zu finden")
},
})Jetzt, wenn wir "go test" ausführen, wird nicht nur die gesamte Lebenszyklus-Testreihe durchlaufen, sondern auch nach dem erfolgreichen Bereitstellen des Stacks eine zusätzliche Überprüfung des Endzustands durchgeführt.
Runtime-Tests
Bisher bezogen sich alle Tests ausschließlich auf das Verhalten bei der Bereitstellung und auf das Ressourcenmodell von Pulumi. Was tun, wenn Sie überprüfen möchten, ob Ihre vorbereitete Infrastruktur tatsächlich funktioniert? Zum Beispiel, ob die virtuelle Maschine läuft, der S3-Bucket den erwarteten Inhalt hat usw.
Sie haben sich vielleicht schon gedacht, wie das geht: die Option ExtraRuntimeValidation für ProgramTestOptions — bietet hierfür eine hervorragende Möglichkeit. An diesem Punkt führen Sie einen beliebigen Go-Test mit Zugriff auf den vollständigen Zustand der Ressourcen Ihrer Anwendung aus. Dieser Zustand umfasst Informationen wie IP-Adressen der virtuellen Maschinen, URLs und alles, was für die echte Interaktion mit den bereitgestellten Cloud-Anwendungen und der Infrastruktur erforderlich ist.
Zum Beispiel exportiert unser Testprogramm die Eigenschaft webEndpoint des Buckets mit dem Namen websiteUrl, die die vollständige URL darstellt, über die wir das konfigurierte index document. Obwohl wir in der Zustandsdatei nachsehen und diese Eigenschaft direkt ablesen könnten, exportieren unsere Stacks in vielen Fällen nützliche Eigenschaften wie diese, die wir bequem zur Überprüfung verwenden können: bucket und diese Eigenschaft direkt zu lesen, exportieren unsere Stacks in vielen Fällen nützliche Eigenschaften wie diese, die wir bequem zur Überprüfung verwenden können:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// wie zuvor ...
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
url := "http://" + stack.Outputs["websiteUrl"].(string)
resp, err := http.Get(url)
if !assert.NoError(t, err) {
return
}
if !assert.Equal(t, 200, resp.StatusCode) {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if !assert.NoError(t, err) {
return
}
assert.Contains(t, string(body), "Hallo, Pulumi!")
},
}) Wie bei unseren vorherigen Runtime-Überprüfungen wird diese Überprüfung unmittelbar nach dem Bereitstellen des Stacks ausgeführt, als Antwort auf einen einfachen Aufruf. go test. Und das ist nur die Spitze des Eisbergs – alle Testmöglichkeiten von Go stehen zur Verfügung, die Sie im Code schreiben können.
Kontinuierliche Integration der Infrastruktur
Es ist gut, die Tests auf einem Laptop ausführen zu können, wenn viele Änderungen an der Infrastruktur vorgenommen werden, um sie vor der Codeüberprüfung zu verifizieren. Aber wir und viele unserer Kunden testen die Infrastruktur in verschiedenen Phasen des Entwicklungszyklus:
- In jedem offenen Pull-Request wird vor dem Mergen getestet.
- Als Antwort auf jeden Commit, um sicherzustellen, dass das Mergen korrekt durchgeführt wurde.
- Zweitweise, beispielsweise nachts oder wöchentlich für zusätzliche Tests.
- Im Rahmen von Leistungstests oder Stresstests, die normalerweise über längere Zeiträume durchgeführt werden und Tests parallel ausführen und/oder das gleiche Programm mehrfach bereitstellen.
Für jede dieser Optionen unterstützt Pulumi die Integration mit Ihrem bevorzugten Continuous Integration System. Bei der kontinuierlichen Integration erhalten Sie denselben Testabdeckungsgrad für Ihre Infrastruktur wie für Ihre Anwendungssoftware.
Pulumi bietet Unterstützung für gängige CI-Systeme. Hier sind einige:
Für weitere Informationen konsultieren Sie bitte die Dokumentation zu .
ephemeren Umgebungen
Eine sehr kraftvolle Fähigkeit, die Ihnen zur Verfügung steht, ist die Möglichkeit, ephemere Umgebungen ausschließlich für Abnahmetests bereitzustellen. Das Konzept Pulumi ist so konzipiert, dass Sie isolierte und unabhängige Umgebungen ganz einfach bereitstellen und entfernen können – alles mit wenigen einfachen CLI-Befehlen oder über ein Integrationstest-Framework.
Wenn Sie GitHub verwenden, bietet Pulumi , die Ihnen hilft, Akzeptanztests an Pull-Requests innerhalb Ihrer CI-Pipelines anzuschließen. Installieren Sie einfach die App in Ihrem GitHub-Repository und Pulumi in Ihrer CI, damit Informationen zu Infrastruktur-Previews, Updates und Testergebnissen zu den Pull-Requests hinzugefügt werden:

Durch die Verwendung von Pulumi für Ihre Akzeptanztests eröffnen sich neue Automatisierungsmöglichkeiten, die die Teamleistung verbessern und das Vertrauen in die Qualität der Änderungen stärken.
Zusammenfassung
In diesem Artikel haben wir gesehen, dass wir mit der Verwendung von allgemeinen Programmiersprachen viele Softwareentwicklungsverfahren zur Verfügung haben, die für die Entwicklung unserer Anwendungen nützlich waren. Dazu gehören modulares Testen, Integrationstests sowie deren Interaktion zur Durchführung umfassender Runtime-Tests. Tests lassen sich auf Anfrage oder in Ihrem CI-System einfach ausführen.
Pulumi — eine Open-Source-Software, die kostenlos genutzt werden kann und mit Ihren bevorzugten Programmiersprachen und Clouds arbeitet — !
→
Quelle: habr.com
