Ciao a tutti. Oggi condividiamo con voi l'ultima parte dell'articolo , una traduzione preparata appositamente per gli studenti del corso .

Test di distribuzione
Lo stile di test trattato è un potente approccio che ci consente di effettuare test a scatola bianca per controllare il funzionamento interno del nostro codice infrastrutturale. Tuttavia, limita alcune delle cose che possiamo testare. I test vengono eseguiti sulla base di un piano di distribuzione in memoria creato da Pulumi prima della distribuzione effettiva, e quindi la distribuzione stessa non può essere testata. In questi casi, Pulumi ha un framework per test di integrazione. E questi due approcci funzionano magnificamente insieme!
Il framework di testing di integrazione Pulumi è scritto in Go e grazie a esso testiamo gran parte del nostro codice interno. Se l'approccio al testing modulare descritto in precedenza era più simile a un testing di white box, il testing di integrazione è un black box. (Ci sono anche varianti di testing interno approfondito.) Questo framework è stato creato per prendere un'intera applicazione Pulumi e svolgere varie operazioni del ciclo di vita, come il deploy di un nuovo stack da zero, il suo aggiornamento con variazioni e la sua eliminazione, potenzialmente più volte. Li eseguiamo regolarmente (ad esempio, durante la notte) e come test di stress.
(Noi , affinché possibilità simili di testing di integrazione siano disponibili nel SDK nativo dei linguaggi. Puoi usare il framework di testing di integrazione Go indipendentemente dal linguaggio con cui è scritta la tua applicazione Pulumi).
Eseguendo l'applicazione utilizzando questo framework, puoi verificare quanto segue:
- Il codice del tuo progetto è sintatticamente corretto e funziona senza errori.
- Le impostazioni di configurazione dello stack e dei segreti funzionano e vengono interpretate correttamente.
- Il tuo progetto può essere distribuito con successo nel provider cloud da te scelto.
- Il tuo progetto può essere aggiornato con successo dallo stato iniziale a N altri stati.
- Il tuo progetto può essere distrutto e rimosso dal tuo provider cloud.
Come vedremo presto, questo framework può essere utilizzato anche per eseguire la validazione di runtime.
Un test di integrazione semplice
Per vedere questo in azione, guarderemo il repository pulumi/examples, poiché il nostro team e la comunità Pulumi lo utilizzano per testare le proprie richieste pull, commit e build notturne.
Di seguito è riportato un test semplificato del nostro :
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,
},
})
} Questo test passa attraverso 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 riportare il test completato:
$ go test .
PASS
ok ... 43.993s Ci sono molti parametri per configurare il comportamento di questi test. Un elenco completo delle opzioni è disponibile. ProgramTestOptions. Ad esempio, puoi configurare l'endpoint Jaeger per il tracciamento (Tracing), indicare che ti aspetti un fallimento del test durante i test negativi (ExpectFailure), applicare una serie di “correzioni” al programma per la transizione sequenziale degli stati (EditDirs) e molto altro ancora. Vediamo come usarli per verificare il deployment dell'applicazione.
Verifica delle proprietà delle risorse
L'integrazione di cui si è parlato sopra garantisce che il nostro programma 'funzioni'—non si arresta. Ma cosa succede se vogliamo controllare le proprietà dello stack ottenuto? Ad esempio, che determinati tipi di risorse siano (o non siano) stati preparati e che abbiano determinati attributi.
Caratteristica ExtraRuntimeValidation per ProgramTestOptions ci permette di esaminare lo stato registrato da Pulumi dopo il deployment (post-deployment state), così possiamo effettuare controlli aggiuntivi. Questo include una fotografia completa dello stato dello stack risultante, comprese le configurazioni, i valori di output esportati, tutte le risorse e i valori delle loro proprietà, oltre a tutte le dipendenze tra le risorse.
Per vedere un esempio di base di questo, controlliamo che il nostro programma crei un S3 Bucket:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// come prima...
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 eseguiremo go test, non solo passerà attraverso una serie di test del ciclo di vita, ma, dopo un successful deployment dello stack, eseguirà anche un controllo aggiuntivo dello stato risultante.
Runtime-test
Fino ad ora, tutti i test si sono concentrati esclusivamente sul comportamento durante il deployment e sul modello delle risorse di Pulumi. Cosa fare se vuoi verificare che la tua infrastruttura predisposta funzioni davvero? Ad esempio, che la macchina virtuale sia in esecuzione, che il bucket S3 contenga ciò che ci aspettiamo e così via.
Hai già intuito come farlo: l'opzione ExtraRuntimeValidation per ProgramTestOptions è un'ottima opportunità per questo. A questo punto, esegui un test Go arbitrario con accesso allo stato completo delle risorse della tua applicazione. Questo stato include informazioni come gli indirizzi IP delle macchine virtuali, gli URL e tutto ciò che è necessario per interagire realmente con le applicazioni e l'infrastruttura cloud ricevute.
Ad esempio, il nostro programma di test esporta la proprietà webEndpoint del bucket chiamato websiteUrl, che rappresenta l'URL completo attraverso cui possiamo accedere al documento index. Anche se potremmo dare un'occhiata al file di stato per trovare bucket e leggere direttamente questa proprietà, in molti casi i nostri stack esportano proprietà utili, come questa, che ci è comodo utilizzare per le verifiche:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// come sempre ...
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 runtime, questo controllo verrà eseguito subito dopo il deploy dello stack, e tutto questo in risposta a una semplice chiamata. go test. E questa è solo la punta dell'iceberg: sono disponibili tutte le capacità di test di Go che puoi scrivere nel codice.
Integrazione continua dell'infrastruttura
È utile poter eseguire test sul laptop quando vengono apportate molte modifiche all'infrastruttura, per verificarle prima di inviarle per la revisione del codice. Ma anche noi e molti dei nostri clienti testiamo l'infrastruttura in vari stadi del ciclo di vita dello sviluppo:
- In ogni pull request aperta per test prima della fusione.
- In risposta a ogni commit, per ricontrollare che la fusione sia stata eseguita correttamente.
- Periodicamente, ad esempio, di notte o settimanalmente per ulteriori test.
- Nell'ambito delle prove di prestazione o dei test di stress, che di solito vengono eseguiti per un lungo periodo e lanciano test in parallelo e/o distribuiscono lo stesso programma più volte.
Per ognuno di essi, Pulumi supporta l'integrazione con il tuo sistema di integrazione continua preferito. Con l'integrazione continua, questo ti offre una copertura dei test per la tua infrastruttura, esattamente come per il software applicativo.
Pulumi ha supporto per i sistemi CI più comuni. Ecco alcuni di essi:
Per ulteriori informazioni, consulta la documentazione su .
Ambienti efimeri
Una possibilità molto potente che si apre è quella di distribuire ambienti efimeri esclusivamente per scopi di test di accettazione. Il concetto di Pulumi è progettata per facilitare il deploy e la rimozione di ambienti completamente isolati e indipendenti, il tutto con alcuni semplici comandi CLI o tramite un framework di test di integrazione.
Se utilizzi GitHub, Pulumi offre , che ti aiuterà a collegare il testing di accettazione alle pull request all'interno del tuo pipeline CI. Basta installare l'app nel repository GitHub e Pulumi nel tuo CI, e le pull request saranno arricchite con informazioni sull'anteprima dell'infrastruttura, aggiornamenti e risultati dei test:

Utilizzando Pulumi per i tuoi principali test di accettazione, avrai nuove opportunità di automazione che miglioreranno le prestazioni del team e garantiranno la qualità delle modifiche.
Risultato
In questo articolo abbiamo visto che, utilizzando linguaggi di programmazione di uso generale, abbiamo accesso a molti metodi per lo sviluppo software che sono stati utili nella creazione delle nostre applicazioni. Questi includono il testing modulare, il testing di integrazione, e la loro combinazione per eseguire ampi test runtime. I test possono essere facilmente avviati su richiesta o nel vostro sistema CI.
Pulumi — è un software open source, gratuito da usare e compatibile con i vostri linguaggi di programmazione e cloud preferiti — !
→
Fonte: habr.com
