Add comprehensive concurrent compilation and hot-reload testing infrastructure
to validate thread safety and file stability during race conditions.
## New Components
### AutoCompiler Helper (tests/helpers/AutoCompiler.{h,cpp})
- Automatically modifies source files to bump version numbers
- Compiles modules repeatedly on separate thread (15 iterations @ 1s interval)
- Tracks compilation success/failure rates with atomic counters
- Thread-safe compilation statistics
### Race Condition Test (tests/integration/test_04_race_condition.cpp)
- **3 concurrent threads:**
- Compiler: Recompiles TestModule.so every 1 second
- FileWatcher: Detects .so changes and triggers hot-reload with mutex protection
- Engine: Runs at 60 FPS with try_lock to skip frames during reload
- Validates module integrity (health status, version, configuration)
- Tracks metrics: compilation rate, reload success, corrupted loads, crashes
- 90-second timeout with progress monitoring
### TestModule Enhancements (tests/modules/TestModule.cpp)
- Added global moduleVersion variable for AutoCompiler modification
- Version bumping support for reload validation
## Test Results (Initial Implementation)
```
Duration: 88s
Compilations: 15/15 (100%) ✅
Reloads: ~30 (100% success) ✅
Corrupted: 0 ✅
Crashes: 0 ✅
File Stability: 328ms avg (proves >100ms wait) ✅
```
## Known Issue (To Fix in Next Commit)
- Module versions not actually changing during reload
- setConfiguration() overwrites compiled version
- Reload mechanism validated but version bumping needs fix
## Files Modified
- tests/CMakeLists.txt: Add AutoCompiler to helpers, add test_04
- tests/modules/TestModule.cpp: Add version bumping support
- .gitignore: Add build/ and logs/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
183 lines
4.8 KiB
CMake
183 lines
4.8 KiB
CMake
# Hot-reload test suite
|
|
|
|
# Test module as shared library (.so) for hot-reload
|
|
add_library(TestModule SHARED
|
|
modules/TestModule.cpp
|
|
)
|
|
|
|
target_link_libraries(TestModule PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl # For JsonDataNode implementation
|
|
)
|
|
|
|
# Don't add "lib" prefix on Linux (we want TestModule.so, not libTestModule.so)
|
|
set_target_properties(TestModule PROPERTIES PREFIX "lib")
|
|
set_target_properties(TestModule PROPERTIES OUTPUT_NAME "TestModule")
|
|
|
|
# Basic hot-reload test executable (manual dlopen/dlclose)
|
|
add_executable(test_hotreload
|
|
hotreload/test_hotreload.cpp
|
|
)
|
|
|
|
target_link_libraries(test_hotreload PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl # For JsonDataNode implementation
|
|
${CMAKE_DL_LIBS} # For dlopen/dlclose
|
|
)
|
|
|
|
# Make sure test module is built before test executable
|
|
add_dependencies(test_hotreload TestModule)
|
|
|
|
# Copy test module to test executable directory after build
|
|
add_custom_command(TARGET test_hotreload POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy
|
|
$<TARGET_FILE:TestModule>
|
|
$<TARGET_FILE_DIR:test_hotreload>/
|
|
COMMENT "Copying TestModule.so to test directory"
|
|
)
|
|
|
|
# Engine hot-reload test (uses DebugEngine + SequentialModuleSystem + FileWatcher)
|
|
add_executable(test_engine_hotreload
|
|
hotreload/test_engine_hotreload.cpp
|
|
)
|
|
|
|
target_link_libraries(test_engine_hotreload PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
${CMAKE_DL_LIBS}
|
|
)
|
|
|
|
add_dependencies(test_engine_hotreload TestModule)
|
|
|
|
add_custom_command(TARGET test_engine_hotreload POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy
|
|
$<TARGET_FILE:TestModule>
|
|
$<TARGET_FILE_DIR:test_engine_hotreload>/
|
|
COMMENT "Copying TestModule.so to engine test directory"
|
|
)
|
|
|
|
# ================================================================================
|
|
# Integration Tests
|
|
# ================================================================================
|
|
|
|
# Helpers library (partagée par tous les tests)
|
|
add_library(test_helpers STATIC
|
|
helpers/TestMetrics.cpp
|
|
helpers/TestReporter.cpp
|
|
helpers/SystemUtils.cpp
|
|
helpers/AutoCompiler.cpp
|
|
)
|
|
|
|
target_include_directories(test_helpers PUBLIC
|
|
${CMAKE_CURRENT_SOURCE_DIR}
|
|
)
|
|
|
|
target_link_libraries(test_helpers PUBLIC
|
|
GroveEngine::core
|
|
spdlog::spdlog
|
|
)
|
|
|
|
# Set PIC for static library
|
|
set_target_properties(test_helpers PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
|
|
|
# TankModule pour tests d'intégration
|
|
add_library(TankModule SHARED
|
|
modules/TankModule.cpp
|
|
)
|
|
|
|
target_link_libraries(TankModule PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
spdlog::spdlog
|
|
)
|
|
|
|
# Ensure spdlog is compiled with PIC
|
|
set_target_properties(spdlog PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
|
|
|
# Test 01: Production Hot-Reload
|
|
add_executable(test_01_production_hotreload
|
|
integration/test_01_production_hotreload.cpp
|
|
)
|
|
|
|
target_link_libraries(test_01_production_hotreload PRIVATE
|
|
test_helpers
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
)
|
|
|
|
add_dependencies(test_01_production_hotreload TankModule)
|
|
|
|
# CTest integration
|
|
add_test(NAME ProductionHotReload COMMAND test_01_production_hotreload)
|
|
|
|
# ChaosModule pour tests de robustesse
|
|
add_library(ChaosModule SHARED
|
|
modules/ChaosModule.cpp
|
|
)
|
|
|
|
target_link_libraries(ChaosModule PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
spdlog::spdlog
|
|
)
|
|
|
|
# Test 02: Chaos Monkey
|
|
add_executable(test_02_chaos_monkey
|
|
integration/test_02_chaos_monkey.cpp
|
|
)
|
|
|
|
target_link_libraries(test_02_chaos_monkey PRIVATE
|
|
test_helpers
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
)
|
|
|
|
add_dependencies(test_02_chaos_monkey ChaosModule)
|
|
|
|
# CTest integration
|
|
add_test(NAME ChaosMonkey COMMAND test_02_chaos_monkey)
|
|
|
|
# StressModule pour tests de stabilité long-terme
|
|
add_library(StressModule SHARED
|
|
modules/StressModule.cpp
|
|
)
|
|
|
|
target_link_libraries(StressModule PRIVATE
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
spdlog::spdlog
|
|
)
|
|
|
|
# Test 03: Stress Test - 10 minutes stability
|
|
add_executable(test_03_stress_test
|
|
integration/test_03_stress_test.cpp
|
|
)
|
|
|
|
target_link_libraries(test_03_stress_test PRIVATE
|
|
test_helpers
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
)
|
|
|
|
add_dependencies(test_03_stress_test StressModule)
|
|
|
|
# CTest integration
|
|
add_test(NAME StressTest COMMAND test_03_stress_test)
|
|
|
|
# Test 04: Race Condition Hunter - Concurrent compilation & reload
|
|
add_executable(test_04_race_condition
|
|
integration/test_04_race_condition.cpp
|
|
)
|
|
|
|
target_link_libraries(test_04_race_condition PRIVATE
|
|
test_helpers
|
|
GroveEngine::core
|
|
GroveEngine::impl
|
|
)
|
|
|
|
# This test uses TestModule (not TankModule)
|
|
add_dependencies(test_04_race_condition TestModule)
|
|
|
|
# CTest integration
|
|
add_test(NAME RaceConditionHunter COMMAND test_04_race_condition)
|