This commit implements a complete test infrastructure for validating hot-reload stability and robustness across multiple scenarios. ## New Test Infrastructure ### Test Helpers (tests/helpers/) - TestMetrics: FPS, memory, reload time tracking with statistics - TestReporter: Assertion tracking and formatted test reports - SystemUtils: Memory usage monitoring via /proc/self/status - TestAssertions: Macro-based assertion framework ### Test Modules - TankModule: Realistic module with 50 tanks for production testing - ChaosModule: Crash-injection module for robustness validation - StressModule: Lightweight module for long-duration stability tests ## Integration Test Scenarios ### Scenario 1: Production Hot-Reload (test_01_production_hotreload.cpp) ✅ PASSED - End-to-end hot-reload validation - 30 seconds simulation (1800 frames @ 60 FPS) - TankModule with 50 tanks, realistic state - Source modification (v1.0 → v2.0), recompilation, reload - State preservation: positions, velocities, frameCount - Metrics: ~163ms reload time, 0.88MB memory growth ### Scenario 2: Chaos Monkey (test_02_chaos_monkey.cpp) ✅ PASSED - Extreme robustness testing - 150+ random crashes per run (5% crash probability per frame) - 5 crash types: runtime_error, logic_error, out_of_range, domain_error, state corruption - 100% recovery rate via automatic hot-reload - Corrupted state detection and rejection - Random seed for unpredictable crash patterns - Proof of real reload: temporary files in /tmp/grove_module_*.so ### Scenario 3: Stress Test (test_03_stress_test.cpp) ✅ PASSED - Long-duration stability validation - 10 minutes simulation (36000 frames @ 60 FPS) - 120 hot-reloads (every 5 seconds) - 100% reload success rate (120/120) - Memory growth: 2 MB (threshold: 50 MB) - Avg reload time: 160ms (threshold: 500ms) - No memory leaks, no file descriptor leaks ## Core Engine Enhancements ### ModuleLoader (src/ModuleLoader.cpp) - Temporary file copy to /tmp/ for Linux dlopen cache bypass - Robust reload() method: getState() → unload() → load() → setState() - Automatic cleanup of temporary files - Comprehensive error handling and logging ### DebugEngine (src/DebugEngine.cpp) - Automatic recovery in processModuleSystems() - Exception catching → logging → module reload → continue - Module state dump utilities for debugging ### SequentialModuleSystem (src/SequentialModuleSystem.cpp) - extractModule() for safe module extraction - registerModule() for module re-registration - Enhanced processModules() with error handling ## Build System - CMake configuration for test infrastructure - Shared library compilation for test modules (.so) - CTest integration for all scenarios - PIC flag management for spdlog compatibility ## Documentation (planTI/) - Complete test architecture documentation - Detailed scenario specifications with success criteria - Global test plan and validation thresholds ## Validation Results All 3 integration scenarios pass successfully: - Production hot-reload: State preservation validated - Chaos Monkey: 100% recovery from 150+ crashes - Stress Test: Stable over 120 reloads, minimal memory growth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.0 KiB
8.0 KiB
Plan Global - Tests d'Intégration GroveEngine
🎯 Objectif
Implémenter une suite complète de tests d'intégration end-to-end pour valider la robustesse du système de hot-reload et de gestion de modules du GroveEngine.
Contraintes:
- ✅ 100% automatique (zéro interaction utilisateur)
- ✅ Reproductible (seed fixe pour aléatoire)
- ✅ Métriques automatiques (temps, mémoire, CPU)
- ✅ Pass/Fail clair (exit code 0/1)
- ✅ CI/CD ready
📋 Scénarios de Test (Priorité)
Phase 1: MUST HAVE (~2-3 jours)
| Scénario | Description | Durée | Criticité |
|---|---|---|---|
| 1. Production Hot-Reload | Hot-reload avec state complexe en conditions réelles | ~30s | ⭐⭐⭐ |
| 2. Chaos Monkey | Failures aléatoires (crashes, corruptions) | ~5min | ⭐⭐⭐ |
| 3. Stress Test | Long-running avec reloads répétés | ~10min | ⭐⭐⭐ |
Phase 2: SHOULD HAVE (~1-2 jours)
| Scénario | Description | Durée | Criticité |
|---|---|---|---|
| 4. Race Condition Hunter | Compilation concurrente + reload | ~10min | ⭐⭐ |
| 5. Multi-Module Orchestration | Interactions entre modules | ~1min | ⭐⭐ |
Phase 3: NICE TO HAVE (~1 jour)
| Scénario | Description | Durée | Criticité |
|---|---|---|---|
| 6. Error Recovery | Crash detection + auto-recovery | ~2min | ⭐ |
| 7. Limite Tests | Large state, long init, timeouts | ~3min | ⭐ |
| 8. Config Hot-Reload | Changement config à la volée | ~1min | ⭐ |
🏗️ Architecture des Tests
Structure de Fichiers
tests/
├─ integration/
│ ├─ test_01_production_hotreload.cpp
│ ├─ test_02_chaos_monkey.cpp
│ ├─ test_03_stress_test.cpp
│ ├─ test_04_race_condition.cpp
│ ├─ test_05_multimodule.cpp
│ ├─ test_06_error_recovery.cpp
│ ├─ test_07_limits.cpp
│ └─ test_08_config_hotreload.cpp
│
├─ modules/
│ ├─ TankModule.cpp # Module réaliste avec state complexe
│ ├─ ProductionModule.cpp # Auto-spawn entities
│ ├─ MapModule.cpp # Gestion carte/terrain
│ ├─ CrashModule.cpp # Crash contrôlé pour tests
│ └─ HeavyStateModule.cpp # State 100MB
│
└─ helpers/
├─ TestMetrics.h/.cpp # Collecte métriques (memory, CPU, FPS)
├─ TestAssertions.h # Macros ASSERT_*
├─ AutoCompiler.h/.cpp # Trigger compilation automatique
└─ TestReporter.h/.cpp # Génération rapports pass/fail
Composants Communs
1. TestMetrics
class TestMetrics {
public:
void recordReloadTime(float ms);
void recordMemoryUsage(size_t bytes);
void recordFPS(float fps);
void recordCrash(const std::string& reason);
// Rapport final
void printReport();
bool meetsThresholds(const Thresholds& t);
};
2. TestAssertions
#define ASSERT_TRUE(cond, msg)
#define ASSERT_EQ(actual, expected)
#define ASSERT_WITHIN(actual, expected, tolerance)
#define ASSERT_LT(value, max)
#define ASSERT_GT(value, min)
3. AutoCompiler
class AutoCompiler {
public:
void compileModuleAsync(const std::string& moduleName);
void compileModuleSync(const std::string& moduleName);
bool isCompiling() const;
void waitForCompletion();
};
4. TestReporter
class TestReporter {
public:
void setScenarioName(const std::string& name);
void addMetric(const std::string& key, float value);
void addAssertion(const std::string& name, bool passed);
void printFinalReport();
int getExitCode(); // 0 = pass, 1 = fail
};
📊 Métriques Collectées
Toutes les Tests
- ✅ Temps de reload (avg, min, max, p99)
- ✅ Memory usage (initial, final, growth, peak)
- ✅ FPS (min, avg, max, stddev)
- ✅ Nombre de crashes (expected vs unexpected)
- ✅ File descriptors (détection leaks)
Spécifiques
- Chaos Monkey: Taux de recovery (%)
- Stress Test: Durée totale exécution
- Race Condition: Taux de succès compilation (%)
- Multi-Module: Temps isolation (impact reload d'un module sur autres)
🎯 Seuils de Succès (Thresholds)
Production Hot-Reload
reload_time_avg: < 500ms
reload_time_max: < 1000ms
memory_growth: < 5MB
fps_min: > 30
state_preservation: 100%
Chaos Monkey
engine_alive: true
memory_growth: < 10MB
recovery_rate: > 95%
no_deadlocks: true
Stress Test
duration: 10 minutes
reload_count: ~120 (toutes les 5s)
memory_growth: < 20MB
reload_time_p99: < 1000ms
fd_leaks: 0
Race Condition
compilation_cycles: 1000
crash_count: 0
corrupted_loads: 0
reload_success_rate: > 99%
Multi-Module
isolated_reload: true (autres modules non affectés)
execution_order_preserved: true
state_sync: 100%
🚀 Plan d'Exécution
Semaine 1: Fondations + Phase 1
Jour 1-2:
- Créer architecture helpers (TestMetrics, Assertions, etc.)
- Implémenter TankModule (module réaliste)
- Scénario 1: Production Hot-Reload
Jour 3:
- Scénario 2: Chaos Monkey
Jour 4:
- Scénario 3: Stress Test
Jour 5:
- Tests + corrections Phase 1
Semaine 2: Phase 2 + Phase 3
Jour 6-7:
- Scénario 4: Race Condition Hunter
- Scénario 5: Multi-Module Orchestration
Jour 8-9:
- Scénarios 6, 7, 8 (error recovery, limites, config)
Jour 10:
- Documentation finale
- CI/CD integration (GitHub Actions)
📝 Format des Rapports
Exemple de sortie attendue
================================================================================
TEST: Production Hot-Reload
================================================================================
Setup:
- Module: TankModule
- Entities: 50 tanks
- Duration: 30 seconds
- Reload trigger: After 15s
Metrics:
✓ Reload time: 487ms (threshold: < 1000ms)
✓ Memory growth: 2.3MB (threshold: < 5MB)
✓ FPS min: 58 (threshold: > 30)
✓ FPS avg: 60
✓ State preservation: 50/50 tanks (100%)
Assertions:
✓ All tanks present after reload
✓ Positions preserved (error < 0.01)
✓ Velocities preserved
✓ No crashes
Result: ✅ PASSED
================================================================================
🔧 Commandes d'Exécution
Compilation
cd build
cmake -DBUILD_INTEGRATION_TESTS=ON ..
cmake --build . --target integration_tests
Exécution
# Tous les tests
ctest --output-on-failure
# Test individuel
./test_01_production_hotreload
./test_02_chaos_monkey --duration 300 # 5 minutes
# Avec verbosité
./test_03_stress_test --verbose
# CI mode (pas de couleurs)
./test_04_race_condition --ci
Analyse
# Génération rapport JSON
./test_01_production_hotreload --output report.json
# Agrégation tous les rapports
python3 scripts/aggregate_test_reports.py
📌 Notes Importantes
- Seeds fixes: Tous les tests avec aléatoire utilisent un seed fixe (reproductibilité)
- Timeouts: Chaque test a un timeout max (évite tests infinis)
- Cleanup: Tous les tests nettoient leurs ressources (fichiers temporaires, etc.)
- Isolation: Chaque test peut tourner indépendamment
- Logs: Niveau de log configurable (DEBUG pour dev, ERROR pour CI)
📚 Détails par Scénario
Pour les détails complets de chaque scénario, voir:
scenario_01_production_hotreload.mdscenario_02_chaos_monkey.mdscenario_03_stress_test.mdscenario_04_race_condition.mdscenario_05_multimodule.mdscenario_06_error_recovery.md(Phase 3)scenario_07_limits.md(Phase 3)scenario_08_config_hotreload.md(Phase 3)
Dernière mise à jour: 2025-11-13 Statut: Planning phase