Lobo, Continuous Tuning
O Seu Primeiro Teste: Passo a Passo
1. Download do jar
Antes de mais nada, baixe a distribuição jar do site da OnCast.
O arquivo jar tem tudo que você precisa para escrever, rodar e reportar testes de performance sobre a sua aplicação.
Existem duas versões do arquivo jar: uma com todas as dependências e outra sem. Você os encontra diretamente nos seguintes links:
O pacote completo pode ser encontrado em:
Para informações sobre atualizações de versão e outros materiais do Lobo, acesse sempre o site do Lobo:
O arquivo jar tem tudo que você precisa para escrever, rodar e reportar testes de performance sobre a sua aplicação.
Existem duas versões do arquivo jar: uma com todas as dependências e outra sem. Você os encontra diretamente nos seguintes links:
Lobo sem dependências
http://www.oncast.com.br/dev/lobo/dist/oncast-lobo-1.0.alpha.jar
Lobo com dependências
http://www.oncast.com.br/dev/lobo/dist/oncast-lobo-with-deps-1.0.alpha.jar
Ou baixe o pacote completo, que cotêm:http://www.oncast.com.br/dev/lobo/dist/oncast-lobo-1.0.alpha.jar
Lobo com dependências
http://www.oncast.com.br/dev/lobo/dist/oncast-lobo-with-deps-1.0.alpha.jar
- As bibliotecas (ambas com e sem dependências);
- As dependências;
- O tutorial passo a passo;
- O manual do usuário;
- A licença GPL;
- Exemplos;
- E o código fonte.
Para informações sobre atualizações de versão e outros materiais do Lobo, acesse sempre o site do Lobo:
2. Escrevendo o teste de performance
Você quer medir a performance de algum código, digamos, o método "search" da classe a seguir:
|
public
class SearchEngine { public static int search(List<Integer> list, Integer i) { return Collections.binarySearch(list, i); } } |
Vamos escrever um profile-case para coletar métricas de performance do código acima. Esta é somente mais uma classe java com uma anotação:
|
import
java.util.ArrayList; import java.util.List; import java.util.Random; import br.oncast.dev.lobo.Profile; public class ProfileSearchEngine { @Profile public void profileSearch() { SearchEngine.search(generateAThousandNumbers(3), 3); } private List<Integer> generateAThousandNumbers(int unique) { (...) } } |
É isso! Você agora está monitorando a performance do código no corpo do método anotado!
Lobo é capaz de coletar métricas sobre porções de um método anotado se você quiser. Verifique no manual do usuário como coletar várias métricas sobre um cenário.
3. Rodando testes de performance no Ant
Agora que nós temos um cenário anotado, nós devemos rodar os testes de performance.
O objetivo deste passo é basicamente gerar um arquivo XML com as métricas resultantes dos cenários anotados. O nome do arquivo será profile-results.xml e seu conteúdo será algo parecido ao que segue:
O objetivo deste passo é basicamente gerar um arquivo XML com as métricas resultantes dos cenários anotados. O nome do arquivo será profile-results.xml e seu conteúdo será algo parecido ao que segue:
|
<profile-report> <profile-case case-class="ProfileSearchEngine"> <profile-scenario scenario-method="profileSearch"> <profile-metric key="scenario-timespan" type="SINGLE" value="300.0" /> </profile-scenario> </profile-case> </profile-report> |
Para fazer isso vamos utilizar a infra-estrutura de build do Ant. O que nós precisamos é um arquivo de build como este:
|
<?xml
version="1.0"?> <project name="MyProject" default="build-and-profile"> <path id="profiler-classpath"> <fileset file="lib/oncast-lobo-with-deps-1.0.alpha.jar" /> </path> <taskdef name="profile" classname="br.oncast.dev.lobo.task.ProfilerTask" classpathref="profiler-classpath" /> <target name="build-and-profile"> <mkdir dir="build" /> <mkdir dir="build/classes" /> <javac srcdir="src/java" destdir="build/classes" /> <javac srcdir="src/performance" destdir="build/classes" classpathref="profiler-classpath" /> <profile output="build/profile-results.xml"> <classpath> <path location="build/classes" /> </classpath> <batchProfile> <fileset dir="build/classes" includes="**/Profile*.class" /> </batchProfile> </profile> </target> </project> |
O trecho marcado em verde escuro define a task <profile>, justamente a task que roda os casos de testes.
O trecho marcado em vermelho roda a task <profile> declarada anteriormente. Ela é composta pelas tags <classpath> e <batchProfile>:
- A tag <classpath> define o classpath a ser usado. Não é necessário incluir as classes de teste;
- A tag <batchProfile> especifica os arquivos que definem os casos de teste. Note que estas classes devem ser realmente arquivos bytecode (.class), ou seja, já devem estar compiladas.
Rode este build e você terá a performance do seu código avaliada.
4. Coletando resultados para comparação
Neste momento nós já temos um arquivo XML, chamado profile-results.xml, com as métricas de performance coletadas. Mas, qual o benefício de ter um XML? Bem, se você tem o bastante deles, você poderá monitorar como sua performance evoluiu ao longo de refactorings e novas implementações.
Então, vamos coletar esta informação!
O Lobo define um caminho padrão para coletar e manter os dados de performance para posterior referência e relatórios. Para isto, o Lobo também utiliza o Ant, sendo perfeito para sistemas de integração contínua como o CruiseControl.
Abaixo você encontra o que você deve adicionar ao build do CruiseControl para coletar e armazenar as metricas de performance geradas nos passos anteriores:
Então, vamos coletar esta informação!
O Lobo define um caminho padrão para coletar e manter os dados de performance para posterior referência e relatórios. Para isto, o Lobo também utiliza o Ant, sendo perfeito para sistemas de integração contínua como o CruiseControl.
Abaixo você encontra o que você deve adicionar ao build do CruiseControl para coletar e armazenar as metricas de performance geradas nos passos anteriores:
|
<path
id="profiler-classpath"> <fileset file="lib/oncast-lobo-with-deps-1.0.alpha.jar" /> </path> <taskdef name="profile-merge" classname="br.com.oncast.dev.lobo.task.ProfilerMergeTask" classpathref="profiler-classpath" /> (...) <target name="merge"> <profile-merge buildName="1" merge="merge.xml" buildmetrics="profile-results.xml" /> </target> |
Esta listagem representa as linhas que você deve adicionar ao build para ligar diversaos arquivos XML de métricas em um único merge XML. Um bom lugar para inserir esta task é no seu build mestre do CruiseControl. Desta forma, ele irá armazenar as métricas coletadas em cada build.
Depois desta task ser executada pela primeira vez, um arquivo chamado merge.xml é criado com a informação do profile-results.xml. Todas as execuções seguintes irão adicionar no arquivo merge as métricas presentes no profile-results.xml.
Uma vez feita esta ligação dos resultados em um arquivo merge, você pode considerar segura a informação contida em profile-results.xml. Lembre, é claro, de manter o arquivo merge.xml em um lugar seguro. Toda vez que você tem um novo resultado de performance, rode a task <profile-merge> novamente e ele será armazenado no arquivo merge.xml.
Ok, nós tínhamos um monte de arquivos XML, agora nós temos apenas um. Como isto pode me ajudar a monitorar minha performance? Siga para o próximo tópico...
5. Reportando a evolução da performance
Se você chegou até aqui deve ter um meio de coletar métricas de performance para todos seus builds e armazená-las em um lugar simples e centralizado. Para tirar vantagem de toda essa informação nós precisamos de um jeito melhor para interpretar estas métricas.
O Lobo oferece como uma facilidade a geração de relatórios, que ajudam você a comparar os valores das métricas de diferentes builds. Por exemplo, se você tem uma métrica que expõe o tempo de resposta de um web-service, você será capaz de ver como o tempo de de resposta do web-service evoluiu durante o desenvolvimento.
A ferramenta de relatórios irá gerar um gráfico para cada uma das métricas definidas, como o seguinte:
Se estes são os tempos de resposta do web-service nós poderíamos dizer que entre os builds 1 e 2 você teve uma boa melhora na performance, mas começou a piorar novamente durante os builds 2 e 3.
Como gerar este gráfico? Um outra task do Ant. Esta terá o arquivo merge.xml como entrada e irá ter como saída os gráficos organizados em um HTML. Vamos fazer isto:
O Lobo oferece como uma facilidade a geração de relatórios, que ajudam você a comparar os valores das métricas de diferentes builds. Por exemplo, se você tem uma métrica que expõe o tempo de resposta de um web-service, você será capaz de ver como o tempo de de resposta do web-service evoluiu durante o desenvolvimento.
A ferramenta de relatórios irá gerar um gráfico para cada uma das métricas definidas, como o seguinte:
Como gerar este gráfico? Um outra task do Ant. Esta terá o arquivo merge.xml como entrada e irá ter como saída os gráficos organizados em um HTML. Vamos fazer isto:
|
<path
id="profiler-classpath"> <fileset file="lib/oncast-lobo-with-dependencies-1.0.alpha.jar" /> </path> <taskdef name="profile-report" classname="br.com.oncast.dev.lobo.task.ProfilerReporterTask" classpathref="profiler-classpath" /> (...) <target name="report"> <mkdir dir="build/report" /> <profile-report input="merge.xml" output="report" /> </target> |
A task <profile-report> realiza toda a formatação. Neste caso, irá tratar a informação encontrada no arquivo merge.xml gerando todos os relatórios no diretório report.
Um bom lugar para inserir esta task seria logo após a geração do arquivo merge, pois você teria sempre os resultados mais recentes a sua disposição nos gráficos. Lembre-se de por um link da sua página de artefatos do projeto para os relatórios de performance, garantindo assim a visibilidade.
Um bom lugar para inserir esta task seria logo após a geração do arquivo merge, pois você teria sempre os resultados mais recentes a sua disposição nos gráficos. Lembre-se de por um link da sua página de artefatos do projeto para os relatórios de performance, garantindo assim a visibilidade.