Como testar seu container com DGOSS

Ou com o Goss voltado para Docker

Yehudi Mikhael
Jun 12 · 7 min read
Image for post
Image for post

Recentemente eu descobri uma ferramenta que tem me ajudado muito no projeto em que estou trabalhando, entregando uma imagem Docker validada por uma bateria de testes personalizados.

Atualmente vemos muito nos projetos em que participamos a preocupação com testes relacionados a códigos em nosso pipeline, e com isso acabamos deixando de olhar outros tipos de testes, que também são necessários e importantes e, nós DevOps precisamos ficar atentos.

Foi pensando nisso, pesquisando e conversando com colegas de trabalho que eu descobri o goss, uma ferramenta para validação de servidores que possibilita fazer vários tipos de testes. Com ela, eu tenho entregado imagens com a certeza que passaram naqueles requisitos que eu defini. Se você quiser saber mais sobre o Goss, é só dar uma olhada na página oficial.

O que o Goss pode fazer?

Como já falamos, o Goss é uma ferramenta de validação de servidores. Com ela, você pode verificar desde uma simples existência de um arquivo e seu owner até verificar parâmetros do kernel, versão de pacotes instalados, interface de rede e várias outras coisas.

O legal do Goss é que isso não serve só para, como no nosso exemplo, imagens Docker. Você pode utilizá-lo baixando o binário e fazendo validações em seus servidores bare-metal, como por exemplo utilizando o KGoss para Kubernetes.

O Goss permitiu resolver o problema de garantir que a aplicação que eu precisava subir estava subindo e correspondendo como o esperado. Com isso, eu garanti que a imagem que eu estava subindo no meu Artifactory estava atendendo aos requisitos por mim definidos. E, com essa validação, pude subir a imagem para os ambientes sem problemas.

Vamos para a prática!

Vamos utilizar a ferramentaDGOSS, que é o "Goss voltado para Docker", ou seja, a ferramenta voltada para Docker que basicamente copia a goss para dentro da sua imagem já buildada.

A instalação é feita da seguinte forma:

# Install dgoss
curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss
chmod +rx /usr/local/bin/dgoss

# Download desired goss version to your preferred location (e.g. v0.3.6)
curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.6/goss-linux-amd64 -o ~/Downloads/goss-linux-amd64

# Set your GOSS_PATH to the above location
export GOSS_PATH=~/Downloads/goss-linux-amd64

# Use dgoss
dgoss edit ...
dgoss run ...

curl -L https://github.com/aelsabbahy/goss/releases/latest/download/goss-linux-amd64 -o /usr/local/bin/goss
chmod +rx /usr/local/bin/goss

curl -L https://github.com/aelsabbahy/goss/releases/latest/download/dgoss -o /usr/local/bin/dgoss
# Alternatively, using the latest master
# curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss
chmod +rx /usr/local/bin/dgoss

Criando o primeiro teste

Eu criei duas pastas para podermos praticar lá no meu github. Então corre lá e já baixa essas pastas que nada mais são que uma aplicação em Node.Js que só retorna um Hello World na porta 8080.

No exemplo 1 criamos o arquivo goss.yaml, e nele vamos validar se o arquivo server.js existe na imagem do container. Além dessa validação, podemos verificar se o processo NODE está rodando no container, se a porta 8080 está aberta e se está retornando 200 ao chamar o endereço http://localhost:8080.

Depois de criar o arquivo e fazer o build da imagem Docker, vamos executar o comando para começar a configurar os testes:

#dgoss edit "NOME DA IMAGEM"
$ dgoss edit example_1

O que esse comando faz? Basicamente carrega a ferramenta goss para dentro do seu container. Depois de executá-lo, você vai entrar no shell da máquina e lá você vai poder executar todos os comandos da ferramenta goss.

Agora vamos configurar o primeiro teste, que é a validação se o arquivo foi copiado para dentro da imagem.

Vamos precisar entrar na pasta em que o arquivo server.js está localizado e digitar o seguinte comando:

$ goss add file server.js

O comando add serve para adicionar recursos ao seu teste, como esses que você encontra neste link. E depois de cada comando digitado ele vai salvando dentro do arquivo goss.yaml as informações dos testes, que depois podem ser alterados caso haja necessidade.

Com o comando File estamos adicionando o recurso file, e nele você consegue validar existência, permissionamento, informações (tamanho, etc.) e conteúdo.

$ goss add process node

Com o comando Process, por sua vez, estamos adicionando o recurso process, e com ele vamos validar se o processo está rodando. Nesse caso não vamos validar o nome do processo, mas sim o binário que é encontrado por meio do comando ps -p <PID> -o comm.

$ ps -p 1 -o comm
COMMAND
node
$ goss add port 8080

Com o comando Port adicionamos o recurso port, que vai validar o status da porta local. Ex: 80, 8080 ou udp:123. Os protocolos que podemos testar são:

  • tcp
  • tcp6
  • udp
  • udp6
$ goss add http http://localhost:8080

Com o comando http adicionamos o recurso http, com o qual vamos validar o código do response e se o body vai ser Hello World. Porém, podemos também validar outras coisas com esse recurso, como header, se contém uma URI, username, password para autenticação e entre outros. Veja mais exemplos neste link.

Obs: sobre o body, após digitar o comando ele não vai já identificar que ele precisa obter um Hello World . O que vamos fazer é, depois de ele gerar todos os testes que queremos, editar o goss.yaml para que fique da forma que queremos testar.

Depois de finalizar os comandos de configuração, vamos ter o seguinte arquivo goss.yaml . Vamos sair do terminal, digitando exit

file:
/usr/src/app/server.js:
exists: true
mode: "0644"
size: 257
owner: root
group: root
filetype: file
contains: []
process:
node:
running: true
port:
tcp:8080:
listening: true
ip:
- 0.0.0.0
http:
http://localhost:8080/:
status: 200
allow-insecure: false
no-follow-redirects: false
timeout: 5000
body: []

Agora, no arquivo gerado na sua pasta do projeto, adicione o valor no campo do body para esperar que ele receba como resposta o Hello World .

file:
/usr/src/app/server.js:
exists: true
mode: "0644"
size: 257
owner: root
group: root
filetype: file
contains: []
process:
node:
running: true
port:
tcp:8080:
listening: true
ip:
- 0.0.0.0
http:
http://localhost:8080/:
status: 200
allow-insecure: false
no-follow-redirects: false
timeout: 5000
body:
- Hello World

Executando o teste

Após a finalização das configurações necessárias, vamos executar o teste na imagem. E para isso vamos digitar o seguinte comando:

$ dgoss run example_1
Image for post
Image for post

Podemos receber essa resposta:

Image for post
Image for post

Ou seja, o teste quebrou. Por quê? Vamos explicar melhor no próximo exemplo.

Neste exemplo vamos utilizar os mesmos testes, mas agora vamos separar os testes de port e http. Vamos adicionar à nossa pasta o arquivo goss_wait.yaml com o conteúdo desses dois recursos.

O que é esse arquivo? Nesse arquivo você define quais recursos vão ser testados depois que a aplicação subir. Ou seja, caso você suba uma imagem mas o serviço demore, o teste vai falhar como foi o nosso caso lá em cima. Adicionar esse arquivo com mais alguns parâmetros vai te ajudar a executá-los depois de sua aplicação subir.

Então, vamos criar o arquivo goss_wait.yaml contendo só esses recursos. E para podermos testar, precisamos passar via variável de ambiente a seguinte variável: GOSS_WAIT_OPTS

Essa variável GOSS_WAIT_OPTS precisa receber dois valores. O primeiro é —-retry-timeout ou -r e o segundo é o —-sleep ou -s. Basicamente, no primeiro parâmetro você define a quantidade total que vai ocorrer, enquanto que no segundo vamos ter o tempo de espera.

-r 60s -s 10s

O total de retentativa vai ser quando chegar em 60s, mas ele vai fazer no intervalo de 10s. Ou seja, ele vai retentar 6 vezes, caso passe na segunda retentativa ele termina.

Nosso arquivo goss_wait.yaml ficou assim:

port:
tcp:8080:
listening: true
ip:
- 0.0.0.0
http:
http://localhost:8080/:
status: 200
allow-insecure: false
no-follow-redirects: false
timeout: 5000
body:
- Hello World

$ GOSS_WAIT_OPTS=”-r 60s -s 10s” dgoss run -e PORT=”8080" -p 8080:8080 example_node_1

OU

$ dgoss run -e GOSS_WAIT_OPTS=”-r 60s -s 10s” -e PORT=”8080" -p 8080:8080 example_node_1

Após executar algum desses comandos você deve ter um resultado parecido com o abaixo, o print do resultado de um teste feito em uma imagem do Camunda. Neste exemplo, o serviço do camunda demora para subir porque precisa configurar certos parâmetros.

Por isso, peguei como exemplo para mostrar a função `GOSS_WAIT_OPTS`.

Image for post
Image for post
Image for post
Image for post

E é isso! Se você quiser aprender um pouco mais sobre o assunto é só dar uma olhada em alguns dos links que utilizei para escrever este post:

Ficou alguma dúvida ou tem algo a dizer? É só deixar um comentário. E se você quiser vir aprender com um time que adora compartilhar, é só dar uma olhada aqui e se candidatar. Vamos aprender juntos!

Concrete

Nós desenvolvemos produtos digitais com inovação, agilidade…

Yehudi Mikhael

Written by

Concrete

Concrete

Nós desenvolvemos produtos digitais com inovação, agilidade e excelentes práticas, para que o mercado brasileiro e latino-americano acompanhe a velocidade do mercado digital mundial.

Yehudi Mikhael

Written by

Concrete

Concrete

Nós desenvolvemos produtos digitais com inovação, agilidade e excelentes práticas, para que o mercado brasileiro e latino-americano acompanhe a velocidade do mercado digital mundial.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store