From d350d0337b1ab6867e8814cc89005b6cdc505a17 Mon Sep 17 00:00:00 2001 From: Joel Alvarez Date: Mon, 27 Jul 2026 09:19:59 -0700 Subject: [PATCH] docs: expand chaos testing chapter --- Cargo.toml | 4 +++ diagrams/09-chaos-testing.mmd | 8 +++++ docs/09-chaos-testing.md | 60 +++++++++++++++++++++++++++++++++++ examples/chaos_testing.rs | 29 +++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 diagrams/09-chaos-testing.mmd create mode 100644 examples/chaos_testing.rs diff --git a/Cargo.toml b/Cargo.toml index bca537f..c6ddece 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,3 +138,7 @@ path = "examples/soluciones/performance_testing_nivel_2.rs" [[example]] name = "performance_testing_nivel_3" path = "examples/soluciones/performance_testing_nivel_3.rs" + +[[example]] +name = "chaos_testing" +path = "examples/chaos_testing.rs" diff --git a/diagrams/09-chaos-testing.mmd b/diagrams/09-chaos-testing.mmd new file mode 100644 index 0000000..68cbcec --- /dev/null +++ b/diagrams/09-chaos-testing.mmd @@ -0,0 +1,8 @@ +flowchart TD + A[Hipótesis operativa] --> B[Acotar radio de impacto] + B --> C[Definir guarda y detención] + C --> D[Inyectar falla controlada] + D --> E{Resultado esperado?} + E -->|Sí| F[Registrar recuperación] + E -->|No| G[Detener e investigar] + G --> H[Mejorar sistema o hipótesis] diff --git a/docs/09-chaos-testing.md b/docs/09-chaos-testing.md index 93b1507..3c32c0a 100644 --- a/docs/09-chaos-testing.md +++ b/docs/09-chaos-testing.md @@ -45,4 +45,64 @@ concentra en el criterio para diseñar experimentos seguros y legibles. El modelo representará la hipótesis, el alcance, el tipo de falla y los riesgos que impiden interpretar un experimento con confianza. +## Teoría + +Un experimento de caos empieza con una afirmación falsable: ante una falla +concreta, el sistema debe conservar, degradar o recuperar cierto comportamiento. +El alcance pequeño permite observar la señal sin convertir el experimento en un +incidente. El resultado inesperado no se descarta: es precisamente la evidencia +que justifica investigar. + +## Diagrama + +```mermaid +flowchart TD + A[Hipótesis operativa] --> B[Acotar radio de impacto] + B --> C[Definir guarda y detención] + C --> D[Inyectar falla controlada] + D --> E{Resultado esperado?} + E -->|Sí| F[Registrar recuperación] + E -->|No| G[Detener e investigar] + G --> H[Mejorar sistema o hipótesis] +``` + +El archivo fuente vive en `diagrams/09-chaos-testing.mmd`. + +## Complejidad + +La complejidad está en controlar el radio de impacto y observar recuperación. +Una falla en entorno compartido o sin condición de detención no es un ejercicio +pedagógico seguro. El modelo hace visible esa diferencia antes de ejecutar nada. + +## Implementación + +`ChaosDecision` en `src/chaos_testing.rs` conserva hipótesis, tipo de falla, +radio de impacto, resultado y huecos de seguridad. + +## Pruebas + +El módulo incluye pruebas unitarias, un consumidor externo y un doctest. No +inyecta fallas reales: modela la decisión previa al experimento. + +## Benchmarks + +No hay benchmark propio. `cargo bench --all-targets` verifica la ruta, pero no +pretende medir la resiliencia de infraestructura real. + +## Ejemplos + +```bash +cargo run --example chaos_testing +``` + +## Ejercicios + +Los ejercicios y soluciones graduadas se agregan al cerrar el capítulo. + +## Referencias internas + +- RFC-0001 §13: Rust como núcleo técnico. +- RFC-0001 §14: anatomía de cursos y capítulos. +- RFC-0001 §20: revisión humana diferida. + No está marcado como `reviewed` ni `published`. diff --git a/examples/chaos_testing.rs b/examples/chaos_testing.rs new file mode 100644 index 0000000..62e8c6c --- /dev/null +++ b/examples/chaos_testing.rs @@ -0,0 +1,29 @@ +use rust_testing::chaos_testing::{ + BlastRadius, ChaosDecision, ChaosGap, ExperimentOutcome, FailureKind, +}; +fn main() -> Result<(), rust_testing::chaos_testing::ChaosError> { + for d in [ + ChaosDecision::new( + "reintenta solicitud", + FailureKind::Latency, + BlastRadius::Local, + ExperimentOutcome::Recovered, + )?, + ChaosDecision::new( + "muestra degradación", + FailureKind::InvalidResponse, + BlastRadius::Local, + ExperimentOutcome::Degraded, + )?, + ChaosDecision::new( + "recupera dependencia", + FailureKind::DependencyUnavailable, + BlastRadius::IsolatedFlow, + ExperimentOutcome::Recovered, + )? + .with_gap(ChaosGap::MissingStopCondition), + ] { + println!("{} => {:?}", d.hypothesis(), d.signal()); + } + Ok(()) +}