Performance des tests OpenClaw
Utilisez d'abord des preuves. L'objectif est une amélioration réelle de la vitesse/RSS de pnpm test, de la suite de plugins et de l'inspecteur de plugins, avec la couverture intacte, et non un réglage de l'exécuteur par conjecture.
Flux de travail
- Lisez les fichiers
AGENTS.mdlocaux pertinents avant de modifier :src/agents/AGENTS.mdpour les agents/hotspots d'importation.src/channels/AGENTS.mdetsrc/plugins/AGENTS.mdpour la paresse des plugins/canaux.src/gateway/AGENTS.mdpour les tests de cycle de vie du serveur.test/helpers/AGENTS.mdetsrc/channels/plugins/contracts/test-helpers/AGENTS.mdpour les aides de contrat partagés.src/infra/outbound/AGENTS.mdpour les tests sortants/média/action.
- Établissez une référence avant de modifier le code :
- Préférez
pnpm test:perf:groups --full-suite --allow-failures --output <fichier>pour le classement de la suite complète. - Pour la largeur des plugins groupés, exécutez la plus petite commande
pnpm test:extensions:batch <plugin[,plugin...]>ou inspecteur de plugins pertinente avant de passer au balayage complet des extensions. - Pour un hotspot ciblé, utilisez :
/usr/bin/time -l pnpm test <fichier-ou-fichiers> --maxWorkers=1 --reporter=verbose - En cas de suspicion d'importations lourdes, ajoutez :
OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1.
- Préférez
- Séparez le bruit du mur/de l'exécuteur du coût réel du fichier :
- Comparez la durée Vitest, le timing du corps du test, la répartition des importations, le temps réel et le RSS maximum.
- Réexécutez des fichiers uniques lorsque les nombres de la suite groupée/complete semblent obsolètes ou bruités.
- Si une exécution groupée de la suite complète signale un échec de voie mais que le JSON indique que les tests ont réussi, capturez cela comme un bruit d'infrastructure et vérifiez le fichier suspect directement.
- Choisissez la prochaine attaque en fonction du retour et du risque :
- Retour élevé : un fichier/test domine les secondes ou le RSS et a une cause racine claire.
- Levier élevé : un plugin ou un baril SDK provoque le chargement d'un environnement d'exécution large à chaque exécution de l'inspecteur de plugins ou du lot d'extensions.
- Risque plus faible : descripteurs statiques, analyse de cible, routage, contournement d'authentification, indices de configuration, éléments de registre ou cycle de vie du serveur de test.
- Risque plus élevé : comportement réel de la mémoire/exécution, fournisseurs en direct, contrats de protocole ou refactorisations larges de la production.
- Corrigez la cause racine, pas le symptôme :
- Déplacez les métadonnées/l'analyse statiques dans des aides étroits ou des artefacts légers réutilisés par l'exécution complète et les chemins rapides.
- Préférez l'injection de dépendances, la recherche uniquement par plugin chargé, des éléments explicites et des aides purs aux simulations larges.
- Réutilisez les serveurs/clients au niveau de la suite lorsqu'une nouvelle prise de contact est sans importance.
- Gardez les planificateurs/boucles d'arrière-plan désactivés à moins que le test ne prouve la planification.
- Dans les chemins de plugins, déplacez les métadonnées statiques dans le manifeste/des artefacts légers et conservez les charges de l'exécution du plugin derrière des limites d'exécution explicites.
- Préservez la forme de la couverture :
- Ne supprimez pas une preuve d'intégration lente à moins que la composition exacte de production ne soit extraite dans un aide nommé et testée.
- Conservez un test de fumée d'intégration peu coûteux lorsque le câblage inter-composants est important.
- Indiquez explicitement quelle couverture accessoire a été supprimée, le cas échéant.
- Re-benchmarkez la même commande après le changement et calculez les secondes ainsi que le gain en pourcentage.
- Mettez à jour le rapport en cours lorsqu'il est demandé ou que ce fil en suit un. Incluez les commandes avant/après, les artefacts, les notes de couverture, la vérification et le prochain ordre d'attaque.
- Stadez les chemins prévus, validez avec Git standard et poussez lorsque l'utilisateur a demandé des validations/pushs. Stadez uniquement les fichiers touchés pour cette attaque.
Flux de travail de la suite de plugins
Utilisez cette section lorsque le travail de performance implique des plugins groupés, l'inspecteur de plugins, les barils SDK, les tests de limite de paquets ou les suites d'extensions.
- Cartographiez d'abord la forme de la suite :
- tests source :
pnpm test extensions/<id>oupnpm test:extensions:batch <id> - limites de paquets :
pnpm run test:extensions:package-boundary:canaryetpnpm run test:extensions:package-boundary:compile - tous les tests source groupés :
pnpm test:extensions - mémoire d'importation de plugin :
pnpm test:extensions:memory -- --json .artifacts/test-perf/extensions-memory.json - travail d'inspecteur/rapport de plugin : gardez les primitives de rapport dans
plugin-inspector; gardez les wrappers fins et collectez le RSS de pointe lorsque la commande le supporte.
- tests source :
- Commencez étroitement, puis élargissez :
- un plugin modifié : exécutez les tests de ce plugin et la tranche de l'inspecteur de plugins.
- baril SDK/public modifié : ajoutez des plugins représentatifs de fournisseur, canal, mémoire et fonctionnalité.
- miroir chargeur/exécution modifié : ajoutez des vérifications de limite de paquets et une preuve de construction/paquetage selon les besoins.
- comportement de plugin partagé inconnu : exécutez les groupes
test:extensions:batchavantpnpm test:extensions.
- Traitez les échecs de l'inspecteur de plugins comme des signaux produit :
- Le JSON doit pouvoir être analysé.
- Les avertissements/erreurs doivent être classifiés, non cachés.
- La capture d'exécution doit être silencieuse et tolérante à la configuration.
- La sortie de commande doit inclure le temps réel, le code de sortie et le RSS de pointe lorsque disponible.
- Suivez
$openclaw-testingpour la sélection de l'hôte. Les benchmarks de source fiable peuvent être exécutés localement avec des conditions de machine/charge comparables. Utilisez$crabboxlorsque un paquetage propre, un comportement Linux/plateforme, un isolement ou une demande distante explicite fait partie de la preuve ; réutilisez et nettoyez uniquement le bail détenu. - Si la performance du plugin est sensible aux artefacts de paquetage, passez à
release-openclaw-plugin-testinget à l'acceptation de paquetage plutôt que de vous fier au timing de la source uniquement.
Collecte de métriques
Collectez au moins une métrique stable avant et après. Préférez la même machine et la même commande. Pour les comparaisons Testbox, utilisez le même identifiant tbx_... lorsque possible.
| Métrique | Utilisation pour | Source préférée |
|---|---|---|
| temps mural | coût de la suite visible par l'utilisateur | /usr/bin/time -l, durée du wrapper de test, temps d'exécution Testbox |
| durée Vitest | coût du corps du test / des importations | sortie Vitest par fichier/tranche |
| durée d'importe | charges larges de baril / d'exécution | OPENCLAW_VITEST_IMPORT_DURATIONS=1 |
| RSS maximum | pression mémoire et risque de OOM | /usr/bin/time -l, pnpm test:extensions:memory, résumés mémoire du wrapper |
| CPU/utilisateur/système | division CPU vs attente | /usr/bin/time -l localement, timing du job Testbox lorsque le CPU local est bruité |
| preuve de tas | fuite réelle vs graphe de modules retenus | flux de travail openclaw-test-heap-leaks |
Commande locale ciblée avec CPU/RSS :
timeout 240 /usr/bin/time -l pnpm test <fichier> --maxWorkers=1 --reporter=verbose
Profil de mémoire d'importation de plugin :
pnpm build
pnpm test:extensions:memory -- --top 20 --json .artifacts/test-perf/extensions-memory.json
Mémoire d'importation de plugin ciblée :
pnpm test:extensions:memory -- --extension discord --extension telegram --skip-combined
Escalade du tas/RSS :
pnpm test:perf:groups \
--config test/vitest/vitest.unit-fast.config.ts \
--allow-failures \
--output .artifacts/test-perf/unit-fast-memory.json
pnpm test:perf:profile:runner -- \
--output-dir .artifacts/test-perf/vitest-runner-profile -- <fichier>
Utilisez openclaw-test-heap-leaks lorsque le RSS continue de croître entre les intervalles, les travailleurs OOM, ou que la commande suspecte a une rétention d'objets d'application. N'appelez pas une croissance du RSS une fuite tant que des instantanés ou des détenteurs ne la soutiennent pas.
Causes racines courantes
- Environnement d'exécution complet du canal/plugin groupé chargé pour des données statiques.
- Recours à
getChannelPlugin()lorsqu'un élément déjà chargé ou un analyseur pur suffirait. - Barils larges
api.ts,runtime-api.ts,test-api.tsou plugin-sdk tirés dans des tests chauds. - Alias racine SDK ou barils de paquets tirant des sous-chemins ciblés dans un graphe de plugin large.
- Inspecteur de plugins chargeant du code d'exécution juste pour rendre des métadonnées, des rapports ou des scores de politique CI.
- Capture de plugin groupé réutilisant un état réel de configuration/domicile au lieu d'un état synthétique, expurgé et isolé.
- Simulations partiellement réelles utilisant
importActual()autour de modules larges. vi.resetModules()plus des importations fraîches dans des boucles par test.- Registre de plugin de test amorcé dans
beforeAlltandis que l'état d'exécution est réinitialisé dansafterEach. - Démarrage de passerelle/serveur/client par test lorsqu'une réinitialisation d'état suffirait.
- Sélection de modèle/auth par exécution/défaut payée par des instantanés ou des éléments inactifs.
- Découverte de média/action détenue par un plugin déclenchée avant de vérifier si les arguments contiennent des champs détenus par le plugin.
- Exécutions Vitest parallèles partageant
node_modules/.experimental-vitest-cachesans valeurs distinctes deOPENCLAW_VITEST_FS_MODULE_CACHE_PATH.
Commandes de benchmark
Fichier ciblé :
timeout 240 /usr/bin/time -l pnpm test <fichier> --maxWorkers=1 --reporter=verbose
Fichier ciblé avec répartition des importations :
timeout 240 /usr/bin/time -l env \
OPENCLAW_VITEST_IMPORT_DURATIONS=1 \
OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 \
pnpm test <fichier> --maxWorkers=1 --reporter=verbose
Suite groupée :
pnpm test:perf:groups --full-suite --allow-failures \
--output .artifacts/test-perf/<nom>.json
Lot d'extensions :
pnpm test:extensions:batch <plugin[,plugin...]> -- --reporter=verbose
Tous les tests d'extensions :
pnpm test:extensions
Vérifications de limite de paquets de plugins :
pnpm run test:extensions:package-boundary:canary
pnpm run test:extensions:package-boundary:compile
Réutiliser un rapport JSON Vitest existant :
pnpm test:perf:groups --report <vitest-json> \
--output .artifacts/test-perf/<nom>.json
Vérification
- Exécutez toujours la surface de test ciblée qui prouve le changement.
- Modifications source : tests locaux ciblés + vérification de type/lint/format avant le push ;
pnpm check:changedoptionnel. CI PR = preuve large. Testbox uniquement pour les lacunes CI/locales, subvention immédiate ; réutilisation de Testbox réchauffé lorsqu'il est sélectionné. - Pour les modifications uniquement de test, exécutez
pnpm test:changedou les tests exacts modifiés. - Exécutez
pnpm buildlors de la modification du chargement paresseux, des artefacts groupés, des limites de paquets, des importations dynamiques, de la sortie de construction ou des surfaces publiques. - Pour les modifications SDK/baril/exécution de plugin, comparez les commits exacts avec
pnpm plugin-sdk:api:diff -- --base <sha-base> --head <sha-tête>lorsque la surface de l'API publique peut dériver. Pour une preuve locale de PR, utilisez la base de fusion de la branche comme<sha-base>et le commit de tête exact testé comme<sha-tête>. - Pour les correctifs de performance de la suite de plugins, vérifiez au moins un lot de plugins représentatif plus la passerelle modifiée ; utilisez l'acceptation de paquetage si le bogue n'existe que dans un artefact empaqueté.
- Si les dépendances sont manquantes/obsolètes, exécutez
pnpm installet réessayez la commande exacte ayant échoué une fois. - Utilisez le format de rapport :
| Métrique | Avant | Après | Gain |
| ---------------- | ------: | ------: | ----------: |
| Temps réel | `Xs` | `Ys` | `-Zs` (`P%`) |
| RSS max | `XMB` | `YMB` | `-ZMB` (`P%`)|
| CPU util/sys | `X/Ys` | `A/Bs` | expliquer|
Transfert
Gardez le final concis :
- Cause racine.
- Portée de la suite/plugin.
- Fichiers modifiés.
- Nombres avant/après de temps réel, Vitest/importation, CPU et RSS, lorsque disponibles.
- Classification de fuite si la mémoire était impliquée : fuite réelle, graphe de modules retenu ou non concluant.
- Couverture conservée.
- Commandes de vérification.
- ID Testbox ou URL du flux de travail pour une preuve distante.
- Hash de commit et statut du push.