Testando infraestrutura como código com Pulumi. Parte 2

Olá a todos. Hoje compartilhamos com vocês a parte final do artigo. "Testando infraestrutura como código com Pulumi", cuja tradução foi preparada especificamente para alunos do curso "Práticas e ferramentas DevOps".

Testando infraestrutura como código com Pulumi. Parte 2

Teste de implantação

Esse estilo de teste é uma abordagem poderosa e nos permite realizar testes de caixa branca para testar o funcionamento interno do nosso código de infraestrutura. No entanto, limita um pouco o que podemos testar. Os testes são realizados com base no plano de implantação na memória criado por Pulumi antes da implantação real e, portanto, a implantação em si não pode ser testada. Para tais casos, Pulumi possui um framework de testes de integração. E essas duas abordagens funcionam muito bem juntas!

A estrutura de teste de integração Pulumi é escrita em Go, que é como testamos a maior parte do nosso código interno. Embora a abordagem de teste de unidade discutida anteriormente fosse mais parecida com um teste de caixa branca, o teste de integração é uma caixa preta. (Também existem opções para testes internos rigorosos.) Esta estrutura foi criada para pegar um programa Pulumi completo e executar várias operações de ciclo de vida nele, como implantar uma nova pilha do zero, atualizá-la com variações e excluí-la, possivelmente várias vezes. . Nós os executamos regularmente (por exemplo, à noite) e como testes de estresse.

(Nós estamos trabalhando nisso, para que recursos de teste de integração semelhantes estejam disponíveis no SDK nativo das linguagens. Você pode usar a estrutura de teste de integração Go independentemente da linguagem em que seu programa Pulumi foi escrito).

Ao executar o programa usando esta estrutura você pode verificar o seguinte:

  • O código do seu projeto está sintaticamente correto e é executado sem erros.
  • As definições de configuração de pilha e segredos funcionam e são interpretadas corretamente.
  • Seu projeto pode ser implantado com sucesso no provedor de nuvem de sua escolha.
  • Seu projeto pode ser atualizado com êxito do estado inicial para N outros estados.
  • Seu projeto pode ser destruído e removido com sucesso do seu provedor de nuvem.

Como veremos em breve, este framework também pode ser usado para realizar validação em tempo de execução.

Teste de integração simples

Para ver isso em ação, daremos uma olhada no repositório pulumi/examples, já que nossa equipe e a comunidade Pulumi o usam para testar nossas próprias solicitações pull, commits e builds noturnos.

Abaixo está um teste simplificado do nosso exemplo que fornece bucket S3 e alguns outros objetos:

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

Este teste passa pelo ciclo de vida básico de criação, modificação e destruição de uma pilha de uma pasta aws-js-s3-folder. Levará cerca de um minuto para relatar um teste aprovado:

$ go test .
PASS
ok      ... 43.993s

Existem muitas opções para personalizar o comportamento desses testes. Veja a lista completa de opções. na estrutura ProgramTestOptions. Por exemplo, você pode configurar o endpoint Jaeger para rastrear (Tracing), indique que você espera que o teste falhe se o teste for negativo (ExpectFailure), aplicar uma série de “edições” ao programa de transição sequencial de estados (EditDirs) e muito mais. Vamos ver como usá-los para testar a implantação do seu aplicativo.

Verificando propriedades de recursos

A integração discutida acima garante que nosso programa “funcione” – ele não trave. Mas e se quisermos verificar as propriedades da pilha resultante? Por exemplo, que determinados tipos de recursos foram (ou não) provisionados e que possuem determinados atributos.

Parâmetro ExtraRuntimeValidation para ProgramTestOptions nos permite observar o estado pós-implantação registrado pelo Pulumi para que possamos fazer verificações adicionais. Isso inclui um instantâneo completo do estado da pilha resultante, incluindo configuração, valores de saída exportados, todos os recursos e seus valores de propriedade e todas as dependências entre recursos.

Para ver um exemplo básico disso, vamos verificar se nosso programa cria um Balde 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")
        },
    })

Agora, quando executarmos go test, ele não apenas passará por uma bateria de testes de ciclo de vida, mas também, após implantar a pilha com sucesso, realizará uma verificação adicional no estado resultante.

Testes de tempo de execução

Até agora, todos os testes foram puramente sobre o comportamento de implantação e o modelo de recursos Pulumi. E se você quiser verificar se sua infraestrutura provisionada realmente funciona? Por exemplo, se a máquina virtual está em execução, o bucket S3 contém o que esperamos e assim por diante.

Você já deve ter adivinhado como fazer isso: opção ExtraRuntimeValidation para ProgramTestOptions - esta é uma grande oportunidade para isso. Neste ponto, você executa um teste Go personalizado com acesso ao estado completo dos recursos do seu programa. Esse estado inclui informações como endereços IP de máquinas virtuais, URLs e tudo o que é necessário para realmente interagir com os aplicativos e a infraestrutura em nuvem resultantes.

Por exemplo, nosso programa de teste exporta a propriedade webEndpoint balde chamado websiteUrl, que é o URL completo onde podemos obter o configurado index document. Embora pudéssemos pesquisar no arquivo de estado para encontrar bucket e lemos essa propriedade diretamente, mas em muitos casos nossas pilhas exportam propriedades úteis como esta que achamos convenientes para usar para verificação:

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

Como nossas verificações de tempo de execução anteriores, esta verificação será executada imediatamente após aumentar a pilha, tudo em resposta a uma simples chamada go test. E isso é apenas a ponta do iceberg: todos os recursos de teste Go que você pode escrever em código estão disponíveis.

Integração Contínua de Infraestrutura

É bom poder executar testes em um laptop quando muitas alterações na infraestrutura estão sendo feitas para testá-los antes de enviá-los para revisão de código. Mas nós e muitos de nossos clientes testamos a infraestrutura em vários estágios do ciclo de vida de desenvolvimento:

  • Em cada solicitação pull aberta para teste antes da fusão.
  • Em resposta a cada commit, para verificar se a mesclagem foi feita corretamente.
  • Periodicamente, como à noite ou semanalmente, para testes adicionais.
  • Como parte de testes de desempenho ou de estresse, que normalmente são executados durante um longo período de tempo e executam testes em paralelo e/ou implantam o mesmo programa várias vezes.

Para cada um deles, Pulumi oferece suporte à integração com seu sistema de integração contínua favorito. Com integração contínua, isso proporciona a mesma cobertura de testes para sua infraestrutura e para seu software aplicativo.

Pulumi tem suporte para sistemas CI comuns. Aqui estão alguns deles:

Para informações mais detalhadas, consulte a documentação do Entrega Contínua.

Ambientes Efêmeros

Uma oportunidade muito poderosa que se abre é a capacidade de implantar ambientes efêmeros apenas para fins de testes de aceitação. Conceito projetos e pilhas Pulumi foi projetado para implantar e destruir facilmente ambientes completamente isolados e independentes, tudo em alguns comandos CLI simples ou usando uma estrutura de teste de integração.

Se você usa GitHub, Pulumi oferece Aplicativo GitHub, que o ajudará a conectar testes de aceitação a solicitações pull em seu pipeline de CI. Basta instalar o aplicativo no repositório GitHub e Pulumi adicionará informações sobre visualizações de infraestrutura, atualizações e resultados de testes às suas solicitações de CI e pool:

Testando infraestrutura como código com Pulumi. Parte 2

Ao usar o Pulumi para seus principais testes de aceitação, você obterá novos recursos de automação que melhorarão a produtividade da equipe e lhe darão confiança na qualidade de suas mudanças.

Total

Neste artigo, vimos que, ao usar linguagens de programação de uso geral, muitas técnicas de desenvolvimento de software se tornam disponíveis para nós e que têm sido úteis no desenvolvimento de nossos aplicativos. Eles incluem testes unitários, testes de integração e como eles trabalham juntos para realizar testes extensivos em tempo de execução. Os testes são fáceis de executar sob demanda ou em seu sistema de CI.

Pulumi - software de código aberto, de uso gratuito e que funciona com suas linguagens de programação e nuvens favoritas - experimente hoje!

A primeira parte

Fonte: habr.com

Adicionar um comentário