Testowanie infrastruktury jako kodu za pomocą Pulumi. Część 2

Cześć wszystkim. Dziś dzielimy się z Wami ostatnią częścią artykułu. „Testowanie infrastruktury jako kodu za pomocą Pulumi”, którego tłumaczenie zostało przygotowane specjalnie dla studentów kursu „Praktyki i narzędzia DevOps”.

Testowanie infrastruktury jako kodu za pomocą Pulumi. Część 2

Testowanie wdrożeniowe

Ten styl testowania jest skutecznym podejściem i pozwala nam przeprowadzać testy białej skrzynki w celu przetestowania wewnętrznego działania naszego kodu infrastruktury. Jednak w pewnym stopniu ogranicza to, co możemy przetestować. Testy przeprowadzane są na podstawie planu wdrożenia w pamięci utworzonego przez Pulumi przed faktycznym wdrożeniem, dlatego samo wdrożenie nie może zostać przetestowane. W takich przypadkach Pulumi ma platformę testów integracyjnych. I te dwa podejścia świetnie ze sobą współpracują!

Framework do testowania integracji Pulumi jest napisany w Go i w ten sposób testujemy większość naszego wewnętrznego kodu. Podczas gdy omówione wcześniej podejście do testów jednostkowych przypominało bardziej testy białej skrzynki, testy integracyjne są czarną skrzynką. (Istnieją również opcje rygorystycznych testów wewnętrznych). Ta platforma została stworzona, aby wziąć kompletny program Pulumi i wykonywać na nim różne operacje cyklu życia, takie jak wdrażanie nowego stosu od zera, aktualizowanie go za pomocą odmian i usuwanie, prawdopodobnie wiele razy . Wykonujemy je regularnie (na przykład w nocy) oraz jako testy warunków skrajnych.

(My pracujemy nad tym, dzięki czemu podobne możliwości testowania integracji są dostępne w natywnym zestawie SDK języków. Możesz używać frameworka do testów integracyjnych Go niezależnie od języka, w którym napisany jest Twój program Pulumi).

Uruchamiając program przy użyciu tego frameworka, możesz sprawdzić, co następuje:

  • Kod Twojego projektu jest poprawny składniowo i działa bez błędów.
  • Ustawienia konfiguracji stosu i sekretów działają i są poprawnie interpretowane.
  • Twój projekt może zostać pomyślnie wdrożony u wybranego dostawcy chmury.
  • Twój projekt może zostać pomyślnie zaktualizowany ze stanu początkowego do N innych stanów.
  • Twój projekt może zostać pomyślnie zniszczony i usunięty od dostawcy usług w chmurze.

Jak wkrótce się przekonamy, tego frameworka można również używać do sprawdzania poprawności w czasie wykonywania.

Prosty test integracyjny

Aby zobaczyć to w akcji, zajrzymy do repozytorium pulumi/examples, ponieważ nasz zespół i społeczność Pulumi używają go do testowania własnych żądań ściągnięcia, zatwierdzeń i nocnych kompilacji.

Poniżej uproszczony test naszego przykład udostępniający wiadro S3 i kilka innych obiektów:

przykład_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,
        },
    })
}

Ten test przechodzi przez podstawowy cykl życia polegający na tworzeniu, modyfikowaniu i niszczeniu stosu folderu aws-js-s3-folder. Zgłoszenie zaliczonego testu zajmie około minuty:

$ go test .
PASS
ok      ... 43.993s

Istnieje wiele opcji dostosowywania zachowania tych testów. Zobacz pełną listę opcji. w strukturze ProgramTestOptions. Na przykład możesz skonfigurować punkt końcowy Jaeger do śledzenia (Tracing), wskazują, że spodziewasz się niepowodzenia testu, jeśli wynik testu będzie negatywny (ExpectFailure), zastosuj serię „edycji” programu w celu sekwencyjnego przejścia stanów (EditDirs) i wiele więcej. Zobaczmy, jak ich używać do testowania wdrożenia aplikacji.

Sprawdzanie właściwości zasobów

Omówiona powyżej integracja gwarantuje, że nasz program „działa” – nie ulega awarii. Co jednak, jeśli chcemy sprawdzić właściwości powstałego stosu? Na przykład, że określone typy zasobów zostały (lub nie zostały) udostępnione i mają określone atrybuty.

Parametr ExtraRuntimeValidation dla ProgramTestOptions pozwala nam sprawdzić stan po wdrożeniu zarejestrowany przez Pulumi, dzięki czemu możemy przeprowadzić dodatkowe kontrole. Obejmuje to pełną migawkę stanu wynikowego stosu, w tym konfigurację, wyeksportowane wartości wyjściowe, wszystkie zasoby i wartości ich właściwości oraz wszystkie zależności między zasobami.

Aby zobaczyć podstawowy przykład tego, sprawdźmy, czy nasz program go tworzy Wiadro S3:

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

Teraz, gdy uruchomimy go test, nie tylko przejdzie on przez szereg testów cyklu życia, ale także, po pomyślnym wdrożeniu stosu, wykona dodatkową kontrolę powstałego stanu.

Testy wykonawcze

Jak dotąd wszystkie testy dotyczyły wyłącznie zachowania podczas wdrażania i modelu zasobów Pulumi. A co jeśli chcesz sprawdzić, czy zapewniona infrastruktura faktycznie działa? Na przykład, że maszyna wirtualna jest uruchomiona, wiadro S3 zawiera to, czego oczekujemy, i tak dalej.

Być może już zgadłeś, jak to zrobić: opcja ExtraRuntimeValidation dla ProgramTestOptions – to świetna ku temu okazja. W tym momencie uruchamiasz niestandardowy test Go z dostępem do pełnego stanu zasobów programu. Ten stan obejmuje informacje, takie jak adresy IP maszyn wirtualnych, adresy URL i wszystko, co jest potrzebne do faktycznej interakcji z powstałymi aplikacjami i infrastrukturą w chmurze.

Na przykład nasz program testowy eksportuje właściwość webEndpoint wiadro zadzwoniło websiteUrl, czyli pełny adres URL, pod którym możemy uzyskać konfigurację index document. Chociaż moglibyśmy pogrzebać w pliku stanu, aby znaleźć bucket i bezpośrednio czytaj tę właściwość, ale w wielu przypadkach nasze stosy eksportują przydatne właściwości, takie jak te, które uważamy za wygodne w użyciu do sprawdzania:

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

Podobnie jak nasze poprzednie kontrole w czasie wykonywania, ta kontrola zostanie wykonana natychmiast po podniesieniu stosu, a wszystko to w odpowiedzi na proste wywołanie go test. A to tylko wierzchołek góry lodowej — dostępna jest każda funkcja testowa Go, którą możesz napisać w kodzie.

Ciągła integracja infrastruktury

Dobrze jest móc przeprowadzić testy na laptopie, gdy wprowadzanych jest wiele zmian w infrastrukturze, aby je przetestować przed przesłaniem ich do przeglądu kodu. Jednak my i wielu naszych klientów testujemy infrastrukturę na różnych etapach cyklu życia oprogramowania:

  • W każdym otwartym żądaniu ściągnięcia w celu przetestowania przed połączeniem.
  • W odpowiedzi na każde zatwierdzenie, aby dokładnie sprawdzić, czy scalanie zostało wykonane poprawnie.
  • Okresowo, na przykład wieczorem lub co tydzień w celu przeprowadzenia dodatkowych badań.
  • W ramach testów wydajnościowych lub testów warunków skrajnych, które zazwyczaj trwają przez długi czas i przeprowadzają testy równolegle i/lub wielokrotne wdrażanie tego samego programu.

Dla każdego z nich Pulumi wspiera integrację z Twoim ulubionym systemem ciągłej integracji. Dzięki ciągłej integracji zapewnia to taki sam zakres testów dla infrastruktury, jak dla oprogramowania aplikacyjnego.

Pulumi obsługuje popularne systemy CI. Tutaj jest kilka z nich:

Bardziej szczegółowe informacje można znaleźć w dokumentacji dot Ciągłe dostawy.

Środowiska efemeryczne

Bardzo potężną możliwością, jaka się otwiera, jest możliwość wdrażania środowisk efemerycznych wyłącznie do celów testów akceptacyjnych. Pojęcie projekty i stosy Pulumi zaprojektowano z myślą o łatwym wdrażaniu i niszczeniu całkowicie odizolowanych i niezależnych środowisk, a wszystko to za pomocą kilku prostych poleceń CLI lub przy użyciu platformy testów integracyjnych.

Jeśli korzystasz z GitHuba, Pulumi oferuje Aplikacja GitHub, które pomogą Ci połączyć testy akceptacyjne z żądaniami ściągania w ramach potoku CI. Wystarczy zainstalować aplikację w repozytorium GitHub, a Pulumi doda informacje o podglądach infrastruktury, aktualizacjach i wynikach testów do Twoich żądań CI i puli:

Testowanie infrastruktury jako kodu za pomocą Pulumi. Część 2

Używając Pulumi do kluczowych testów akceptacyjnych, zyskasz nowe możliwości automatyzacji, które poprawią produktywność zespołu i dadzą Ci pewność co do jakości wprowadzanych zmian.

Łączny

W tym artykule widzieliśmy, że dzięki używaniu języków programowania ogólnego przeznaczenia dostępnych jest wiele technik tworzenia oprogramowania, które okazały się przydatne przy tworzeniu naszych aplikacji. Obejmują one testy jednostkowe, testy integracyjne oraz sposób ich współpracy w celu przeprowadzenia szeroko zakrojonych testów w czasie wykonywania. Testy można łatwo uruchomić na żądanie lub w systemie CI.

Pulumi - oprogramowanie open source, bezpłatne i współpracujące z Twoimi ulubionymi językami programowania i chmurami - spróbuj dzisiaj!

Pierwsza część

Źródło: www.habr.com

Dodaj komentarz