• Nenhum resultado encontrado

Importância da Arquitetura de Sistemas Baseados em Componentes para os Testes por Injeção de Falhas

N/A
N/A
Protected

Academic year: 2021

Share "Importância da Arquitetura de Sistemas Baseados em Componentes para os Testes por Injeção de Falhas"

Copied!
7
0
0

Texto

(1)

Importância da Arquitetura de Sistemas Baseados em Componentes para

os Testes por Injeção de Falhas

Regina Lúcia de Oliveira Moraes

Universidade Estadual de Campinas (UNICAMP) Centro Superior de Educação Tecnológica (CESET)

regina@ceset.unicamp.br +55 19 3404-7105

Resumo.

Este trabalho apresenta uma visão da arquitetura de sistema sob o ponto de vista dos testes utilizando a técnica de Injeção de Falhas. Destaca a importância da arquitetura em camadas, o uso de conectores robustos entre essas camadas e a utilização de wrappers para um melhor acoplamento de componentes heterogêneos. Enfatiza também a importância dos conectores e wrappers como pontos de controle e observação para os testes por Injeção de Falhas, particularmente para os testes de sistemas baseados em componentes que utilizam componentes caixas-pretas.

Abstract.

This work presents some aspects of the system’s architecture under the point of view of the tests using the Fault Injection technique. It detaches the importance of the architecture in layers, the use of robust connectors between these layers and the use of wrappers for better coupling of heterogeneous components. It also emphasizes the importance of the connectors and wrappers as points of control and observation for the Fault Injection tests, particularly for the component-based systems using black-box components.

Palavras Chaves: Testes de Componentes, Sistemas baseados em Componentes, Injeção de Falhas.

1. Introdução

Os sistemas atuais estão sendo construídos a partir da composição de diversos componentes. Esses componentes podem ter sido construídos na empresa ou adquiridos de terceiros. Ainda assim, os componentes desenvolvidos dentro da empresa podem ter sido desenvolvidos por outras equipes que não aquela que os está utilizando para a composição do novo sistema.

A utilização de componentes auxilia a equipe de desenvolvimento a cumprir os prazos exíguos e a atender restrições de custos impostas aos projetos. Por outro lado, o controle sobre o sistema fica dependente de informações que, na maioria dos casos, não são suficientes para o completo entendimento do componente. Essas informações ficam restritas a resumos e interfaces públicas que são essenciais para a integração desses componentes aos sistemas. O código fonte, informações a respeito dos critérios de qualidade do processo de desenvolvimento e dos testes aplicados aos componentes, dificilmente são entregues aos usuários.

Para suprir essas deficiências, o entendimento da arquitetura e os testes por injeção de falhas podem ser bastante úteis, para que os usuários possam testar o sistema, avaliar sua robustez, e validá-lo no novo ambiente computacional.

(2)

2. Visão Arquitetural de um Sistema Baseado em Componentes

Arquitetura de Software pode ser entendida como um modelo de sistemas de alto grau de abstração que captura informações sobre os componentes do sistema e como esses componentes estão interconectados [4]. Algumas arquiteturas de software também capturam informações sobre possíveis estados dos componentes e sobre o comportamento dos componentes que envolvem suas interações.

A arquitetura de sistemas atuais é baseada em camadas. Uma forma de separação em camadas é apresentada por Cheesman [3] e consiste na divisão de quatro camadas: de Interface de Usuário, de Diálogo do Usuário, de Serviços do Sistema e de Negócios. A camada de Interface de Usuário é responsável pela apresentação de informações direcionada ao usuário e pela captura das entradas por ele providas. A camada de Diálogo do Usuário gerencia o diálogo do usuário em uma sessão. Serviços do Sistema é a camada responsável pela representação externa do sistema, provendo acesso aos seus serviços e finalmente a camada de Negócios implementa os núcleos das informações de negócio, suas regras e transformações. Assim, os componentes devem ser distribuídos nessas camadas, de acordo com suas características próprias.

Figura 1: Camadas da Arquitetura [3]

No momento de integrar um componente, uma das maiores dificuldades que surge é a incompatibilidade arquitetural (em inglês, architectural mismatch) [4]. Isso se dá quando os componentes a serem integrados não têm interfaces compatíveis com outros componentes do sistema ou apresentam conflitos com o ambiente onde estão inseridos. Isso ressalta a importância da arquitetura do sistema: uma boa solução arquitetural aumenta a qualidade do sistema proposto. Para contornar esse problema, a equipe de desenvolvimento utiliza os conectores. Conectores são porções de código desenvolvido internamente que têm a função de “grudar” os componentes, resolvendo as incompatibilidades entre os formatos das informações que transitam entre esses componentes [4].

Dificuldades surgem também quanto à qualidade dos requisitos do sistema. Como assegurar confiabilidade e disponibilidade, uma vez que o sistema é composto de componentes heterogêneos, desenvolvidos de forma independente? Como garantir que a mesma qualidade apresentada pelo componente no ambiente de desenvolvimento irá se manter no novo contexto? Sabemos que a garantia da qualidade é dependente da realização de testes. Um componente precisa ser testado tanto isoladamente quanto a cada reutilização, já que os cenários de comportamento do componente que são relevantes para um sistema podem não ter sido cuidadosamente testados. A injeção de falhas pode ser uma abordagem interessante tanto para validar componentes isolados como para validar a integração desses componentes em um sistema. Numa

Interface de Usuário Diálogo de Usuário Serviços de Sistemas

(3)

arquitetura em camadas é necessário que haja robustez nas interfaces entre essas camadas e a Injeção de Falhas pode contribuir para atingir o nível de robustez esperado. Através da introdução de falhas ou erros em diferentes componentes (componentes desenvolvidos internamente ou adquiridos de terceiros) de um sistema, a técnica é útil para responder questões tais como: (i) um componente irá falhar quando receber entradas inválidas de outros componentes ou do ambiente? (ii) um defeito em um componente irá causar que todo o sistema falhe? [2]. A abordagem a ser utilizada é a introdução de falhas de interface. Nessa técnica, as falhas são inseridas na interface do componente alterando parâmetros de entrada ou saída, como também, valores de retorno de métodos [6]. Para essa alteração em tempo de carga e para o monitoramento do comportamento do sistema em presença de falhas, é utilizada uma ferramenta, a Jaca [7] que foi desenvolvida para introduzir falhas no bytecode de aplicações escritas na linguagem Java. O fato de se alterar o bytecode das aplicações é muito importante para o desenvolvimento baseado em componentes, pois o sistema pode ser composto de diversos componentes terceirizados, dos quais não se tem acesso ao código fonte (componentes caixas-pretas). Mesmo assim, algum controle para manipular entradas e saídas e observação dessas entradas e do comportamento operacional do sistema é necessário. Dessa forma, é necessário que se defina os pontos de injeção e de observação, que precisam ser distintos entre si, uma vez que a injeção num determinado componente poderá afetar o resultado da observação nesse mesmo componente. Sendo assim, os conectores são partes importantes da arquitetura do sistema baseados em componentes, para que se possa fazer esse controle e essa observação do sistema que está sendo submetido aos testes por injeção de falhas. A Figura 2 apresenta uma possível arquitetura para o sistema de caldeira a vapor, cujo exemplo foi obtido a partir de Anderson et. Al. [1].

Camada 4

Camada 3

Camada 2

Camada 1

Figura 2: Camadas da Arquitetura com Conectores [5] Atuador de Alimentação do fluxo de água Atuador da taxa de alimentação de carvão Atuador do fluxo de ar Sensor de nivelamento do cilindro Sensor de fluxo

do vapor Sensor do bus de pressão do vapor Sensor de concentração de O2 Conector 3 Controlador do fluxo de ar Conector 2 Controlador do

Fluxo de Água Controlador de alimentação de carvão

Controlador da Caldeira

(4)

Os testes por Injeção de Falhas também poderão ser úteis para indicar locais onde são necessários a colocação de wrappers para garantir a tolerância a falhas dos componentes, principalmente se a integração está sendo feita em um sistema crítico. Wrappers são componentes especiais que são inseridos entre um componente e seu ambiente para lidar com fluxos de controle e dados que entram e/ou saem do componente protegido [4]. Os wrappers podem ser utilizados quando é impossível ou muito caro mudar os componentes que estão sendo reutilizados como parte de um sistema, ou quando é mais fácil se adicionar novas características incorporando-as aos wrappers. A utilização de wrappers é uma solução eficiente para muitos problemas no desenvolvimento de sistemas baseados em componentes. Eles podem ser utilizados para proteger tanto o sistema contra comportamentos não desejáveis do componente quanto para proteger o componente contra comportamentos indesejáveis do restante do sistema. Numa arquitetura onde os wrappers são utilizados, esses wrappers também são componentes importantes para serem utilizados como pontos de controle e observação durante os testes por injeção de falhas. Dessa forma, uma possível arquitetura que inclui tanto conectores quanto wrappers para a Camada 3 do exemplo da Figura 2 seria a apresentada na Figura 3. Note que com essa arquitetura o testador amplia o número de pontos de controle e observação, conseguindo uma melhor qualidade dos testes aplicados.

Camada 3

Figura 3: Posição de Wrappers na Camada 3 da Arquitetura Apresentada na

Figura 2.

Para se testar um determinado componente, a arquitetura estabelecida para o sistema deve ser analisada para identificar os sucessores e predecessores desse componente. Identificados, os sucessores/predecessores mais próximos devem ser utilizados para a observação e tratamento dos erros propagados, procurando fazer com que a propagação atinja o menor número de componentes possível. Quando o sistema é composto por um número muito grande de componentes, é necessário que haja uma escolha de quais componentes deverão ser testados, uma vez que o teste de todos os componentes não seria factível dentro de um tempo razoável. Nesse caso, uma estratégia baseada em risco é utilizada. Para se determinar quais componentes são de maior risco, o número de sucessores/predecessores é utilizado como um dos critérios.

Conector 3 Controlador do fluxo de ar Conector 2 Wrapper Camada2 Wrapper Camada4

(5)

3. Testes Aplicados

O sistema de caldeira a vapor, apresentado na Figura 2 foi utilizado como estudo de caso para a aplicação dos testes por Injeção de Falhas.

Primeiramente, foram aplicados os testes levando-se em conta a arquitetura apresentada na Figura 2, quando os conectores foram utilizados como pontos de controle e observação dos testes aplicados. A Figura 4 mostra o acompanhamento dos testes que não detectaram as exceções, fazendo com que os defeitos se propagassem para a saída do sistema na interface externa. Porém, os conectores foram de grande auxílio para que pudéssemos acompanhar os testes, apresentando um passo a passo completo da execução, incluindo os parâmetros e valores retornados.

Na última aplicação dos testes, além dos conectores foram utilizados os wrappers que impunham restrições aos possíveis valores que poderiam ser assumidos por cada um dos componentes com os quais esses wrappers interagiam. Pudemos verificar que os wrappers interagiram de maneira eficiente, detectando valores de exceção e tratando-os para que não atingissem a interface externa. A Figura 5 apresenta o acompanhamento dos testes feitos através dos conectores, mostrando na interface a criação dos wrappers e o tratamento de atividades anormais através dos tratadores de exceções.

Figura 4: Interface Apresentada dos Testes do Sistema utilizando os Conectores Requesting setConfiguration(0,0) Requesting setConfiguration(-1,0) Requesting setConfiguration(0,-1) Requesting timeStep() setCoalFeedRate to 0.020107583324872225 setAirFlow to 0.021455328516543127 readO2Concentration=0.05055916544151988 setAirFlow to 0.005455985743586578 Requesting timeStep() setCoalFeedRate to 0.007043311582244005 setAirFlow to 0.05991884582841263 readO2Concentration=1.0154329607895656 setAirFlow to 0.01514096293858308 Requesting timeStep() setCoalFeedRate to 0.0385545493638987 setAirFlow to 0.09372984703983332 readO2Concentration=2.5836295955568024E-4 setAirFlow to 0.09876538845790614 Requesting timeStep()

(6)

Figura 5: Interface Apresentada dos Testes do Sistema com Wrappers

4. Conclusão

Esse trabalho apresenta uma arquitetura para a composição de sistemas baseados em integração de componentes. Essa arquitetura utiliza conectores e wrappers para a interligação dos componentes. O trabalho enfatiza a importância desses componentes para os testes por injeção de falhas. Conectores têm um papel importante, visto que podem ser usados como pontos de monitoração quando os testes estão sendo aplicados, como também, pontos de injeção para que através deles possa se propagar erros para os componentes terceirizados, cujo código fonte não esteja disponível.

Conectores e wrappers são também utilizados como componentes importantes para se definir uma estratégia para os testes por injetar falhas em sistemas baseado em integração de componentes. A estratégia pressupõe que o sistema é composto por componentes heterogêneos, alguns adquiridos de terceiros (COTS), outros desenvolvidos pela equipe de desenvolvimento e, além disso, que a arquitetura do sistema é conhecida. Nessa arquitetura, os componentes desenvolvidos pela equipe, podem ser os únicos pontos onde podemos colocar o controle e a observação dos resultados dos testes aplicados. A estratégia auxilia a seleção dos componentes a serem injetados e monitorados baseado na arquitetura do sistema.

Alguns testes foram aplicados utilizando a ferramenta Jaca para se injetar as falhas e pudemos verificar que os wrappers foram eficientes na proteção do componente que estava sendo testado, tratando o erro e impedindo que este se propagasse para a interface externa.

Building new iC2C with ftBoilerSystem.AfcWrappedNormal@a9ae05 and ftBoilerSystem.AFCErrorHandler@1dff3a2

Building new iC2C with boilerSystem.BoilerController@152513a and ftBoilerSystem.BCErrorHandler@152c4d9 Requesting setConfiguration(0,0) Requesting setConfiguration(-1,0) Requesting setConfiguration(0,-1) AbnormalActivity.handle(ftBoilerSystem.InvalidConfigurationSetpoint: O2_ref=-1.0)

Alarm: ftBoilerSystem.InvalidConfigurationSetpoint: O2_ref=-1.0 Aborting operation public abstract void

boilerSystem.IController.setConfiguration(double,double) Requesting timeStep() setCoalFeedRate to 0.06501227633623172 setAirFlow to 0.09789233393024084 readO2Concentration=0.07811226147702977 setAirFlow to 0.06810052259857963 Requesting timeStep() setCoalFeedRate to 0.045859016940856964 setAirFlow to 0.08503619217271464 readO2Concentration=1.0309494702311874 Construção dos Wrappers Tratamento de Exceções e Recuperação de Configuração

(7)

References

[1] Anderson, T.; Feng, M.; Riddle, S.; Romanovsky, A. “Protective Wrapper Development: A Case Study”, Proc. 2nd International Conference on COTS-based Software Systems (ICCBSS 2003), Ottawa, Canada, Feb/2003, Lecture Notes in Computer Science Vol. 2580, pp. 1-14, Springer-Verlog, 2003.

[2] Arlat, J.; Aguera, M.; Amat, L.; Crouzet, Y.; Fabre, J. C.; Laprie, J. C.; Martins, E.; Powell, D. “Fault Injection for Dependability Validation–A Methodology and some Applications”. IEEE Transactions on Software Engineering, 16 (2), Feb/1990, pag 166-182. [3] Cheesman, J; Daniels, J “UML Components – A Simple Process for Specifying Component-Based Software”, The Component Software Series, Addison-Wesley, 2001.

[4] Garlan, D. ; Allen, R.; Ockerbloom, J. Ärchitecture Mismatche, or, why it’s hard to build systems out of existing parts”, proceedings of the 17th ICSE, April/95.

[5] Guerra, P. A. C; Rubira, C. M. F.; Lemos, R “An Idealizaed Fault-Tolerant Architectural Component” , proceedings of International Conference on Software Engineering: Workshop on Architecting Dependable Systems - ICSE/WADS'2002, 2002.

[6] Hsueh, Mei-Chen; Tsai, Timothy; Iyer, Ravishankar. “Fault Injection Techniques and Tools”. IEEE Computer, Abril/1997.

[7] Martins, Eliane, Rubira, Cecília M. F.,Leme, Nelson G. M., “Jaca: A reflective fault injection tool based on patterns“, proceeding of the IPDS, 2002.

Referências

Documentos relacionados

A apixaba- na reduziu o risco de AVE e embolismo sistêmico em mais de 50%: houve 51 eventos entre os pacientes do grupo apixabana versus 113 no grupo do AAS

Não se trata de recurso definidor ou comprobatório da desperticidade, mas uma relação de itens que reúne aspec- tos essenciais da condição de autodesassédio permanente,

Para obten¸c˜ao da interface correspondente a um dado objeto remoto, cujo identificador vem inclu´ıdo na mensagem recebida atrav´es do canal, h´a o recept´aculo interfaces,

In our study we observed a similar finding: higher prevalence of mitral and aortic valvular disease indicative of rheumatic involvement with the use of Doppler

a – Relação entre altura total h e dominante hdom em função do DAP; b – Relação do comprimento de copa cc em função do DAP; c – Relação do índice de competição IC3

São considerados custos e despesas ambientais, o valor dos insumos, mão- de-obra, amortização de equipamentos e instalações necessários ao processo de preservação, proteção

O estudo múltiplo de casos foi aplicado para identificar as semelhanças e dissemelhanças na forma como as empresas relacionam seus modelos de negócios e suas

Na figura 1, podes observar um pacote de pipocas cujo modelo geométrico é um tronco de pirâmide, de bases quadradas e paralelas, representado a sombreado na