Testar infrastruktur som kod med Pulumi. Del 2

Hej alla. Idag delar vi den sista delen av artikeln med dig. "Testar infrastruktur som kod med Pulumi", vars översättning utarbetades speciellt för kursstudenter "DevOps praxis och verktyg".

Testar infrastruktur som kod med Pulumi. Del 2

Implementeringstestning

Denna teststil är ett kraftfullt tillvägagångssätt och låter oss utföra white box-testning för att testa vår infrastrukturkods interna funktion. Det begränsar dock något vad vi kan testa. Testerna utförs baserat på minnesinstallationsplanen som skapats av Pulumi före den faktiska driftsättningen och därför kan själva driftsättningen inte testas. För sådana fall har Pulumi ett ramverk för integrationstest. Och dessa två tillvägagångssätt fungerar utmärkt tillsammans!

Pulumis ram för integrationstestning är skriven i Go, vilket är hur vi testar det mesta av vår interna kod. Medan det tidigare diskuterade tillvägagångssättet för enhetstestning mer liknade white box-testning, är integrationstestning en svart låda. (Det finns också alternativ för rigorösa interna tester.) Detta ramverk skapades för att ta ett komplett Pulumi-program och utföra olika livscykeloperationer på det, som att distribuera en ny stack från början, uppdatera den med varianter och ta bort den, möjligen flera gånger . Vi kör dem regelbundet (till exempel på natten) och som stresstester.

(Vi vi jobbar på det, så att liknande funktioner för integrationstestning är tillgängliga i den inbyggda SDK för språk. Du kan använda Go-integreringstestramverket oavsett vilket språk ditt Pulumi-program är skrivet på).

Genom att köra programmet med detta ramverk kan du kontrollera följande:

  • Din projektkod är syntaktisk korrekt och körs utan fel.
  • Konfigurationsinställningarna för stack och hemligheter fungerar och tolkas korrekt.
  • Ditt projekt kan framgångsrikt distribueras i den molnleverantör du väljer.
  • Ditt projekt kan framgångsrikt uppgraderas från det ursprungliga tillståndet till N andra tillstånd.
  • Ditt projekt kan framgångsrikt förstöras och tas bort från din molnleverantör.

Som vi snart kommer att se kan detta ramverk också användas för att utföra körtidsvalidering.

Enkelt integrationstest

För att se detta i aktion, tittar vi på förvaret pulumi/examples, eftersom vårt team och Pulumi-communityt använder det för att testa våra egna pull-förfrågningar, commits och nattliga builds.

Nedan följer ett förenklat test av vår exempel som tillhandahåller S3 hink och några andra föremål:

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

Detta test går igenom den grundläggande livscykeln för att skapa, ändra och förstöra en stack för en mapp aws-js-s3-folder. Det tar ungefär en minut att rapportera ett godkänt test:

$ go test .
PASS
ok      ... 43.993s

Det finns många alternativ för att anpassa beteendet för dessa tester. Se hela listan med alternativ. i strukturen ProgramTestOptions. Till exempel kan du konfigurera Jaeger endpoint för att spåra (Tracing), ange att du förväntar dig att testet misslyckas om testet är negativt (ExpectFailure), tillämpa en serie "redigeringar" på programmet för en sekventiell övergång av tillstånd (EditDirs) och mycket mer. Låt oss se hur du använder dem för att testa din applikationsdistribution.

Kontrollera resursegenskaper

Integrationen som diskuteras ovan säkerställer att vårt program "fungerar" - det kraschar inte. Men vad händer om vi vill kontrollera egenskaperna hos den resulterande stacken? Till exempel att vissa typer av resurser har (eller inte) tillhandahållits och att de har vissa attribut.

Parameter ExtraRuntimeValidation för ProgramTestOptions tillåter oss att titta på tillståndet efter implementeringen som registrerats av Pulumi så att vi kan göra ytterligare kontroller. Detta inkluderar en fullständig ögonblicksbild av tillståndet för den resulterande stacken, inklusive konfiguration, exporterade utdatavärden, alla resurser och deras egenskapsvärden och alla beroenden mellan resurser.

För att se ett grundläggande exempel på detta, låt oss kontrollera att vårt program skapar en S3 hink:

  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ör go-test, kommer den inte bara att gå igenom ett batteri av livscykeltester, utan också, efter att ha lyckats distribuera stacken, kommer den att utföra en ytterligare kontroll av det resulterande tillståndet.

Runtime tester

Hittills har alla tester enbart handlat om utbyggnadsbeteende och Pulumis resursmodell. Vad händer om du vill verifiera att din provisionerade infrastruktur faktiskt fungerar? Till exempel att den virtuella maskinen är igång, S3-hinken innehåller det vi förväntar oss och så vidare.

Du kanske redan har gissat hur du gör detta: alternativ ExtraRuntimeValidation för ProgramTestOptions – det här är en fantastisk möjlighet för detta. Vid det här laget kör du ett anpassat Go-test med tillgång till hela statusen för ditt programs resurser. Det här tillståndet inkluderar information som IP-adresser för virtuella maskiner, URL:er och allt som behövs för att faktiskt interagera med de resulterande molnapplikationerna och infrastrukturen.

Vårt testprogram exporterar till exempel fastigheten webEndpoint hink kallas websiteUrl, som är den fullständiga webbadressen där vi kan konfigurera index document. Även om vi kunde gräva i tillståndsfilen för att hitta bucket och läs den egenskapen direkt, men i många fall exporterar våra stackar användbara egenskaper som denna som vi tycker är bekväma att använda för att kontrollera:

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!")
        },
    })

Liksom våra tidigare körtidskontroller kommer denna kontroll att utföras omedelbart efter att stacken har höjts, allt som svar på ett enkelt anrop go test. Och det är bara toppen av isberget – varje Go-testfunktion som du kan skriva i kod är tillgänglig.

Kontinuerlig infrastrukturintegration

Det är bra att kunna köra tester på en bärbar dator när många infrastrukturförändringar görs för att testa dem innan du skickar in dem för kodgranskning. Men vi och många av våra kunder testar infrastruktur i olika skeden av utvecklingens livscykel:

  • I varje öppen pull-förfrågan för testning innan sammanslagning.
  • Som svar på varje commit, för att dubbelkontrollera att sammanslagningen gjordes korrekt.
  • Periodvis, till exempel på natten eller varje vecka för ytterligare tester.
  • Som en del av prestations- eller stresstester, som vanligtvis löper över en lång tidsperiod och kör tester parallellt och/eller använder samma program flera gånger.

För var och en av dessa stöder Pulumi integration med ditt favoritsystem för kontinuerlig integration. Med kontinuerlig integration ger detta dig samma testtäckning för din infrastruktur som för din applikationsprogramvara.

Pulumi har stöd för vanliga CI-system. Här är några av dem:

För mer detaljerad information, se dokumentationen för Kontinuerlig leverans.

Efemära miljöer

En mycket kraftfull möjlighet som öppnar sig är möjligheten att distribuera tillfälliga miljöer enbart för acceptanstestning. Begrepp projekt och stackar Pulumi är designad för att enkelt distribuera och riva helt isolerade och oberoende miljöer, allt i några enkla CLI-kommandon eller med hjälp av ett ramverk för integrationstestning.

Om du använder GitHub så erbjuder Pulumi GitHub-appen, som hjälper dig att ansluta acceptanstestning för att hämta förfrågningar inom din CI-pipeline. Installera bara applikationen i GitHub-förvaret, så lägger Pulumi till information om infrastrukturförhandsvisningar, uppdateringar och testresultat till dina CI- och poolförfrågningar:

Testar infrastruktur som kod med Pulumi. Del 2

När du använder Pulumi för dina grundläggande acceptanstest får du nya automatiseringsfunktioner som förbättrar teamets produktivitet och ger dig förtroende för kvaliteten på dina ändringar.

Totalt

I den här artikeln har vi sett att genom att använda generella programmeringsspråk blir många tekniker för mjukvaruutveckling tillgängliga för oss som har varit användbara för att utveckla våra applikationer. De inkluderar enhetstestning, integrationstestning och hur de arbetar tillsammans för att utföra omfattande körtidstestning. Tester är lätta att köra på begäran eller i ditt CI-system.

Pulumi - programvara med öppen källkod, gratis att använda och fungerar med dina favoritprogrammeringsspråk och moln - prova idag!

Den första delen

Källa: will.com

Lägg en kommentar