Pour toute opération de politique d’un crdt.dag.DAG, DAG.estValide doit permettre de retourner sa validité (resp. invalidité), c’est-à-dire un statut de prise en compte (resp. exclusion) de l’opération dans l’évaluation de la politique d’accès. Ce statut permet de distinguer les opérations dont l’effet est acceptable ou inacceptable selon la politique d’accès évaluée à terme. On teste la validité de notre algorithme dans gitlab.inria.fr/coast-team/crdt-ac/tests, sur les scénarios1 qui suivent.
1 les scénarios reprennent les noms utilisés page 12 du rapport 03-mecanismes
On commence par importer la crdt.dag.DAG qui nous permet de représenter un droit pour un site, et les opérations le modifiant.
(b) conflits (résolution descendante)
On teste ici la résolution de conflits où une opération de niveau n prévaut sur une opération concurrente de niveau n + 1.
Certaines combinaisons d’opérations menent à des états de transition invalides (en rouge). Tant que le dernier état converge vers un état conforme à ce qui est attendu (vert), cela veut dire que le modèle d’évaluation converge pour cette combinaison.
L’étape 2/3 de la variante 3 ne correspond pas à l’état final attendu (indiqué en orange), on diverge donc momentanément de l’état désiré. Tant que l’état final converge sur la même évaluation que prévu, l’agorithme est correct.
(c) conflits (résolution ascendante)
On teste ici la résolution de conflits où une opération de niveau n + 1 prévaut sur une opération concurrente de niveau n. On le fait ici en changeant le critère discrétionnaire d’ordre de priorité des opérations. Jusqu’ici, on a implicitement priorisé les opérations suivant l’ordre lexicographique de leurs sites émetteurs. On peut pourtant décider d’un autre critère, arbitraire, tant qu’il est déterministe et partagé par chaque site.
Ici, on explicite juste un ordre différent, qui doit se refléter dans les résultats.
On teste ici une situation où l’opération priorisée est elle-même en conflit avec une troisième opération qui prend la priorité. Que faire dans ce cas ? Rétablir la première opération dont le conflit peut désormais être ignoré ? Ou bien la garder invalide ?
En pratique, cette situation ne se pose pas, comme l’illustre l’exemple suivant. En effet, pour qu’une troisième opération soit en conflit avec la seconde, elle doit aussi être en conflit avec l’opération parente de la première, rendant celle-ci invalide par la même occasion. Pour que la première et la troisième opération soient valides en même temps, il faudrait changer les règles de mise en conflit de deux opérations (qui sont nécessite actuellement une concurrence et un niveau de parité différente entre les deux opérations).
Note
Étant donné le nombre élevé de combinaisons, on ne liste que les dernières étapes de diffusion de chaque combinaison.
Jusqu’ici on testait tout dans le cadre limité d’un DAG représentant un tuple d’accès. Peu nous importaient le signe d’une opération (retrait ou ajout du droit) ou le site qu’elle cible. Mais d’autres conflits existent, notamment les opérations retirant au site émetteur d’une opération le droit d’admin le rendant capable de l’émettre. On contruit ici un tel exemple, similaire aux cas (b) et (c) précédents, adjoints d’une tuple d’admin retirant le droit d’émettre une des opérations.
La représentation montre deux chemins valides : un pour chaque tuple d’accès.
from crdt.dag import DAGfrom crdt.crdt import Rightsorder = ['X', 'B', 'A']G_e__write_A = DAG()G_e__write_A.order = orderG_e__write_A.add_op('a1', ['0'])G_e__write_A.add_op('a2', ['a1'])G_e__write_A.add_op('b1', ['0'])G_e__admin_B = DAG()G_e__admin_B.order = orderG_e__admin_B.add_op('x1', ['0'], last='0') # dernière opération conue de B par X au moment de lui retirer le droit = état initialR_e = Rights()R_e[('C', 'write')] = G_e__write_AR_e[('B', 'admin')] = G_e__admin_BR_e.draw()