Planos de Teste — padrões de carga pré-configurados¶
Read in your language: English · Português · Español
Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze.
Status: 15 planos entregues. Catálogo em
platform/test-plans/catalog.yaml.
Por que Planos de Teste¶
Toda execução de teste neste cluster precisa de três coisas para ser comparável entre engagements:
- Um início e fim definidos — duração em minutos / horas, não "até o engenheiro mandar parar"
- Uma metodologia de ramp-up — agentes não chegam à carga máxima instantaneamente; eles fazem ramp ao longo de uma linha do tempo definida para que o NGFW tenha chance de aquecer
- Um identifier compartilhado — dois engenheiros em geografias diferentes podem dizer "rodei
CAP-FIND-KNEE-30Mcontra este FTD, p99 inflectiu em 720 RPS" e a comparação é inequívoca
Appliances comerciais (Spirent CyberFlood, Ixia BreakingPoint) têm esses conceitos sob nomes como "test profile" / "load specification" / "phase configuration". Este projeto os entrega como YAML no git — versionáveis, revisáveis como código, replayáveis byte-a-byte entre runs.
Os 15 planos¶
O catálogo está agrupado em 7 categorias. Cada plano tem um identifier estável que aparece literalmente no relatório do teste.
| Categoria | # | Identifier | Use quando |
|---|---|---|---|
| Baseline | 1 | BASELINE-SMOKE-5M |
Primeiro run após qualquer mudança no cluster |
| 2 | BASELINE-SLO-30M |
Estabelecer o baseline de referência de SLO antes de qualquer outro run | |
| Capacity | 3 | CAP-FIND-KNEE-30M |
Encontrar a contagem de agentes onde p99 inflecte (o joelho do NGFW) |
| 4 | CAP-MAX-1H |
Sustentar em 90% do joelho descoberto por uma hora | |
| Stress | 5 | STR-OVERLOAD-15M |
Empurrar até 2× a capacidade e observar modos de falha |
| 6 | STR-CONNECTION-FLOOD-10M |
Taxa máxima de novos handshakes TLS (sem reuso de sessão) | |
| Soak | 7 | SOAK-ENDURANCE-24H |
24 h sustentadas em 70% da capacidade — detecta leaks |
| 8 | SOAK-WEEKEND-72H |
72 h com padrão diurno — ciclos de pico/vale | |
| Spike | 9 | SPIKE-RECOVERY-10X-2M |
Burst de 10× com tempo de recuperação medido |
| 10 | SPIKE-FLASH-CROWD-5M |
Padrão flash-crowd assimétrico (estilo Black Friday) | |
| Mix | 11 | MIX-FULL-ARCHETYPES-1H |
Peso igual entre skin/mock/HAR/real-app |
| 12 | MIX-CLONED-HEAVY-30M |
70% para slots Cloned — mix realista de empresa | |
| Protocol | 13 | H3-ONLY-SESSION-PRESSURE-30M |
100% HTTP/3, sessão nova por requisição |
| 14 | H2-LONGLIVED-CONN-30M |
100% HTTP/2 com conexões multiplexadas de vida longa | |
| Realistic | 15 | REPLAY-REAL-CUSTOMER-1H |
HAR-replay de um trace real de cliente |
Anatomia de um plano¶
- identifier: CAP-FIND-KNEE-30M
display_name: "Capacity — Find the knee (30 min)"
description: "Step ramp from 50 → 1000 agents in 5 stages of 2 min each."
duration_total: 30m
phases:
- { name: warm, duration: 2m, pattern: linear, target: { playwright: 50, k6: 100 } }
- { name: s100, duration: 4m, pattern: step, target: { playwright: 100, k6: 500 } }
- { name: s250, duration: 4m, pattern: step, target: { playwright: 250, k6: 1000 } }
- { name: s500, duration: 4m, pattern: step, target: { playwright: 500, k6: 2500 } }
- { name: s750, duration: 4m, pattern: step, target: { playwright: 750, k6: 5000 } }
- { name: s1000, duration: 8m, pattern: step, target: { playwright: 1000, k6: 7500 } }
- { name: rampdown, duration: 4m, pattern: linear, target: { playwright: 0, k6: 0 } }
agent_target_strategy: round_robin_all
persona_mix:
synthetic_archetypes: { skin: 0.40, mock: 0.30, har: 0.20, real_app: 0.10 }
synthetic_weight: 1.0
cloned_weight: 0.0
protocol_mix: { h2: 0.30, h3: 0.70 }
cycle_interval_seconds: 3
ngfw_state_required: decrypt-on
slo_target_p99_seconds: 0.5
Campos explicados¶
| Campo | O que controla |
|---|---|
identifier |
O contrato. Estável para sempre. Citado em relatórios. Formato: CATEGORIA-CARACTERÍSTICA-DURAÇÃO |
display_name |
Versão amigável para humanos em dropdowns de UI |
description |
Por que um operador escolheria este plano. Lido pela UI de seleção |
duration_total |
A duração total que o operador promete alocar. O engine recusa agendar um plano cujas phases excedem isso |
phases[] |
Lista ordenada de phases da timeline |
phases[].pattern |
linear (ramp suave), exponential (aceleração rápida), exponential_decay (decaimento lento), step (salto instantâneo), hold (estável), sinusoidal (diurno) |
phases[].target |
Contagens de agentes alvo no FIM da phase |
phases[].target_min / target_max |
Usado apenas com sinusoidal para definir o envelope da oscilação |
agent_target_strategy |
Como agentes escolhem qual persona atingir: round_robin_all / round_robin_first_5 / random_each_request / weighted_top10 / weighted_cloned_70pct / pinned_first_5 / har_replay_only |
persona_mix.synthetic_archetypes |
Pesos para os 4 archetypes (devem somar 1.0) |
persona_mix.synthetic_weight + cloned_weight |
Divisão entre os 20 slots Synthetic e os 10 Cloned (devem somar 1.0) |
protocol_mix |
Pesos H2 vs H3 (devem somar 1.0) |
cycle_interval_seconds |
Quão frequentemente cada agente faz uma requisição (0 = ritmado pelo trace HAR) |
tls_session_reuse |
Se false, todo ciclo cria um handshake TLS novo — pressiona o engine de handshake do NGFW |
ngfw_state_required |
any / decrypt-on / decrypt-off. O engine recusa iniciar o run se o TLS Decrypt Mode Probe reportar um estado diferente |
slo_target_p99_seconds |
O p99 esperado para ESTE plano. Usado para computar pass/fail no relatório |
prerequisite |
Pré-condições legíveis por humanos (ex.: "5 cloned slots devem ter um SITE_NAME atribuído") |
Como escolher um plano¶
Um engagement típico roda 3–5 planos nesta ordem:
BASELINE-SMOKE-5M— confirmar que o test bed está saudávelBASELINE-SLO-30M— registrar os números de referência de SLOCAP-FIND-KNEE-30M— encontrar a contagem de agentes onde o NGFW dobra o joelhoCAP-MAX-1H— confirmar que o joelho descoberto se mantém por uma hora- (Opcional, se o engagement permitir tempo)
SOAK-ENDURANCE-24Hpara detecção de leaks, OUSTR-OVERLOAD-15Mpara descoberta de modos de falha
Para demos / PoVs você pode parar em #3 — o número do joelho é a manchete. Para teste de aceitação ou planejamento de capacidade, rode todos os cinco.
Comparação entre engagements¶
O identifier é o contrato entre engagements. Dois SEs em países diferentes rodando o mesmo plano contra NGFWs diferentes DEVEM estar comparando o mesmo formato de carga. Para tornar isso seguro:
- Identifiers são imutáveis. Um plano nunca muda seu formato de carga após publicação. Para mudar um formato de carga, publique um novo plano com um novo identifier (ex.:
CAP-FIND-KNEE-30M-v2) - O catálogo é versionado em git. Toda mudança é revisável como código; um job de CI verifica que identifiers permanecem estáveis
- Relatórios citam a versão do catálogo + o identifier: "Run executou
CAP-FIND-KNEE-30Mdo catálogo v1, plan-snapshot-hashsha256:abc.... NGFW = Cisco FTD 7.4. Resultado: joelho em 720 agentes concorrentes, p99 = 487 ms"
API¶
O Dashboard sincroniza o catálogo no Postgres no startup e expõe:
GET /api/test-plans/catalog— lista completaGET /api/test-plans/{identifier}— plano único com phases
Ambos retornam JSON. Sem auth requerida para leitura; o catálogo é informação pública sobre quais planos existem (não sobre o que um run fez).
Adicionar um novo plano¶
- Adicione a nova entrada em
platform/test-plans/catalog.yamlcom um identifier novo seguindo a convenção de nomenclatura - Bump o
version: 1no topo do arquivo (é o metadado de versão do catálogo) - Abra um PR — revisores verificam que o identifier não colide e que o formato de carga faz sentido
- No merge, todo pod do Dashboard re-sincroniza no próximo restart
Depreciar um plano¶
Defina deprecated: true e (opcionalmente) replaced_by: NEW-IDENTIFIER. A API do catálogo ainda retorna o plano (para que relatórios históricos continuem funcionando), mas o picker do Dashboard o esconde de "available plans" e o expõe apenas como "view legacy plans".
Relacionados¶
platform/test-plans/catalog.yaml— fonte de verdade do catálogoMONITORING_TEST_VALIDITY.md— alertas que confirmam que o test bed em si não é o gargaloTLS_DECRYPT_MODE_VERIFICATION.en.md— enforcement dengfw_state_requiredTRACING.md— tracing distribuído durante runs