Mauricio Magnani bio photo

Mauricio Magnani

A guy who loves technology and new challenges!

Email Twitter LinkedIn Github

Integração Contínua e Implantação contínua com Jenkins Build Pipeline

JaCoCo: Melhorando a Cobertura dos Testes

Ferramentas que analisam a cobertura de código, tais como o Cobertura e JaCoCo são bastante úteis para ajudar a identificar trechos de código que não possuem testes. Vale ressaltar que 100% de cobertura de código, na maioria das vezes, não é necessário e nem factível. Cabe ao desenvolvedor avaliar a real necessidade.

Para automatizar a análise da cobertura de testes da aplicação conference, será utilizado plugin JaCoCo que foi instalado inicialmente no Jenkins.

Edite o JOB Conference e na opção Build e Goals and options, adicione os parâmetros para o report do JaCoCo:

mvn jacoco:report test -Parquillian-wildfly-remote

adicione em Add Post-build Actions a opção Record JaCoCo coverage report. É necessário configurar três informações:

  • Caminho do arquivo jacoco.exec.

    Deve ser preenchido com **/jacoco.exec.

  • Caminho do diretório que contém os arquivos .class.

    Deve ser preenchido com **/target/classes.

  • Caminho do diretório de código fonte do projeto conference.

    Deve ser preenchido com **/src/main/java.

Salve as alterações.

Na aplicação conference edite o pom.xml e adicione o plugin:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.6-SNAPSHOT</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Faça o git commit e push da alteração no pom.xml:

[mmagnani@localhost conference]$ git commit -m "Testes com JaCoCo " pom.xml
[master c94ddba] Testes com JaCoCo
 1 file changed, 147 insertions(+), 127 deletions(-)
 rewrite pom.xml (98%)
[mmagnani@localhost conference]$ git push origin master

O JaCoCo foi executado com sucesso no Build:

[JaCoCo plugin] Collecting JaCoCo coverage data...
[JaCoCo plugin] **/target/**.exec;**/target/classes;**/src/main/java; locations are configured
[JaCoCo plugin] Number of found exec files for pattern **/target/**.exec: 1
[JaCoCo plugin] Saving matched execfiles:  /var/lib/jenkins/jobs/Conference/workspace/target/jacoco.exec
[JaCoCo plugin] Saving matched class directories for class-pattern: **/target/classes:  /var/lib/jenkins/jobs/Conference/workspace/target/classes
[JaCoCo plugin] Saving matched source directories for source-pattern: **/src/main/java:  /var/lib/jenkins/jobs/Conference/workspace/src/main/java
[JaCoCo plugin] Loading inclusions files..
[JaCoCo plugin] inclusions: []
[JaCoCo plugin] exclusions: []
[JaCoCo plugin] Thresholds: JacocoHealthReportThresholds [minClass=0, maxClass=0, minMethod=0, maxMethod=0, minLine=0, maxLine=0, minBranch=0, maxBranch=0, minInstruction=0, maxInstruction=0, minComplexity=0, maxComplexity=0]
[JaCoCo plugin] Publishing the results..
[JaCoCo plugin] Loading packages..
[JaCoCo plugin] Done.

No jenkins os relatório estão disponíveis em Code Coverage Trend :

Como dito anteriormente o objetivo desse tutorial é demonstrar a parte operacional e quais ferramentas utilizar, sendo assim não será realizada a criação de um novo teste para melhorar a cobertura dó código mas nada impede que o leitor implemente por conta própria.

Configurando WildFly Maven Plugin

O WildFly Maven plugin é utilizado para deploy e undeploy de aplicações. Ele pode ser utilizado também para deploy de outros artefatos com driver JDBC. Também é possível executar comandos utilizando o JBoss CLI.

Esse plugin será utilizado para implementação da prática de Continuous Deployment (Implantação contínua) da aplicação conference.

Altere o pom.xml da aplicação confence e adicione o plugin do wildfly:

      <profile>
          <id>wildfly-remote</id>
          <build>     
          <plugins>    
            <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-maven-plugin</artifactId>
            <version>1.0.2.Final</version>
            <configuration>
              <hostname>${wildfly-hostname}</hostname>
              <port>${wildfly-port}</port>
              <username>${wildfly-username}</username>
              <password>${wildfly-password}</password>
            </configuration>
          </plugin>
          </plugins>
          </build>
      </profile>

Altere também o arquivo arquillian.xml e deixe-o como abaixo:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
  <container qualifier="arquillian-wildfly-remote"  default="true">
        <configuration>
            <property name="managementAddress">{wildfly-hostname}</property>
            <property name="managementPort">${wildfly-port}</property>
            <property name="username">${wildfly-username}</property>
            <property name="password">${wildfly-password}</property>
        </configuration>
    </container>    
</arquillian>

Faça um pequeno teste para verificar o funcionamento das alterações. Na máquina do desenvolvedor no projeto conference execute:

[mmagnani@localhost conference]$ mvn wildfly:deploy -Pwildfly-remote -Dwildfly-hostname=wildfly -Dwildfly-port=9990 -Dwildfly-username=devops -Dwildfly-password=devops@2015 -DskipTests=true
INFO: JBoss Remoting version 4.0.3.Final
Authenticating against security realm: ManagementRealm
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.353 s
[INFO] Finished at: 2015-10-25T19:15:40-02:00
[INFO] Final Memory: 15M/136M
[INFO] ------------------------------------------------------------------------

Esse procedimento realiza o deploy da aplicação conference no servdor remoto wildfly. Navegue até a URL http://wildfly:8080/conference/ e veja se a aplicação realmente foi implantada:

Faça um teste com o JUnit e Arquillian:

[mmagnani@localhost conference]$ mvn jacoco:report test -Parquillian-wildfly-remote -Dwildfly-hostname=wildfly -Dwildfly-port=9990 -Dwildfly-username=devops -Dwildfly-password=devops@2015
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.conference.view.SpeakerBeanTest
Oct 25, 2015 7:20:57 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.2.0.Beta4
Oct 25, 2015 7:20:57 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.2.0.Beta4
Oct 25, 2015 7:20:57 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version (unknown)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 6.773 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.093 s
[INFO] Finished at: 2015-10-25T19:21:02-02:00
[INFO] Final Memory: 22M/295M
[INFO] ------------------------------------------------------------------------

O teste também foi realizado com sucesso e já pode ser utilizado no Pipeline.

Criando o Pipeline Inicial

Basicamente um pipeline na cultura DevOps é a automatização do processo de entrega de software, desde a alteração, testes, até sua implantação.

Mais informações sobre pipeline podem ser encontradas no livro DevOps na prática: entrega de software confiável e automatizada.

Atualmente a arquitetura proposta já possui dois passos distintos:

  • Testes de integração com Arquillian;

  • Build e implantação no WildFLy;

Para implementar o pipeline será utilizado o Build Pipeline Plugin do Jenkins. Para a instalação desse plugin acesse a opção Manage Jenkins localizada no menu lateral, em seguida Selecione Manage Plugins. Clique na aba Available. Selecione o plugin:

Build Pipeline Plugin;

Crie um novo JOB chamado Conference_Implantacao baseado no JOB Conference:

Em Build e Goals and options e adicione as configurações do WildFly remoto:

mvn wildfly:deploy -Pwildfly-remote -Dwildfly-hostname=wildfly -Dwildfly-port=9990 -Dwildfly-username=devops -Dwildfly-password=devops@2015 -DskipTests=true

Remova o Post-build Actions relacionado ao JaCoCo e clique em Save.

Novamente crie um novo JOB chamado Conference_Integracao baseado no JOB Conference:

Altere o Build e Goals and options e adicione as configurações do WildFly remoto:

mvn jacoco:report test -Parquillian-wildfly-remote -Dwildfly-hostname=wildfly -Dwildfly-port=9990 -Dwildfly-username=devops -Dwildfly-password=devops@2015

Em Post-build Actions adicione trigger parameterized build on other projects. Deixe-o como abaixo:

Clique em Save.

Essa ação diz ao Jenkins para disparar o JOB Conference_Implantacao se o Build estiver estável.

Remova o JOB Conference.

Clicando no símbolo de + do lado da palavra All crie uma nova View chamada Conference_Pipeline do tipo Build Pipeline View:

Na opção Select Initial Job selecione Conference_Integracao. Em No Of Displayed Builds coloque o valor 3:

Clique em OK. Agora que a visualização do pipeline está criada, basta clicar em Run e observar a execução dos JOBs:

Veja que o JOB Conference_Integracao não foi executado com sucesso, sendo assim o JOB Conference_Implantacao não foi disparado!

O que pode ter acontecido? Simples, as alterações do pom.xml e do arquillian.xml ainda não foram enviadas para o repositório remoto.

[mmagnani@localhost conference]$ git commit -m "Testando o Pipeline" .
[mmagnani@localhost conference]$ git push origin master

Como os projetos estão configurados com o mecanismo de WebHook o pipeline foi executado automaticamente ao enviar as alterações para o GitLab. Um novo erro ocorreu mas agora é nas configurações. Nos dois JOBs remova o parâmetro mvn:

Navegue novamente para o pipeline http://jenkins:8080/view/Conference_Pipeline e clique em Run:

Depois de algumas pequenas correções o Pipeline foi executado com sucesso!

Acesse a URL da aplicação Conference, que foi testada e implantada remotamente através de um pipeline de entrega:

Durante os passos anteriores o foco foi no funcionamento e em nenhum momento foi implementando boas práticas de segurança em relação as senhas, ajustes nos repositórios para um novo release ou até mesmo a escalabilidade do Jenkins.

Lembre-se que esse é um assunto muito extenso e muita coisa ainda será refatorada e evoluída conforme a necessidade da arquitetura.

Referências

WildFly Maven Plugin

JaCoCO

WildFly