Test af infrastruktur som kode med Pulumi. Del 2

Hej alle. I dag deler vi den sidste del af artiklen med dig. "Test infrastruktur som kode med Pulumi", hvis oversættelse er udarbejdet specielt til kursister "DevOps-praksis og værktøjer".

Test af infrastruktur som kode med Pulumi. Del 2

Implementeringstest

Denne teststil er en kraftfuld tilgang og giver os mulighed for at udføre white box-test for at teste den interne funktion af vores infrastrukturkode. Det begrænser dog noget, hvad vi kan teste. Testene udføres baseret på in-memory-implementeringsplanen oprettet af Pulumi før den faktiske implementering, og derfor kan selve implementeringen ikke testes. Til sådanne tilfælde har Pulumi en integrationstestramme. Og disse to tilgange fungerer godt sammen!

Pulumis integrationstestramme er skrevet i Go, hvilket er sådan, vi tester det meste af vores interne kode. Mens den tidligere diskuterede enhedstestmetode mere lignede white box-test, er integrationstest en sort boks. (Der er også muligheder for streng intern test.) Denne ramme blev skabt til at tage et komplet Pulumi-program og udføre forskellige livscyklusoperationer på det, såsom at implementere en ny stak fra bunden, opdatere den med variationer og slette den, muligvis flere gange . Vi kører dem regelmæssigt (for eksempel om natten) og som stresstest.

(Vi vi arbejder på det, så lignende integrationstestfunktioner er tilgængelige i sprogets oprindelige SDK. Du kan bruge Go-integrationstestrammerne, uanset hvilket sprog dit Pulumi-program er skrevet på).

Ved at køre programmet ved hjælp af denne ramme kan du kontrollere følgende:

  • Din projektkode er syntaktisk korrekt og kører uden fejl.
  • Indstillingerne for stak og hemmeligheder fungerer og fortolkes korrekt.
  • Dit projekt kan med succes implementeres i den cloud-udbyder, du vælger.
  • Dit projekt kan med succes opgraderes fra den oprindelige tilstand til N andre tilstande.
  • Dit projekt kan med succes ødelægges og fjernes fra din cloud-udbyder.

Som vi snart vil se, kan denne ramme også bruges til at udføre runtime-validering.

Simpel integrationstest

For at se dette i aktion, vil vi se på depotet pulumi/examples, da vores team og Pulumi-fællesskabet bruger det til at teste vores egne pull-anmodninger, commits og natlige builds.

Nedenfor er en forenklet test af vores eksempel, der giver S3 spand og nogle andre genstande:

eksempel_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,
        },
    })
}

Denne test gennemgår den grundlæggende livscyklus med at oprette, ændre og ødelægge en stak til en mappe aws-js-s3-folder. Det vil tage omkring et minut at rapportere en bestået test:

$ go test .
PASS
ok      ... 43.993s

Der er mange muligheder for at tilpasse adfærden af ​​disse tests. Se den fulde liste over muligheder. i strukturen ProgramTestOptions. For eksempel kan du konfigurere Jaeger-endepunkt til at spore (Tracing), angiver, at du forventer, at testen mislykkes, hvis testen er negativ (ExpectFailure), anvende en række "redigeringer" til programmet for en sekventiel overgang af tilstande (EditDirs) og meget mere. Lad os se, hvordan du bruger dem til at teste din applikationsimplementering.

Kontrol af ressourceegenskaber

Den ovenfor diskuterede integration sikrer, at vores program "virker" - det går ikke ned. Men hvad hvis vi vil kontrollere egenskaberne for den resulterende stak? For eksempel at visse typer ressourcer er (eller ikke er) blevet klargjort, og at de har bestemte attributter.

Parameter ExtraRuntimeValidation for ProgramTestOptions giver os mulighed for at se på tilstanden efter implementering, der er registreret af Pulumi, så vi kan foretage yderligere kontroller. Dette inkluderer et komplet øjebliksbillede af den resulterende staks tilstand, inklusive konfiguration, eksporterede outputværdier, alle ressourcer og deres egenskabsværdier og alle afhængigheder mellem ressourcer.

For at se et grundlæggende eksempel på dette, lad os kontrollere, at vores program opretter et S3 spand:

  integration.ProgramTest(t, &integration.ProgramTestOptions{
        // as before...
        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, "Expected to find a single AWS S3 Bucket")
        },
    })

Nu, når vi kører go test, vil den ikke kun gennemgå et batteri af livscyklustests, men også, efter succesfuld implementering af stakken, vil den udføre en yderligere kontrol af den resulterende tilstand.

Runtime tests

Indtil videre har alle test udelukkende handlet om implementeringsadfærd og Pulumi-ressourcemodellen. Hvad hvis du vil bekræfte, at din klargjorte infrastruktur rent faktisk fungerer? For eksempel at den virtuelle maskine kører, S3-bøtten indeholder det, vi forventer, og så videre.

Du har måske allerede gættet, hvordan du gør dette: mulighed ExtraRuntimeValidation for ProgramTestOptions - det er en fantastisk mulighed for dette. På dette tidspunkt kører du en brugerdefineret Go-test med adgang til den fulde tilstand af dit programs ressourcer. Denne tilstand inkluderer information såsom virtuelle maskiners IP-adresser, URL'er og alt, hvad der er nødvendigt for faktisk at interagere med de resulterende cloud-applikationer og infrastruktur.

For eksempel eksporterer vores testprogram ejendommen webEndpoint spand kaldt websiteUrl, som er den fulde URL, hvor vi kan få konfigureret index document. Selvom vi kunne grave i statens fil for at finde bucket og læs den egenskab direkte, men i mange tilfælde eksporterer vores stakke nyttige egenskaber som denne, som vi finder praktiske at bruge til at kontrollere:

integration.ProgramTest(t, &integration.ProgramTestOptions{
            // as before ...
        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), "Hello, Pulumi!")
        },
    })

Ligesom vores tidligere runtime-tjek vil denne kontrol blive udført umiddelbart efter at have hævet stakken, alt sammen som svar på et simpelt opkald go test. Og det er kun toppen af ​​isbjerget – hver Go-testfunktion, du kan skrive i kode, er tilgængelig.

Kontinuerlig infrastrukturintegration

Det er godt at kunne køre test på en bærbar computer, når der foretages en masse infrastrukturændringer for at teste dem, før de indsendes til kodegennemgang. Men vi og mange af vores kunder tester infrastruktur på forskellige stadier af udviklingens livscyklus:

  • I hver åben pull anmodning om test før sammenlægning.
  • Som svar på hver commit, for at dobbelttjekke, at fletningen blev udført korrekt.
  • Periodisk, såsom om natten eller ugentligt for yderligere test.
  • Som en del af præstations- eller stresstest, som typisk løber over en længere periode og kører test parallelt og/eller implementerer det samme program flere gange.

For hver af disse understøtter Pulumi integration med dit foretrukne kontinuerlige integrationssystem. Med kontinuerlig integration giver dette dig samme testdækning for din infrastruktur som for din applikationssoftware.

Pulumi har understøttelse af almindelige CI-systemer. Her er nogle af dem:

For mere detaljeret information henvises til dokumentationen vedr Kontinuerlig tilførsel.

Kortvarige miljøer

En meget stærk mulighed, der åbner sig, er evnen til at implementere flygtige miljøer udelukkende til accepttestformål. Koncept projekter og stakke Pulumi er designet til nemt at implementere og rive fuldstændigt isolerede og uafhængige miljøer ned, alt sammen i nogle få simple CLI-kommandoer eller ved hjælp af en integrationstestramme.

Hvis du bruger GitHub, så tilbyder Pulumi GitHub app, som vil hjælpe dig med at forbinde accepttest for at trække anmodninger inden for din CI-pipeline. Du skal bare installere applikationen i GitHub-lageret, og Pulumi tilføjer oplysninger om infrastrukturforhåndsvisninger, opdateringer og testresultater til dine CI- og poolanmodninger:

Test af infrastruktur som kode med Pulumi. Del 2

Når du bruger Pulumi til dine kerneaccepttests, får du nye automatiseringsfunktioner, der vil forbedre teamets produktivitet og give dig tillid til kvaliteten af ​​dine ændringer.

Total

I denne artikel har vi set, at ved at bruge programmeringssprog til generelle formål, bliver mange softwareudviklingsteknikker tilgængelige for os, som har været nyttige i udviklingen af ​​vores applikationer. De omfatter enhedstest, integrationstest, og hvordan de arbejder sammen for at udføre omfattende runtime test. Tests er nemme at køre efter behov eller i dit CI-system.

Pulumi - open source software, gratis at bruge og fungerer med dine foretrukne programmeringssprog og skyer - prøv det i dag!

Den første del

Kilde: www.habr.com

Tilføj en kommentar