Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adiciona Github Actions para rodar os testes #76

Merged
merged 6 commits into from
Jul 21, 2021
Merged

Conversation

filipedeschamps
Copy link
Owner

@filipedeschamps filipedeschamps commented Jul 21, 2021

Closes: #74 (PR anterior onde explico o ambiente de testes local)
Closes: #62 (Issue relacionada da Milestone)

Foi uma aventura perceber como o ambiente em que se roda o Github Actions é diferente do meu ambiente local aqui :)

  1. O módulo wait-on funciona localmente que é uma maravilha, mas quebra no ambiente do Github Actions. Eu tava ficando quase maluco tentando isolar o problema de todas as formas e finalmente esbarrei nessa issue. Removi ela das dependências.
  2. Até nosso amigo axios se demonstra bugado na última versão 0.21.1 conforme essa issue e tive que voltar para versão 0.19.0. Como essa versão tem falha de segurança, movi ela para as dependências de desenvolvimento até a próxima versão sair.
  3. Pra testar as Actions sem precisar ficar fazendo push toda hora aqui para o repositório, eu descobri uma ferramenta sensacional chamada act. Ela simula o container que o Github roda nas Actions. É muito legal e foi por ali que peguei o bug do wait-on, porque essa lib falava que tal url ainda não estava disponível, mas por dentro do container fazendo curl ela estava normalmente.
  4. Tem uma última característica que só acontece dentro do ambiente do Github Actions que é a forma de fechar processos, tanto que apesar de fechar eles no código, eu precisei rodar o jest com a flag --forceExit. Mais para frente vou investigar.

[edit]

  1. Não para essa sprint, mas para próxima eu quero tentar uma outra abordagem que é fazer o up e downdos serviços por fora do script de teste. Por mais que eu gosto da ideia de eles estarem explícitos ali no arquivo de teste, fazer o build o Next é algo custoso (é mais demorado que levantar o Postgres).

And transform it from a Model to a infrastructure
component. Also make every method responsible of
opening and closing the database connection, since
it's safer this way.
* Works with ES6 modules
* Works with Next.js Absolute Paths
@vercel
Copy link

vercel bot commented Jul 21, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/tabnews/tabnews/8cvAsof7EPNqK7pM7dWLriETQHqV
✅ Preview: https://tabnews-git-actions-tabnews.vercel.app

@huogerac
Copy link

Hey @filipedeschamps

Logo logo, acredito que voce vai precisar de um postgres rodando no CI, o massa que o GH Actions suporta, já fiz isto é bem tranquilo! Espero que ajude:


jobs:
  build:

    runs-on: ubuntu-latest

    services:

      postgres:
        image: postgres:11
        env:
          POSTGRES_DB: mydb
          POSTGRES_PASSWORD: MyP@sS2021$
          POSTGRES_USER: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
    - uses: actions/checkout@v2

    - name: Setup Python
      uses: actions/setup-python@v2
      with:
        python-version: 3.8

    - name: Install dependencies
      run: |
        python -m pip install -r requirements-dev.txt

    - name: Create the database
      run: flask db upgrade
      env:
        FLASK_ENV: testing
        FLASK_APP: pontos.app
        DATABASE_URI: postgresql://postgres:MyP@sS2021$@localhost/mydb

    - name: Test with pytest
      run: pytest --cache-clear --cov=pontos tests/ > pytest-coverage.txt
      env:
        FLASK_ENV: testing
        FLASK_APP: pontos.app
        DATABASE_URI: postgresql://postgres:MyP@sS2021$@localhost/mydb

Copy link

@huogerac huogerac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu devo estar fazendo algo errado, mas está dando timeout no Jest:

| > jest --runInBand --forceExit
| 
|  FAIL  pages/api/v1/migrations/index.test.js
|   ● [e2e] First GET to /api/v1/migrations › should list all pending migrations
| 
|     thrown: "Exceeded timeout of 120000 ms for a hook.
|     Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
| 
|        5 | const allServices = allServicesFactory();
|        6 |
|     >  7 | beforeAll(async () => {
|          | ^
|        8 |   return await allServices.start();
|        9 | });
|       10 |
| 
|       at Object.<anonymous> (pages/api/v1/migrations/index.test.js:7:1)
|       at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
|       at runJest (node_modules/@jest/core/build/runJest.js:387:19)

Após instalar o act (que é muito massa, não conhecia), rodei diretamente act e deu erro de timeout
Tentei deixar o docker do postgres rodando e rodei novamente o act, mesma coisa.
Pode ser que está tarde, vou tentar amanhã, quem sabe entendo oq está acontecendo.

@filipedeschamps
Copy link
Owner Author

Logo logo, acredito que voce vai precisar de um postgres rodando no CI, o massa que o GH Actions suporta, já fiz isto é bem tranquilo! Espero que ajude:

Show @huogerac ! Ele já está rodando o Postgres lá pelo docker-compose 👍 mas eu fiquei interessado nessa parte do seu arquivo:

        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

Como que funciona isso? 🤝

E já respondendo aqui sua dúvida do act, ele precisa de uma imagem para rodar a sua action, e as imagens podem variar de tamanho e recursos dentro dessa imagem. A que eu estou usando e que possui o docker-compose é uma que tem 18gb de tamanho 😂

Para configurar ela, modifique ou crie o arquivo ~/.actrc com isso:

-P ubuntu-latest=lucasalt/act_base:latest

Daí tente rodar o act novamente 👍

@filipedeschamps
Copy link
Owner Author

@huogerac vou dar merge nessa versão (mas quero fazer uma outra mais otimizada).

Em paralelo, se você tiver qualquer problema com o act me avisa para debugarmos junto, pois essa ferramenta me ajudou muito a debuggar as coisas da Action, inclusive dentro do container, foi fundamental fazer tudo localmente 👍

E se puder esclarecer aqui a dúvida sobre o health options ali, seria show, mesmo com esse PR fechado 🤝

@filipedeschamps filipedeschamps merged commit bbd1903 into main Jul 21, 2021
@filipedeschamps filipedeschamps deleted the actions branch July 21, 2021 17:27
@huogerac
Copy link

@filipedeschamps

  1. Passei a imagem docker que voce indicou e funcionou! Legal, tambem vi que é possível passá-la via parâmetro para nao precisar alterar o arquivo ~/.actrc (nao testei ainda)
  2. Rodei via npm run test e também os testes passaram, logo, parece que tudo está funcionando!

MAS, ainda não estou convencido que está abordagem é legal, desculpa, não me entenda mal, apenas me parece que tem muita coisa não explicita (ou pelo menos eu nao estou acostumado com esta abordagem).

Bom, vamos lá, vou tentar dar mais detalhes (e isto remete a sua pergunta/minha sugestão do postgres no GH Actions)

  • A ferramenta ACT é fantastica e ponto!
  • E se a gente tratar o banco de dados como uma caixa preta, a string de conexão é injetada na nossa aplicacao ou teste, assim não importa como subimos ele...ou seja, se localmente a gente sobe via docker-compose. Em outras palavras, não deveria ser responsabilidade dos testes subir o docker-compose, nem a base de qualquer forma. Tem que ter uma base rodando e a gente precisa setar a variável de ambiente.
  • Dai para rodar o testes deveriamos ter algo como: docker-compose up && jest test (está explicito e se eu quiser apontar para outra base, está tudo certo tambem)
  • Desta forma, no github actions a base não será disponibilizada via docker-compose, será criada uma em runtime (como passei no exemplo acima, e tudo que precisamos setar é a variavel de ambiente para os testes

Como poderia ser o primeiro teste do banco?

Talvez fazer um database.query("SELECT 40 + 2") == 42
Este primeiro teste apenas vai garantir que temos uma conexão, por acaso localmente subimos o postgres via docker-compose e no GH Actions via container image

Enfim, pode ser que ainda não entendi direito o caminho que este PR está seguindo, vou tentar mergulhar mais no código ou quem sabe implementar algo mais concreto com minha ideia:

No geral a gente precisa:

  • Receber uma string com a conexão do banco (mas o teste nao sabe subir o banco)
  • Rodar as migrations para criar todas as tabelas antes de rodar cada teste
  • Deletar todas as tabelas ao final de cada teste

Valeu

@huogerac
Copy link

huogerac commented Jul 21, 2021

@filipedeschamps

Respondendo sua pergunta dos parâmetros. É comum nos testes ou até mesmo quando temos diversos containers, um subir antes do outro (por isto existe no docker-compose o depends-on)

Desta forma, por mais que peguei isto do exemplo do github actions, está relacionado com não deixar o teste falhar antes mesmo do banco estar pronto para receber a conexão...
Ao invés de fazer um sleep de X segundos antes de iniciar os testes (enquanto o postgres sobe), estes parâmetros fazem este papel...

Referencia:
https://docs.github.com/en/actions/guides/creating-postgresql-service-containers

p.s: Mas confesso que não explorei muito estes parâmetros, então pode ser que algum esteja ai sem real necessidade

@filipedeschamps
Copy link
Owner Author

  • E se a gente tratar o banco de dados como uma caixa preta, a string de conexão é injetada na nossa aplicacao ou teste, assim não importa como subimos ele...ou seja, se localmente a gente sobe via docker-compose. Em outras palavras, não deveria ser responsabilidade dos testes subir o docker-compose, nem a base de qualquer forma. Tem que ter uma base rodando e a gente precisa setar a variável de ambiente.

Sensacional e concordo 100%! Fora que vai ficar muito mais rápido quando tiver mais testes, pois esse setup é feito uma só vez globalmente. Vou terminar as outras issues da Milestone e depois lapidar essa parte dos testes 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rodar testes local e CI
2 participants