Précédent : Logiciels Remonter : Projet PAMPA, Modèles et
outils Suivant : Actions industrielles
Participants : Thierry Jéron , Pierre Morel , César Viho ,
Claude Jard , Sébastien Encognère (Stagiaire DEA/IFSIC)
Mots-clés : Test de conformité, tests abstraits, tests
exécutables, abstraction, déterminisation, génération à la volée,
vérification, objectif de test
Résumé : L'activité relative au test de conformité revêt deux aspects: la génération automatique de tests de conformité qui produit des cas de tests abstraits et l'implémentation de ces tests abstraits en tests exécutables. Concernant la génération de tests, nous continuons notre activité essentiellement algorithmique pour améliorer les tests produits, faciliter leur sélection, prendre en compte différentes architectures de test. Sur ce point, en 97 nous avons développé un module permettant la génération de tests à la volée, et avons conçu un nouvel algorithme permettant de générer des tests ayant moins de cas inconcluants. L'implémentation des tests est une activité qui démarre cette année. Le but est dans un premier temps d'identifier les problèmes liés à l'implémentation et l'exécution des tests et dans un second temps de proposer des solutions pour faciliter le passage des test abstraits aux tests exécutables.
La génération automatique de tests consiste à produire des cas
de tests à partir d'objectifs de tests et d'une spécification.
L'algorithme que nous avons élaboré produit des cas de tests
pendant le parcours en profondeur de l'IOLTS
représentant le comportement visible de la spécification. Le
problème principal qui se pose est que la spécification est
donnée dans un langage décrivant le comportement interne et
externe de la spécification et que le graphe d'état de cette
spécification est souvent énorme voire même infini. Comme en
vérification, on se trouve face au problème bien connu de
l'explosion combinatoire dû à la description de données et à la
concurrence. Une solution est d'effectuer la génération de test à
la volée [29]. En
effet, pour construire un cas de test
correspondant à
l'objectif
,il n'est pas forcément nécessaire de parcourir
en entier mais seulement un sous graphe
de
,et par conséquent il n'est pas
nécessaire de construire que la partie correspondante
de
l'IOLTS
représentant le comportement global de la
spécification. Or
est obtenu par abstraction des
actions internes et déterminisation à partir de
. Il
faut donc effectuer ces opérations à la volée de manière
efficace. L'algorithme est une adaptation de l'algorithme de
Tarjan qui calcule les arbres réduits de composantes fortement
connexes par actions internes. La gestion globale de ces arbres
réduits permet d'obtenir une complexité linéaire dans le nombre
de transitions de
. La déterminisation implique une
complexité au pire exponentielle dans le nombre d'états puisque
les états de
sont les parties de
.Cet
algorithme d'abstraction et déterminisation à la volée a été
intégré à l'outil TGV et nous a déjà permis de produire des tests
pour des spécifications de taille industrielle dont il était
impossible de générer le graphe complet.
L'algorithme actuel de TGV produit des tests acycliques en
coupant le graphe obtenu par produit synchrone entre et
sur l'occurence de boucles. Ceci a pour
effet d'augmenter le nombre de cas de verdicts inconcluants
(INCONCLUSIF) et pour conséquence lors de l'exécution des tests
d'être obligé de repasser les tests jusqu'à obtention d'un
verdict PASS ou FAIL. Or les tests écrits à la main font souvent
apparaître des boucles par exemple sur des réceptions qui
n'influent pas sur le comportement attendu. Nous avons donc conçu
un nouvel algorithme permettant de produire des tests ayant des
cycles. Il est basé sur l'algorithme de calcul de composantes
fortement connexes de Tarjan. Il peut aussi être vu comme une
adaptation d'algorithmes de model-checking de propriétés
d'accessibilité. La différence principale réside dans le fait que
dans le cas du model-checking, on se contente soit d'une réponse
positive, soit d'une séquence de diagnostic invalidant la
propriété. Dans notre cas, il faut synthétiser un cas de test,
i.e. un graphe image miroir d'un sous-graphe de
accepté par TP. Cet algorithme est en cours
d'intégration dans TGV et donnera lieu à publication après
expérimentation.
Une des entrées de l'algorithme de génération de tests est l'objectif de test. Cet objectif est spécifié par un automate qui permet la sélection des tests en décrivant de manière abstraite certaines interactions à tester. Le pouvoir d'expression de ces objectifs est un élément important pour permettre à l'utilisateur de spécifier ses objectifs. Nous travaillons à l'amélioration de ce pouvoir d'expression, afin entre autres, de s'abstraire des valeurs des paramètres des interactions et de spécifier des actions internes, ce qui a pour conséquence des modifications dans les algorithmes de TGV.
Les cas de tests produits par nos algorithmes sont des tests abstraits au sens où ils sont indépendants d'une implémentation particulière. Mais les tests réellement passés sur une IUT se font via un testeur qui utilise des tests exécutables. Ces tests exécutables doivent être produits à partir des tests abstraits par compilation et en renseignant certains paramètres du test (PICS et PIXIT) comme la valeur effective des temporisateurs, les adresses effectives, etc. Nous commençons à regarder de plus près cet aspect d'un point de vue expérimental pour le moment. Ne disposant ni de compilateur TTCN, ni de testeur, ni d'implémentations réelles de nos études de cas, l'idée est de produire des implémentations par compilation de spécifications formelles et de traduire les tests abstraits en tests exécutables pour une architecture de test distant.
Participants : Stéphane Écolivet , Jean-Marc Jézéquel ,
Pascale Launay , Jean-Lin Pacherie , Alain Le Guennec ,
Jean-Louis Pazat
Mots-clés : frameworks, grappes, objets, transformation de
programme
Résumé : L'objectif est ici d'étudier, concevoir et valider des modèles et des méthodes de construction de logiciels pour architectures réparties dans un contexte de programmation par objets. Les défis scientifiques à relever concernent :
- la définition de modèles de conception d'architectures d'objets réparties grâce à un certain nombre de motifs de conception (Design Patterns),
- la définition et la réalisation efficace des composants génériques nécessaires et des outils de validation associés, ainsi que leur composabilité (modèle(s) d'organisation et d'interopérabilité, méthodes de validation),
- la définition de transformations de programmes basée sur les frameworks tout en en maîtrisant finement leur sémantique.
Nous explorons depuis quelques années ces problèmes dans le cadre objet, avec des domaines d'application variés comme le calcul scientifique intensif [30,32] ou les télécommunications [17,34]. Nous avons également exploré des techniques de transformation de programmes pour le parallélisme de données dans le cadre de langages impératifs [35].
Notre contribution à EPEE a porté cette année sur la mise en place d'un système de motifs de conception permettant d'améliorer la réutisabilité, l'extensibilité et la maintenabilité des traitements d'énumérations en s'appuyant sur un formalisme mathématique rigoureux [13,38].
L'objectif de parallélisation est atteint en exploitant les propriétés du système de motifs de conception afin de permettre la transformation d'applications séquentielles en applications parallèles. Ce qui nous a amené d'une part à définir les abstractions intervenant dans la parallélisation des traitements et la répartition des collections, et d'autre part à organiser leurs collaborations au sein du système de motifs. Il s'agit donc d'identifier les abstractions liées au domaine de la distribution dirigées par les données et celles issues de l'interprétation des motifs dans ce nouveau contexte.
L'idée que nous défendons est qu'une application construite de manière à garantir la réutilisation, l'extensibilité et la maintenabilité dispose des qualités suffisantes à sa parallélisation. Grâce au système de motifs, nous disposons d'une information sur l'architecture générale des composants dédiés aux traitements des collections. Le processus de parallélisation s'appuie alors sur la réinterprétation des composants séquentiels dans un contexte parallèle.
L'originalité de notre démarche vient de son intégration dans une approche résolument orienté vers la qualité logicielle, indépendamment du problème de la parallélisation. L'intérêt est alors de ne pas imposer de contraintes au niveau de la conception séquentielle dans le seul but de pouvoir en dériver le code en application parallèle.
En collaboration avec l'Université de Tokyo [JMSY96], nous avons travaillé à proposer de nouvelles abstractions permettant d'assurer un découplage entre la distribution des données et le parallélisme [30]. Partant de l'observation qu'un calcul basé sur un modèle d'exécution SPMD peut être considéré comme l'application ordonnée d'une fonction (ou opérateur) sur une collection d'éléments, l'idée est d'abstraire les partitions de données et l'accès à ces données par l'utilisation de structures de données hiérarchiques, hierarchical containers, et d'itérateurs composables, composable traversers.
L'introduction des collections hiérarchiques doit permettre d'étendre de façon orthogonale le parallélisme et la distribution afin de pouvoir utiliser facilement et efficacement des schémas de distribution et de parallélisme complexes sans transformation du code du client. Les collections hiérarchiques possèdent des relations d'ordre partiel entre les objets situés à un même niveau hiérarchique et des relations d'appartenance entre des collections adjacentes dans la hiérarchie. Les calculs sur des collections hiérarchiques sont effectués à l'aide d'itérateurs qui parcourent les éléments en respectant les relations d'ordre ainsi définies, les objets n'étant pas ordonnés peuvent être traités en parallèle.
De façon similaire, on peut décomposer les itérateurs parcourant les structures de données de l'application à l'aide d'itérateurs de base. A partir de la définition d'une librairie d'itérateurs simples, il devient alors possible en les composant de parcourir de diverses manières les différentes couches des collections hiérarchiques tout en satisfaisant les contraintes de distribution et en maximisant le parallélisme.
Ainsi, selon ces principes, un calcul basé sur l'application d'un opérateur sur une collection d'éléments se fait en décomposant de façon hiérarchique cette dernière afin de séparer parallélisme et distribution et en effectuant une composition d'itérateurs élémentaires pour pouvoir s'adapter à cette configuration particulière.
Cette méthode permet ainsi au programmeur de définir
facilement des schémas relativement complexes de distribution. Ce
dernier n'a en effet qu'à choisir les collections et les
itérateurs de base définis dans cette extension d'EPEE et de les
composer afin de les adapter à son problème. Nous avons commencé
à appliquer ces idées au méta-computing, c'est à dire à
l'utilisation combinée de ressources de calculs hétérogènes
(réseaux de stations de travail, calculateurs parallèles, etc.)
couplés avec des réseaux à très haut débit (cf. module ).
Les collections hiérarchiques ainsi que les itérateurs qui leur sont associés présentent l'avantage de pouvoir refléter cette hiérarchie mémoire et semblent donc bien adaptés à la programmation de telles architectures [32]. Nous commençons à étudier comment il serait possible de tirer parti des possibilités offertes par ces dernières dans des domaines comme la cartographie fine de génomes [37].
Pour effectuer une première généralisation de l'approche de transformation de programmes que nous avions étudiée dans le cadre du projet PANDORE, nous proposons de réaliser des transformations de programmes explicitement parallèles en des programmes parallèles et répartis [PL96]. Par rapport à l'approche HPF, nous prenons en compte dans un même cadre la génération de code réparti par distribution de contrôle et par distribution de données. Pour ce projet, nous avons choisi d'utiliser le langage à objets JAVA sans en modifier la syntaxe mais en ``encadrant'' la programmation par un framework qui permet de restreindre le parallélisme exprimable.
Dans le modèle de programmation nous considérons deux types d'objets :
Nous définissons des Collections qui sont des objets génériques, pouvant contenir tout type d'éléments (et en particulier des tâches). Une collection de tâches est donc définie par instanciation du type des éléments de la collection.
Le parallélisme s'obtient par le ``parcours'' conjoint de deux collections :
Ce parcours consiste à activer chacune des tâches de la première collection avec les données correspondantes de la deuxième. Ce modèle de programmation parallèle est structuré sous forme d'un framework qui est basé sur le framework des opérateurs. Nous n'utilisons aucune extension du langage : le ``parcours'' des collections (activation parallèle des tâches) est prédéfini dans une classe ``Par'', qui est elle même, par héritage, une tâche (ce qui permet l'imbrication du parallélisme).
Dans le modèle d'exécution, les seuls objets fragmentés sont les collections. La distribution des collections guide le placement des éléments (tâches ou données) qu'elles contiennent. Les collections distribuées sont prédéfinies et possèdent la même interface que les collections centralisées.
La transformation d'un programme centralisé en programme réparti se fait en changeant la bibliothèque des collections utilisées pour le parallélisme (utilisation des collections distribuées). D'autre part, l'utilisation du RMI Java pour les communications nécessite de transformer les objets du programme (tâches et données). Cette transformation est actuellement faite automatiquement [35].
L'étude de la transformation ``parallèle vers réparti'' que nous avons commencée doit nous fournir des pistes :
Participants : Claude Jard , Renée Boubour , Jean-Marc
Jézéquel , François Pennaneach (stagiaire DEA/Supelec), Alain Le
Guennec , Hubert Canon , Benoît Caillaud , Loic Helouet
Mots-clés : télécom, objets, ordres partiels,
concurrence, UML, MSC, Réseaux de Petri, (Max,+)
Résumé : L'aspect central que nous étudions dans la modélisation pour les logiciels de télécommunication est la représentation de la concurrence et de la causalité dans le cadre d'objets communicants. Nos travaux sur ce thème sont jeunes et abordent plusieurs questions scientifiques complémentaires qui se regroupent actuellement dans le cadre des applications industrielles du projet. Au coeur du travail se situe la définition d'un modèle sémantique pour les vues comportementales d'UML et son utilisation pour intégrer des outils de validation. La recherche s'est concrétisée par l'utilisation du meta-modèle UML et la conception du modèle BDL, fondé sur des ordres partiels synchronisés. En amont, nous étudions des techniques mathématiques d'analyse et de transformation des modèles : une algèbre (Max,+) pour raisonner sur des ordres partiels temporisés et la théorie des régions pour générer des squelettes de synchronisation. Enfin, la sémantique d'ordre partiel des réseaux de Petri s'est avérée un outil puissant pour traiter du suivi en ligne des comportements répartis.
La notation UML (Unified Modeling Language) est issue des travaux de Booch, Rumbaugh et Jacobson, auteurs des méthodes de développement à objets parmi les plus utilisées (les méthodes Booch, OMT et OOSE). UML est le successeur commun de ces trois méthodes, dont elle reprend la plupart des concepts et notations, dans un souci d'unification. Le manque d'uniformisation, les difficultés à communiquer entre outils constituaient en effet un frein au déploiement des méthodes de développement à objets. Il était donc souhaitable de créer un langage commun convenant à la modélisation des systémes informatiques, mais également suffisamment générique pour prendre en compte des problèmes d'autres domaines. Contrairement à ces prédecesseurs, UML impose un langage (en cours de normalisation par l'OMG), mais laisse libre le choix du processus de développement associé.
La principale particularité de la notation UML réside dans sa base formelle appelée méta modèle : la sémantique des concepts manipulés par la notation UML est décrite en utilisant la notation elle-même. Cela a pour conséquence l'amélioration de la correction des modèles (suppression des ambiguïtés et des incohérences), et permet d'envisager l'utilisation de techniques formelles à des fins de vérification/validation, les éléments d'un modèle devant respecter les propriétés et contraintes définies dans le méta-modèle.
L'outil UMLAUT actuellement en cours de développement vise à montrer la validité d'une telle approche. Cet outil intègre le méta-modèle UML et fournit un ensemble de facilités permettant de raisonner sur des modélisations UML.
Les modèles sont fournis à l'outil dans le format CDIF (CASE Data Interchange Format), qui est un format destiné à l'échange de données entre outils de modélisation et supporté par les principaux logiciels de modélisation. Courant 1998, une version de CDIF adaptée à la notation UML devrait être normalisée par l'OMG.
Dans un futur proche, l'outil acceptera également en entrée des sources de programmes Java, afin de générer automatiquement les modèles UML correspondants (reverse-engineering).
UMLAUT intégrant le méta-modèle UML, il est possible de réaliser simplement des transformations de modèles définies par un ensemble de règles fournies par l'utilisateur. Une application possible serait l'intégration automatique d'un cadre de conception dédié à la validation, avec génération du code correspondant [17,33].
Problématique : Notre problématique est la synthèse de squelettes de programmes répartis ; c'est-à-dire des synchronisations et des consensus répartis nécessaires à la mise en oeuvre d'un service sur une architecture distribuée. Ceci concerne une grande variété d'applications, allant de la synthèse de protocoles du plus bas niveau (transport, etc) jusqu'au prototypage rapide de services évolués dans les réseaux dits intelligents .
Employés pour le prototypage de tels services, les diagrammes
de séquences (message sequence charts en anglais,
abbréviation MSC ) permettent la définition de
comportements de systèmes réactifs répartis à partir de
spécifications incomplètes. Cette notation s'inscrit bien dans
une démarche de conception incrémentale. Son style déclaratif la
rend attrayante auprès des ingénieurs en
télécommunications ; elle s'intègre particulièrement bien
dans une méthode de développement fondée sur la notation UML.
Elle est aussi étroitement liée au langage BDL
(voir ).
Reste alors à savoir engendrer des programmes répartis à partir d'un ensemble de diagrammes de séquences. Autrement dit, le problème est de produire un squelette de programme réparti dont les comportements satisfassent chacune des vues partielles du système que sont les diagrammes de séquences.
Les avancées récentes sur le problème de la synthèse de réseaux de Petri permettent maintenant le développement de techniques nouvelles en matière de synthèse de programmes répartis. Elles permettent de dépasser les limites imposées par les techniques classiques de répartition automatique étudiées ces dernières années dans le projet Pampa [41]. Nous travaillons à la généralisation des techniques de synthèse de réseaux au modèle qui soustend les diagrammes de séquences : les expressions régulières d'ensembles ordonnés étiquetés.
Synthèse de réseaux de Petri : Le problème de synthèse
est de produire un réseau de Petri borné dont le graphe des
marquages est isomorphe à un système de transition
donné . Les algorithmes de synthèse de réseaux
développés dans le projet Paragraphe reposent sur le concept de
régions dans les systèmes de transition et ramène la synthèse
d'un réseau à la résolution d'un ensemble de programmes linéaires
en nombres rationnels.
Nous avons étendu et adapté ces algorithmes à nos besoins, à savoir, l'aide à la génération de squelettes de programmes répartis : pour cela, la synthèse doit être contrainte par un placement des événements sur une architecture répartie de sorte que le réseau synthétisé ne comporte pas de conflit répartis et puisse être automatiquement transformé en programme réparti sur cette architecture.
SYNET : une outil de synthèse de réseaux de Petri : Il nous a semblé utile d'inscrire ce travail de recherche dans une démarche expérimentale ; c'est pourquoi les algorithmes de synthèse décrits plus haut ont été intégrés dans un prototype, l'outil SYNET [41] (voir http://www.irisa.fr/pampa/SYNET/synetFR.html).
Les techniques de synthèse de réseaux mises en oeuvre sont d'une très grande souplesse. Cela se traduit par une grande modularité de l'outil SYNET. Il est architecturé autour de trois composants : un noyau de programmation linéaire (algorithme du simplexe) en nombres rationnels, une bibliothèque de calculs sur les graphes (systèmes de transitions) et un ensemble d'afficheurs de graphes (réseaux et systèmes de transition).
L'outil SYNET accepte le format de représentation des systèmes
de transition de l'atelier de vérification Caesar/Aldebaran
(voir http://www.inrialpes.fr/vasy/pub/cadp.html).
Il a été développé en Caml-light avec une petite partie (méthode
du simplexe) codée en C et optimisée pour l'architecture
super-Sparc.
Les ordres partiels sont un modèle de base pour représenter les dépendances causales dans les systèmes répartis. On se préoccupe d'équiper ces ordres avec des informations de date, dans l'objectif de définir une notion d'instant au sens des langages synchrones (on obtient alors un modèle mixte asynchrone-synchrone), et de façon plus générale, de définir un calcul permettant de raisonner indifféremment sur les comportements (suites d'actions) et les dates. Typiquement, les questions qui nous intéressent sont : "Quels sont les comportements possibles en un temps t?", "Combien de temps faut-il nécessairement pour effectuer un comportement donné?". Nous essayons d'exprimer ces questions dans un cadre algébrique de type (Max,+). Aujourd'hui, nous avons mis en évidence un nouveau dioide permettant de raisonner conjointement sur les comportements (mots d'actions) et les dates multiformes (mots de dates), et qui peut s'appliquer à des modèles variés comme les automates d'ordres ou les réseaux de Petri. Nous poursuivons l'étude des propriétés de ce dioide et des algorithmes de calcul associés dans la perspective d'applications à l'optimisation et l'analyse de systèmes asynchrones temporisés. Ce travail est mené conjointement par Claude Jard (projet Pampa), Albert Benveniste (projet Ep-Atr) et Stéphane Gaubert (projet META2).
Poussés par la question du diagnostic en environnement réparti qui se pose régulièrement dans toutes les études que nous menons dans le projet Pampa, nous avons essayé d'utiliser les réseaux de Petri comme un outil pour l'observation des comportements. Dans ce cadre, les dépendances causales attendues sont exprimées par le réseau de Petri et doivent être confrontées aux dépendances observées. Nous avons résolu deux problèmes :
Ce travail est mené conjointement avec des chercheurs du
projet SIGMA2 (Armen Aghasaryan, Albert Benveniste et Eric Fabre)
qui ont étendu le modèle et les algorithmes avec des aspects
stochastiques pour former un modèle hybride de type HMM. Des
discussions ont lieu sur ces questions avec le projet Paragraphe.
Le travail est alimenté par l'application au suivi de pannes dans
les réseaux de télécommunication (cf. module ).