Vous êtes sur la page 1sur 4

Vérification et Validation

Année 2010-2011
www.lri.fr/∼wolff/teach-material/2010-11/PolyTech-VnV

Prof. Burkhart Wolff Delphine Longuet


wolff@lri.fr longuet@lri.fr

Test boı̂te noire à partir de spécifications OCL


Date : 02/03/2011

Exercice 1 (Logique)
Mettre en Forme Normale Disjonctive (DNF) les expressions suivantes.
1. ((A ∨ B) ∧ C) ∧ (A implies (C ∧ D))
2. let x = if (A ∨ B) then p else q in ((C ∧ D) ∨ E)

Rappels de logique. La conjonction et la disjonction sont associatives, commutatives


et distributives l’une par rapport à l’autre :
(A ∧ B) ∧ C = A ∧ (B ∧ C) = A ∧ B ∧ C A∧B =B∧A
(A ∨ B) ∨ C = A ∨ (B ∨ C) = A ∨ B ∨ C A∨B =B∨A
A ∧ (B ∨ C) = (A ∧ B) ∨ (A ∧ C) A ∨ (B ∧ C) = (A ∨ B) ∧ (A ∨ C)

La négation suit les lois suivantes (VRAI est noté > et FAUX est noté ⊥) :

¬¬A = A A ∧ ¬A = ⊥ A ∨ ¬A = >
¬(A ∧ B) = ¬A ∨ ¬B ¬(A ∨ B) = ¬A ∧ ¬B (lois de De Morgan)
De plus, on a les lois suivantes pour les expressions OCL :
(A implies B) = (A ⇒ B) = (¬A ∨ B)
(if A then B else C) = (A ∧ B) ∨ (¬A ∧ C)
(let x = p in A) = (x = p ∧ A)
FiXme:
Should be FALSE
RULE ;
(let x = E in A) = A[x ← E]) EXO
MAKES
NO SENSE

1
Exercice 2 (Test boı̂te noire)
On modélise un système de fichiers simple qui couvre certains aspects du système UNIX.
On suppose que pour chaque session d’un utilisateur (un shell login par exemple), il existe
un propriétaire (modélisé par le type abstrait UID) et une collection des groupes auxquels
l’utilisateur appartient (modélisé par le type abstrait GROUPID). Les opérations principales
qu’un utilisateur peut effectuer sont celles de la classe UserSession. Ces entités d’UNIX
sont visibles en effectuant dans le shell :
bu$ whoami
> bu
bu$ groups
> bu _lpadmin _appserveradm _appserverusr admin
D’un autre coté, il existe des objets de la classe FILE qui exigent certaines permissions
(modélisées par le type énuméré Permission : {R, W, X} pour “read”, “write” et “execu-
te”). Un fichier possède un propriétaire, appartient à un groupe, et possède, bien entendu,
un contenu. Pour chaque fichier il existe une description des permissions, qui spécifie les
droits d’accès pour les trois classes suivantes d’utilisateurs : propriétaire, groupe, ou tout
le monde. Ces entités d’UNIX sont visibles en effectuant dans le shell :
bu$ ls -la exam29.4.98.tex
> -rw-r--r--@ 1 bu bu 7131 28 Apr 10:37 exam29.4.98.tex
Les instances de la classe UserSession n’ont pas d’accès direct aux fichiers mais nécessitent
des descripteurs de fichiers comme intermédiaires. Ces descripteurs de fichiers doivent être
générés, ce qui peut échouer si l’utilisateur n’a pas les bons droits d’accès. Le nombre des
descripteurs de fichiers est limité dans UNIX, dans notre modèle il est même borné a un
descripteur maximum : un object de la classe UserSession possède un attribut curr fd qui
contient un descripteur. Par défaut, cet attribut est null.

package simple_filesystem
-----------------------------------------------------------------
-- File --
-----------------------------------------------------------------
context File
inv: File::allInstances() -> isUnique(x | x.name)

context File::HasAccess(uid:UID, groups:Set(GROUPID),


p:Permission) : Boolean
post: if owner = uid
then result = perm.owner -> includes(p)
else if groups -> includes(group)
then result = perm.group -> includes(p)
else result = perm.world -> includes(p)

-----------------------------------------------------------------

2
-- UserSession --
-----------------------------------------------------------------
context UserSession
inv: UserSession::allInstances() -> forall(x, y |
x.uid = y.uid implies x.groups = y.groups)

context UserSession::open(n:String, w:Boolean) : Boolean


post: res : result=File::allInstances()->exists(x|x.name=n)
post: write: result and w implies
if has_access(n, W) then
self.curr_fd.isNewInState() and
self.curr_fd.openForWrite and
self.curr_fd.position=0
else self.curr_fd = null
post: read: result and not w implies
if has_access(n, R) then
self.curr_fd. oclIsNew() and
not self.curr_fd.openForWrite and
self.curr_fd.position=0
else self.curr_fd = null
post: error: not result implies self.curr_fd = null

3
context UserSession::has_access(n:String, p:Permission) : Boolean
post: result = File::allInstances -> exists(x | x.name=n and
x.HasAccess(uid,groups,p))

context UserSession::chmod(n:String, w:Set(Permission),


g:Set(Permission),
o:Set(Permission))
pre: File::allInstances -> exists(x | x.name=n and
x.HasAccess(uid,groups,W))
post: File::allInstances -> select(x | x.name=n).perm.world=w
and File::allInstances -> select(x | x.name=n).perm.group=g
and File::allInstances -> select(x | x.name=n).perm.owner=o

endpackage

1. Construire des cas de test pour l’opération HasAccess en calculant la DNF à partir
de self.HasAccess(u,g,p).
2. Construire un jeu de tests en donnant des instances qui satisfont les cas de test (c’est-
à-dire des conjonctions dans la DNF). Pour cela, il faut choisir un état du système
et des données concrètes pour self, groups, et perm.
3. Utiliser le jeu de tests précédent pour construire un jeu de tests pour l’opération
open.

Vous aimerez peut-être aussi