319 lines
13 KiB
Markdown
319 lines
13 KiB
Markdown
|
|
|
|
## Objectif
|
|
|
|
Ce document liste les tests à prévoir pour un pilote du `Content Publication Engine`.
|
|
|
|
Le but n'est pas seulement de vérifier que les JSON sont générés. Le but est de valider que l'architecture est fiable dans les cas réels:
|
|
|
|
- export Louise/Mogador incomplet;
|
|
- bug fournisseur;
|
|
- produit retiré;
|
|
- correction d'urgence;
|
|
- vidéo JWP manquante;
|
|
- cache CDN;
|
|
- rollback;
|
|
- run partiellement généré;
|
|
- consommation par un site fournisseur.
|
|
|
|
## Principe du pilote
|
|
|
|
Le pilote devrait être limité à une plateforme ou à un sous-ensemble.
|
|
|
|
Options recommandées:
|
|
|
|
```text
|
|
Option 1: ONFR
|
|
- plus petit volume;
|
|
- plus facile à valider;
|
|
- bon premier test technique.
|
|
|
|
Option 2: sous-ensemble TFO
|
|
- plus proche des enjeux réels;
|
|
- permet de tester collections/saisons/épisodes;
|
|
- plus représentatif pour la production.
|
|
```
|
|
|
|
Le pilote ne devrait pas remplacer Directus ou la synchro actuelle immédiatement. Il devrait tourner en parallèle.
|
|
|
|
## Critères de réussite
|
|
|
|
- Le CPE génère un run JSON complet et valide.
|
|
- `manifest.json` pointe seulement vers un run validé.
|
|
- Les sites peuvent consommer le feed via manifest + fichiers JSON.
|
|
- Une correction d'urgence peut être publiée rapidement.
|
|
- Un rollback peut être exécuté rapidement.
|
|
- Un produit inchangé n'est pas écrasé par une donnée source suspecte.
|
|
- Les anomalies sont visibles avant les plaintes de production.
|
|
- Les performances sont suffisantes pour la plateforme pilote.
|
|
- Le format JSON est validé par au moins un fournisseur/site consommateur.
|
|
|
|
## Tests d'ingestion source
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Export SQL reçu correctement|Le CPE détecte le nouvel export ou son statut d'import|
|
|
|Export SQL absent|Alerte, aucun nouveau run publié|
|
|
|Export SQL trop petit|Alerte, aucun run publié sans validation manuelle|
|
|
|Export SQL identique au précédent|Run ignoré ou marqué sans changement|
|
|
|Import MySQL réussi|Snapshot peut commencer|
|
|
|Import MySQL échoué|Alerte, manifest inchangé|
|
|
|Mogador Toolkit indisponible|Alerte, manifest inchangé|
|
|
|Réponses API lentes|Retry/backoff, rapport de lenteur|
|
|
|Réponses API partielles|Anomalie, pas d'écrasement massif|
|
|
|
|
## Tests de snapshot et diff
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Nouveau produit|Produit présent dans `latest.added` et fichier produit généré|
|
|
|Produit modifié|Produit présent dans `latest.updated` et fichier produit régénéré|
|
|
|Produit supprimé|Produit absent des indexes, présent dans `latest.removed`|
|
|
|Programmation ajoutée|`today.json` ou `schedule/YYYY-MM-DD.json` mis à jour|
|
|
|Programmation modifiée|`changed_fields` indique le changement|
|
|
|Programmation supprimée|Programme absent du schedule concerné|
|
|
|Image modifiée|Produit ou collection impactée régénérée|
|
|
|Média modifié|Produit/collection impactée régénérée|
|
|
|Aucun changement|Nouveau run optionnel, ou aucun run publié|
|
|
|
|
## Tests de publication incrémentale protégée
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Run 1 contient 8 000 produits, run 2 ajoute 10 produits|Le CPE traite les 10 nouveaux et conserve les fichiers inchangés|
|
|
|Run 2 retire 5 produits|Les 5 produits disparaissent des indexes du run 2|
|
|
|Produit inchangé dans le snapshot|Le dernier JSON valide est conservé|
|
|
|Produit inchangé devient soudainement incomplet|Anomalie, ancien JSON valide conservé|
|
|
|Bug source sur plusieurs anciens produits|Alerte globale, pas d'écrasement massif|
|
|
|Trop d'anomalies dans un run|Run bloqué ou publié avec seuil contrôlé|
|
|
|Diff incohérent|Manifest inchangé, rapport d'erreur|
|
|
|
|
Point à ne pas oublier: il faut définir des seuils.
|
|
|
|
Exemples:
|
|
|
|
```text
|
|
Si plus de 5% des produits deviennent incomplets sans raison connue:
|
|
-> bloquer le run
|
|
|
|
Si 1 produit nouveau est incomplet:
|
|
-> publier avec avertissement ou exclure selon règle métier
|
|
|
|
Si un produit prévu aujourd'hui à 6h est incomplet:
|
|
-> alerte critique
|
|
```
|
|
|
|
## Tests de génération JSON
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|`manifest.json` généré|Contient `schema_version`, `platform`, `run_id`, `base_path`, `published_at`|
|
|
|`today.json` généré|Contient les programmes légers du jour|
|
|
|`schedule/YYYY-MM-DD.json` généré|Contient les programmes de la date|
|
|
|Schedule J+10 généré|Les 10 prochains jours sont disponibles|
|
|
|`products/{product_key}.json` généré|Contient produit, programmations, média, images|
|
|
|`collections/{biznumber}/full.json` généré|Contient collection -> saisons -> épisodes|
|
|
|Produit multi-plateforme|Chaque plateforme a sa version contextualisée|
|
|
|Champs obligatoires manquants|Validation échoue ou anomalie créée|
|
|
|JSON invalide|Run non publié|
|
|
|JSON Schema échoue|Run non publié|
|
|
|
|
## Tests de fichiers et chemins
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Chemins sans caractères problématiques|Aucun espace ou caractère ambigu dans les paths|
|
|
|`product_key` numérique ou string|Convention documentée et stable|
|
|
|`biznumber` avec zéros en début|Zéros conservés|
|
|
|Produit absent|Retour HTTP attendu défini, ex. 404|
|
|
|Ancien run consulté|Disponible pendant la rétention|
|
|
|Run supprimé par rétention|Plus accessible après purge contrôlée|
|
|
|Chemins de liens dans `today.json`|Pointent vers le bon `base_path`|
|
|
|
|
## Tests de publication atomique
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Run complet généré avec succès|Fichiers uploadés, validation OK, manifest mis à jour|
|
|
|Run échoue pendant génération|Manifest reste sur ancien run|
|
|
|Run échoue pendant upload|Manifest reste sur ancien run|
|
|
|Run échoue après upload partiel|Manifest reste sur ancien run, fichiers incomplets nettoyés ou ignorés|
|
|
|Manifest upload échoue|Ancien manifest reste actif|
|
|
|Manifest pointe vers run inexistant|Détecté par validation pré-publication|
|
|
|Deux runs simultanés|Lock empêche collision ou ordre déterministe|
|
|
|
|
## Tests de cache CDN
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|`manifest.json` cache court|Nouveau run visible après TTL attendu|
|
|
|Fichiers de run cache long|Fichiers immuables servis efficacement|
|
|
|Rollback manifest|Site revient au run précédent après TTL/purge|
|
|
|Purge manifest CDN|Nouveau manifest visible rapidement|
|
|
|Fichier immutable modifié par erreur|Test doit échouer, les runs sont immuables|
|
|
|Site garde un ancien manifest|Comportement acceptable documenté|
|
|
|
|
Point facile à oublier: les sites doivent gérer le cas où le manifest change pendant une navigation.
|
|
|
|
Recommandation:
|
|
|
|
```text
|
|
Une page devrait utiliser un seul run_id pendant son rendu.
|
|
Elle ne devrait pas mélanger des fichiers de deux runs différents dans la même réponse.
|
|
```
|
|
|
|
## Tests de rollback
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Rollback vers run précédent|Manifest repointe vers le run précédent|
|
|
|Rollback après bug source|Anciens JSON valides disponibles|
|
|
|Rollback après mauvais override|Override désactivé, run précédent ou nouveau run correct publié|
|
|
|Rollback audité|Qui, quand, pourquoi enregistré|
|
|
|Rollback communiqué au site|Site détecte nouveau `run_id`|
|
|
|
|
## Tests de Publication Console
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Login édimestre|Accès autorisé seulement en interne|
|
|
|Rôle read-only|Consultation seulement|
|
|
|Rôle édimestre|Peut créer override autorisé|
|
|
|Rôle admin|Peut approuver, rollback, republier|
|
|
|Override avec expiration|Désactivation automatique après expiration|
|
|
|Override sans raison|Refusé|
|
|
|Override sans audit|Refusé|
|
|
|Override produit|`publication_job` ciblé créé|
|
|
|Override collection|Collection et indexes impactés régénérés|
|
|
|Override supprimé|Nouveau run revient aux données source|
|
|
|Conflit override vs nouveau snapshot|Rapport d'écart généré|
|
|
|
|
Point facile à oublier: un override doit avoir une durée de vie.
|
|
|
|
Sans expiration, la Publication Console devient un CMS parallèle et on recrée le problème de gouvernance.
|
|
|
|
## Tests Media Pipeline / JWP
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Vidéo prête|`media_assets.status = ready`, produit republié|
|
|
|Vidéo manquante|`media_assets.status = missing`, alerte si critique|
|
|
|Vidéo en encodage|`processing`, JSON indique un état contrôlé|
|
|
|Vidéo échouée|`failed`, rapport visible|
|
|
|Poster manquant|Anomalie non bloquante ou bloquante selon règle|
|
|
|Sous-titres manquants|Anomalie selon règle d'accessibilité|
|
|
|Media Pipeline down|CPE continue avec dernier `media_assets` connu|
|
|
|JWP indisponible|Pas d'écrasement des anciens médias valides|
|
|
|`publication_job media_ready`|Produit/collection impactés republiés|
|
|
|
|
Point facile à oublier: le CPE ne devrait pas appeler JWP directement pour construire chaque JSON. Il doit lire l'état interne `media_assets`.
|
|
|
|
## Tests de sécurité et accès
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|App interne non exposée Internet|Accès bloqué hors réseau/VPN/SSO|
|
|
|Bucket par plateforme ou préfixe|Chaque fournisseur voit seulement son feed|
|
|
|Secrets absents des JSON|Aucun token, URL signée privée ou donnée interne sensible|
|
|
|`product_key` visible selon règle|Confirmer ce qui peut être exposé aux fournisseurs|
|
|
|Logs sans secret|Aucun credential dans logs/rapports|
|
|
|Accès écriture bucket limité|Seul le CPE peut publier|
|
|
|Suppression accidentelle bucket|Protection IAM ou versioning bucket|
|
|
|
|
Point facile à oublier: les JSON publics ne doivent pas contenir d'information réservée à l'équipe interne.
|
|
|
|
## Tests d'observabilité
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Rapport par run|Disponible après chaque tentative|
|
|
|Rapport attendu vs publié|Écarts listés clairement|
|
|
|Alerte export absent|Envoyée rapidement|
|
|
|Alerte programme 6h absent|Critique avant l'heure de diffusion|
|
|
|Alerte queue bloquée|Visible avant impact site|
|
|
|Alerte trop d'anomalies|Run bloqué ou escaladé|
|
|
|Dashboard dernier run|Plateforme, statut, durée, anomalies|
|
|
|Logs corrélés par `run_id`|Diagnostic possible rapidement|
|
|
|
|
## Tests de performance
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Génération complète pilote|Durée mesurée|
|
|
|Génération incrémentale 10 produits|Beaucoup plus rapide qu'une génération complète|
|
|
|Publication 8 000 produits|Durée upload mesurée|
|
|
|Publication 22 000 produits|Estimation IDELLO réaliste|
|
|
|Lecture manifest CDN|Latence faible|
|
|
|Lecture produit CDN|Latence faible|
|
|
|Lecture collection full|Taille et latence acceptables|
|
|
|Search index|Taille acceptable ou moteur dédié requis|
|
|
|
|
Mesures à collecter:
|
|
|
|
```text
|
|
durée extraction source
|
|
durée diff
|
|
durée génération JSON
|
|
durée validation JSON Schema
|
|
durée upload
|
|
durée publication manifest
|
|
nombre de fichiers
|
|
taille totale
|
|
nombre d'anomalies
|
|
temps de rollback
|
|
```
|
|
|
|
## Tests avec fournisseurs sites
|
|
|
|
|Test|Résultat attendu|
|
|
|---|---|
|
|
|Fournisseur lit `manifest.json`|OK|
|
|
|Fournisseur charge `today.json`|OK|
|
|
|Fournisseur charge un produit via `links.product`|OK|
|
|
|Fournisseur charge une collection complète|OK|
|
|
|Fournisseur gère `latest.json`|OK ou besoin clarifié|
|
|
|Fournisseur gère un produit retiré|OK|
|
|
|Fournisseur gère un rollback|OK|
|
|
|Fournisseur ne mélange pas deux runs|OK|
|
|
|Champs manquants identifiés|Ajustement JSON v1 avant gel|
|
|
|
|
## Détails faciles à oublier
|
|
|
|
Voici les points qui peuvent sembler petits, mais qui ont un gros impact:
|
|
|
|
- `manifest.json` ne doit jamais pointer vers un run incomplet.
|
|
- Les fichiers dans `/runs/{run_id}/` doivent être immuables.
|
|
- Une page site doit utiliser un seul `run_id` pendant son rendu.
|
|
- Les zéros au début des `biznumber` doivent être conservés.
|
|
- Les dates doivent inclure la timezone.
|
|
- `product_key` et `program_key` doivent avoir un type stable, idéalement string dans les JSON.
|
|
- Les produits multi-plateformes doivent être contextualisés par plateforme.
|
|
- Les overrides doivent expirer.
|
|
- Les suppressions doivent être visibles dans `latest.json` et dans les rapports.
|
|
- Les produits retirés ne doivent plus apparaître dans les indexes.
|
|
- Les anciens fichiers retirés ne doivent pas rester découvrables via les indexes actifs.
|
|
- Les fichiers lourds comme `collections/{biznumber}/full.json` doivent être mesurés.
|
|
- Les champs internes ou sensibles ne doivent pas sortir dans les JSON publics.
|
|
- Le CPE doit être idempotent: relancer un job ne doit pas casser l'état.
|
|
- Les seuils d'anomalies doivent être définis avant le pilote.
|
|
- Le run doit avoir un rapport lisible par humains, pas seulement des logs techniques.
|
|
- Le rollback doit être testé avant le premier incident réel.
|
|
- La rétention doit être automatisée.
|
|
- Le bucket/CDN doit avoir une stratégie de purge du manifest.
|
|
- Les sites doivent savoir quoi faire si un fichier lié retourne 404.
|
|
- Les liens dans les JSON doivent être relatifs au `base_path` ou documentés clairement.
|
|
- Les JSON Schema doivent être validés dans le pipeline.
|
|
- Le feed JSON ne doit pas devenir une API dynamique cachée.
|
|
|
|
## Décision de fin de pilote
|
|
|
|
À la fin du pilote, il faut pouvoir répondre clairement:
|
|
|
|
- Est-ce que les sites peuvent consommer le feed JSON?
|
|
- Est-ce que la génération est assez rapide?
|
|
- Est-ce que le modèle protège contre les bugs source?
|
|
- Est-ce que les rapports permettent d'être proactifs?
|
|
- Est-ce que les corrections d'urgence sont assez rapides?
|
|
- Est-ce que le rollback est simple?
|
|
- Est-ce que le périmètre reste maîtrisé?
|
|
- Est-ce qu'on peut généraliser à TFO, IDELLO, ONFR et linéaire? |