5 pontos por GN⁺ 2025-01-17 | 1 comentários | Compartilhar no WhatsApp
  • rqlite é um banco de dados relacional distribuído, leve e de código aberto, escrito em Go e desenvolvido com base em SQLite e Raft
  • O desenvolvimento começou em 2014, priorizando confiabilidade e qualidade, e mesmo após mais de 10 anos de desenvolvimento e implantação, foram relatados menos de 10 casos de panic em ambientes de produção
  • Testar sistemas distribuídos exige consideração cuidadosa em várias camadas, seguindo a filosofia de manter a qualidade dentro da simplicidade

Pirâmide de testes: uma abordagem eficaz

  • Os testes do rqlite seguem a "pirâmide de testes"
    • Pirâmide de testes: estrutura baseada em testes unitários, incluindo testes de integração e um número mínimo de testes end-to-end (E2E)
  • Isso fornece uma suíte de testes eficiente, fácil de depurar e orientada por objetivos

Testes unitários: o núcleo da qualidade

  • Os testes unitários verificam componentes independentes e oferecem um equilíbrio entre velocidade e precisão
  • Com base no SQLite e na arquitetura "shared nothing", a maior parte das funcionalidades pode ser coberta por testes unitários
  • De todo o código do rqlite (cerca de 75.000 linhas), os testes unitários somam aproximadamente 27.000 linhas
  • Os testes são concluídos em poucos minutos, permitindo execuções frequentes durante o desenvolvimento

Testes em nível de sistema: validação do consenso

  • Os testes em nível de sistema validam a interação entre o módulo de consenso Raft e o SQLite
  • Principais itens testados:
    • Replicação de instruções SQLite entre nós
    • Operações de leitura em diferentes níveis de consistência
    • Validação da recuperação de falhas do cluster e da eleição de líder
  • Com cerca de 7.000 linhas de código de teste, cobrem de forma abrangente as interações em configurações de nó único e de múltiplos nós

Testes end-to-end: uma camada mínima

  • Os testes end-to-end atuam como smoke tests para verificar inicialização do sistema, formação do cluster e comportamento básico
  • Foram escritos em Python e validam funções principais executando um cluster real do rqlite
  • Exemplo: validação de backup para AWS S3
  • O código de teste é limitado a cerca de 5.000 linhas, adotando uma abordagem restrita para minimizar o custo de depuração

Testes de desempenho: testando os limites

  • Os testes de desempenho avaliam métricas como:
    • Velocidade máxima de INSERT
    • Processamento de consultas simultâneas
    • Comparação de uso de memória, CPU e disco
  • Incluem testes com bancos de dados SQLite acima de 2GB, analisando gerenciamento de memória e gargalos de escrita em disco
  • Identificam problemas de desempenho e garantem estabilidade por meio de otimizações

Lições aprendidas

  • Comece a testar desde o início
    • Testes unitários são a forma mais eficaz de construir confiança no sistema
    • Não se deve adiar a escrita de testes unitários durante o desenvolvimento, pois eles permitem encontrar bugs mais rapidamente do que testes de integração ou E2E
  • Mantenha o código de teste simples
    • A suíte de testes não é o lugar para insistir em refatorações complexas ou no princípio DRY (Don't Repeat Yourself)
    • É importante escrever código fácil de entender, aceitando até mesmo código boilerplate adicional
  • Valide os testes
    • Ao escrever testes, execute-os novamente invertendo temporariamente o resultado esperado
    • Um teste bem escrito deve falhar nesse caso, o que ajuda a evitar erros no próprio código de teste com antecedência
  • Não ignore falhas de teste
    • Mesmo falhas raras ou difíceis de entender fornecem informações importantes sobre o software
    • Casos de falha difíceis de depurar frequentemente podem ser uma oportunidade para descobrir defeitos críticos no código
  • Maximize o determinismo
    • Construa mecanismos que permitam executar manualmente os processos automáticos do sistema
    • Exemplo: a funcionalidade de snapshot do Raft normalmente roda de forma semiautomática, mas foi projetada para poder ser acionada explicitamente durante os testes
  • Seja deliberado
    • Testes de integração de nível mais alto ou testes E2E só devem ser adicionados quando sua necessidade estiver claramente comprovada
    • Testes em excesso podem reduzir a velocidade de desenvolvimento e de depuração
  • Aplicar e iterar
    • Nos testes de desempenho, as chamadas de fsync foram identificadas como o principal gargalo, e as entradas de log do Raft passaram a ser compactadas antes de serem gravadas em disco para otimizar o uso do disco
  • Valorize a eficiência
    • Manter uma suíte de testes que roda em poucos minutos permite um ciclo rápido de desenvolvimento iterativo
    • Essa é uma vantagem essencial para manter e dar continuidade a um projeto de código aberto

Qualidade em primeiro lugar

  • Segue-se a pirâmide de testes, com cada camada projetada para ter um propósito claro
  • À medida que a complexidade dos sistemas distribuídos aumenta, manter a simplicidade dos testes é essencial
  • O objetivo é construir um banco de dados confiável e fácil de operar

1 comentários

 
GN⁺ 2025-01-17
Comentários do Hacker News
  • O primeiro teste é o mais difícil, mas vale a pena adicioná-lo. Depois disso, os testes ficam mais fáceis

    • Testes parametrizados reduzem código repetido e permitem uma variedade maior de testes
    • É útil quando é possível validar restrições de forma minuciosa
    • Testes baseados em propriedades ajudam a verificar consistência e invariantes
    • É importante usar mutation testing para confirmar se você está realmente testando
  • O comprometimento com o projeto é impressionante

  • A pirâmide de testes faz sentido, mas muitas vezes nem todos os níveis existem, então é preciso melhorar isso rapidamente

    • Ao colaborar com várias equipes, preencher a camada de e2e acaba sendo uma tarefa que ninguém assume
    • Quando se usam mecanismos de autenticação como Auth0, testar fica difícil
    • Sem testes e2e, o sistema pode quebrar facilmente
    • Testes e2e automatizados facilitam identificar problemas e fazer rollback
  • Parece haver um erro de copiar e colar no FAQ

  • Estou ansioso pelo relatório do Jepsen

  • Também gostei do formato em vídeo

  • Tenho inveja da configuração de testes de performance

  • Já usei o rqlite, e ele transmite bem a simplicidade

  • Pergunta-se a opinião sobre testes de simulação determinística

  • Há curiosidade sobre o uso do rqlite em produção

  • O rqlite é um projeto original e genial