PD-47 — Scénarios de tests contractuels
1. Références
- Spécification :
PD-47-specification.md - Epic :
EPIC-XX - Jira :
PD-47 - Repos concernés :
ProbatioVault-backend, ProbatioVault-infra
2. Matrice de couverture
| ID Invariant | ID Critère | ID Test | Couverture | Commentaire |
| INV-47-01 | CA-47-04 | TC-INV-01 | Oui | Vérifie suppression artefact clair <= 300 s |
| INV-47-02 | CA-47-03 | TC-INV-02 | Oui | Vérifie AES-256-GCM + SSE-KMS |
| INV-47-03 | — | TC-INV-03 | Oui | Vérifie séparation clé backup / clé maître (incl. rotation K_backup sans perte de déchiffrement) [CORR E-13] |
| INV-47-04 | — | TC-INV-04 | Oui | Vérifie bucket non public + IAM dédiée |
| INV-47-05 | CA-47-06 | TC-INV-05 | Oui | Vérifie >= 1 événement append-only par tentative + déduplication par backup_id [CORR E-04] |
| INV-47-06 | CA-47-08 | TC-INV-06 | Oui | Vérifie indépendance watchdog |
| INV-47-07 | CA-47-09 | TC-INV-07 | Oui | Vérifie transitions autorisées/interdites |
| INV-47-08 | CA-47-07 | TC-INV-08 | Oui | Vérifie hash avant validation finale |
| INV-47-09 | — | TC-INV-09 | Oui | Vérifie envelope encryption + cycle de vie DEK (pas de persistance en clair) [CORR E-18] |
| INV-47-01,02,05 | CA-47-01,03,04,06 | TC-NOM-01 | Oui | Flux quotidien nominal |
| INV-47-02,05 | CA-47-02,06 | TC-NOM-02 | Oui | Flux WAL continu + P95 lag + hash SHA3-256 par segment WAL [CORR E-12] |
| INV-47-02,05 | CA-47-03,06 | TC-NOM-03 | Oui | Flux basebackup hebdo |
| INV-47-08 | CA-47-07 | TC-NOM-04 | Oui | Restauration PITR staging |
| INV-47-06 | CA-47-08 | TC-NOM-05 | Oui | Détection absence backup malgré panne orchestrateur + escalade si relance échoue [CORR E-17] |
| INV-47-07 | CA-47-05,09 | TC-NOM-06 | Oui | Rétention + transitions EXPIRED/DELETED |
| — | CA-47-09 | TC-NOM-07 | Oui | Crash pré-commit : pas de SUCCESS durable (réf. §5.6) [CORR E-10] |
| — | CA-47-09 | TC-NOM-08 | Oui | Crash post-commit : réconciliation obligatoire + observable (réf. §5.6) [CORR E-09][CORR E-10] |
| INV-47-07 | CA-47-09 | TC-ERR-07 | Oui | Rejet format invalide (code de rejet FAILED_FORMAT hors enum status) [CORR E-02] |
| INV-47-07 | CA-47-09 | TC-ERR-08 | Oui | Incident conformité sur échec restauration trimestriel (périodicité contractualisée) [CORR E-16] |
3. Scénarios de test – Flux nominaux
TEST-ID: TC-NOM-01
Référence spec: F1, INV-47-01/02/05, CA-47-01/03/04/06
GIVEN
- Scheduler configuré sur Europe/Paris
- Base source disponible et stable
- Bucket S3 cible accessible avec SSE-KMS actif
WHEN
- L’horloge atteint 03:00 Europe/Paris
THEN
- Un objet backup_YYYYMMDD.enc est présent avant 04:00 Europe/Paris
- Le chiffrement déclaré est AES-256-GCM+SSE-KMS
AND
- Aucun artefact clair ne persiste au-delà de 300 s après fin d’export
- Au moins un événement append-only horodaté est émis pour la tentative (doublons dédupliqués par backup_id) [CORR E-04]
TEST-ID: TC-NOM-02
Référence spec: F2, INV-47-02/05, CA-47-02/06
GIVEN
- Activité transactionnelle continue pendant 24 h
- Collecte métrique de lag WAL disponible
WHEN
- Les segments WAL sont archivés en continu
THEN
- Le lag de livraison WAL P95 sur 24 h est strictement < 5 min
AND
- Les objets WAL sont chiffrés avant persistance distante
- Un hash SHA3-256 est calculé et journalisé par segment WAL (et/ou vérifiable via métadonnées attendues) [CORR E-12]
- La journalisation append-only respecte le contrat segment/lot défini
TEST-ID: TC-NOM-03
Référence spec: F3, INV-47-02/05, CA-47-03/06
GIVEN
- Fenêtre hebdomadaire active (dimanche 02:00 Europe/Paris)
- Cible S3 et KMS opérationnelles
WHEN
- Le processus de basebackup démarre
THEN
- L’artefact basebackup chiffré est uploadé avec SSE-KMS actif
AND
- Au moins un événement append-only backup_type=basebackup est présent (doublons dédupliqués par backup_id) [CORR E-04]
TEST-ID: TC-NOM-04
Référence spec: F4, INV-47-08, CA-47-07
GIVEN
- Un backup logique J0 valide et WAL intermédiaires disponibles
- Point cible PITR T déterminé
WHEN
- Une restauration staging est exécutée au point T
THEN
- Le hash SHA3-256 des artefacts restaurés est validé avant validation finale
- La cohérence schéma/données attendues est conforme au référentiel métier contractuel
AND
- Une preuve de test de restauration est enregistrée
TEST-ID: TC-NOM-05
Référence spec: F1, INV-47-06, CA-47-08, ERR-47-05
GIVEN
- Orchestrateur principal indisponible
- Backup du jour absent à 04:00 Europe/Paris
WHEN
- Le watchdog indépendant s’exécute
THEN
- Une alerte absence backup est émise
AND
- Une relance contrôlée unique est initiée
- Si la relance échoue, une escalade critique est émise (observable via alerte dédiée et/ou ouverture incident) [CORR E-17]
TEST-ID: TC-NOM-06
Référence spec: F3/F5.7/F5.8, INV-47-07, CA-47-05/09
GIVEN
- Objets backup âgés de 31 jours sans exception de conservation
WHEN
- La policy lifecycle est appliquée
THEN
- L’état passe SUCCESS -> EXPIRED puis EXPIRED -> DELETED uniquement
AND
- Aucun objet J+31 non protégé n’est encore accessible
TEST-ID: TC-NOM-07
Référence spec: §5.6 (Crash pré-commit état local)
GIVEN
- Une tentative de backup est en cours (statut RUNNING)
WHEN
- Un crash survient avant le commit de l’état local
THEN
- Aucun état durable "SUCCESS" n’existe pour la tentative
AND
- La reprise n’aboutit qu’à une exécution cohérente (nouvelle tentative ou échec explicite), sans fausse réussite [CORR E-10]
TEST-ID: TC-NOM-08
Référence spec: §5.6 (Crash post-commit état local), CA-47-09
GIVEN
- Un commit d’état local a eu lieu
WHEN
- Un crash survient avant cohérence complète état↔objet↔journal
THEN
- Une réconciliation est exécutée jusqu’à cohérence
AND
- L’exécution de la réconciliation et son résultat sont observables (trace/log/événement d’audit exploitable par test) [CORR E-09][CORR E-10]
4. Scénarios de test – Cas d’erreur
TEST-ID: TC-ERR-01
Référence spec: ERR-47-01
GIVEN
- Export logique déclenché
WHEN
- L’export échoue
THEN
- Statut final FAILED
- Retry <= 3 tentatives
AND
- Alerte critique émise à épuisement des retries
TEST-ID: TC-ERR-02
Référence spec: ERR-47-02
GIVEN
- Artefact logique produit
WHEN
- Le chiffrement applicatif échoue
THEN
- Aucun upload distant n’est effectué
- Statut FAILED
AND
- Purge artefact clair confirmée
- Alerte critique émise
TEST-ID: TC-ERR-03
Référence spec: ERR-47-03, §5.7
GIVEN
- Artefact chiffré prêt à uploader
WHEN
- L’upload échoue
THEN
- Retry <= 3 tentatives (dans la même tentative, sans transition FAILED -> SCHEDULED) [CORR E-11]
- Statut FAILED après épuisement
AND
- Alerte émise
TEST-ID: TC-ERR-04
Référence spec: ERR-47-04
GIVEN
- Upload terminé
WHEN
- Le hash post-upload est invalide
THEN
- Objet marqué invalide/non exploitable restauration
AND
- Alerte critique émise
TEST-ID: TC-ERR-05
Référence spec: ERR-47-05
GIVEN
- Aucun backup du jour détectable à 04:00
WHEN
- Le watchdog vérifie la présence attendue
THEN
- Alerte émise
AND
- Relance contrôlée unique exécutée
- Si la relance échoue, escalade critique obligatoire (observable) [CORR E-17]
TEST-ID: TC-ERR-06
Référence spec: ERR-47-06
GIVEN
- Archivage WAL en cours
WHEN
- Interruption WAL survient
THEN
- Alerte immédiate émise
- Reprise automatique engagée
AND
- Contrôle de rattrapage exécuté et tracé
TEST-ID: TC-ERR-07
Référence spec: ERR-47-07, §5.1
GIVEN
- Événement avec champ hors format contractuel (regex/type/taille)
WHEN
- L’événement est soumis au système
THEN
- Rejet explicite avec code de rejet FAILED_FORMAT (hors enum status) [CORR E-02]
AND
- Journal d’erreur obligatoire présent
TEST-ID: TC-ERR-08
Référence spec: ERR-47-08, §5.8
GIVEN
- Campagne de restauration trimestrielle planifiée (périodicité contractualisée à 90 jours) [CORR E-16]
WHEN
- Le test de restauration échoue
THEN
- Incident conformité ouvert
AND
- Clôture interdite sans plan d’action formel
5. Tests d’invariants (non négociables)
| Invariant | Test(s) dédiés | Observable | Commentaire |
| INV-47-01 | TC-INV-01, TC-NOM-01, TC-ERR-02 | Timestamp fin export vs suppression fichier clair <= 300 s | Seuil non configurable, violation = arrêt + alerte |
| INV-47-02 | TC-INV-02, TC-NOM-01/02/03 | Preuve chiffrement applicatif + métadonnée SSE-KMS | Double preuve obligatoire |
| INV-47-03 | TC-INV-03 | Matériau clé backup dérivé via mécanisme dédié, séparé clé maître | Vérification de séparation cryptographique + rotation sans perte de déchiffrement [CORR E-13] |
| INV-47-04 | TC-INV-04 | Bucket non public, accès IAM dédiée uniquement | Contrôle policy + accès effectif |
| INV-47-05 | TC-INV-05, TC-NOM-01/02/03 | >= 1 événement append-only par tentative + déduplication par backup_id | Cardinalité minimale + idempotence/dédup [CORR E-04] |
| INV-47-06 | TC-INV-06, TC-NOM-05 | Détection watchdog maintenue malgré panne orchestrateur | Test d’indépendance par injection de panne |
| INV-47-07 | TC-INV-07, TC-NOM-06, TC-ERR-07 | Aucune transition hors table §5.7 | Transition interdite refusée et journalisée |
| INV-47-08 | TC-INV-08, TC-NOM-04 | Hash SHA3-256 validé avant acceptation restauration | Ordonnancement de validation obligatoire |
| INV-47-09 | TC-INV-09 | Aucun artefact crypto temporaire en clair au repos (DB/disque) | Inclut cycle de vie DEK [CORR E-18] |
6. Tests de non-régression
| Test ID | Objet | Observable | Commentaire |
| TC-NR-01 | Respect formats §5.1 sur tous champs | 0 régression regex/type/tailles | Rejouer jeu de données valide/invalide |
| TC-NR-02 | Machine d’états §5.7 | 0 transition illégale acceptée | Doit inclure transitions terminales |
| TC-NR-03 | SLA temporels §5.8 | RPO/RTO/lag/TTL conformes | Contrôle périodique automatisable |
| TC-NR-04 | Rétention 30 jours | J+31 absent (hors exceptions) | Vérifie lifecycle réel, pas seulement config |
| TC-NR-05 | Exhaustivité journal append-only | 1 événement minimum par tentative | Inclut succès, échecs, retries (doublons dédupliqués) [CORR E-04] |
7. Tests négatifs et adversariaux
| Test ID | Entrée invalide / abus | Résultat attendu | Observable |
| TC-NEG-01 | backup_id hors regex ou uppercase | Rejet FAILED_FORMAT (code de rejet) [CORR E-02] | Journal erreur + absence transition succès |
| TC-NEG-02 | hash_sha3_256 non hex lowercase/64 | Rejet + alerte critique | Événement rejeté, alerte émise |
| TC-NEG-03 | s3_object_key_backup hors pattern | Upload rejeté | Aucun objet stocké au mauvais chemin |
| TC-NEG-04 | Tentative SUCCESS -> RUNNING | Transition refusée | Journal refus explicite |
| TC-NEG-05 | Tentative DELETED -> * | Transition refusée | État terminal inchangé |
| TC-NEG-06 | Tentative accès public bucket | Accès refusé | Logs IAM/S3 deny |
| TC-NEG-07 | Injection faux événement dupliqué même backup_id | Déduplication appliquée | Pas de double comptage audit |
8. Observabilité requise pour les tests
- État système : états backup (
SCHEDULED/RUNNING/SUCCESS/FAILED/EXPIRED/DELETED), timestamps, retries, durées. [CORR E-03] - Réponse API/commande : statuts de traitement (incl. code de rejet
FAILED_FORMAT, hors enum status) et motifs d’échec. [CORR E-02] - Journal d’audit append-only : horodatage UTC,
backup_id, backup_type, statut, hash, taille, durée, identifiant tentative. - Événements horodatés : alertes watchdog, alertes critiques chiffrement/upload/hash/WAL ; escalade critique si relance watchdog échoue. [CORR E-17]
- Stockage objet : présence/absence objet attendu, métadonnées SSE-KMS, clé objet conforme pattern, suppression lifecycle ; hash
SHA3-256 par segment WAL vérifiable. [CORR E-12] - Réconciliation : trace/log/événement d’audit indiquant exécution et résultat de la réconciliation post-crash post-commit. [CORR E-09]
- Preuves probatoires exportables : rapport restauration staging, validation hash SHA3-256, cohérence métier validée.
9. Règles non testables
| Règle | Raison | Impact |
| Critère exact de “cohérence données métier attendues” (Q-47-03) | Jeu contractuel de tables/compteurs non défini | Majeur |
| Granularité de journal WAL (segment vs lot) (Q-47-02) | Contrat de cardinalité événementielle incomplet | Majeur |
| Politique lifecycle sur versions S3 non courantes (Q-47-04) | Ambiguïté sur suppression vs conservation légale | Majeur |
| Gestion explicite DST Europe/Paris pour seuils 03:00/04:00 (Q-47-01) | Cas été/hiver non figé contractuellement | Mineur |
| SLO de prise en charge des alertes (Q-47-05) | Délai opérationnel non contractualisé | Mineur |
10. Verdict QA
- ⚠️ Testable partiellement (avec réserves listées).
- Le socle est largement testable et automatisable, mais la conformité complète exige la levée des ambiguïtés Q-47-01 à Q-47-05 (priorité sur Q-47-02/03/04).