Testare l'infrastruttura come codice con Pulumi. Parte 2

Ciao a tutti. Oggi condividiamo con voi la parte finale dell'articolo. "Testare l'infrastruttura come codice con Pulumi", la cui traduzione è stata preparata appositamente per gli studenti del corso "Pratiche e strumenti DevOps".

Testare l'infrastruttura come codice con Pulumi. Parte 2

Test di distribuzione

Questo stile di test è un approccio potente e ci consente di eseguire test white box per testare il funzionamento interno del nostro codice infrastrutturale. Tuttavia, ciò limita in qualche modo ciò che possiamo testare. I test vengono eseguiti in base al piano di distribuzione in memoria creato da Pulumi prima della distribuzione effettiva e pertanto la distribuzione stessa non può essere testata. Per questi casi, Pulumi dispone di un framework di test di integrazione. E questi due approcci funzionano benissimo insieme!

Il framework di testing dell'integrazione Pulumi è scritto in Go, che è il modo in cui testiamo la maggior parte del nostro codice interno. Mentre l’approccio del test unitario discusso in precedenza era più simile al test della scatola bianca, il test di integrazione è una scatola nera. (Ci sono anche opzioni per rigorosi test interni.) Questo framework è stato creato per prendere un programma Pulumi completo ed eseguire varie operazioni del ciclo di vita su di esso, come distribuire un nuovo stack da zero, aggiornarlo con variazioni ed eliminarlo, possibilmente più volte . Li eseguiamo regolarmente (ad esempio di notte) e come stress test.

(Noi ci stiamo lavorando, in modo che funzionalità di test di integrazione simili siano disponibili nell'SDK nativo delle lingue. Puoi utilizzare il framework di testing dell'integrazione Go indipendentemente dalla lingua in cui è scritto il tuo programma Pulumi).

Eseguendo il programma utilizzando questo framework è possibile verificare quanto segue:

  • Il codice del tuo progetto è sintatticamente corretto e viene eseguito senza errori.
  • Le impostazioni di configurazione dello stack e dei segreti funzionano e vengono interpretate correttamente.
  • Il tuo progetto può essere implementato con successo nel provider cloud di tua scelta.
  • Il tuo progetto può essere aggiornato con successo dallo stato iniziale ad N altri stati.
  • Il tuo progetto può essere distrutto e rimosso con successo dal tuo provider cloud.

Come vedremo tra breve, questo framework può essere utilizzato anche per eseguire la validazione del runtime.

Test di integrazione semplice

Per vederlo in azione, esamineremo il repository pulumi/examples, poiché il nostro team e la comunità Pulumi lo utilizzano per testare le nostre richieste pull, commit e build notturne.

Di seguito è riportato un test semplificato del ns esempio che fornisce il bucket S3 e alcuni altri oggetti:

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

Questo test attraversa il ciclo di vita di base della creazione, modifica e distruzione di uno stack per una cartella aws-js-s3-folder. Ci vorrà circa un minuto per segnalare un test superato:

$ go test .
PASS
ok      ... 43.993s

Sono disponibili molte opzioni per personalizzare il comportamento di questi test. Visualizza l'elenco completo delle opzioni. nella struttura ProgramTestOptions. Ad esempio, puoi configurare l'endpoint Jaeger per tracciare (Tracing), indicano che si prevede che il test fallisca se il test risulta negativo (ExpectFailure), applicare una serie di “modifiche” al programma per una transizione sequenziale di stati (EditDirs) e altro ancora. Vediamo come utilizzarli per testare la distribuzione dell'applicazione.

Controllo delle proprietà delle risorse

L'integrazione discussa sopra garantisce che il nostro programma "funzioni" e non si blocchi. Ma cosa succede se vogliamo verificare le proprietà dello stack risultante? Ad esempio, che è stato effettuato (o meno) il provisioning di determinati tipi di risorse e che hanno determinati attributi.

Parametro ExtraRuntimeValidation per ProgramTestOptions ci consente di esaminare lo stato post-distribuzione registrato da Pulumi in modo da poter effettuare ulteriori controlli. Ciò include uno snapshot completo dello stato dello stack risultante, inclusa la configurazione, i valori di output esportati, tutte le risorse e i relativi valori delle proprietà e tutte le dipendenze tra le risorse.

Per vedere un esempio di base, controlliamo che il nostro programma ne crei uno Secchio 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")
        },
    })

Ora, quando eseguiamo il go test, non solo verrà eseguito una serie di test del ciclo di vita, ma, dopo aver distribuito con successo lo stack, verrà eseguito un controllo aggiuntivo sullo stato risultante.

Test di esecuzione

Finora, tutti i test hanno riguardato esclusivamente il comportamento di distribuzione e il modello di risorsa Pulumi. E se volessi verificare che la tua infrastruttura fornita funzioni effettivamente? Ad esempio, che la macchina virtuale sia in esecuzione, che il bucket S3 contenga ciò che ci aspettiamo e così via.

Potresti aver già indovinato come farlo: opzione ExtraRuntimeValidation per ProgramTestOptions - questa è una grande opportunità per questo. A questo punto, esegui un Go test personalizzato con accesso allo stato completo delle risorse del tuo programma. Questo stato include informazioni come indirizzi IP delle macchine virtuali, URL e tutto ciò che è necessario per interagire effettivamente con le applicazioni e l'infrastruttura cloud risultanti.

Ad esempio, il nostro programma di test esporta la proprietà webEndpoint secchio chiamato websiteUrl, che è l'URL completo da cui è possibile ottenere il file configurato index document. Anche se potremmo scavare nel file di stato per trovare bucket e leggiamo direttamente quella proprietà, ma in molti casi i nostri stack esportano proprietà utili come questa che troviamo conveniente utilizzare per controllare:

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

Come i nostri precedenti controlli di runtime, questo controllo verrà eseguito immediatamente dopo aver aumentato lo stack, il tutto in risposta a una semplice chiamata go test. E questa è solo la punta dell'iceberg: tutte le funzionalità di Go test che puoi scrivere nel codice sono disponibili.

Integrazione continua dell'infrastruttura

È utile poter eseguire test su un laptop quando vengono apportate molte modifiche all'infrastruttura per testarli prima di inviarli per la revisione del codice. Ma noi e molti dei nostri clienti testiamo l'infrastruttura in varie fasi del ciclo di vita dello sviluppo:

  • In ogni richiesta pull aperta per il test prima della fusione.
  • In risposta a ciascun commit, per ricontrollare che l'unione sia stata eseguita correttamente.
  • Periodicamente, ad esempio di notte o settimanalmente per ulteriori test.
  • Come parte di test di prestazioni o stress, che in genere vengono eseguiti per un lungo periodo di tempo ed eseguono test in parallelo e/o distribuiscono lo stesso programma più volte.

Per ognuno di questi, Pulumi supporta l'integrazione con il tuo sistema di integrazione continua preferito. Con l'integrazione continua, questo ti offre la stessa copertura di test per la tua infrastruttura e per il tuo software applicativo.

Pulumi supporta i comuni sistemi CI. Ecco qui alcuni di loro:

Per informazioni più dettagliate fare riferimento alla documentazione di Consegna continua.

Ambienti effimeri

Un'opportunità molto potente che si apre è la possibilità di distribuire ambienti temporanei esclusivamente a scopo di test di accettazione. Concetto progetti e stack Pulumi è progettato per distribuire e rimuovere facilmente ambienti completamente isolati e indipendenti, il tutto con pochi semplici comandi CLI o utilizzando un framework di test di integrazione.

Se usi GitHub, Pulumi offre Applicazione GitHub, che ti aiuterà a connettere i test di accettazione alle richieste pull all'interno della pipeline CI. Basta installare l'applicazione nel repository GitHub e Pulumi aggiungerà informazioni sulle anteprime dell'infrastruttura, sugli aggiornamenti e sui risultati dei test alle tue richieste CI e pool:

Testare l'infrastruttura come codice con Pulumi. Parte 2

Quando utilizzi Pulumi per i tuoi principali test di accettazione, otterrai nuove funzionalità di automazione che miglioreranno la produttività del team e ti daranno fiducia nella qualità delle tue modifiche.

risultato

In questo articolo, abbiamo visto che utilizzando linguaggi di programmazione generici, diventano disponibili molte tecniche di sviluppo software che sono state utili nello sviluppo delle nostre applicazioni. Includono test unitari, test di integrazione e il modo in cui lavorano insieme per eseguire test estesi di runtime. I test sono facili da eseguire su richiesta o nel tuo sistema CI.

Pulumi - software open source, gratuito da usare e funziona con i tuoi linguaggi di programmazione e cloud preferiti - provalo oggi!

La prima parte

Fonte: habr.com

Aggiungi un commento