• Nenhum resultado encontrado

7.6

Análise de Comportamentos

Quando se executa o TLC no modo de simulação, ele aleatoriamente gera comportamen- tos, sem tentar checar todos os estados alcançaveis [58]. Considerando isso, invocou-se o TLC nesse modo várias vezes (1000) para a especificação TestExecutionChecking AssertionInvariant.tlaredirecionando-se a saída padrão e de erro das várias ro- dadas para um arquivo chamado EarlyLateAssertions.out. Dessa forma se pôde obter alguns diferentes exemplos da execução do modelo em que foram encontrados auto- maticamente comportamentos que violam a invariante NotEarlyOrLateAssertion.

Para diferenciar os casos de asserções antecipadas e tardias, implementou-se um pro- grama Java chamado BehaviorsAnalyzer. Esse programa analisa a saída do TLC removendo repetições de comportamentos e analisando quais dos comportamentos encon- trados representam asserções antecipadas e também os que representam asserções tardias. Alguns exemplos desses casos de asserções detectados são mostrados nos apêndices E e F respectivamente. Esses exemplos provam que não se pode garantir a ausência de tais tipos de asserções quando as threads não são monitoradas (em consonância com o Teorema 1 da Seção 4.1).

Como previamente apresentado, nenhum dos estados alcançáveis gerado pelo modo de checagem de modelos do TLC para a execução de teste monitorada representava um caso de asserção antecipada ou tardia. Esse mesmo resultado foi obtido estendendo a especificação para utilizar cinco threads (o que segue a mesma idéia da especificação original aumentando apenas o número de estados a serem analisados, que passou a ser 3158). Dessa forma, pôde- se mostrar que uma execução de teste seguindo a abordagem Thread Control for Tests não leva a comportamentos caracterizando asserções antecipadas ou tardias. Considerando isso, não é necessário executar o TLC no modo de simulação para encontrar comportamentos que- brando a invariante já que tais comportamentos não seriam encontrados. Quando se executa o TLC nesse modo com o arquivo MonitoredTestExecution.tla, essa execução nunca para.

7.7 Conclusões Parciais 121

7.7

Conclusões Parciais

Nesse capítulo mostrou-se um modelo de teste utilizando a abordagem Thread Control for

Tests em TLA+ e um outro em que a monitoração das threads de teste não é considerada

durante a sua execução. Demonstrou-se mais uma vez que sem monitoração e sem prover um certo nível de controle das threads do sistema evitando certas transições de estado em momentos inoportunos dos testes, não se pode garantir que falsos positivos causados por asserções antecipadas ou tardias não irão ocorrer.

Utilizando as ferramentas de suporte de TLA+ pôde-se verificar o modelo gerado e ins- tanciado para estados comuns de threads, tentando identificar casos de asserções antecipadas ou tardias, os quais não foram identificados no modelo representando uma execução de teste seguindo a abordagem Thread Control for Tests.

O modelo em TLA+ demonstrou ser bem próximo da implementação da abordagem utilizando a ferramenta ThreadControl e apresentou a vantagem de ser executável comparado a outras formas de modelar formalmente a abordagem de testes apresentada neste trabalho.

Capítulo 8

Combinando a Abordagem Thread

Control for Tests com Geradores de Ruído

Como previamente comentado, o uso de monitoração de threads durante os testes de apli- cações pode afetar no escalonamento das threads, em alguns casos podendo levar ao deno- minado “efeito de monitoração” ou “efeito de observação” (probe effect ou observer effect). Através desse efeito, alguns defeitos no código podem se revelar com menos frequência du- rante a execução dos testes. Com o intuito de investigar maneiras para tentar evitar este efeito, foram buscadas ferramentas que poderiam ser utilizadas em combinação com a abor- dagem proposta nesta tese para ajudar na exploração de diferentes caminhos de escalona- mento durante os testes de sistemas multi-threaded, como geradores de ruído.

Neste capítulo, através da apresentação de um exemplo prático de uso da abordagem em uma aplicação simples, demonstra-se como a abordagem Thread Control for Tests pode ser combinada com a técnica de geradores de ruído (noise makers) para que assim se possam incentivar diferentes escalonamentos das threads durante re-execuções dos testes. Um gera- dor de ruído (noise maker) tem o objetivo de aumentar a probabilidade de se exercitar um comportamento incorreto relacionado a algum bug de concorrência [10]. No exemplo prá- tico que será apresentado foi utilizado o arcabouço de testes ThreadControl e a ferramenta ConTest [2]. A metodologia utilizada para o desenvolvimento desse estudo de caso está detalhada na Seção 8.4.

Com o estudo de caso apresentado neste capítulo pretende-se mostrar que é possível combinar a abordagem proposta nesta tese com ferramentas que ajudam a explorar diferentes

8.1 A Ferramenta ConTest 123

escalonamentos durante a execução de testes de sistemas multi-threaded. Essa combinação é algo desejável não só para tentar evitar o efeito de monitoração, mas também para auxiliar no processo de detecção de defeitos de concorrência por meio de testes que precisam ser confiáveis.

8.1

A Ferramenta ConTest

A ferramenta ConTest surgiu como parte de um método proposto para achar defeitos de concorrência de maneira efetiva [29]. ConTest é uma ferramenta da IBM para o teste de aplicações Java Multi-threaded [3]. Ela é principalmente utilizada para expor e eliminar

bugs relacionados a concorrência em software paralelo e distribuído.

A idéia geral da ferramenta ConTest é que ela sistematicamente e de maneira transparente escalona a execução das threads de um programa de forma que cenários que são mais pro- pensos a possuírem condições de corrida, impasses (deadlocks) e outros bugs intermitentes, ou seja, problemas de sincronização, sejam forçados a aparecer com uma maior frequên- cia. Busca-se fazer com que o uso da ferramenta tenha pouco impacto no esforço de teste aproveitando testes existentes que podem ser re-executados.

ConTest já foi usada em grandes aplicações (como o WebSphere da IBM) e além da capacidade de gerar ruídos, pode também ser usada para medir cobertura de teste, auxiliar em depuração, permitir re-execução (replay) e para apresentar informação de deadlocks.

A versão da ConTest disponível para download se apresenta como uma ferramenta de uso simples para facilitar a identificação de bugs através de testes existentes. Ela trabalha instrumentando o código da aplicação com instruções condicionais desleepeyieldheu- risticamente controladas. Em tempo de execução, o ConTest às vezes tenta causar trocas de contexto nesses locais instrumentados. Os locais escolhidos são aqueles cuja ordem relativa entre as threads tem maior propensão de afetar no resultado: entrada e saída de blocos sin- cronizados, acesso a variáveis compartilhadas, etc. As decisões são randômicas de forma que diferentes ordens de execução das threads sejam testadas a cada rodada. Heurísticas são usadas para tentar revelar bugs típicos [74].

Para utilizar o ConTest basta que o usuário configure um arquivo de proprieda- des indicando as classes a serem instrumentadas (arquivo KingProperties) e que