• Nenhum resultado encontrado

BTS:uma ferramenta de suporte ao desenvolvimento sistemático de sistemas confiáveis baseados em componentes

N/A
N/A
Protected

Academic year: 2017

Share "BTS:uma ferramenta de suporte ao desenvolvimento sistemático de sistemas confiáveis baseados em componentes"

Copied!
94
0
0

Texto

(1)

BTS: Uma ferramenta de suporte ao desenvolvimento

de sistemas confiáveis baseados em componentes

Natal/RN

(2)

BTS: Uma ferramenta de suporte ao desenvolvimento

de sistemas confiáveis baseados em componentes

Dissertação apresentada ao Programa de Pós-graduação em Sistemas e Computação do Departamento de Informática e Matemá-tica Aplicada da Universidade Federal do Rio Grande do Norte, como requisito parcial para a obtenção do grau de Mestre em Ciência da Computação.

Orientador:

Prof. Dr. Marcel Vinícius Medeiros Oliveira

Universidade Federal do Rio Grande do Norte Centro de Ciências Exatas e da Terra

Departamento de Informática e Matemática Aplicada Programa de Pós-graduação em Sistemas e Computação

Natal/RN

(3)

Catalogação na fonte.

Ficha catalográfica elaborada pela Bibliotecária Aline Nascimento Silva CRB 15/711

Silva, Sarah Raquel da Rocha.

BTS: uma ferramenta de suporte ao desenvolvimento de sistemas confiáveis baseados em componentes / Sarah Raquel da Rocha. – Natal, RN, 2013.

81 f. : il.

Orientador: Dr. Marcel Vinícius Medeiros Oliveira

Dissertação (Mestrado) – Universidade Federal do Rio Grande do Norte. Centro de Ciências Exatas e da Terra. Departamento de Informática e

Matemática Aplicada. Programa de Pós-Graduação em Sistemas e Computação.

1. Métodos formais – Dissertação. 2. Desenvolvimento baseado em componentes – Dissertação. 3. Concorrência – Dissertação. 4. Verificação de modelos – Dissertação. I. Oliveira, Marcel Vinícius Medeiros. II. Universidade Federal do Rio Grande do Norte. III. Título

(4)

❞❡ s✐st❡♠❛s ❝♦♥✜á✈❡✐s ❜❛s❡❛❞♦s ❡♠ ❝♦♠♣♦♥❡♥t❡s

❙❛r❛❤ ❘❛q✉❡❧ ❞❛ ❘♦❝❤❛ ❙✐❧✈❛

Dissertação de Mestrado aprovada em 13 de dezembro de 2013 pela banca examinadora composta pelos seguintes membros:

Prof. Dr. Marcel Vinícius Medeiros Oliveira (orientador) . . . DIMAp/UFRN

Profa. Dra. Anamaria Martins Moreira . . . DIMAp/UFRN

(5)

Agradecimentos

A Deus, por ter me dado saúde e força para superar as dificuldades.

Ao professor Marcel, pela orientação e confiança.

Ao meu amigo, companheiro de trabalho e irmão na amizade Dalay, pelo carinho, ajuda pessoal, psicológica e pela amizade que vai continuar presente em minha vida.

A Igor, por ter me dado apoio para entrar no mestrado, e por todo incentivo e carinho para enfrentar e superar as dificuldades.

Aos meus pais (Rita e Francisco) e meus irmãos (Sérgio e Filipe), pelo amor, incentivo e apoio incondicional. Por serem meu porto seguro, por sempre me apoiarem e por me mostrarem que nenhum de nós nasce pronto, mas somos moldados pelas nossas escolhas.

A todos os amigos que me ajudaram direta ou indiretamente. A minha amiga de infância Luciana, por ser sempre minha amiga de todas as horas. A meus companheiros de laboratório Viviane, Ernesto, Sidney e Hélio, que fizeram parte dessa fase ao qual crie laços que espero levar por toda minha vida.

A secretaria de pós-graduação da UFRN, que por intermédio da professora Fernanda Nervo Raffin, me forneceu ajuda financeira durante essa fase.

(6)

Resumo

O desenvolvimento de sistemas baseados em componentes revolucionou o processo de desenvolvimento de software, facilitando a manutenção, trazendo mais confiabilidade e reutilização. Porém, mesmo com todas as vantagens atribuídas ao componente, é neces-sário uma análise detalhada de sua composição. Realizar verificação a partir de testes de software não é o suficiente para se ter uma composição segura, pois esses não são baseados em modelos semânticos formais nos quais podemos descrever precisamente o comportamento do sistema. Nesse contexto, os métodos formais oferecem a possibili-dade de especificarmos sistemas de forma precisa, através de notações com forte base matemática, trazendo, entre outros benefícios, mais segurança. O método formal CSP possibilita a especificação de sistemas concorrentes e verificação de propriedades inerentes a tais sistemas, bem como refinamento entre diferentes modelos. Existem abordagens que aplicam restrições usando CSP, para verificar o comportamento da composição entre com-ponentes, auxiliando a verificação desses componentes antecipadamente. Visando auxiliar esse processo, tendo em vista que o mercado de software busca cada vez mais automação, minimizando trabalhos e trazendo agilidade nos negócios, este trabalho apresenta uma fer-ramenta que automatiza a verificação da composição entre componentes, onde o conjunto de verificações CSP impostas é gerado e verificado internamente, oculto para o usuário. Dessa forma, através de uma interface simples, a ferramenta BTS (BRIC-Tool-Suport) ajuda a criar e compor componentes, prevendo, com antecedência, comportamentos inde-sejáveis no sistema, comodeadlocks.

(7)

Abstract

The component-based development of systems revolutionized the software development process, facilitating the maintenance, providing more confiability and reuse. Nevertheless, even with all the advantages of the development of components, their composition is an important concern. The verification through informal tests is not enough to achieve a safe composition, because they are not based on formal semantic models with which we are able to describe precisally a system’s behaviour. In this context, formal methods provide ways to accurately specify systems through mathematical notations providing, among other benefits, more safety. The formal method CSP enables the specification of concurrent systems and verification of properties intrinsic to them, as well as the refinement among different models. Some approaches apply constraints using CSP, to check the behavior of composition between components, assisting in the verification of those components in advance. Hence, aiming to assist this process, considering that the software market increasingly requires more automation, reducing work and providing agility in business, this work presents a tool that automatizes the verification of composition among components, in which all complexity of formal language is kept hidden from users. Thus, through a simple interface, the tool BST (BRIC-Tool-Suport) helps to create and compose components, predicting, in advance, undesirable behaviors in the system, such as deadlocks.

(8)

Sumário

Lista de Figuras p. viii

Lista de Tabelas p. xi

1 Introdução p. 1

1.1 Visão Geral . . . p. 1

1.2 Motivação . . . p. 2

1.2.1 Proposta . . . p. 3

1.2.2 Trabalhos Relacionados . . . p. 4

1.3 Objetivos . . . p. 5

1.3.1 Objetivos Gerais . . . p. 5

1.3.2 Objetivos Específicos . . . p. 5

1.4 Estrutura da Dissertação . . . p. 6

2 Fundamentação Teórica p. 7

2.1 Sistemas Baseados em Componentes . . . p. 7

2.2 CSP . . . p. 9

2.2.1 Semântica CSP . . . p. 13

2.2.2 Ferramentas para CSP . . . p. 18

2.3 Abordagem para o desenvolvimento sistemático de sistemas confiáveis . p. 22

3 Uma verificação formal para desenvolvimento de sistemas confiáveis baseados em

componentes p. 36

(9)

4 BTS: Ferramenta de suporte ao desenvolvimento de sistemas confiáveis baseados

em componentes p. 46

4.1 Detalhes Técnicos . . . p. 46

4.2 Ferramenta BTS . . . p. 47

4.2.1 Aplicação prática da estratégia pela BTS . . . p. 55

4.2.2 Considerações Finais . . . p. 64

5 Estudo de Caso p. 65

5.1 Buffer Circular . . . p. 65

5.2 Aplicação do Buffer Circular na BTS . . . p. 68

5.2.1 Contrato BRIC de Cell e Controller . . . p. 68

5.2.2 Composição . . . p. 70

5.3 Análise do Estudo de Caso . . . p. 74

6 Considerações finais p. 76

6.1 Trabalhos Futuros . . . p. 77

(10)

Lista de Figuras

2.1 Atividades Para o Desenvolvimento com Componentes . . . p. 8

2.2 Exemplo de especificação CSP . . . p. 10

2.3 Máquina de estado do processo PARQUEcriada pelo FDR2 . . . p. 15

2.4 Processos PORTAO1 e PORTAO2 com seus estados e suas recusas . . . p. 16

2.5 Processos divergentes . . . p. 17

2.6 Interface da FDR2 . . . p. 20

2.7 Interface da ProBe . . . p. 20

2.8 Interface da ProB . . . p. 21

2.9 Modelo de componente . . . p. 22

2.10 Exemplo de um Cliente-Servidor . . . p. 23

2.11 Descrição dos tipos e canais . . . p. 23

2.12 Descrição do comportamento do componente Cliente . . . p. 23

2.13 Descrição do comportamento do componente Máquina . . . p. 23

2.14 Protocolo do Cliente para o canal maq . . . p. 26

2.15 Protocolo da Maquina para o canal maq . . . p. 27

2.16 Dual-protocol de Prot_Cliente . . . p. 28

2.17 Reutilização de componente . . . p. 28

2.18 Criando um novo componente Máquina . . . p. 29

2.19 Exemplo de comunicação via Buffer . . . p. 29

2.20 Canais desacoplados . . . p. 31

2.21 Compatibilidade de Auto-Injeção com Buffer . . . p. 31

(11)

4.1 Diagrama de Caso de Uso da BTS . . . p. 47

4.2 Diagrama de sequência da criação de tipos . . . p. 48

4.3 Interface para criação de tipos . . . p. 49

4.4 Interface para criação de canais . . . p. 49

4.5 Diagrama de sequência da criação de contrato . . . p. 50

4.6 Interface para criação de contrato . . . p. 51

4.7 Tela de resultado . . . p. 51

4.8 Tela de instanciação . . . p. 52

4.9 Diagrama de sequência da composição . . . p. 53

4.10 Tela de Composição . . . p. 53

4.11 Estrutura da BTS . . . p. 54

4.12 Entradas e saídas da BTS . . . p. 54

4.13 Interface BTS . . . p. 55

4.14 Exemplo de comportamento do componente . . . p. 57

4.15 Interface de saída do TypeChecker . . . p. 57

5.1 Buffer Circular . . . p. 66

5.2 Representação do componente Cell . . . p. 66

5.3 Representação do componente Controller . . . p. 66

5.4 Interface para descrição de eventos de entrada e saída . . . p. 69

5.5 Interface para descrição protocolo edual-protocols . . . p. 71

5.6 Tela de composição com o exemplo da composição em interleave . . . . p. 71

5.7 Composição em interleave de Cell1 e Cell2 . . . p. 72

5.8 Composição em interleave de Cell1, Cell2 eCell3 . . . p. 72

5.9 Composição em Communication doController com as Células . . . p. 73

5.10 Composição em feedback do componente resultante das células com o

(12)

5.11 Composição em reflexive do componente resultante da composição em

(13)

Lista de Tabelas

2.1 Operadores da linguagem CSP . . . p. 11

(14)

1

Introdução

Neste capítulo apresentaremos uma visão geral e os fatores motivadores desta disser-tação, além da proposta e objetivos que buscamos alcançar. Por fim, apresentaremos a estrutura que segue este documento, descrevendo o que será visto em cada capítulo.

1.1

Visão Geral

A engenharia de software surgiu como uma forma de organizar e gerenciar o desenvol-vimento de software [WIRTH, 2008]. Esta preocupa-se com todos os aspectos de produção do sistema, desde a especificação inicial, passando pela implementação, implantação e ma-nutenção.

Cada vez mais buscam-se características que melhorem a qualidade do software, como maior facilidade de manutenção, confiabilidade e reutilização. Uma grande ideia que revolucionou o processo de desenvolvimento foi compor o sistema em pequenos pedaços que chamamos de componentes [MCILROY, 1968], descritos em [SZYPERSKI, 2002] da seguinte forma: "Um componente de software é uma unidade de composição com interfaces especificadas através de contratos e dependências de contexto explícitas. Um componente de software pode ser distribuído independentemente e está sujeito a composição com outras partes".

(15)

Uma característica importante para obter sucesso no desenvolvimento de um com-ponente é verificar adequadamente suas funcionalidades. Hoje, a prática mais utilizada para essa verificação ainda é o teste de software. Porém, garantir a qualidade do software apenas com inspeções informais é muito difícil, principalmente quando lidamos com soft-ware complexos. Nesse contexto, surgem os métodos formais, os quais constituem outro grande avanço em direção à construção de software de qualidade. Através de linguagens formais, as quais possuem uma base matemática, os desenvolvedores especificam o sis-tema mantendo a precisão da especificação. Além disso, estas linguagens possuem uma semântica formal, através da qual é possível realizar provas matemáticas para verificar características como, por exemplo, a ausência dedeadlocks.

CSP [HOARE, 1985] é um método formal que permite a modelagem e verificação formal de sistemas concorrentes. Ele possui um conjunto de ferramentas e alguns tra-balhos na literatura [HOARE, 1985] [ROSCOE et al., 1997] [SCHNEIDER, 1999]. A linguagem CSP é baseada em processos que se comunicam através de eventos (ações) e esses representam o fluxo do seu comportamento. A linguagem também possui modelos semânticos, os quais permitem a verificação e comparação entre processos. As ferramen-tas que dão suporte a CSP auxiliam tanto no processo de modelagem e verificação, como na visualização gráfica do comportamento do processo. São exemplos dessas ferramentas, o FDR2 [BROWNLEE, 2000], proBE [PROBE. . . , 2003] e TypeChecker1. Além dessas, CSP ainda dispõe do provador de teorema CSP-Prover [ISOBE; ROGGENBACH, ]. Este é uma integração das teorias de CSP com o provador de teorema Isabelle [NIPKOW et al., 2002].

Por todas essas características e suporte de ferramentas, CSP tem ganho muita im-portância nos últimos tempos, com grandes aplicações na indústria [NOGUEIRAet al., 2008] [FEITOSA et al., 2008] [PERES; MOTA, 2007] [NETO, 2007]. Atualmente, seus benefícios vêm sendo explorados junto à área de testes para uma melhor geração e au-tomação dos testes de software [BERTOLINI; MOTA, 2008] [CAVALCANTI; GAUDEL, 2007] [NOGUEIRAet al., 2008] [NETO, 2007].

1.2

Motivação

No processo de desenvolvimento baseado em componentes é importante uma análise detalhada de como esses se integram no sistema, não bastando apenas verificar o

(16)

nente, mas também sua composição. A falta de uma verificação adequada da composição entre esses componentes pode gerar problemas como deadlocks, os quais ocorrem quando os componentes ficam impedidos de continuar suas execuções, pois cada um fica bloqueado aguardando o outro. Nesse sentido, é preciso fazer com que os componentes se integrem de forma que consigam se comunicar adequadamente. Uma abordagem ideal deveria pre-ver esses comportamentos com antecedência. Linguagens formais, como CSP, podem ser utilizadas com esta finalidade.

Em [RAMOS, 2011] é descrita uma estratégia que propõe a composição sistemática e segura de componentes baseada na linguagem formal CSP. A estratégia define quatro regras de composição: interleave, communication, feedback ereflexive, as quais asseguram a ausência de deadlocks no componente resultante da composição.

A abordagem, a ser descrita mais detalhadamente no Capítulo 2, baseia-se em um modelo de componentes que impõe as restrições necessárias para uma interação segura. As regras oferecem um método sistematizado para preservar propriedades comportamentais por construção. Com isso é possível identificar, através de propriedades conhecidas do sistema, comportamentos da composição entre componentes antes de sua implementação.

1.2.1

Proposta

A abordagem proposta em [RAMOS, 2011] apresenta características de grande impor-tância para verificação da composição entre componentes. Porém, o mercado de software busca automação de processos [GROOVER, 2007]. Assim sendo, a aplicação de um mé-todo, como o proposto em [RAMOS, 2011], na prática, exige ferramentas que facilitem sua utilização, auxiliando o usuário e trazendo agilidade ao desenvolvimento.

Este trabalho apresenta o desenvolvimento de uma ferramenta de apoio à estraté-gia proposta em [RAMOS, 2011], visando facilitar sua utilização. A ideia é abstrair a complexidade imposta pelos modelos formais. Como benefícios, a ferramenta trará um método de verificação prático, com agilidade no processo de desenvolvimento. Para isso, a avaliamos através de um estudo de caso.

(17)

1.2.2

Trabalhos Relacionados

São muitos os trabalhos publicados que apresentam modelos de desenvolvimento ba-seado em componentes [LAU; NTALAMAGKAS, 2009] [LAU et al., 2011] [LAU et al., 2005] [BARN; BROWN, 1998]. Existem alguns voltados para a verificação de componen-tes, como o proposto em [MARCILON, 2012] que apresenta a descrição de um processo de derivação e verificação de propriedades de componentes nas nuvens. O processo envolve a especificação formal do comportamento do componente por meio de contratos descritos pela linguagem Circus [WOODCOCK; CAVALCANTI, 2002]. Esse contrato é refinado e traduzido, chegando à implementação de um componente. Essa proposta tem em comum com a abordagem descrita em [RAMOS, 2011] o fato que ambos conseguem verificar com antecedência o comportamento do componente, devido à utilização de modelos formais.

Existem algumas ferramentas voltadas para verificação funcional automática de com-ponentes. Em [BARBOSA, 2005] é descrita uma ferramenta que gera, executa e analisa os resultados de testes funcionais para componentes de software a partir de especifica-ções UML [RUMBAUGH et al., 2004] e restrições OCL [WARMER; KLEPPE, 2003]. Em nossa ferramenta, essa verificação é voltada para análise formal da composição entre componentes.

Podemos encontrar em [EASSA; ABULNAJA, 2001] a proposta de um conjunto de sub-ferramentas que auxiliam na construção de sistemas baseados em componentes, atra-vés da descrição de casos de uso em UML [RUMBAUGH et al., 2004]. Em nossa fer-ramenta, o desenvolvimento dos componentes é baseado na descrição de um modelo de componente usando características da linguagem formal CSP.

O conjunto de ferramentas VEST [STANKOVICet al., 2003] apoia o desenvolvimento distribuído de sistemas embarcados baseados em componentes, cujo objetivo é fornecer um conjunto de verificação de dependências baseado nos conceitos de aspecto [KICZALES

et al., 2001] para lidar com problemas não funcionais. Nossa ferramenta lida com a verificação de segurança para problemas de deadlocks, baseado em características dos componentes.

(18)

Em [MATSUMOTO; FUTATSUGI, 2000b] é proposta uma ferramenta que assegura uma alta confiabilidade no desenvolvimento de sistemas baseados em componentes. O desenvolvimento da ferramenta foi baseado na arquitetura em árvore [MATSUMOTO; FUTATSUGI, 2000a]. Ela recebe como entrada uma especificação dos requisitos do soft-ware e uma especificação refinada de como combinar os componentes, que é descrita atra-vés da linguagem de especificação CafeOBJ [DIACONESCU; FUTATSUGI, 1998]. Além disso, são especificados os componentes javaBeans (componentes descritos através da lin-guagem Java). Como saída a ferramenta apresenta um componente que é resultado dos componentes descritos na entrada, juntamente com os conectores. A alta confiabilidade é garantida através da verificação dos requisitos e geração da conexão entre os componen-tes de forma automática. Esse trabalho possui características bem parecidas com nossa proposta, levando-se em consideração a confiabilidade imposta através da verificação rea-lizada a partir de linguagens formais. Nessa ferramenta, a conexão entre os componentes é gerada automaticamente, de acordo com a especificação descrita na entrada. Já na nossa esse comportamento é invertido, onde a descrição da conexão é realizada manualmente, bem como o comportamento do componente, e ela gera automaticamente o conjunto as-serções de verificação.

1.3

Objetivos

1.3.1

Objetivos Gerais

O objetivo geral desse trabalho consiste no desenvolvimento de um ambiente auto-matizado para verificação da composição entre componentes. Esse ambiente auxiliará o usuário na verificação e prevenção de comportamentos indesejáveis da interação entre componentes.

1.3.2

Objetivos Específicos

São objetivos específicos deste trabalho:

(19)

principalmente, da verificação de sua composição a partir de várias propriedades descritas através da especificação formal CSP.

Estudar a verificação formal da abordagem proposta. Em [OLIVEIRA, 2012b] foi realizada uma análise formal a partir da implementação das regras e restrições pro-posta em [RAMOS, 2011]. Nesse estudo, conseguimos identificar comportamentos e extrair características necessárias para a implementação de nossa ferramenta.

Desenvolver ferramenta de apoio. Nessa etapa foi desenvolvida a ferramenta que automatiza a abordagem proposta em [RAMOS, 2011]. Para implementação utili-zamos a linguagem java e a IDE NetBeans. Além disso, a fim de realizar as verifica-ções necessárias nos scripts CSP gerados, foram integradas outras duas ferramentas de suporte CSP: TypeChecker e FDR2.

Validar a ferramenta. Através da aplicação da estratégia, utilizando a ferramenta em um estudo de caso proposto em [OLIVEIRA, 2012b]. Nesta aplicação, analisa-mos se, de fato, a especificação descrita manualmente no estudo de caso é gerada automaticamente e corretamente pela ferramenta, sendo possível extrair caracterís-ticas como: interface amigável, melhor entendimento, facilidade de uso e redução da complexidade.

1.4

Estrutura da Dissertação

(20)

2

Fundamentação Teórica

Neste capítulo serão apresentados os conceitos necessários para o entendimento desse trabalho. Começaremos explicando os conceitos fundamentais de sistemas baseados em componentes. Logo em seguida serão apresentados os conceitos da linguagem CSP, seus modelos semânticos clássicos e as ferramentas de apoio à linguagem. Finalizaremos com a descrição da abordagem utilizada como base nesse trabalho.

2.1

Sistemas Baseados em Componentes

O desenvolvimento de sistemas baseados em componentes surgiu da necessidade de se melhorar o processo de desenvolvimento de software, tendo como motivação a busca pelo aumento da produtividade, da qualidade e da redução nos custos do software, trazendo com isso novas perspectivas para o desenvolvimento [VINCENZIet al., 2005].

Existe um grande interesse no desenvolvimento de software através da integração pla-nejada de componentes existentes [BROWN; WALLNAU, 1998]. Com o desenvolvimento baseado em componentes, sistemas que antes eram construídos em um único módulo, agora são divididos em várias partes, onde cada uma representa uma funcionalidade do sistema. Esse processo possui muitas vantagens, entre elas podemos citar a reutilização e manutenção de componentes [VINCENZI et al., 2005].

A ideia de componente de software não é novidade. Em 1968 McIlroy já acredi-tava no futuro da indústria de componentes de software reutilizáveis [MCILROY, 1968]. Na literatura podemos encontrar várias definições de componentes. A definição que mais assemelha-se a nosso trabalho foi proposta em [SZYPERSKI, 2002] e define o componente de software como uma unidade de composição com interfaces contratualmente especifica-das, podendo ser usado independentemente e combinado com outras partes.

(21)

O desenvolvimento de componentes representa a sua implementação. Já no desenvolvi-mento com componentes, considera-se a existência destes e os relacionam as atividades necessárias para sua composição no sistema.

Segundo [BROWN; SHORT, 1997] existem as seguintes atividades essenciais para o desenvolvimento com componentes: 1) encontrar componentes; 2) selecionar componen-tes; 3) realizar adaptações; 4) realizar a composição dos componencomponen-tes; e 5) atualizar os componentes. A Figura 2.1 ilustra essas atividades.

Figura 2.1: Atividades Para o Desenvolvimento com Componentes

Na primeira atividade são selecionados componentes com potencial para serem usados no desenvolvimento do sistema. A atividade de seleção deve garantir que o componente selecionado execute as funcionalidades necessárias para a aplicação. A adaptação consiste em corrigir potenciais fontes de conflitos entre componentes selecionados para compor o sistema. A atividade de composição utiliza uma infraestrutura comum para a realização da composição dos componentes. Por último, a atividade de atualização consiste na subs-tituição de versões antigas por novos componentes. Esta tem um impacto muito grande, pois uma alteração no componente sem um planejamento pode acarretar comportamentos inesperados em outros componentes do sistema.

Nierstrasz e Dami definem a composição de componentes como “o processo de cons-truir aplicações por interconectar componentes de softwares através de seus plugins” [NI-ERSTRASZ; DAMI, 1995]. Esses plugins definem o meio de interação e comunicação entre os componentes. Em [RAMOS, 2011], essa interação é descrita no modelo de componente, o qual chamamos de contrato. Um contrato de componente descreve o comportamento que o mesmo deve ter para se comportar de maneira confiável. Nesse sentido, métodos formais tornam-se uma ferramenta importante, visto que eles permitem a formalização e verificação de consistência dos componentes e seus contratos, trazendo assim um alto grau de confiabilidade ao componente resultante.

(22)

mas também à confiabilidade da composição desses componentes. O trabalho proposto em [RAMOS, 2011], que está sendo abordado nesta proposta de dissertação, define regras para compor componentes de forma segura, que são baseadas em um modelo de contrato. Ainda nesse capítulo, você encontrará mais informações sobre essa abordagem.

2.2

CSP

CSP [HOARE, 1978] é uma linguagem formal que descreve o sistema em termos de processos. Esses processos operam independentemente e interagem com os outros através de ações (eventos). CSP é suportada por uma teoria matemática, um conjunto de ferramentas de prova e alguns trabalhos literários [HOARE, 1985] [ROSCOE et al., 1997] [SCHNEIDER, 1999]. Sua abordagem tem sido utilizada para especificação, análise e verificação de sistemas concorrentes e em tempo real [SCHNEIDER, 1999]. Nessa seção apresentaremos algumas características e operadores da linguagem, mais especificamente, aqueles que fazem parte do contexto desse trabalho.

A Figura 2.2 apresenta um exemplo de especificação utilizando uma notação funcional chamada CSPM, o qual tomaremos como base para apresentar os conceitos da linguagem.

A especificação descreve o comportamento de entrada em um parque de diversões. O parque possui os clientes e um CAIXAque recebe o dinheiro, entrega o bilhete e o troco. Outros comportamentos serão apresentados de acordo com a descrição da linguagem.

Iniciamos os conceitos de CSP apresentando a descrição de tipos e canais. Na lin-guagem, tipos compreendem conjuntos de valores e operações que podem ser realizados sobre estes valores. Estes podem ser descritos, por exemplo, como inteiros, intervalos, booleanos, entre outros. Na especificação da Figura 2.2 temos o exemplo da declara-ção de um tipo intervalo que representa o valor a ser pago na entrada do parque. CSP também permite a criação de novos tipos através da palavra reservada datatype, onde seus conjuntos de valores não fazem parte dos valores já definidos pela linguagem e são representados como tipos enumerados ou uma união disjunta. Em nossa especificação definimos o tipoALFAque é representado por três valores (datatype ALFA = a | b

| c), ondea, be c representam os clientes do sistema.

(23)

Valor ={0..10}

datatype ALFA = a | b | c channel entrar, brincar, sair

channel dinheiro, bilhete, troco, moeda, passe : ALFA channel entrada : Valor

PARQUE = entrar -> brincar -> sair -> PARQUE

CAIXA = dinheiro?clt -> bilhete!clt -> troco!clt -> CAIXA

USUARIOS = USUARIO(a) ||| USUARIO(b) ||| USUARIO(c)

USUARIO(clt) =

((entrar -> moeda!clt ->

(passe.clt -> troco.clt -> SKIP

[] troco.clt -> passe.clt -> SKIP)); brincar -> sair -> USUARIO(clt)) |~|

((moeda!clt -> entrar ->

(passe.clt -> troco.clt -> SKIP

[] troco.clt -> passe.clt -> SKIP)); brincar -> sair -> USUARIO(clt))

ENTRADA_PARQUE = entrada?x ->

if (x==8) then SISTEMA_PARQUE else ENTRADA_PARQUE

MAQUINA = CAIXA [[dinheiro <- moeda, bilhete <- passe]]

SISTEMA_PARQUE = (USUARIOS [|{|moeda,passe,troco|}|]

(PARQUE ||| MAQUINA)) \ {|moeda,passe,troco|}

(24)

e bilhete.a são possíveis eventos do processo CAIXA, que representa a bilheteria do parque.

Em CSP, também é possível definir comportamentos de entrada e saída. Um processo pode receber ou fornecer um valor. Esses são descritos através dos operadores ? (para receber) e ! (para fornecer). Na Figura 2.2 o comportamento do processo CAIXA é descrito inicialmente pelo recebimento do dinheiro de um cliente(dinheiro?clt), em seguida tem duas ações de saída(bilhete!clt e troco!clt).

Além dos conceitos apresentados anteriormente, CSPM contém alguns operadores.

Esses operadores são considerados padrão para as ferramentas existentes e são utiliza-dos para relacionar eventos e processos. A tabela 2.1 apresenta alguns operadores da linguagem. Os outros operadores serão omitidos por não fazerem parte do escopo desse trabalho.

STOP deadlock

SKIP finalização com sucesso

a -> Processo prefixação

Processo [] Processo Escolha externa Processo |˜| Processo Escolha interna

Processo ; Processo composição sequencial de processos if <condiçao> then Processo else Processo escolha condicional

<condicão> & Processo processo guardado Processo ||| Processo Intercalação de processos Processo [| cs |] Processo Paralelismo

Processo \ <cs> ocultação de canais Processo [[ <lista_renomeação> ]] renomeação

Tabela 2.1: Operadores da linguagem CSP

Iniciamos apresentando os processos primitivos da linguagem, que têm comporta-mento básico, como o STOP que não faz nada (representa o deadlock) e o SKIP que representa terminação com sucesso.

O prefixo é o operador mais básico da linguagem: a -> P denota um processo que inicialmente comunica o evento a e comporta-se como P após esta comunicação. Pode-mos ilustrar esse operador através do processo CAIXA (Fig. 2.2), ele inicialmente ofe-rece o evento dinheiro?clt. Após esta comunicação, o processo oferece os eventos

bilhete.clt e troco.clt, nesta ordem, voltando novamente a seu estado inicial após ambas as comunicações ocorrerem.

(25)

Na especificação (Fig. 2.2), o processo USUARIO decide internamente (|˜|) se inici-almente o cliente entra, ou só depois que efetuar pagamento. No mesmo processo existe uma escolha externa ([]), onde o processo decide, de forma perceptível ao ambiente, se emite primeiramente o bilhete seguido do trocoou vice-versa, .

O operador de composição (;) combina dois processos: P;Q de tal forma que executa inicialmente o processo P e caso esse termine com sucesso, Q é executado. Podemos observar esse comportamento no processo USUARIO, que independente das escolhas, ao finalizá-lo, realiza sequencialmente as ações debrincaresairlevando ao estado inicial deUSUARIO.

As escolhas condicionais são recursos da linguagem CSP para determinar o fluxo de um processo através de expressões lógicas. Na especificação (Fig. 2.2) a esco-lha condicional é usada no processo ENTRADA_PARQUE, onde a expressão if x == 8 then SISTEMA_PARQUE else ENTRADA_PARQUErepresenta um comportamento onde, caso a condiçãox == 8seja atendida, o processoSISTEMA_PARQUEé executado, senão ele volta a seu estado inicial (ENTRADA_PARQUE). Essa condicional se assemelha às das linguagens de programação. Podemos também definir uma condicional através da con-dição de processo guardado, onde o comportamento (x == 8) & SISTEMA_PARQUE

define que PARQUE é executado se a condição x == 8 for verdadeira, caso contrário, o processo é bloqueado.

Na composição em interleave, dois processos P ||| Q não se comunicam entre si, apenas com o ambiente. O processo USUARIOS (Fig. 2.2) é descrito através de uma composição entrelaçada (do Inglês, interleaving) entre de três clientes (USUARIO(a) ||| USUARIO(b) ||| USUARIO(c)), onde cada um é executado independentemente do outro.

A expressão P [| cs |] Q denota um paralelismo, tal que P e Q são processos e

csé o conjunto de canais de sincronização. Na especificação da Figura 2.2 encontramos o uso desse operador no processoSISTEMA_PARQUE. O processo executa paralelamente

USUARIOS e CAIXA, que se comunicam através da sincronização nos seguintes eventos:

dinheiro, bilhete, troco. Além disso, essas ações são escondidas do ambiente utilizando-se do operador de abstração (\). A ocultação de canais é descrita através da expressão P \ cs, tal que o processo se comporta como P, exceto que os eventos no conjunto cs não são visíveis pelo ambiente externo ao processo. Nesse contexto, os eventos visíveis do processoSISTEMA_PARQUEsão apenasentrar, brincaresair.

(26)

ocorrência do evento a será substituída pelo evento b. A renomeação é essencial quando se fala em reuso. Através deste operador é possível obter novos processos apenas renomeando seus eventos, ou seja, pode-se reaproveitar descrições específicas do comportamento de um processo sem a necessidade de reescrevê-lo. Como exem-plo, podemos citar o comportamento do processo CAIXA (Fig. 2.2) que é descrito como o seguinte: dinheiro?clt -> bilhete!clt -> troco!clt -> CAIXA. Caso desejemos reaproveitar esse processo para criar uma máquina com comporta-mento similar, mas que trabalhe em um conjunto de canais diferente, podemos uti-lizar o operador de renomeação. Por exemplo, MAQUINA é representado da seguinte forma: MAQUINA = CAIXA [[dinheiro <- moeda, bilhete <- passe]], re-cebe o comportamento de CAIXA e a seta <- representa a renomeação do canal da es-querda pelo da direita.

Em FDR2 [BROWNLEE, 2000], podemos também fazer uso de uma linguagem funcio-nal que possui diversas funções sobre conjuntos, sequências, tuplas, assim como casamento de padrões. Por exemplo, union, inter e diff representam as operações de união, interseção e diferença entre conjuntos, respectivamente. O member(x, cs) verifica se o evento x faz parte do conjunto de eventos cs. Por exemplo, podemos verificar se o evento brincar faz parte do conjunto de eventos J = {entrar, brincar, sair}

analisando semember(brincar, J). Finalizando,extension(c)retorna o conjunto de valores que ”completam” o canal c. Por exemplo, na especificação da figura 2.2, são

extension(dinheiro) os valores a, be c.

Como as interfaces são usualmente definidas em termos de canais, uma notação que especial é fornecida para a escrita do conjunto de eventos de um canal. A notação{|c|}

expande o conjunto de eventos a partir dec, ou seja, todas as possíveis comunicações ao longo do canalc. Por exemplo, o conjunto de eventos do canal entradaé descrito como o seguinte: {|entrada|} = {entrada.1,entrada.2,...,entrada.10}.

A seguir apresentaremos a descrição dos modelos semânticos da linguagem CSP.

2.2.1

Semântica CSP

(27)

denotacional, CSP pode ser interpretada em três níveis: modelo de traces, falhas e falha-divergência [SCHNEIDER, 1999], que serão apresentadas a seguir.

Modelo de traces

Um aspecto importante do comportamento de um processo está relacionado a ocor-rência dos eventos na ordem de seus acontecimentos. No modelo de traces, o processo é descrito através (do conjunto) das possíveis sequências de eventos que ele pode vir a executar. O conjunto de todos os possíveis traces de um processoP é chamadotraces(P) e define a semântica de um processo.

Um trace pode ser representado explicitamente pela ordem da listagem de seus elementos. Para entendermos melhor, vamos considerar o seguinte processo:

PARQUE = entrar -> brincar -> sair -> SKIP. Podemos extrair as seguin-tes sequências em cada execução de PARQUE:

entrar -> brincar -> sair -> SKIP

entrar → hentrari

brincar -> sair -> SKIP

brincar → hentrar, brincari

sair -> SKIP

sair → hentrar, brincar, sairi

SKIP

↓√ → hentrar, brincar, sair, ticki

Como podemos observar, cada sequência de ações realizada por um processo representa um trace, tal que, por exemplo, hai descreve uma sequência de execuções do processo e

ha, biconsiste nos eventosa seguido porb, que descreve outra sequência. Logo, levando-se em consideração que a sequência vazia hi sempre fará parte do conjunto de traces do processo, os traces dePARQUE são representados como:

traces(P ARQU E) ={hi,hentrari,hentrar, brincari,hentrar, brincar, sairi,

hentrar, brincar, sair, ticki}

O processoPARQUEpoderia ter um conjunto infinito de traces caso ele fosse recursivo:

PARQUE = entrar -> brincar -> sair -> PARQUE. Neste caso, seu modelo de traces será representado da seguinte forma:

traces(P ARQU E) ={hi,hentrari,hentrar, brincari,hentrar, brincar, sairi,

(28)

e seu comportamento sempre leva ao estado inicial. Porém, seu espaço de estados é finito, ou seja, o processo executa infinitamente, mas cada ação do seu comportamento é executada finitamente. como descrito na Figura 2.3.

Figura 2.3: Máquina de estado do processo PARQUEcriada pelo FDR2

Por se tratar de uma sequência, diversas operações podem ser utilizadas para compor traces. A operação de concatenação é uma delas, ondeseqseq2 representa a sequência

de elementos deseq1 seguida pelos deseq2. Com esse operador é possível gerar um novo

trace através da junção de outros dois. Por exemplo, no processoPARQUEa concatenação dos traces hentrar, brincar, sairi ˆhentrari gera o trace hentrar, brincar, sair, entrari.

A operação #seq define o tamanho de uma sequência, retornando o número de elementos contidos nela. Por exemplo, #hentrar, bricar, sairi = 3. A projeção de uma sequência seq sobre os elementos de um conjunto A (seqA) representa uma subsequência de todos os elementos de seq que estão nesse conjunto. Por exemplo,

hentrar, brincar, sair, entrari{entrar, brincar} = hentrar, brincar, entrari.

Se seq é uma sequência não vazia, ela pode ser descrita como hs0i ˆs1, onde

s0 é o primeiro elemento e s1 é o resto da sequência. Nesse contexto, duas

fun-ções são definidas: head(seq) = s0 e tail(seq) = s1. Por exemplo, para a sequência hentrar, brincar, sair, entrari:s0 = entrar e s1 =hbrincar, sair, entrari.

A semântica de traces de um processo CSP é descrita através de um conjunto de regras, as quais são descritas de acordo com os operadores da linguagem. A seguir apresentaremos algumas delas:

traces(SKIP) ={hi,hi} traces(ST OP) ={hi}

traces(aP) ={hi} ∪ {hai ˆtr|trtraces(P)}

traces(P[]Q) =traces(P)∪traces(Q)

traces(P |˜|Q) =traces(P)traces(Q)

(29)

([]) e interna (|˜|) possuem os mesmos conjuntos de traces, pois este modelo preocupa-se apenas com a sequência de eventos que um processo pode executar, definindo uma visão apropriada para as propriedades de segurança. No entanto, não é possível definir com esse modelo onde os processos podem falhar.

Para tal, a fim de diferenciar o não-determinismo, é preciso estender o modelo de traces com informações adicionais, o que é feito pelo modelo que apresentamos a seguir.

Modelo de falhas

O modelo de falhas descreve o que um processo pode fazer e quais conjuntos de eventos podem ser recusados ao executar cada ação do processo, ou seja, esse modelo determina quais eventos podem não ser aceitos pelo processo após uma ação dele. Essa falha é definida através do par (t, X), tal que ttraces(P) e X representa todos os valores que podem ser recusados por P após a execução de t. Com isso, o conjunto de todas as possíveis falhas de P é chamado de f ailures(P).

Esse modelo permite verificar se um processo é determinístico ou não, o que não é possível no modelo de traces. Um processo é dito determinístico se toda vez que seu com-portamento é observado a partir de um estado conhecido/determinado (mesma entrada), o resultado é sempre o mesmo.

Para exemplificar o modelo de falhas, vamos considerar os seguin-tes processos: PORTAO1 = entrar -> STOP [] sair -> STOP e

PORTAO2 = entrar -> STOP |˜| sair -> STOP. Os processos PORTAO1

e PORTAO2 possuem os mesmos traces, porém não são semanticamente equivalentes, considerando os conjuntos de eventos que podem não ser aceitos em cada transição. A Figura 2.4 ilustra o gráfico de transição desses processos no modelo de falha.

(30)

Observando a transição de estados doPORTAO1, ao executar qualquer ação, o processo recusa ambos eventos. Por exemplo, para as duas opções que o processo tem, caso ele execute entrar, depois dessa ação, ele pode recusar entrar e sair. Já o processo

PORTAO2, devido a escolha interna (representada pelo símbolo τ), possui uma transição que permite executar um evento e recusar o outro.

Essa abordagem é válida para processos que não divergem. Quando há necessidade de analisar esse comportamento, devemos usar o modelo a seguir.

Modelo de falha-divergência

O modelo de falhas/divergência tem sido considerado padrão para CSP, pois inclui os dois modelos anteriores. Este permite investigar o que um processo pode fazer, identificar suas falhas e verificar suas divergências.

A divergência é um dos piores comportamentos que um componente do sistema pode apresentar, levando-se em consideração que outros componentes podem ficar na espera, consumindo recursos computacionais, enquanto aguardam que em algum momento o pro-cesso consiga sincronizar [SCHNEIDER, 1999].

Quando um processo realiza uma sequência infinita de eventos internos, não há garan-tias de que em algum momento o processo vai alcançar um estado estável. A Figura 2.5 ilustra o exemplo de dois processos divergentes.

Figura 2.5: Processos divergentes

Os processos PORTAO3 = entrar -> PORTAO3 e

PORTAO4 = entrar -> PORTAO4 [] sair -> STOP que são representados através das maquinas de estado da seguinte forma: PORTAO3 \ {entrar} e

PORTAO4 \ {entrar} , têm execuções divergentes, devido à ocultação de seus canais.

(31)

f ailures(P) =f ailures(P)∪ {(s, X)|sdivergences(P)}, ou seja, o conjunto de falhas do processo após divergir. Esse comportamento é diferente das f ailures(P), que repre-senta o conjunto de falhas do processo após a execução de cada trace.

Refinamento

Refinar um sistema significa criar uma nova modelagem ou implementação (sair do abstrato para algo mais próximo da implementação) de modo que o comportamento seja compatível. Em CSP, todos os três modelos semânticos apresentados anteriormente (tra-ces, falhas e falhas-divergência) possuem suas formas de refinamento que são possíveis verificar através da ferramenta FDR2.

O modelo de traces está relacionado a sequência de eventos que um processo pode executar. Nesse modelo, um processoP é refinado por um processo Q(P T Q) se todas

as possíveis sequências de eventos de Qsão possíveis em P (traces(Q)traces(P)). O modelo de falhas indica o que um processo pode recusar após a execução de um trace. Nesse modelo, um processo P é refinado por um processo Q (P F Q) se Q não

introduz nenhuma falha quando substitui P, além de não introduzir nova sequência de comunicaçãotraces(Q)⊆traces(P) e f ailures(Q)⊆f ailures(P).

O modelo de falhas e divergências é o único capaz de investigar se o pro-cesso refinado não introduz mais divergências. Um processo P é refinado por Q se as possíveis sequências em que Q diverge e seu conjunto de falhas ao divergir, são possíveis em P. Seu refinamento é definido como seguinte:

PF D Qf ailures(Q)⊥ ⊆ f ailures(P)⊥ ∧ divergences(Q)⊆ divergences(P).

Baseado nesses modelos semânticos, foram implementadas diversas ferramentas de suporte a CSP. A seguir, apresentaremos algumas delas.

2.2.2

Ferramentas para CSP

CSP possui algumas ferramentas que auxiliam tanto no processo de modelagem e verificação, como na visualização gráfica do comportamento dos processos. A seguir apre-sentamos quatro dessas ferramentas: FDR2, ProBE, ProB e TypeChecker.

FDR2

(32)

Sendo um produto da Formal System1, FDR2 foi a primeira ferramenta comercial disponível para CSP e desempenhou um papel importante na sua evolução. O FDR2 está disponível para as plataformas Linux, Solaris e Mac OS.

Usando FDR2, é possível verificar refinamento de processos nos três modelos descritos anteriormente. Além disso, é possível a utilização do FDR2 sem interface gráfica. Em nosso trabalho, usamos a interface ’batch’ para executar as asserções do script gerado pela BTS. Essas asserções são usadas para afirmar propriedades e refinamento, e são definidas da seguinte forma:

assert Abstract [X= Concrete

onde Abstract e Concrete são processos e o X indica o tipo de comparação: T para traces, F para falhas e FD para falha e divergência.

FDR2 também permite a verificação de várias condições de exatidão, como ausência de deadlocks e livelocks, podendo ser investigado os motivos quando essas não são satis-feitas, e nos auxilia na verificação de comportamentos determinísticos para os modelos apresentados anteriormente. A seguir, temos alguns exemplos de asserções que podem ser aplicadas na especificação da Figura 2.2.

assert PARQUE :[ deterministic [FD] ]

assert USUARIOS :[ deadlock free [F] ]

assert SISTEMA_PARQUE :[ divergence free ]

assert SISTEMA_PARQUE [T= PARQUE

Como podemos observar, além da verificação de refinamento, o FDR2 também permite avaliar diretamente se um processo é determinístico, livre de deadlocks e divergência.

Na Figura 2.6 podemos visualizar a interface da ferramenta FDR2, bem como a ilus-tração da verificação dessas asserções na parte central. O resultado da verificação dessas asserções, válido ou não, é representado por um √ verde e um χ vermelho, respectiva-mente.

Uma característica importante do FDR2 são os contraexemplos. Quando uma asserção é selecionada para depuração, é criada uma nova janela com informações de contraexem-plos que foram encontrados (caso haja) enquanto a asserção era analisada. Sendo possível explorar as razões das asserções falsas.

(33)

Figura 2.6: Interface da FDR2

ProBe

ProBe [PROBE. . . , 2003] é um animador para CSP que permite ao usuário explorar o comportamento dos modelos interativamente. A ferramenta exibe uma lista com as possíveis ações e estados que um processo pode executar. Assim o usuário pode verificar um dado comportamento do processo e detectar problemas.

O ProBe é gratuito e possui versões para Windows, Linux, FreeBSD e Solaris. Além de ser muito simples de usar, é notável sua importância para o ensino de CSP, pois é possível visualizar o comportamento dos processos de forma interativa, como podemos observar na Figura 2.7.

(34)

ProB

Assim como o ProBe, o ProB2(Fig. 2.8) é outro animador emodel-checker [CLARKE JR.et al., 1999] que oferece suporte a CSP e outras linguagens formais, como método B [SCHNEIDER, 2001], Z [SMITH, 2000], Event-B [ABRIAL et al., 2010] e TLA [LAM-PORT, 1994]. Esta permite que as especificações sejam verificadas de forma automática e animada, ajudando na detecção de erros.

ProB é gratuito e possui versões Windows, Linux e OS X.

Figura 2.8: Interface da ProB

Na Figura 2.8 podemos visualizar, na parte superior, uma especificação CSP e na parte inferior central é possível explorarmos o comportamento dos processos CSP, clicando sobre eles.

TypeChecker

TypeChecker é um verificador de tipos da linguagem CSP, ou seja, ele é utilizado basi-camente para verificar se a especificação foi definida corretamente, no tempo de tradução do programa (ou tempo de compilação). OTypeChecker não possui interface gráfica e é executado através de linhas de comando.

Em nossa ferramenta utilizamos o verificador de tipo para analisar os comportamentos

(35)

externos, descritos pelo usuário.

2.3

Abordagem para o desenvolvimento sistemático e

confiável de sistemas baseados em componentes

O trabalho desenvolvido em [RAMOS, 2011] apresenta uma abordagem que propõe a composição sistemática e segura de componentes. Essa descreve um modelo de com-ponente que se concentra em seus conectores e impõe restrições necessárias para uma interação segura. A estratégia define quatro regras de composição: interleave, communi-cation, feedback e reflexive. Estas asseguram corretude na composição, como a ausência dedeadlocks.

Iniciaremos a apresentação da abordagem descrevendo o modelo de componente pro-posto.

Modelo de componente

Um contrato descreve o comportamento que um componente deve ter para obter con-fiança. Nesse sentido, [RAMOS, 2011] definiu um modelo de componente que representa o componente, seus conectores e sua interação semântica, formando a base para uma composição segura.

Na abordagem, componentes e conectores (Figura 2.9) são representados basicamente por elementos caixa-preta, descritos através de um processo CSP, com seus canais e tipos específicos, que definem um comportamento externo, seus pontos de interação (ou portas) e suas interfaces, respectivamente.

Figura 2.9: Modelo de componente

Para ilustrar melhor, vamos considerar um exemplo clássico de um cliente-servidor

(Figura 2.10). O exemplo consiste em um sistema de caixa eletrônico, onde oCliente e a

(36)

Figura 2.10: Exemplo de um Cliente-Servidor

Utilizaremos esse exemplo durante toda essa seção para apresentar as regras e propri-edades da abordagem. O comportamento dos componentes, bem como seus tipos e canais são descritos a seguir.

NUM = {0..20}

datatype DADOSMQ = rt.NUM | requisitaSaldo | ackRt.Bool | recSaldo.NUM datatype DADOSCL = insereCartao.NUM | digitaSenha.NUM | retiraDin.NUM |

saldo | retiraCartao | recebeDin | mostraSaldo channel cl : DADOSCL

channel maq : DADOSMQ

Figura 2.11: Descrição dos tipos e canais

Cliente = cl.insereCartao?num -> cl.digitaSenha?num -> (SAQUE [] SALDO) ; cl!retiraCartao -> Cliente

SAQUE = cl.retiraDin? val -> maq.rt.val -> maq.ackRt?a -> cl!recebeDin -> SKIP

SALDO = cl.saldo -> maq.requisitaSaldo -> maq.recSaldo?x -> cl!mostraSaldo -> SKIP

Figura 2.12: Descrição do comportamento do componente Cliente

Maquina =

|~| a: Bool @ maq.rt?x -> maq.ackRt.a -> Maquina []

|~| y: NUM @ maq.requisitaSaldo -> maq!recSaldo.y -> Maquina

Figura 2.13: Descrição do comportamento do componente Máquina

A especificação inicialmente apresenta os tipos e canais (Fig. 2.11) utilizados pelos componentes. Em seguida, temos o comportamento deCliente(Fig. 2.12) eMaquina(Fig. 2.13). O processo Cliente recebe do usuário, através do canal cl, o número do cartão seguido da senha. Logo após, é oferecida um escolha entre sacar dinheiro (SAQUE) e verificar saldo (SALDO). Já o processoMaquina tem o comportamento de retirar dinheiro ou verificar saldo, de acordo com a escolha do Cliente. Por exemplo, maq.retirar.val

(37)

Nesse processo existe uma escolha externa entre retirar dinheiro ou requisitar saldo. O operador @ representa uma separação entre o valor que está sendo recebido internamente e a execução dos eventos.

Como podemos observar, o comportamento do componente está relacionado à ação de interação, não se preocupando com o que ocorre internamente. Ou seja, relaciona-se com o que ele pode receber e fornecer para outro componente. Por isso as ações de seu comportamento são externas.

Nesse contexto, a interface de comunicação do componente é representada por dois conjuntos de eventos CSP: eventos de entrada e eventos de saída, onde os valores de saída de um componente são recebidos na entrada de outro e essa comunicação pode representar um par request-response. O comportamento da comunicação entre dois componentes (representado pelo elemento central da Fig. 2.10 (CON)) será explicado mais a frente. A seguir apresentaremos a definição do modelo de componente.

Definição 1 (Contrato de Componente). U m contrato de componente Ctr:hB, R, I, Ci

é descrito através de um comportamento B, um conjunto de canais (portas) de comunicação C, um conjunto de interf aces I e uma f unção total entre canais e interf aces R:CI, tal que:

• B é um processo de entrada e saída (I/O P rocess).

• R representa a relação entre canais e o conjunto de tipos, cujo dom(R) =C img(R) =I.

• Os eventos de todos os seus canais C devem estar associados a dois conjuntos dis-juntos: inputs e outputs.

O comportamento desses componentes é representado por umI/O P rocess(processo de entrada e saída), que em CSP é definido por um processoP que deve satisfazer a cinco condições:

1. Canais de entrada e saída: Os eventos de um canal fazem parte das ações de entrada ou saída de um processo. Por exemplo, no sistema Cliente-servidor as entradas e saídas para o Cliente são definidas através das funções inputs e outputs, como o seguinte:

inputs(maq, Cliente) = { maq.ack, maq.recSaldo}

(38)

onde a interseção deinputseoutputsé vazia e a sua união é subconjunto de {|maq|}.

Como podemos observar, o processo Cliente satisfaz essa condição, pois não possui eventos em comum nas entradas e saídas.

2. Traces infinitos: P deve ter traces infinitos (mas espaço de estado finito).

3. Ausência de divergência: P é livre de divergência.

4. Entrada Determinística: Se um conjunto de eventos de entrada em P é oferecido pelo ambiente, nenhum desses pode ser recusado. Esse determinismo é muito im-portante, pois o processo nunca vai recusar um serviço oferecido por outro processo (componente). Essa condição é baseada na semântica de falhas que garante que se

P executa um trace s ˆ hc.ai, tal que hc.ai é uma entrada, então esse evento não pode ser recusado por P após s ((s,{c.a})/f ailures(P)).

Nos processos Cliente e servidor essa propriedade é satisfeita, visto que não há escolha interna entre os eventos de entrada.

5. Saída Fortemente Decisiva: todas as escolhas entre eventos de saída de um determi-nado canal em P são internas. Essas decisões são baseadas nas ações de entrada do processo, o que gera um não determinismo na saída. Na saída decisiva, dado o trace

s ˆhc.bital quec.bpertence à saída de P, toda saída emcserá recusada, excetoc.b

- representado por (s, outputs(c)\ hc.bi) ∈f ailures(P). Com isso, é notável que o processo sempre irá oferecer uma saída nesse canal.

Os processos Cliente e servidor satisfazem essa condição, pois não há escolha nas suas saídas e quando essa é oferecida, existe apenas uma opção de saída.

Os comportamentos de Entrada Determinística e Saída Decisiva são propriedades que indicam como um componente deve aceitar e enviar informações.

Esse modelo de componente é chamado de BRIC (Behavior, relation, interfaces, chan-nels) e descreve as condições que devem ser atendidas para se obter um componente con-fiável. No sistema Cliente-servidor (Fig. 2.10), o contrato de componente de Cliente e

Maquina são definidos como o seguinte:

CtrCliente=hCliente,{cl7→DADOSCL, maq7→DADOSM Q},{DADOSCL, DADOSM Q},{cl, maq}i

(39)

Como podemos observar, as definições descritas até agora observam o componente e seu comportamento. Essas características são fundamentais para que as propriedades e restrições dos componentes sejam garantidas e a aplicação das regras de composição tenham o resultado desejado. Por isso, uma das principais características da aborda-gem proposta em [RAMOS, 2011] é resolver os problemas esperados antes de integrar os componentes.

Descreveremos a seguir algumas propriedades importantes relacionadas a verificação da interação segura desses componentes.

Protocolos de comunicação

Outra importante característica do componente é o protocolo de comunicação. Esse está relacionado a interação de um componente com outro no sistema.

Os protocolos são importantes para realizar verificações mais específicas sobre a in-teração dos componentes, analisando a comunicação através de um canal. A seguir apre-sentaremos algumas características doprotocolo de comunicação.

Implementação: A implementação do protocolo de um canal ch do pro-cesso P é descrita como todo comportamento do processo sobre ch

(P rotIM P(P, ch)≡F P ↾{ch}), tal que P rotIM P deve ter os mesmos traces e

fa-lhas do processo sobre a projeção desse canal. Ou seja, os traces e fafa-lhas desses devem ser equivalentes (≡F). A projeção é toda execução de chem P.

No exemplo do Cliente-servidor o canal maq representa a interação de cada com-ponente. Existe o protocolo a partir do ponto de vista do Cliente e da Maquina. Estes são definidos a partir do comportamento do processo. Por exemplo, definido o comportamento do componente Cliente, seu protocolo representa todo comporta-mento de Cliente no canal maq, como descrito na Figura 2.14. Da mesma forma, para a Maquina, seu protocolo é representado por todo comportamento do processo

Maquina sobre o canal maq, como descrito na Figura 2.15.

Prot_Cliente =

|~|x: NUM @ maq!rt.x -> maq.ackRt?a -> Prot_Cliente []

maq.requisitaSaldo -> maq.recSaldo?x -> Prot_Cliente

(40)

Prot_Maquina =

|~| a: Bool @ maq.rt?x -> maq.ackRt.a -> Prot_Maquina []

|~|x: NUM @ maq.requisitaSaldo -> maq!recSaldo.x -> Prot_Maquina

Figura 2.15: Protocolo da Maquina para o canal maq

Os protocolos de comunicação descritos na Figura 2.14 e 2.15 são referentes a to-das as ações do canal de interação maq, tanto para o componente Cliente como a

Maquina.

Nesse exemplo, não é implementado protocolo de comunicação para o canal cl, pois este não interage com nenhum componente. Se quisermos tratar o ambiente (usuá-rio) que utiliza esse serviço como outro componente, consequentemente teremos uma interação deste com o componente Cliente.

Satisfação: Um protocolo é válido quando ele satisfaz o seguinte refinamento: (QF

P rotIM P(P, ch)), onde Q corresponde a um protocolo que deve ser refinado pela

comunicação do processo P sobre o canal ch.

No exemplo do Cliente-Servidor, para analisar se o protocoloProt_Cliente satisfaz o processoCliente é necessário realizar uma verificação através do refinamento CSP, ou seja, verificar se o conjunto de traces e falhas da projeção de Cliente sobre o canal maq refinaProt_Cliente (P rot_ClienteF P rotIM P(Cliente, maq)).

Esses protocolos de comunicação são descritos para analisar a relação entre a comu-nicação de dois processos, focando unicamente em seus protocolos. Verificar a compati-bilidade desses é uma forma de garantir que a comunicação entre dois processos, que são

I/O processes, é livre de deadlocks. A propriedade de compatibilidade de protocolo é descrita a seguir.

Protocolos fortemente Compatíveis: a saída de um processo sempre será aceita pelo outro processo. Esse tipo de verificação é de extrema importância para o sis-tema, pois consegue garantir que nenhuma informação gerada (saída) pelo compo-nente será perdida.

Analisar a compatibilidade entre dois protocolos através de refinamento CSP pode ser definido através do processo chamadodual protocol [VALLECILLO et al., 2006]. O dual

(41)

é igual as outputs(Q) e inputs(Q), respectivamente, e que tem os mesmos conjuntos de traces, ou seja, os eventos de entrada deQ correspondem a saída de seudual e os eventos de saída deQ são correspondidos na entrada de seu dual.

Nesse contexto, podemos definir o dual protocol do Prot_Cliente como descrito na Figura 2.16.

DUAL_Prot_Cliente =

|~|a: Bool @ maq.rt?x -> maq.ackRt.a -> DUAL_Prot_Cliente []

|~|x: NUM @ maq.requisitaSaldo -> maq.recSaldo!x -> DUAL_Prot_Cliente

Figura 2.16: Dual-protocol de Prot_Cliente

Para ser compatível, o DUAL_Prot_Cliente deve ser refinado pelo protocolo do outro componente, em nosso exemplo,Prot_Maquina, cuja condição é satisfeita.

Instância de Componente

Uma das vantagens do desenvolvimento baseado em componente é a reutilização. Normalmente um componente é definido uma vez e reusado múltiplas vezes, e em vários contextos diferentes. Nessa abordagem, o contexto é representado por um conjunto de canais (que representam os pontos de interação) e é usado para comunicar um único componente no ambiente. Nesse sentido, a substituição dos canais de um componente por outros, significa que ele supostamente poderá interagir com outro ambiente. Essa substituição é representada pela renomeação de um conjunto de canais de um componente em novos. Nesse contexto, a reutilização é feita através da atribuição de nova identificação ao componente que se deseja usar.

Figura 2.17: Reutilização de componente

(42)

Maquina1 = Maquina [[ maq <- maq_1 ]]

Figura 2.18: Criando um novo componente Máquina

No exemplo doCliente-servidor, uma instância do componenteMaquina pode ser defi-nido como na Figura 2.18, onde o componenteMaquina1 possui o mesmo comportamento deMaquina, porém, com seu nome e canal renomeado.

A instância de componente é útil quando desejamos construir sistemas cujos compo-nentes possuem características idênticas.

Composição

Nessa abordagem, a comunicação entre componentes é assíncrona. Para representar essa comunicação um buffer é apresentado como elemento intermediário da composição (Figura 2.19). Ele copia as informações de um canal para outro, ignorando se o outro componente está ativo para receber entradas.

Apresentaremos a seguir como a comunicação assíncrona dos processos que são I/O P rocessé especificada via buffer.

A definição de buffer em CSP é descrita como um processo com dois canais, sendo um de entrada e um de saída, onde eles possuem o mesmo tipo. O buffer copia as informações do seu canal de entrada para o seu canal de saída de modo que nenhuma produção é perdida.

Figura 2.19: Exemplo de comunicação via Buffer

Na abordagem de [RAMOS, 2011], o mapeamento entre entrada e saída é traduzida como uma renomeação entre as interfaces. Considerando isso, foi definida uma função

(43)

de saída. A renomeação usada no buffer é descrita como: RaIOb ={a.x7→b.x}, tal que

x é uma extensions(a) e a.xoutputs. Desta forma, RaIOb substitui saídas em a por entradas correspondentes em b.

Para sistemas modelados por meio de máquinas de estado e especificados via buffer, existem duas propriedades que permitem o mecanismo de verificação, sem explosão dos estados:

Entrada e Saída Confluente: Se um processo possui ações de canais distintos a serem executadas, uma não impede a outra de ser executada, a menos que seja no mesmo canal.

Os processos Cliente e Maquina são I/O Confluente. Eles são o exemplo mais sim-ples, onde não há escolha entre os eventos de diferentes canais, nem entre entradas e saídas.

Propriedade de Saída Finita: Como o comportamento de I/O process é livre de divergência, a ausência de divergência ao ocultar a saída de um canal garante que o processo sempre comunica um número finito de saídas possíveis (ou seja, o tipo do canal é finito).

Nesse sentido, um processoCliente, por exemplo, tem propriedade de saída finita se para todo canal c pertencente ao conjunto de canais de Cliente, o comportamento

Cliente\outputs(c, Cliente) é livre de divergência.

Como descrito anteriormente, a compatibilidade de protocolo é usada para verificar a comunicação entre dois processos. Porém, é interessante verificar a relação entre dife-rentes canais de um mesmo componente para preservar propriedades comportamentais na composição. Apresentaremos a seguir duas propriedades que comparam a comunicação entre eventos de um mesmo processo.

Canais Desacoplados: A comunicação do canal de um processo não interfere na comunicação do outro. Na Figura 2.20, a comunicação do canal c1 é independente de c2. Nesse contexto, os canais são desacoplados porque não introduzem nenhum ciclo de dependência.

(44)

Figura 2.20: Canais desacoplados

Figura 2.21: Compatibilidade de Auto-Injeção com Buffer

Regras de Composição

As regras de composição introduzidas em [RAMOS, 2011] são apresentadas em uma ordem incremental de complexidades e focam em cenários específicos de composição. As quatro regras são interleave, communication, feedback e reflexive. Estas podem prever a ausência de deadlocks e cada composição criam um novo componente que inclui os dois anteriores.

A Figura 2.22 apresenta a estrutura de três dessas regras de composição. As composi-ções eminterleaveecommunicationsão binárias (comunicam canais de dois componentes). Já as composições em feedback e reflexive são unárias, pois estão relacionadas a comuni-cação de diferentes canais em um mesmo componente. As regras de composição unária têm a mesma estrutura, sendo diferenciadas apenas pelas condições impostas.

Figura 2.22: Exemplo de três regras de composição

(45)

Definição 2(Composição em Interleave). Se P e Q são dois contratos de componentes, tal que P e Q não possuem canais em comum (CPCQ=∅, ondeCP e CQ representam

o conjunto de canais dos processos P e Q, respectivamente), então, a composição em interleave de P e Q é dada por:

P[k|]Q=PhihiQ

O operador de composição ≍representa uma interação assíncrona entre duas sequên-cias de canais, mediada pela ideia de buffers infinitos. Na definição acima, a composição não envolve comunicação, o que indica não haver qualquer tipo de interferência de um sobre o outro. Tomando como exemplo o sistemaCliente-servidor (Fig. 2.10), para adici-onarmos dois componentesCliente no sistema, não é necessário existir comunicação entre eles, apenas deles com a Maquina. Para isso, podemos compor esses componentes da seguinte forma:

Cliente1 =Cliente[[cl <cl1, maq <maq1]]

Cliente2 =Cliente[[cl <cl2, maq <maq2]]

Cliente1[k|]Cliente2 =Cliente1hihiCliente2

onde inicialmente dois componentes Cliente são instanciados e posteriormente são colo-cados em interleave.

A segunda regra de composição é o caso tradicional, ou seja, caminho mais comum para comunicar canais de diferentes componentes, como no exemplo da comunicação entre oCliente e a Maquina.

Definição 3(Composição por Comunicação). Se P e Q são dois contratos de componentes e ic e oc dois canais de comunicação, tal que

icCPocCQ,

CPCQ=∅

e os protocolos de comunicação P rotIM P(P, ic) [[RicIOoc]] e P rotIM P(Q, oc) [[RocIOic]]

• Possuem Entrada e saída confluente

Imagem

Figura 2.1: Atividades Para o Desenvolvimento com Componentes
Tabela 2.1: Operadores da linguagem CSP
Figura 2.3: Máquina de estado do processo PARQUE criada pelo FDR2
Figura 2.4: Processos PORTAO1 e PORTAO2 com seus estados e suas recusas
+7

Referências

Documentos relacionados

Os dados observados para a calibração e validação do modelo ORYZA/APSIM foram obtidos por meio de dois experimentos realizados na Embrapa Arroz e Feijão (16º29´46.7´´S,

Estudos mais recentes utilizaram os registros paroquiais como fontes da pesquisa e história social da escravidão como aporte teórico para estudar a sociedade

Em outras palavras, não basta, para que se configure o perigo de vida, por exemplo, uma lesão perfurante das alças intestinais; é preciso que dessa lesão haja

A gradeço de público, na grata oportunidade que se me oferece, ao Sem inário Teológico W artburg pelo grau de doutor honoris causa a mim conferido por d

107 State Research Center of Russian Federation, Institute for High Energy Physics, Protvino, Russia 108 University of Belgrade, Faculty of Physics and Vinca Institute of

dos diferentes jogos e o aspecto curricular que se deseja desenvolver (PCNs, 2000, p. De acordo com as ideias dos PCNs, aplicar jogos nas aulas de Matemática é uma das

No paradigma da doença avançada (N3, N4 ou evidência de invasão vascular) ou metastizada (M1), a resseção cirúrgica com intenção curativa não se assume como

A limited sixteen-hour period per year was set for this community experience for two reasons: first, in accordance with an agreement with public service dentists, the students