test(daemon): add fake_dragonxd, a slow dragonxd stand-in for stop/kill testing
A scriptable fake dragonxd that reproduces, in minutes, the incident where the GUI hard-killed a node busy with an hour-long witness rebuild: - dragonxd's HTTP-RPC queue (8 workers + 16 queued, -rpcthreads / -rpcworkqueue honoured): a full queue answers an immediate plain-text 500 "Work queue depth exceeded", and a request whose client gave up keeps its slot until a worker reaches it - a global cs_main held by a "witness rebuild" that logs the real markers; every method except stop/help takes it - warmup -28 with the daemon's allow-list, an optional startup replay - dragonxd's shutdown order: stop (or SIGTERM on POSIX) unbinds RPC, 503s open connections, waits for the rebuild, then logs "Shutdown: In progress..." / "Shutdown: done" and exits 0 Everything is appended to <datadir>/fake_dragonxd.events; a missing "clean-exit" line means the process was killed. One portable C++17 file (POSIX + Winsock), OFF by default (-DDRAGONX_BUILD_FAKE_DAEMON=ON), built into <build>/fake_dragonxd/ so it can't shadow the real bin/dragonxd. run-gui-with-fake.sh runs the GUI against it in a throwaway HOME. Against master's GUI on Linux it reproduces the bug: closing during a rebuild queues stop behind cs_main-blocked workers, then the GUI sends SIGTERM and SIGKILL mid-rebuild, with no clean exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,7 @@ option(DRAGONX_ENABLE_EMBEDDED_DAEMON "Enable embedded dragonxd support" ON)
|
||||
option(DRAGONX_BUILD_LITE "Build ObsidianDragonLite variant without full-node features" OFF)
|
||||
option(DRAGONX_ENABLE_LITE_BACKEND "Enable real lite wallet backend integration" OFF)
|
||||
option(DRAGONX_ENABLE_CHAT "Enable the HushChat protocol/UI integration" ON)
|
||||
option(DRAGONX_BUILD_FAKE_DAEMON "Build the fake slow dragonxd test stub (tools/fake_dragonxd); never shipped" OFF)
|
||||
set(DRAGONX_LITE_BACKEND_LIBRARY "" CACHE FILEPATH "Path to a prebuilt SDXL-compatible lite backend library")
|
||||
set(DRAGONX_LITE_BACKEND_INCLUDE_DIR "" CACHE PATH "Optional include directory for SDXL-compatible lite backend headers")
|
||||
set(DRAGONX_LITE_BACKEND_EXTRA_LIBS "" CACHE STRING "Additional libraries needed by the SDXL-compatible lite backend")
|
||||
@@ -1105,6 +1106,27 @@ else()
|
||||
message(STATUS "wallet-rebuild helper: OFF (no Berkeley DB found; set DRAGONX_BDB_ROOT for release builds)")
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# fake_dragonxd — a deliberately slow, scriptable dragonxd stand-in that reproduces the daemon-stop
|
||||
# incident (usage and the incident it models: tools/fake_dragonxd/README.md).
|
||||
# Test tooling only: OFF by default, never packaged, and written to <build>/fake_dragonxd/ so its
|
||||
# "dragonxd" name can't shadow the real bin/dragonxd.
|
||||
# -----------------------------------------------------------------------------
|
||||
if(DRAGONX_BUILD_FAKE_DAEMON)
|
||||
add_executable(fake_dragonxd tools/fake_dragonxd/fake_dragonxd.cpp)
|
||||
target_link_libraries(fake_dragonxd PRIVATE nlohmann_json::nlohmann_json)
|
||||
if(WIN32)
|
||||
target_link_libraries(fake_dragonxd PRIVATE ws2_32)
|
||||
else()
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(fake_dragonxd PRIVATE Threads::Threads)
|
||||
endif()
|
||||
set_target_properties(fake_dragonxd PROPERTIES
|
||||
OUTPUT_NAME dragonxd
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/fake_dragonxd)
|
||||
message(STATUS "fake_dragonxd test stub: ON (${CMAKE_BINARY_DIR}/fake_dragonxd/)")
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Tests
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user