Skip to main content

Smoke tests : cycle bout en bout par exchange/paire

Les positions créées en isTest servent de jeu de données d’une phase à l’autre. Le cleanup (suppression des positions isTest) est isolé à la fin du run, une fois tout le cycle validé.

Phases à couvrir

Deux approches possibles

A. Tout via webhook (conditions réelles, timing dépendant)

  • Phase 1 : un POST par paire (comme aujourd’hui) → positions NEW.
  • Phase 2 : re-POST même paire, nouvelle bougie (SMOKETIME + offset) : le flux traite la position existante ; si BUY1 est déjà fermé côté exchange, transition NEW → RUNNING.
  • Phase 3 : pas d’appel HTTP dédié ; on considère que le rapport de la phase 2 (ou un GET de santé) suffit, ou on ajoute un GET /tests/smoke/validate qui retourne l’état des positions isTest (NEW / RUNNING / CLOSED par exchange/paire).
  • Phase 4 : re-POST avec une bougie qui déclenche le changement de tendance (trend bear pour une position LONG, trend bull pour une position SHORT) pour que swingPositions appelle processClose → CLOSED.
  • Phase 5 : même GET de validation ou rapport phase 4.
  • Phase 6 : cleanup (GET cleanup-test-positions).
Intérêt : aucun code métier spécifique “test”, tout passe par le vrai webhook.
Inconvénient : dépend de l’exécution réelle des ordres (BUY1 peut ne pas être fermé entre deux runs) et du timing des bougies.

B. Endpoints dédiés “smoke” (contrôlé, recommandé pour CI) — implémenté

Exposer de petits endpoints protégés (Bearer CI_TEST_SECRET) qui enchaînent la logique métier sur les positions isTest uniquement : La CI enchaînerait :
check-exchangesPhase 1 (N curls webhook) → Phase 2 (POST advance-to-running) → Phase 3 (GET status, vérifier RUNNING) → Phase 4 (POST advance-to-closed) → Phase 5 (GET status, vérifier CLOSED) → Phase 6 (GET cleanup-test-positions) → génération rapports/badges.
Intérêt : exécution déterministe, pas de dépendance au remplissage des ordres en temps réel.

Implémentation actuelle (option B)

  • GET /tests/smoke/status : implémenté ; réponse { success, positions: [{ id, exchange, pair, status, orderSide, buy1OrderId, … }], generatedAt }.
  • POST /tests/smoke/advance-to-running : implémenté ; réponse { success, phase, advanced, errors, generatedAt } (207 si au moins une erreur).
  • POST /tests/smoke/advance-to-closed : implémenté ; mise à jour DB seule (closedReason TEST_NEW).
  • GET /tests/cleanup-test-positions : existant ; à appeler une seule fois en fin de cycle.

Lancer les smoke tests en local

  1. Secret : exporte CI_TEST_SECRET (même valeur que dans GitHub / SST). Optionnel : crée un .env à la racine avec CI_TEST_SECRET=... puis source .env.
  2. Cible :
    • Prod (défaut) : npm run smoke:local ou SMOKE_TARGET=prod npm run smoke:localhttps://api.poihunter.com
    • Dev : SMOKE_TARGET=dev npm run smoke:localhttps://api.dev.poihunter.com
    • URL personnalisée (ex. sst dev) : API=https://xxx.lambda-url....on.aws npm run smoke:local
  3. Commande :
    Le script enchaîne check-exchanges, Phase 1 (webhooks), 2 à 6 (advance, status, cleanup) et affiche les réponses. Les rapports sont écrits dans docs/reports/webhook-smoke/ et docs/reports/vitest/specs/.
Paires exécutées : la Phase 1 ne lance des webhooks que pour les paires listées dans scripts/ci/webhook-smoke/pairs-to-run.txt (une par ligne, nom du fichier sans .json). Par défaut seule kucoinfutures-griffainusdt est activée ; ajouter binance-syrupusdc et mexc-damusdt quand nécessaire.

Comportement en CI

Le nombre de positions créées en Phase 1 (et donc advanced en Phase 2, deletedCount en Phase 6) peut être inférieur au nombre de requêtes webhook : la création d’une position exige une previousCandle en base pour la paire/timeframe et le respect des conditions LONG/SHORT (wma50 vs wma50_htf, rangeFilter). Chaque webhook renvoie 200 avec eptProcessed: 1 dès que la bougie et les EPT sont traités ; seules les paires qui ont déjà une bougie “précédente” et les conditions remplies déclenchent processBuy1. Le cycle (NEW → RUNNING → CLOSED → cleanup) s’applique à toutes les positions isTest créées lors du run.

Rapport unique “cycle” (optionnel)

Un même fichier docs/reports/webhook-smoke/cycle-report.json pourrait agréger :
  • phase1 : résultat des POST webhook par paire (déjà en place).
  • phase2 : résultat de l’avancement vers RUNNING (par paire ou global).
  • phase3 : extrait du GET status (positions RUNNING).
  • phase4 : résultat de l’avancement vers CLOSED.
  • phase5 : extrait du GET status (positions CLOSED).
  • phase6 : résultat du cleanup (deletedCount).
Cela permet d’avoir un seul artefact “cycle bout en bout par exchange/paire” et de lier les badges ou la doc à ce rapport.