Nota de teste de integração usando Jenkins no Kubernetes

Boa tarde


Quase imediatamente após a instalação e configuração do CI / CD, de acordo com as instruções da postagem anterior , a equipe teve uma pergunta de como executar corretamente os testes de integração. Já tínhamos experiência em executar dependências de teste em contêineres do docker, mas isso se tornou problemático desde que o próprio assembly foi lançado no contêiner. Neste artigo, gostaria de descrever dois métodos possíveis de teste de integração dentro do contêiner que se adequassem à minha equipe.


Requisitos de teste de integração


Por definição, o teste de integração é um teste que testa a operação de um aplicativo com seus componentes dependentes. Exemplos incluem bancos de dados, filas e outros serviços.


Como parte do teste, queríamos:


  • executar testes igualmente localmente e em jenkins
  • Evite pré-instalação e configuração de aplicativos dependentes
  • declarar e executar dependências usando arquivos no repositório do projeto
  • ser capaz de executar várias montagens em paralelo
  • é aconselhável poder adicionar novas dependências no futuro
  • é aconselhável poder testar com versões diferentes da mesma dependência

Com base nesses requisitos, descartamos imediatamente a idéia de ter instalações comuns permanentes de bancos de dados e filas de teste devido a problemas no compartilhamento de recursos entre assemblies e à dificuldade de manter e alterar essa infraestrutura.


Opção 1: Soluções incorporadas


Existem algumas bibliotecas no ecossistema java que executam uma dependência para um teste:



Essa abordagem é o mais simples possível e satisfaz a maioria dos requisitos descritos anteriormente, mas não é universal em termos de adição de novas dependências de teste (mysql?) Ou uso de versões específicas ou de várias dependências.


Adequado para serviços simples com 1-2 dependências.


Opção 2: contêineres de teste


O Docker é uma maneira lógica de resolver as deficiências da abordagem anterior: você pode encontrar (ou criar uma imagem do Docker) para qualquer dependência de qualquer versão. Provavelmente, algumas das dependências na produção estão sendo executadas usando as mesmas imagens.


Se iniciar a imagem localmente (ou várias usando a docker-compose) não for um problema, haverá dificuldades no IC, pois a montagem em si ocorre no contêiner. Embora seja possível executar a janela de encaixe na janela de encaixe, isso não é recomendado pelo criador do dind . A maneira preferida de contornar esse problema é reutilizar o processo de docker que já está em execução, geralmente chamado de docker de irmãos. Para fazer isso, você precisa do processo da janela de encaixe filho para usar /var/run/docker.sock do pai. Em uma postagem anterior, isso já era usado para publicar imagens do docker com um aplicativo compilado.


Decidiu-se usar a biblioteca testcontainers , uma vez que:


  • fornece uma boa API de gerenciamento de dependência
  • possui integrações com os bancos de dados e filas mais populares
  • usa a abordagem do docker de irmãos ao executar no contêiner
  • funciona da mesma maneira localmente e em ci
  • interrompe contêineres após a montagem

Adequado para serviços mais complexos ou para serviços com requisitos especiais de dependência.


Gerenciamento de recursos


Em seguida, preste atenção ao consumo de recursos pelo conjunto do projeto (que pode aumentar significativamente após a adição de testes de integração).


No momento, o assembly não indica a quantidade necessária de compartilhamentos de memória e CPU, que podem ser dois problemas em potencial:


  • O primeiro são muitos conjuntos paralelos na mesma máquina, o que resultará em um alto fator de carga. As assembléias provavelmente serão aprovadas, mas elas passarão muito mais tempo nisso.
  • O segundo é matar OOM. O Kubernetis pode decidir que você está consumindo muita memória e simplesmente mata os assemblies antes que eles sejam concluídos.

Você pode limitar os recursos do contêiner na lareira usando a construção:


  resources: requests: cpu: 1 memory: 512Mi limits: cpu: 1 memory: 512Mi 

O Jdk9 e superior já têm suporte para trabalhar em um contêiner (-XX: + UseContainerSupport (ativado por padrão), funciona em combinação com -XX: InitialRAMPercentage / -XX: MaxRAMPercentage)


Um exemplo completo pode ser encontrado aqui .


Para que o Jdk8 funcione corretamente, é necessária a atualização 131 ou superior com os -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap para ler a memória disponível do cgroup e não da máquina host ou sempre que especificar o tamanho de heap disponível manualmente usando Xmx .
Um exemplo está disponível aqui .


Vale ressaltar que o kubernetes não sabe nada sobre os recursos gastos em contêineres em execução usando contêineres de teste ou docker de irmãos. Para funcionar corretamente nessa situação, você pode reservar recursos no contêiner de maven, levando em consideração todas as dependências de teste.


Conclusão


O teste de integração ao iniciar uma construção em um contêiner é possível e não é uma tarefa difícil.


Um aplicativo de exemplo com testes de integração usando contêineres de teste, você pode encontrar aqui e a configuração para executar o Jenkins no kubernetes aqui .

Source: https://habr.com/ru/post/pt451588/


All Articles