Integração contínua com Buildbot

CI (Continuous Integration - Integração Contínua) na teoria e na prática usando uma ferramenta baseada em Python

Os dias de "cowboy coding" já se passaram em muitas organizações, substituídos por um renovado interesse na geração de softwares de qualidade. O teste de Integração contínua (CI) é um componente vital na prática de técnicas de programação ágil que leva ao software de alta qualidade. Conheça a teoria e a prática do teste de CI explorando o Buildbot, um sistema de CI de software livre baseado em Python.

Noah Gift , Founder, GiftCS, LLC

Photo of Noah Gift

Noah Gift é o coautor do livro Python For UNIX and Linux System Administration pela O'Reilly, e também está trabalhando no livro Google App Engine In Action para a Manning. Ele é autor, palestrante, consultor e líder de comunidades, escrevendo para publicações como Red Hat Magazine, O'Reilly e MacTech. O site da sua empresa de consultoria é http://www.giftcs.com, e grande parte de suas obras pode ser encontrada em http://noahgift.com. Também é possível seguir Noah no Twitter.

Noah tem mestrado em CIS pela Cal State Los Angeles e Bacharelado em Ciências Nutricionais pela Cal Poly San Luis Obispo. Ele é administrador de sistemas certificado pela Apple e pela LPI e trabalhou em empresas como Caltech, Disney Feature Animation, Sony Imageworks, Turner Studios e Weta Digital. Em seu tempo livre, gosta de passar o tempo com a esposa, Leah, e com seu filho, Liam, compondo para o piano, correndo em maratonas e se exercitando religiosamente.


nível de autor Contribuidor do
        developerWorks

02/Jul/2010

A Integração contínua (CI) é um processo de desenvolvimento de software que promove os seguintes princípios:

  • Manter um repositório de fonte isolada
  • Automatizar a construção
  • Tornar sua construção capaz de se autotestar
  • Todos se cometem todos os dias
  • Todo cometimento deve construir a linha principal em uma máquina de integração
  • Manter a construção rápida
  • Testar em um clone do ambiente de produção
  • Facilitar para que todos obtenham o mais recente executável
  • Todos podem ver o que está acontecendo
  • Automatizar a implementação

Amplamente popularizado por Martin Fowler, a ideia básica da CI é testar e construir continuamente seu software em cada ramificação e também quando o código é mesclado no tronco. Isso leva a um aumento geral na integridade da base do código e também a um aumento na comunicação com os membros da equipe e a uma oportunidade de obter feedback sobre a qualidade geral do seu código. Frequentemente, as pessoas usam esse ciclo para gerar relatórios de cobertura do código e outras estatísticas.

O Buildbot, como outros sistemas de CI, ajuda a automatizar esse ciclo de registro, construção e teste. Os escravos do Buildbot geralmente são executados em plataformas como Win32, Solaris, Intelx64 etc. O Buildbot pode enviar uma notificação por e-mail quando uma construção falha e manter um controle de todas as construções em execução, para que o desenvolvedor possa obter uma visão panorâmica de todo o processo. Finalmente, as pessoas frequentemente utilizam o ciclo automatizado para gerar métricas sobre a qualidade do seu software a qualquer momento. O final deste artigo trata das métricas e por que faz sentido executá-las em um sistema de CI.

Introdução ao Buildbot

Antes de entrarmos nos elementos básicos do Buildbot, vamos dar uma olhada na sua arquitetura. Como mostra a Figura 1, existem essencialmente três camadas na parte superior do processo de construção. Há uma camada de controle de versão que se anexa a notificações de um sistema de controle de versão. Há uma camada de construção que realiza a comunicação a partir do mestre de construção e retorna os resultados da construção. Finalmente, há a camada de notificação, que frequentemente é configurada para enviar e-mails, ou uma mensagem IRC, quando a construção falha ou para que uma página da Web exiba os resultados coletados das construções com o passar do tempo.

Figura 1. Visão geral da arquitetura do Buildbot
Buildbot architectural overview

Um dos outros principais recursos da arquitetura do Buildbot é a dependência da biblioteca Twisted baseada em Python para identificar comunicação assíncrona entre mestres e escravos. Essa arquitetura baseada em retorno de chamada permite um loop de feedback mestre/escravo muito simples, embora robusto. Encontre mais detalhes sobre a biblioteca Twisted na seção Recursos deste artigo, mais adiante.

Se você ainda não tiver ouvido falar sobre Buildbot, algumas pesquisas no Google revelarão uma grande coleção de mestres e escravos associados a grandes e pequenos projetos de software livre. Um escravo, que mencionei brevemente antes, é literalmente uma máquina escrava controlada pelo servidor Buildbot mestre. Normalmente, um escravo é um dentre vários escravos e cada um é executado em uma plataforma de testes diferente. Este é um importante conceito no mundo do servidor Buildbot. Por exemplo, é possível que você esteja na lista de e-mails de um projeto de software aberto e ouça alguém dizer, "Alguém quer oferecer uma máquina virtual para um escravo Windows"?

O projeto de linguagem Python usa uma grande coleção de escravos Buildbot para testar e construir continuamente a versão mais recente de Python em quantas plataformas for possível. A Figura 2 mostra uma grande variedade de máquinas executando esses escravos de construção do tronco Python, bem como testes. Com os recentes avanços em virtualização, atualmente é comum pedir a membros da sua comunidade de desenvolvimento que hospedem o escravo Buildbot, ou que simplesmente executem várias máquinas virtuais que emulam diferentes configurações de hardware.

Figura 2. Buildbot Python; consulte a figura ampliada
Python Buildbot

Outro usuário do Buildbot muito conhecido é o projeto do navegador Google Chrome. A Figura 3 mostra uma versão altamente customizada do Buildbot, que melhora significativamente a aparência e os recursos da interface do usuário do Buildbot. Felizmente, o Google transformou essas melhorias em software livre para o Buildbot e, na seção Recursos a seguir, é possível obter a fonte e a construção dessa versão customizada.

Figura 3. Buildbot aprimorado pelo Google Chrome; veja afigura ampliada
Google Chrome-enhanced Buildbot

A construção dessa configuração específica está fora do escopo deste artigo, mas recomendo que você dê uma olhada por conta própria. Agora, vamos fazer com que o servidor mestre Buildbot seja executado rapidamente.


Configurando o Buildbot em cinco minutos

Essas etapas foram executadas no Ubuntu 8.10, mas devem funcionar na maioria das distribuições Linux:

  1. Faça o download do ez_setup.py:
    wget http://peak.telecommunity.com/dist/ez_setup.py
  2. Instale o easy_install:
    sudo python ez_setup.py
  3. Instale o pacote Twisted Python com apt-get:
    sudo apt-get install python-Twisted
  4. Siga esta "receita" do collective.buildbot:
    sudo easy_install collective.buildbot

Neste momento, começarão a aparecer várias coisas como o download e instalação automáticos de um grupo pacotes. Quando isso for concluído, você estará pronto para criar um Buildbot! Se a instalação ocorrer corretamente, digite na linha de comando do shell:

$ paster create -t buildbot my.project
$ cd my.project

Já está quase acabando, é sério, mas antes de terminar, deixe-me apontar algumas armadilhas que podem enganá-lo quando você configurar o Buildbot pela primeira vez. Dentro do seu arquivo my.project/master.cfg, você verá algo como:

Listagem 1. Conteúdo de master.cfg
[buildout] master-parts = master passing.project 
# uncomment this to enable polling
poller [master] recipe = collective.buildbot:master 
project-name = passing.project
project # allow to force build with the web interface allow-force = true 
# internal port port = 9051 # http port wport = 9081 # buildbot url. 
change this if you use a
virtualhost url = http://localhost:9081/ # static files public-html =
${buildout:directory}/public_html slaves = localhost 
NaOaPSWb [passing.project]
recipe = collective.buildbot:project slave-names = localhost 
vcs = hg repositories =
/home/ngift/myhgrepo 
# notifications mail-host = localhost email-notification-sender
= buildbot@cortese email-notification-recipient = super@example.com 
# run test each
hour periodic-scheduler=60 
# cron build cron-scheduler = 0 8 * * * 
# You can change the sequences to build / test your app 
# default options should work for most buildout based
projects build-sequence = 
# /usr/bin/python2.5 bootstrap.py -c project.cfg 
# /usr/bin/python2.5 bin/buildout -c project.cfg test-sequence =
nosetests # zope.testing require exit with status 
# bin/test --exit-with-status
[poller] recipe = collective.buildbot:poller 
# don't forget to check this # since
it's generated from the paster template it may be a 
wrong url repositories = /home/ngift/myhgrepo 
#user = h4x0r #password = passwd poll-interval = 120

As coisas mais importantes que devem ser verificadas inicialmente são: você tem o repositório de controle de origem apropriado; você deixou build-sequence em branco inicialmente; e seu test-sequence, "nose" no meu caso, passará nos testes quando o código for depurado no repositório fornecido. Caso você tenha outras dúvidas, procure collective.buildbot no guia de recursos (consulte Recursos para obter um link).

Depois que seu arquivo de configuração tiver sido configurado, basta executar os dois comandos a seguir:

$ python bootstrap.py
$ ./bin/buildout

Quando você executar o comando buildout, obterá algumas saídas que serão semelhantes a isso:

Listagem 2. Saída do comando buildout
{673} > ./bin/buildout Unused options for buildout: 'master-parts'.
Installing master. New python executable in /home/ngift/my.project Installing
setuptools............done. [output suppressed for space]

Quando esse comando terminar, a instalação do Buildbot estará concluída e você estará pronto para fazer as coisas funcionarem. Inicie ambos os daemons do Buildbot executando os seguintes comandos a partir do shell:

$ ./bin/master start $ ./bin/yourhostname start

Em seguida, se você apontar um navegador para a URL definida no arquivo master.cfg que, por padrão é http://localhost:9081/, verá seu Buildbot novinho. É claro que, no início, ele não fará muitas coisas. No entanto, se você fornecer a ele um script de construção e um executor de testes, ele irá depurar, construir e testar seu código automaticamente. Depois você deverá, é claro, buscar algumas opções de configuração, mas o trabalho duro em si já está feito.


Gerando relatórios de métricas de código

Um recente desenvolvimento intelectual dos "nerds de testes" é aproveitar o ciclo de integração contínua para gerar também métricas sobre o código de origem. Uma das técnicas mais populares é executar o coletor de testes nosetest com a opção de cobertura. Se você tivesse um projeto chamado "foo", normalmente executaria:

nosetests --with-coverage --cover-package=example --cover-html \
--cover-html-dir=example_report.html test_example.py

Isso geraria um relatório HTML mostrando todas as linhas de código que não foram cobertas, juntamente com a saída para fluxos padrão, semelhante a:

Listagem 3. Saída de nosetest
 nglep%
nosetests --with-coverage --cover-package=example
--cover-html-dir=example_report.html test_example.py .
Name Stmts Exec Cover Missing
--------------------------------------- example 2 2 100%
----------------------------------------------------------------------
Ran 1 test in
0.004s OK

É possível fazer o download de example.py e test_example.py na seção Download.

A execução desse relatório todas as vezes que o código é revisado fornece ao desenvolvedor e ao gerenciador metadados sobre o que está realmente acontecendo no código. Esse é um exemplo perfeito do motivo pelo qual executar métricas simultaneamente à CI pode ser vantajoso para um projeto.

Outra ferramenta de métrica que fornece metadados sobre seu código é a classificação McCabe da PyMetrics. Nos anos 70, Thomas McCabe surgiu com uma simples, porém engenhosa, observação sobre códigos: quanto mais complexo for um trecho de código, com mais frequência ele irá falhar. Embora isso possa parecer óbvio, infelizmente muitos desenvolvedores parecem não entender a ligação. Ao usar a ferramenta de linha de comando PyMetrics, é possível determinar o número total de ramificações por função.

Geralmente, você deseja manter o número de ramificações inferior a 10 em todos os métodos ou funções que cria, pois independentemente do momento, é difícil manter mais de sete ou oito coisas contextualizadas no cérebro humano. Como ponto de referência, basicamente não é possível testar/manter códigos com classificação superior a 50.

Eu pessoalmente vi código com classificação 140 em produção e o código era muito ruim o que, de fato, valida a teoria de McCabe. Se você puder capturar e sinalizar esse código complexo e frágil no início do processo de desenvolvimento, ele nunca entrará em produção, ainda que todos os testes sejam aprovados.


Conclusão

O principal benefício da integração contínua é a capacidade de otimizar o ciclo de garantia de qualidade com construções automatizadas de software, juntamente com testes e, opcionalmente, métricas de software. Essas construções são acionadas a cada alteração da origem e fornecem feedback instantâneo e relatórios para todo o projeto. Quando a CI é configurada corretamente, ela se torna de fato integrada no processo de produção do código, tanto quanto na criação do código em si.

O Buildbot não é a única alternativa para testes de CI. Dê também uma olhada nas ferramentas Hudson e Bitten. Cada uma delas permite a customização com plug-ins em Python, ainda que Hudson tenha sido escrito em Python. Consulte os recursos a seguir para obter mais informações sobre esses sistemas.


Download

DescriçãoNomeTamanho
Sample Python scriptsexample.zip1KB

Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • Participe da comunidade My developerWorks. Entre em contato com outros usuários do developerWorks enquanto explora os blogs, fóruns, grupos e wikis dos desenvolvedores.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux, Software livre
ArticleID=499117
ArticleTitle=Integração contínua com Buildbot
publish-date=07022010