Skip to content

[KF-021] Test E2E déterministe pour AC #29 (race REPEATABLE READ no-op + mutation parallèle) #50

Closed

Description

@guycorbaz

Contexte

Story 7-3 (KF-004) AC #29 spécifie un test E2E qui doit reproduire la race condition REPEATABLE READ entre un no-op et une mutation parallèle, et asserter le comportement v0.1 attendu (200 OK + body = snapshot v=N stale). Ce test doit servir de régression detector : si une future migration SELECT FOR UPDATE (cf. issue #49 / KF-020) corrige la race, le test devra être mis à jour pour refléter le nouveau comportement (200 stale → 409).

L'implémentation actuelle (crates/kesh-api/tests/kf004_no_op_e2e.rs::no_op_with_parallel_mutation_returns_409_when_sequential) n'a pas pu reproduire la race de manière déterministe en CI : reproduire un commit MariaDB inter-leaved entre BEGIN et le no-op check applicatif exige une vraie concurrence (tokio::join! sur deux pools/connections distincts, voire un pause/advance orchestré côté driver). Le test livré est dégradé en smoke test du flow séquentiel qui asserte 409 (le verrouillage optimiste rejette correctement la version stale en mode séquentiel).

Conséquence : le test ne peut pas détecter une régression liée à la migration SELECT FOR UPDATE — il passe identiquement avant et après la migration.

Scope du fix

Implémenter un test E2E déterministe qui reproduit la race et asserte le comportement v0.1 (200 + stale) :

  • Approche 1 : tokio::join! sur deux MySqlPool distincts (pas de connection sharing) + délai contrôlé sur la transaction A pour fenêtrer le BEGIN de B après le commit de A mais avant que B ne ré-SELECT.
  • Approche 2 : test stress en boucle (N=100 itérations) qui valide la présence d'au moins un cas 200 stale — permet de tolérer la non-déterminisme MariaDB (snapshot isolation) mais reste déterministe sur la borne inférieure.
  • Approche 3 : injection de hook (test-only) dans is_no_op_change pour suspendre l'exécution à un point précis et laisser la transaction parallèle commit.

Choix de l'approche à arbitrer en fonction du framework de test (sqlx::test fournit un pool unique par test).

Critère d'acceptation

  • Le test doit asserter 200 OK + version inchangée + body = snapshot stale quand une mutation parallèle commit pendant le no-op check.
  • Le test doit être déterministe en CI (ou avoir une probabilité de détection ≥ 99%).
  • Le test doit être documenté comme régression detector — si une future migration SELECT FOR UPDATE (issue [KF-020] invoices::update : passer en SELECT FOR UPDATE pour fermer la race no-op KF-004 résiduelle #49) corrige la race, le test doit être mis à jour pour le nouveau comportement (200 stale → 409).

Lien

Priorité

Basse — pas un blocker v0.1. À planifier idéalement avant ou en même temps que la migration SELECT FOR UPDATE (#49) pour valider le passage 200 stale → 409 correctement.

Activity

  1. added
    known-failureTest or behavior known to fail, tracked for future fix
    technical-debtCode quality / refactor debt
    triageNeeds review / prioritization
    on Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    known-failureTest or behavior known to fail, tracked for future fixtechnical-debtCode quality / refactor debttriageNeeds review / prioritization

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions