Testowanie infrastruktury jako kod z użyciem Pulumi. Część 2

Cześć wszystkim. Dzisiaj dzielimy się z wami końcową częścią artykułu «Testowanie infrastruktury jako kod z pomocą Pulumi», tłumaczenie którego przygotowano specjalnie dla studentów kursu „Praktyki i narzędzia DevOps“.

Testowanie infrastruktury jako kod z użyciem Pulumi. Część 2

Testowanie wdrożenia

Omówiony styl testowania to potężne podejście, które pozwala nam przeprowadzać testy białej skrzynki w celu sprawdzenia wewnętrznych operacji naszego kodu infrastrukturalnego. Jednakże nieco ogranicza to, co możemy sprawdzić. Testy są przeprowadzane na podstawie wirtualnego planu wdrożenia, stworzonego przez Pulumi przed rzeczywistym wdrożeniem, co uniemożliwia przetestowanie samego procesu wdrożenia. W takich przypadkach Pulumi posiada framework integracyjnych testów, które doskonale współdziałają z tymi dwoma podejściami!

Framework integracyjnego testowania Pulumi jest napisany w Go i to właśnie dzięki niemu testujemy większość naszego wewnętrznego kodu. Jeśli wcześniej omówione podejście testowania jednostkowego bardziej przypominało testy białej skrzynki, to testowanie integracyjne to testowanie czarnej skrzynki. (Istnieją również możliwości dokładnego testowania wewnętrznego.) Framework ten został stworzony z myślą o wzięciu pełnej aplikacji Pulumi i przeprowadzeniu dla niej różnych operacji w cyklu życia, takich jak wdrożenie nowego stosu od zera, jego aktualizacja z różnymi wariantami oraz usunięcie, mogące odbywać się kilka razy. Regularnie je wykonujemy (na przykład w nocy) oraz jako testy obciążeniowe.

(Pracujemy nad tym , aby podobne możliwości testowania integracyjnego były dostępne w natywne SDK języków. Możesz korzystać z frameworku integracyjnego testowania Go niezależnie od języka, w którym napisana jest twoja aplikacja Pulumi.)Uruchamiając program za pomocą tego frameworku możesz sprawdzić następujące:

Twój kod projektu jest syntaktycznie poprawny i działa bez błędów.

  • Ustawienia konfiguracji stosu i sekretów działają i są poprawnie interpretowane.
  • Twój projekt może być pomyślnie wdrożony w wybranym przez ciebie dostawcy chmury.
  • Twój projekt może być pomyślnie zaktualizowany od stanu początkowego do N innych stanów.
  • Twój projekt może być pomyślnie zniszczony i usunięty z twojego dostawcy chmury.
  • Jak wkrótce zobaczymy, ten framework można także wykorzystać do przeprowadzania walidacji runtime.

Jak wkrótce zobaczymy, ten framework można również wykorzystać do przeprowadzania walidacji w czasie rzeczywistym.

Prosty test integracyjny

Aby zobaczyć to w działaniu, przyjrzymy się repozytorium pulumi/examples, ponieważ nasz zespół i społeczność Pulumi korzystają z niego do testowania własnych pull requestów, commitów i nocnych kompilacji.

Poniżej znajduje się uproszczony test naszego przykładu, który tworzy S3 bucket oraz inne obiekty:

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

Ten test przechodzi przez podstawowy cykl życia tworzenia, modyfikacji i niszczenia stosu dla folderu aws-js-s3-folder. Zajmie to około minuty, aby zgłosić zakończony test:

$ go test .
PASS
ok      ... 43.993s

Istnieje wiele parametrów do dostosowania zachowania tych testów. Pełna lista opcji znajduje się w strukturze ProgramTestOptions. Na przykład możesz skonfigurować punkt końcowy Jaeger do śledzenia (Tracing), wskazać, że oczekujesz na awarię testu podczas testowania negatywnego (ExpectFailure), zastosować serię „poprawek” do programu, aby stopniowo przechodzić przez stany (EditDirs) i wiele więcej. Zobaczmy, jak użyć ich do sprawdzenia wdrożenia aplikacji.

Sprawdzanie właściwości zasobów

Integracja, o której mówiliśmy wcześniej, gwarantuje, że nasz program „działa” — nie kończy się awarią. Ale co, jeśli chcemy sprawdzić właściwości otrzymanego stosu? Na przykład, czy określone typy zasobów zostały (lub nie zostały) przygotowane i czy mają określone atrybuty.

Parametr ExtraRuntimeValidation do ProgramTestOptions pozwala nam spojrzeć na stan zarejestrowany przez Pulumi po wdrożeniu (post-deployment state), abyśmy mogli przeprowadzić dodatkowe kontrole. Obejmuje to pełny zrzut stanu wynikowego stosu, w tym konfigurację, eksportowane wartości wyjściowe, wszystkie zasoby i wartości ich właściwości, a także wszystkie zależności między zasobami.

Aby zobaczyć podstawowy przykład tego, sprawdźmy, że nasz program tworzy jeden S3 Bucket:

  integration.ProgramTest(t, &integration.ProgramTestOptions{
        // jak wcześniej...
        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, "Oczekiwano znalezienia pojedynczego koszyka AWS S3")
        },
    })

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

Testy w czasie wykonywania

Do tej pory wszystkie testy dotyczyły wyłącznie zachowania przy wdrażaniu i modelu zasobów Pulumi. Co zrobić, jeśli chcesz sprawdzić, czy twoja przygotowana infrastruktura naprawdę działa? Na przykład, czy maszyna wirtualna działa, koszyk S3 zawiera to, czego się spodziewamy itd.

Możesz się domyślać, jak to zrobić: opcja ExtraRuntimeValidation do ProgramTestOptions — to doskonała okazja do tego. Na tym etapie uruchamiasz dowolny test Go z dostępem do pełnego stanu zasobów twojego programu. Stan ten zawiera informacje takie jak adresy IP maszyn wirtualnych, adresy URL i wszystko, co jest potrzebne do rzeczywistej interakcji z rzekomo uzyskanymi aplikacjami w chmurze i infrastrukturą.

Na przykład, nasz program testowy eksportuje właściwość webEndpoint koszyka o nazwie websiteUrl, która stanowi pełny adres URL, pod którym możemy uzyskać dostęp do skonfigurowanego index document. Choć moglibyśmy przeszukać plik stanu, aby znaleźć bucket i odczytać tę właściwość bezpośrednio, w wielu przypadkach nasze stosy eksportują przydatne właściwości, takie jak ta, które wygodnie używać do kontroli:

integration.ProgramTest(t, &integration.ProgramTestOptions{
            // jak wcześniej ...
        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 będzie wykonywana zaraz po uruchomieniu stosu, a wszystko to w odpowiedzi na proste wywołanie go test. I to tylko wierzchołek góry lodowej – wszystkie możliwości testowe Go są dostępne, i można je napisać w kodzie.

Ciągła integracja infrastruktury

Dobrze jest móc uruchamiać testy na laptopie, gdy wprowadza się wiele zmian w infrastrukturze, aby sprawdzić je przed przekazaniem do przeglądu kodu. My i wielu naszych klientów testujemy infrastrukturę na różnych etapach cyklu życia rozwoju:

  • W każdym otwartym pull requeście przed połączeniem dla testu.
  • W odpowiedzi na każdy commit, aby ponownie sprawdzić, że połączenie zostało wykonane poprawnie.
  • Okresowo, na przykład w nocy lub co tydzień dla dodatkowego testowania.
  • W ramach testowania wydajności lub testów obciążeniowych, które zazwyczaj są przeprowadzane przez dłuższy czas i uruchamiają testy równolegle i/lub wdrażają ten sam program wielokrotnie.

Dla każdego z nich Pulumi wspiera integrację z Twoim ulubionym systemem ciągłej integracji. W przypadku ciągłej integracji zapewnia to takie samo pokrycie testami dla Twojej infrastruktury, jak dla aplikacji.

W Pulumi istnieje wsparcie dla popularnych systemów CI. Oto niektóre z nich:

Aby uzyskać więcej informacji, zapoznaj się z dokumentacją na temat Continuous Delivery.

Efemeryczne środowiska

Bardzo potężna możliwość, która się otwiera – to możliwość wdrażania efemerycznych środowisk wyłącznie w celach testów akceptacyjnych. Koncepcja projektów i stosów Pulumi została zaprojektowana w taki sposób, aby łatwo wdrażać i usuwać całkowicie izolowane i niezależne środowiska, wszystko w kilku prostych poleceniach CLI lub przy pomocy frameworka testowania integracyjnego.

Jeśli korzystasz z GitHub, Pulumi oferuje GitHub App, które pomoże ci podłączyć testy akceptacyjne do pull requestów w ramach twojego potoku CI. Po prostu zainstaluj aplikację w repozytorium GitHub, a Pulumi w twoim CI i w pull requestach zostanie dodana informacja o podglądzie infrastruktury, aktualizacjach i wynikach testów:

Testowanie infrastruktury jako kod z użyciem Pulumi. Część 2

Korzystając z Pulumi do swoich głównych testów akceptacyjnych, zyskasz nowe możliwości automatyzacji, które poprawią wydajność zespołu i zwiększą pewność co do jakości zmian.

Podsumowanie

W tym artykule zobaczyliśmy, że korzystając z ogólnych języków programowania, mamy dostęp do wielu metod rozwoju oprogramowania, które były przydatne przy tworzeniu naszych aplikacji. Obejmują one testowanie modułowe, testowanie integracyjne, a także ich interakcję w celu przeprowadzania wszechstronnych testów runtime. Testy można łatwo uruchamiać na żądanie lub w Twoim systemie CI.

Pulumi — oprogramowanie open source, jest darmowe w użyciu i działa z Twoimi ulubionymi językami programowania oraz chmurami — wypróbuj go dzisiaj!

Pierwsza część

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster