Desempenho de Testes OpenClaw
Use evidências primeiro. O objetivo é melhoria real de velocidade/RSS do pnpm test, plugin-suite e
plugin-inspector com cobertura intacta, não ajuste por adivinhação.
Fluxo de Trabalho
- Leia os arquivos
AGENTS.mdlocais relevantes antes de editar:src/agents/AGENTS.mdpara hotspots de agente/importação.src/channels/AGENTS.mdesrc/plugins/AGENTS.mdpara lentidão de plugin/canal.src/gateway/AGENTS.mdpara testes de ciclo de vida do servidor.test/helpers/AGENTS.mdesrc/channels/plugins/contracts/test-helpers/AGENTS.mdpara helpers de contrato compartilhados.src/infra/outbound/AGENTS.mdpara testes de saída/mídia/ação.
- Estabeleça uma linha de base antes de alterar código:
- Prefira
pnpm test:perf:groups --full-suite --allow-failures --output <file>para ranqueamento da suite completa. - Para abrangência de plugins empacotados, execute o menor comando relevante
pnpm test:extensions:batch <plugin[,plugin...]>ou plugin-inspector antes de pular para a varredura completa de extensões. - Para um hotspot específico use:
/usr/bin/time -l pnpm test <arquivo-ou-arquivos> --maxWorkers=1 --reporter=verbose - Para suspeita de importações pesadas adicione:
OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1.
- Prefira
- Separe ruído de runner/parede do custo real do arquivo:
- Compare duração do Vitest, tempo do corpo do teste, detalhamento de importação, tempo de parede e RSS máximo.
- Reexecute arquivos individuais quando os números da suite agrupada/completa parecerem desatualizados ou ruidosos.
- Se uma execução agrupada da suite completa relatar falha de lane, mas o JSON disser que os testes passaram, capture isso como ruído/ferramental e verifique o arquivo suspeito diretamente.
- Escolha o próximo ataque pelo retorno e risco:
- Alto retorno: um arquivo/teste domina segundos ou RSS e tem uma causa raiz clara.
- Alta alavancagem: um plugin ou barrel do SDK faz com que cada execução de plugin-inspector ou extensão em lote carregue um runtime amplo.
- Menor risco: descritores estáticos, análise de destino, roteamento, bypass de autenticação, dicas de configuração, fixtures de registro ou ciclo de vida do servidor de teste.
- Maior risco: comportamento real de memória/runtime, provedores ativos, contratos de protocolo ou refatorações amplas de produção.
- Corrija a causa raiz, não o sintoma:
- Mova metadados/análise estáticos para helpers estreitos ou artefatos leves reutilizados pelo runtime completo e caminhos rápidos.
- Prefira injeção de dependência, busca apenas por plugins carregados, fixtures explícitas e helpers puros em vez de mocks amplos.
- Reutilize servidores/clientes no nível da suite quando um handshake novo for irrelevante.
- Mantenha schedulers/loops em segundo plano desligados, a menos que o teste prove agendamento.
- Em caminhos de plugins, mova metadados estáticos para artefatos de manifesto/leves e mantenha cargas de runtime de plugin atrás de limites de execução explícitos.
- Preserve a forma da cobertura:
- Não exclua uma prova de integração lenta a menos que a composição exata de produção seja extraída para um helper nomeado e testada.
- Mantenha um smoke de integração barato quando a conexão entre componentes for relevante.
- Declare explicitamente qual cobertura incidental foi removida, se houver.
- Refaça o benchmark do mesmo comando após a mudança e calcule segundos mais ganho percentual.
- Atualize o relatório em andamento quando solicitado ou quando esta thread estiver rastreando um. Inclua comandos antes/depois, artefatos, notas de cobertura, verificação e próxima ordem de ataque.
- Prepare os caminhos pretendidos, faça commit com Git padrão e envie quando o usuário solicitar commits/envios. Prepare apenas arquivos tocados para este ataque.
Fluxo de Trabalho de Plugin-Suite
Use esta seção quando o trabalho de desempenho envolver plugins empacotados, plugin-inspector, barris do SDK, testes de fronteira de pacote ou suites de extensão.
- Mapeie a forma da suite primeiro:
- testes fonte:
pnpm test extensions/<id>oupnpm test:extensions:batch <id> - fronteiras de pacote:
pnpm run test:extensions:package-boundary:canaryepnpm run test:extensions:package-boundary:compile - todos os testes fonte empacotados:
pnpm test:extensions - memória de importação de plugin:
pnpm test:extensions:memory -- --json .artifacts/test-perf/extensions-memory.json - trabalho de plugin-inspector/relatório: mantenha primitivas de relatório no
plugin-inspector; mantenha wrappers finos e colete o RSS de pico quando o comando suportar.
- testes fonte:
- Comece estreito, depois alargue:
- um plugin alterado: execute os testes desse plugin e a fatia do plugin-inspector.
- barrel público do SDK alterado: adicione provedores, canal, memória e feature plugins representativos.
- loader/runtime mirror alterado: adicione verificações de fronteira de pacote e prova de build/empacotamento conforme necessário.
- comportamento de plugin compartilhado desconhecido: execute grupos
test:extensions:batchantes depnpm test:extensions.
- Trate falhas do plugin-inspector como sinais de produto:
- JSON deve analisar.
- avisos/erros devem ser classificados, não ocultados.
- a captura de runtime deve ser silenciosa e tolerante a configuração.
- a saída do comando deve incluir tempo de parede, código de saída e RSS de pico quando disponível.
- Siga
$openclaw-testingpara seleção de host. Benchmarks de fonte confiável podem ser executados localmente com condições de máquina/carga comparáveis. Use$crabboxquando empacotamento limpo, comportamento Linux/plataforma, isolamento ou uma solicitação remota explícita fizer parte da prova; reutilize e limpe apenas a locação possuída. - Se o desempenho do plugin for sensível a artefatos de pacote, mude para
release-openclaw-plugin-testinge Aceitação de Pacote em vez de confiar apenas no timing da fonte.
Coleta de Métricas
Colete pelo menos uma métrica estável antes e depois. Prefira a mesma máquina e
mesmo comando. Para comparações Testbox, use o mesmo id tbx_... quando possível.
| Métrica | Uso para | Fonte preferida |
|---|---|---|
| tempo de parede | custo da suite visível ao usuário | /usr/bin/time -l, duração do wrapper de teste, tempo de execução Testbox |
| duração Vitest | custo do corpo do teste/importação | Saída do Vitest por arquivo/shard |
| duração import | cargas amplas de barrel/runtime | OPENCLAW_VITEST_IMPORT_DURATIONS=1 |
| RSS máximo | pressão de memória e risco de OOM | /usr/bin/time -l, pnpm test:extensions:memory, resumos de memória do wrapper |
| CPU/user/sys | divisão entre CPU-ligado e espera | /usr/bin/time -l localmente, tempo de job Testbox quando CPU local é ruidoso |
| evidência de heap | vazamento real vs grafo de módulo retido | workflow openclaw-test-heap-leaks |
Comando local específico com CPU/RSS:
timeout 240 /usr/bin/time -l pnpm test <arquivo> --maxWorkers=1 --reporter=verbose
Perfil de memória de importação de plugin:
pnpm build
pnpm test:extensions:memory -- --top 20 --json .artifacts/test-perf/extensions-memory.json
Memória de importação de plugin direcionada:
pnpm test:extensions:memory -- --extension discord --extension telegram --skip-combined
Escalonamento de Heap/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 -- <arquivo>
Use openclaw-test-heap-leaks quando o RSS continuar crescendo entre intervalos, workers
OOM, ou o comando suspeito tiver retenção de objetos de aplicativo. Não chame crescimento de RSS de
vazamento até que snapshots ou retentores o suportem.
Causas Raiz Comuns
- Runtime completo do canal/plugin empacotado carregado para dados estáticos.
- Fallback
getChannelPlugin()usado quando uma fixture já carregada ou parser puro seria suficiente. - Barris amplos
api.ts,runtime-api.ts,test-api.ts, ou plugin-sdk puxados para testes quentes. - Aliases raiz do SDK ou barris de pacote puxando subcaminhos focados de volta para um grafo de plugin amplo.
- Plugin-inspector carregando código de runtime apenas para renderizar metadados, relatórios ou pontuações de política de CI.
- Captura de plugin empacotado reutilizando estado real de configuração/home em vez de estado sintético, editado e isolado.
- Mocks parcialmente reais usando
importActual()em torno de módulos amplos. vi.resetModules()mais importações novas em loops por teste.- Registro de plugin de teste semeado em
beforeAllenquanto o estado do runtime é resetado emafterEach. - Inicialização de gateway/servidor/cliente por teste quando reset de estado seria suficiente.
- Seleção de modelo/auth runtime/padrão paga por snapshots ou fixtures ociosos.
- Descoberta de mídia/ação pertencente a plugin acionada antes de verificar se os argumentos contêm campos pertencentes a plugin.
- Execuções paralelas do Vitest compartilhando
node_modules/.experimental-vitest-cachesem valores distintos deOPENCLAW_VITEST_FS_MODULE_CACHE_PATH.
Comandos de Benchmark
Arquivo específico:
timeout 240 /usr/bin/time -l pnpm test <arquivo> --maxWorkers=1 --reporter=verbose
Arquivo específico com detalhamento de importação:
timeout 240 /usr/bin/time -l env \
OPENCLAW_VITEST_IMPORT_DURATIONS=1 \
OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 \
pnpm test <arquivo> --maxWorkers=1 --reporter=verbose
Suite agrupada:
pnpm test:perf:groups --full-suite --allow-failures \
--output .artifacts/test-perf/<nome>.json
Lote de extensão:
pnpm test:extensions:batch <plugin[,plugin...]> -- --reporter=verbose
Todos os testes de extensão:
pnpm test:extensions
Verificações de fronteira de pacote de plugin:
pnpm run test:extensions:package-boundary:canary
pnpm run test:extensions:package-boundary:compile
Reutilizar um relatório JSON existente do Vitest:
pnpm test:perf:groups --report <vitest-json> \
--output .artifacts/test-perf/<nome>.json
Verificação
- Sempre execute a superfície de teste direcionada que prova a mudança.
- Siga OpenClaw testing para testes focados, builds necessários, roteamento de prova e tempo de publicação.
- Para mudanças apenas em testes, execute os testes exatamente editados através do comando suportado do proprietário.
- Para mudanças no SDK/barrel/runtime do plugin, compare commits exatos com
pnpm plugin-sdk:api:diff -- --base <base-sha> --head <head-sha>quando a superfície da API pública puder variar. Para prova local de PR, use a base de merge do branch como<base-sha>e o commit head exato testado como<head-sha>. - Para correções de desempenho na suite de plugins, verifique pelo menos um lote de plugin representativo mais a porta alterada; use Aceitação de Pacote se o bug existir apenas em um artefato empacotado.
- Para dependências ausentes ou desatualizadas, siga Source dependencies e as instruções do proprietário atual da árvore de trabalho. Use uma rota de prova qualificada.
- Use o formato de relatório:
| Métrica | Antes | Depois | Ganho |
| --------------- | -----: | -----: | ------------: |
| Tempo de parede | `Xs` | `Ys` | `-Zs` (`P%`) |
| RSS Máximo | `XMB` | `YMB` | `-ZMB` (`P%`) |
| CPU user/sys | `X/Ys` | `A/Bs` | explique |
Repasse
Mantenha o final conciso:
- Causa raiz.
- Escopo da suite/plugin.
- Arquivos alterados.
- Números de antes/depois de tempo de parede, Vitest/importação, CPU e RSS, quando disponíveis.
- Classificação de vazamento se memória estiver envolvida: vazamento real, grafo de módulo retido, ou inconclusivo.
- Cobertura mantida.
- Comandos de verificação.
- ID do Testbox ou URL do workflow para prova remota.
- Hash do commit e status de push.