README.md 9573 octets

Fediverse testbed — three-instance Rustwarden topology

Banc d'essai isolé pour valider la fédération identitaire Rustwarden ↔ Rustwarden en local. Trois instances complètes (alpha, beta, gamma) tournent dans Docker, chacune avec sa propre PostgreSQL et son FEDIVERSE_DOMAIN, communiquant via le réseau Docker sans TLS ni reverse proxy.

Cet environnement sert d'itération 0 de la campagne décrite dans docs/plans/2026-05-10-iter0-fediverse-docker-compose.md et docs/plans/2026-05-10-fediverse-promotion-stable-evaluation.md.

Prérequis

  • Docker Engine + Compose plugin v2 (docker compose version doit fonctionner).
  • ~3 Go de RAM libre.
  • Ports 3001, 3002, 3003 libres sur l'hôte.

Aucun ajout dans /etc/hosts n'est nécessaire pour les tests automatisés. Pour piloter le testbed depuis un navigateur sur l'hôte, voir « Accès humain » plus bas.

Démarrage

cd tests/fediverse-testbed
./scripts/setup.sh

Le script :

  1. Build l'image multi-stage (long la première fois, ~5–10 min ; secondes ensuite grâce au cache).
  2. Démarre les 3 PostgreSQL et attend qu'elles soient healthy.
  3. Lance les 3 jobs migrate-* one-shot (SeaORM CLI : migrate up). L'app ne fait pas les migrations au démarrage, ce service le fait à sa place.
  4. Démarre les 3 app-* une fois leur migrate-* sorti en code 0.
  5. Lance les 3 jobs seed-* qui chargent les fixtures Happy Days.
  6. Insère en SQL la trust list croisée (alpha ↔ beta ↔ gamma) et active fediverse_enabled.
  7. Smoke check final depuis l'hôte (curl /health × 3).

Topologie

                          ┌──────────────┐
                          │  fediverse-  │
                          │     net      │
                          │ (bridge)     │
                          └──────┬───────┘
            ┌────────────────────┼─────────────────────┐
            │                    │                     │
  ┌─────────▼────────┐ ┌─────────▼────────┐ ┌─────────▼────────┐
  │ app-alpha        │ │ app-beta         │ │ app-gamma        │
  │ alias alpha.local│ │ alias beta.local │ │ alias gamma.local│
  │ host: :3001      │ │ host: :3002      │ │ host: :3003      │
  └─────────┬────────┘ └─────────┬────────┘ └─────────┬────────┘
            │                    │                     │
  ┌─────────▼────────┐ ┌─────────▼────────┐ ┌─────────▼────────┐
  │ postgres-alpha   │ │ postgres-beta    │ │ postgres-gamma   │
  └──────────────────┘ └──────────────────┘ └──────────────────┘

À l'intérieur du réseau Docker, chaque app résout alpha.local, beta.local, gamma.local vers les containers des autres apps grâce aux network_aliases. Aucune dépendance DNS hôte.

Identifiants seed

Chaque instance a les mêmes 5 utilisateurs Happy Days (cf. crates/rustwarden-core/src/bin/seed.rs) :

LoginEmailRôleMot de passe
joaniejoanie@rustwarden.localadminhappydays123
richierichie@rustwarden.localuserhappydays123
fonziefonzie@rustwarden.localuserhappydays123
potsiepotsie@rustwarden.localuserhappydays123
ralphralph@rustwarden.localuserhappydays123

Vérifications manuelles utiles

# Santé
curl http://localhost:3001/health
curl http://localhost:3002/health
curl http://localhost:3003/health

# WebFinger (un user existant sur alpha)
curl 'http://localhost:3001/.well-known/webfinger?resource=acct:joanie@alpha.local'

# Trust list configurée
docker compose exec -T postgres-alpha psql -U rustwarden -d rustwarden_alpha \
  -c 'SELECT domain FROM fediverse_trusted_domains;'

# Logs en direct d'une instance
docker compose logs -f app-alpha

Accès humain (optionnel)

Les URLs ActivityPub renvoyées par chaque instance contiennent alpha.local / beta.local / gamma.local. Pour suivre ces liens depuis un navigateur sur l'hôte, ajouter une fois pour toutes :

# /etc/hosts
127.0.0.1 alpha.local beta.local gamma.local

Puis pour accéder à chaque instance, utiliser les ports : http://alpha.local:3001, http://beta.local:3002, http://gamma.local:3003. Les tests automatisés (cargo test) n'en ont pas besoin — ils s'adressent à localhost:3001/3002/3003.

Cycle de vie

CommandeEffetQuand l'utiliser
./scripts/setup.shBuild + démarre + migre + seed + trust + smokePremier boot, ou après un teardown
./scripts/stop.shdocker compose stop — pause sans rien perdreTu veux libérer CPU/RAM mais reprendre vite avec l'état actuel (DB préservée)
./scripts/start.shReprend les containers stoppés, attend /healthAprès un stop.sh. Pas de re-seed, pas de re-trust
./scripts/teardown.shdocker compose down -v — purge containers + volumesTu veux repartir d'un état totalement vierge

Cycle typique pour itérer sur des tests sans tout reconstruire :

./scripts/setup.sh        # une fois
cargo test --features ...  # itère
./scripts/stop.sh         # pause quand tu fermes ta session
./scripts/start.sh        # reprend plus tard

Rebuild après modification du code source

setup.sh exécute docker compose up -d --wait qui ne reconstruit pas l'image si elle existe déjà dans le cache local. Quand tu modifies du code Rust (workspace crates/*, app/*) et que tu veux que le testbed reflète ces changements, force le rebuild :

cd tests/fediverse-testbed

# 1. Arrêter et purger les containers + volumes actuels
./scripts/teardown.sh

# 2. Forcer un rebuild de l'image avant le up
docker compose build --no-cache
# (ou `docker compose build` si tu veux laisser cargo réutiliser ses caches via le BuildKit)

# 3. Relancer la séquence setup complète (compose up + migrate + seed + trust)
./scripts/setup.sh

# 4. Vérifier que les 3 instances sont healthy
docker compose ps

# 5. Configurer le trust croisé (rejoué automatiquement par setup.sh mais
#    explicite si tu fais le rebuild en plusieurs étapes)
./scripts/configure-trust.sh

# 6. Smoke runtime côté hôte
curl -s 'http://localhost:3001/.well-known/webfinger?resource=acct:joanie@alpha.local' | jq
curl -s 'http://localhost:3002/.well-known/nodeinfo' | jq
curl -s 'http://localhost:3003/nodeinfo/2.1' | jq

# 7. Lancer la suite d'intégration Rust contre le testbed
#    IMPORTANT : `--test-threads=1` est obligatoire — les tests E2E
#    mutent l'état partagé du testbed (trust list, kill_domain,
#    remote_identities.disabled_at, fediverse_trust_mode) et entrent
#    en collision quand cargo les lance en parallèle (5 failures
#    "fantômes" sur les scénarios S3/S4/S5/S6 sinon).
cd ../..
cargo test -p rustwarden-fediverse --test e2e_fediverse -- --test-threads=1
cargo test -p rustwarden-fediverse --test fediverse_interop -- --test-threads=1

# 8. Inspecter les logs si quelque chose coince
cd tests/fediverse-testbed
docker compose logs app-alpha | tail -50
docker compose logs app-beta  | tail -50
docker compose logs app-gamma | tail -50

# 9. Arrêter le testbed quand fini
./scripts/teardown.sh

Le rebuild Rust dans le container prend 5–10 min la première fois (la couche de deps reste cachée tant que Cargo.lock ne change pas — voir limite "build à froid long" ci-dessous).

Limites connues

  • HTTP plain only. Le flag FEDIVERSE_DEBUG_LOCAL_FEDERATION=true autorise le bypass HTTPS en local — ne jamais activer en production.
  • Build à froid long. Mitigation v2 : intégrer cargo-chef au Dockerfile pour cacher les couches de dépendances.
  • Les seed-* se déclenchent après app-* healthy, donc après que l'app a déjà démarré. Conséquence : les rôles admin/user et les premiers users sont insérés après que le serveur HTTP écoute déjà — bref creux de quelques secondes où l'app tourne sans user. Pas bloquant pour les tests E2E qui attendent setup.sh complet.
  • La trust list est écrite via SQL direct (configure-trust.sh) et non via l'UI admin (CSRF). Si la table fediverse_trusted_domains change de schéma, mettre à jour le script.

Plan d'évolution

Itération 1+ : tests E2E Rust (cargo test --test e2e_fediverse) qui pilotent le testbed via les ports localhost:300X exposés. Code dans crates/rustwarden-fediverse/tests/e2e_fediverse.rs et crates/rustwarden-fediverse/tests/fediverse_interop.rs — déplacés depuis rustwarden-core lors de l'extraction du crate fédération (cf. docs/plans/2026-05-11-extract-rustwarden-fediverse-crate.md).