• Nenhum resultado encontrado

Aplicando a Estratégia

4.3 ANÁLISE QUALITATIVA

• H0(Hipótese nula): A mudança nos parâmetros do Jartege não tem influência na quanti-

dade de falhas encontradas pelo código gerado pelo jmle a partir das especificações JML da API JavaCard.

• H1(Hipótese alternativa): A mudança nos parâmetros do Jartege tem influência na quan-

tidade de falhas encontradas pelo código gerado pelo jmle a partir das especificações JML da API JavaCard.

Para testar estas hipóteses foi realizada uma ANOVA, e seus resultados são demonstrados na Tabela 4.4 (para a realização desta tabela foi utilizada a ferramenta R [VS09]). A partir desta tabela, pode-se perceber que a probabilidade Pr(>F) (ou p-value) é 0,01 (foi assumido

queα= 0.05), o que indica há evidências suficientes para descartar a hipótese nula e a hipótese

alternativa ser aceita. Desta forma, pode-se confirmar que a confiança nos parâmetros estáticos do Jartege tem influência na quantidade de falhas encontradas.

Tabela 4.4 Tabela de dispersão ANOVA

Source DF Sum Sq Mean Sq F value Pr(>F)

Failures 1 834.44 834.44 17.062 2.042e-5

4.3

Análise Qualitativa

Na seção anterior foi verificado que o gerador de código jmle não é totalmente confiável. Po- rém, não foram investigadas as possíveis razões para estas falhas. Assim, nesta seção, os casos de falhas detectados durante a execução dos experimentos serão vistas com mais detalhes.

Para exemplificar algumas falhas que foram encontradas durante a execução dos experimen- tos, foi escolhido, de forma aleatória, um método em que estavam sendo encontradas algumas falhas. O método utilizado para esta análise é opartialEqualsque pertence à classe AID. O método é demonstrado na Figura 4.3.

Faremos uma breve explicação do que o método realiza. Analisando as anotações JML, percebe-se que ele possui uma pré-condição que indica que o parâmetro bArray ou que a soma dos parâmetrosoffsetelengthdeve ser menor que o tamanho total dobArraye que estes dois parâmetros não possuam valores negativos.

A cláusula assignable está indicando que nenhum campo do método pode ter valor alterado. Isto é realizado através da notaçãonothing. Com isso este método pode ser consi- derado como um método de consulta (já que as variáveis não podem ter seus valores modifica- dos).

Já as pós-condições do método indicam que, no resultado final, o parâmetrobArraynão pode ser nulo, o parâmetro lengthé menor que o tamanho de theAID.lengthe que o métodoUtil.arrayComparedeve retornar o valor 0 (zero).

4.3 ANÁLISE QUALITATIVA 43

1 /*@ public normal_behavior

2 @ requires bArray == null ||

3 @ (offset >= 0 && offset+length

4 @ <= bArray.length && length >=0);

5 @

6 @ assignable \nothing;

7 @

8 @ ensures \result == (bArray != null && length

9 @ <= theAID.length &&

10 @ (Util.arrayCompare(bArray, offset,

11 @ theAID, (short)0, length) == 0));

12 @ also

13 @

14 @ public exceptional_behavior

15 @ assignable \nothing;

16 @ signals (NullPointerException) false;

17 @ signals (ArrayIndexOutOfBoundsException)

18 @ (offset < 0 || offset+length > bArray.length);

19 @*/

20

21 public boolean partialEquals( byte[] bArray,

22 short offset,

23 byte length )

24 throws NullPointerException,

25 ArrayIndexOutOfBoundsException;

Figura 4.3 Especificação do métodopartialEquals

• Não deve lançar uma exceção do tipoNullPointerException(indicado pela cons- tante false na cláusula signals). Caso uma exceção deste tipo venha a ocorrer, o JML irá lançar uma exceção relativa à pós-condição;

• Só pode lançar uma exceção do tipo ArrayIndexOutOfBoundsExceptionse o parâmetrooffsetfor menor que zero ou se a soma dos parâmetrosoffsetelength

for maior que o tamanho do parâmetrobArray.

De acordo com a especificação da Figura 4.3, o métodopartialEqualsdeverá retornar um valor true se o conteúdo de um array, que é passado por parâmetro, é um prefixo do objeto chamado e false, caso contrário. O caso de teste que é analisado nesta seção é um caso em que ocorreu uma falha. A Figura 4.4 mostra uma parte de um caso de teste gerado pelo Jartege. Este teste é associado à classe AID e tem como resultado uma falha. O resultado obtido após a execução do script não revela qual o verdadeiro motivo do erro. Por isso, uma análise mais profunda foi realizada para identificação do real motivo.

1 byte[] ob0 = {(byte) 34, (byte) -43, (byte) -56, 2 (byte) -18,(byte) 2, (byte) 4, (byte) 5, (byte) 54} ;

3 javacard.framework.AID ob1 = new AID(ob0, (short) 1, (byte) 6); 4 boolean ob2 = ob1.partialEquals(ob0, (short) 2, (byte) 2); 5 byte[] ob3 = {} ;

6 javacard.framework.AID ob4 = new AID(ob3, (short) 8509, (byte) 20) ;

Figura 4.4 Caso de teste do métodopartialEquals

4.3 ANÁLISE QUALITATIVA 44

possibilidades. Por exemplo, a criação de um objeto AID (uma chamada ao construtor), é composta por duas etapas, e a chamada ao método partialEquals é composta por três etapas (incluindo a chamada ao construtor). Testamos somente as primeiras etapas e, como resultado final do caso de teste, obtivemos sucesso. Logo após, foram consideradas as três etapas (linhas 1-4) e constatou-se uma falha durante a execução. Portanto, o problema está localizado na chamada ao métodopartialEquals e a falha ocorre em um objeto que foi criado com sucesso pelo construtor.

O erro encontrado ocorre quando o teste possui uma pré-condição válida e, como resultado, foi encontrada uma violação da pós-condição (ou invariante); durante a execução do método, uma exceção do tipo “Ensure clause (or invariant) not satisfied” foi lançada. Ou seja, utili- zando o array doob0, o objetoob1referente a classe AID e o número 2 (dois) como o segundo e terceiro parâmetro do método partialEquals (ver Figura 4.4 linha 4), a pré-condição deste método está sendo satisfeita, mas uma exceção está sendo lançada e esta exceção indica que está ocorrendo uma violação da pós-condição ou do invariante. A princípio, este problema pode ocorrer por um erro na especificação, porque, do ponto de vista da especificação, quando possuímos pré-condições válidas, as pós-condições também serão válidas. Apesar de assumir

AEspeci f icaes JML que afirma que as especificações JML da API JavaCard utilizadas estão cor-

retas, foi realizada uma análise qualitativa na especificação do método partialEquals e foi observado que a especificação não possui falhas. Foram utilizados ainda os dados que ti- nham sido fornecidos pelo Jartege para exercitar as especificações JML manualmente (ou seja, realizando uma comparação dos dados com a especificação). Como esperado (de acordo com a hipótese assumida) a pré-condição bem como as pós-condições foram satisfeitas. Portanto, pode-se concluir que o problema está localizado no código gerado pelo jmle.

A falha “Ensure clause (or invariant) not satisfied” também foi encontrada em outros casos de teste, não somente no métodopartialEquals, mas também em outros métodos, e o problema sempre foi igual ao explicado do métodopartialEquals: o código gerado pelo jmle estava causando o lançamento desta exceção.

Após analisar as especificações JML manualmente e verificar que os problemas encontrados estavam sendo causados pelo código gerado pelo jmle, foi realizada uma segunda análise. Foi executado exatamente o mesmo caso de teste do métodopartialEqualsda Figura 4.4 com a implementação fornecida pela Sun Microsystems [Mic10]. O resultado final da execução foi um teste com sucesso. Assim, temos dois importantes argumentos (fatos) para concluir que o código gerado pelo jmle tem ao menos uma falha.

Além disso, foram executados todos os 4000 testes gerados pelo Jartege no código que é disponibilizado pela Sun Microsystems e nenhuma falha foi reportada pelos casos de testes (para isso, foi reutilizada a estratégia apenas com a modificação em que, ao invés da utilização do código gerado pelo jmle, foi utilizado o código da Sun). Portanto, apesar de não terem sido executados testes exaustivos no código da Sun, podemos ao menos afirmar que o código disponibilizado pela Sun possui uma boa qualidade no que se diz respeito às especificações JML que foram utilizadas.

Baseados nos dados fornecidos pela Tabela 4.3, que demonstra que as classes APDU, Ow-

nerPIN1 e OwnerPIN não possuem falhas, foi feita uma análise mais profunda com o objetivo

4.3 ANÁLISE QUALITATIVA 45

guma. Após analisar a especificação JML de todas as classes do JavaCard, com relação aos anteriores, foi identificada que uma das causas que poderiam estar causando estas falhas é a manipulação de arrays. Por exemplo, a especificação do métodopartialEqualspossui a manipulação de array para a obtenção do resultado final. Então, após estas análises, podemos argumentar que o jmle possui problemas em relação à manipulação de arrays.

De outros casos de teste que estavam apresentando falhas, foi percebida outra situação de um problema causado pelo jmle. Em alguns casos de teste, a pré-condição era válida, mas o código da pós-condição não é alcançado. Ou seja, logo após que a pré-condição é considerada válida, o caso de teste reporta um lançamento de exceção. Porém, diferentemente da primeira situação analisada, esta exceção é uma exceção genérica da linguagem Java. Na Tabela 4.3, este tipo de falha foi categorizada como Violação da JCK porque este tipo de falha pode estar relacionado com problemas relativos a JCK constraints. Ao se analisar o processo de tradução realizado pelo jmle, foi verificado que as JCK constraints utilizadas para a obtenção da especificação JML equivalente não é tão equivalente e, em particular, elas exigem fortes pré- condições para evitar o lançamento de exceções. Para facilitar o entendimento deste problema, foi assumida uma situação hipotética e simples. A

pre : y 6= 0,

pos : resultado= x/y

é a especificação de um método. Suponhamos que o gerador de código gerou um código como,

y= (sqrt(y))2;

return x/y

Como a função sqrt(.) (raiz quadrada) precisa de um número positivo como parâmetro, a pré- condição deve ser reforçada para exigir também que y ≥ 0. Então, o resultado da pré-condição (pré-condição original e a pré-condição gerada gerador de código) deve ser y> 0. Mas como a

ferramenta de teste é baseada em modelos, a única pré-condição que será assumida é a y 6= 0.

Quando forem executados os testes originais os resultados serão positivos, pois satisfaz a pré- condição (original). Porém, uma exceção irá ser lançada caso o valor passado seja negativo, isto porque a função sqrt(.) está apenas definida para números positivos. Por isso, embora o contrato original seja completamente satisfeito, o código gerado está assumindo um contrato modificado. Este é um problema básico de qualquer gerador de código (como também de códigos desenvolvidos por humanos): cada comando de uma linguagem de programação tem sua própria pré e pós-condição e isto deve estar inserido na própria conta da pré e pós-condição do método [Hoa69].

Porém, alguns casos de teste não tiveram problemas. Um exemplo de um método em que a execução do teste obteve sucesso é o getAppletShareableInterfaceObject da classe JCSystem. A Figura 4.5 demonstra um trecho do código. Nesse trecho, todas as pré- condições são válidas e tanto os invariantes como suas pós-condições estão sendo satisfeitas.

4.3 ANÁLISE QUALITATIVA 46

/*@ also

@normal_behavior

@ requires serverAID != null &&

@ _previousContext == _JCRE_CONTEXT &&

@ _registeredAIDs.has(serverAID); @ assignable \nothing; @ ensures \result == @ ((Applet)_appletTable.apply(serverAID)).getShareableInterfaceObject @ (null,parameter); @ also @ normal_behavior

@ requires _previousContext != _JCRE_CONTEXT &&

@ _registeredAIDs.has(serverAID); @ assignable \nothing; @ ensures \result == @ ((Applet)_appletTable.apply(serverAID)).getShareableInterfaceObject @ (getPreviousContextAID(),parameter); @ also @ normal_behavior

@ requires serverAID != null && !_registeredAIDs.has(serverAID); @ assignable \nothing;

@ ensures \result == null;

@*/

public static Shareable getAppletShareableInterfaceObject(AID serverAID, byte parameter)

throws NullPointerException,

ArrayIndexOutOfBoundsException

byte[] ob0 = {(byte) 34, (byte) -43, (byte) -56, (byte) -18,

(byte) 2, (byte) 4, (byte) 5, (byte) 54} ;

javacard.framework.AID ob1 = new AID(ob0, (short) 1, (byte) 6) ;

javacard.framework.Shareable ob6 = JCSystem.getAppletShareableInterfaceObject(ob1,

Figura 4.5 MétodogetAppletShareableInterfaceObjecte a sua especificação JML

Esta situação exemplifica um caso de sucesso na execução dos testes. A figura demonstra a especificação JML do método e um trecho de código do teste unitário.

Outra categoria vista na Tabela 4.3 é a de pré-condições violadas. Esta categoria indica que as pré-condições do método não estão sendo respeitadas. Esta validação é realizada pelo código gerado pelo jmle. No entanto, esta categoria, que apesar de ser validada pelo jmle, é causada pela geração de casos de teste do Jartege. A carga de dados realizada pelo Jartege, já que utiliza MBT para geração de testes, deveria ao menos realizar a validação das pré-condições e gerar casos de testes válidos.

Quando executada a classe de teste da Figura 4.6, o código gerado pelo jmle identifica já no construtor do método que as pré-condições não são válidas e a execução do código é inter- rompida. Esta situação de pré-condições inválidas ocorre em vários outros casos de teste. Um melhor cumprimento dos contratos pelo Jartege diminuiria a quantidade de testes que acabam não sendo validados, porque os métodos não estão sendo executados da maneira que deveriam. A Figura 4.6 demonstra o trecho da especificação JML que possui as pré-condições do cons- trutor da classe AID e um trecho de um caso de teste gerado pelo Jartege. Neste caso de teste, todos os parâmetros gerados pelo Jartege estão violando a pré-condição.

Documentos relacionados