From 15ebf375ef0022804368e1de07bffc7bda582d9e Mon Sep 17 00:00:00 2001 From: Latent Prion Date: Sat, 11 Jul 2026 22:03:19 -0400 Subject: [PATCH] spinscale: split probe harness from test support. Move ProbeComponentThreadHarness into spinscale_probe_support (sscl::probe) so tools can link it without gtest; keep a sscl::tests compatibility shim. Co-authored-by: Cursor --- CMakeLists.txt | 15 ++++ probe/CMakeLists.txt | 11 +++ .../probeComponentThread.cpp | 6 +- probe/probeComponentThread.h | 71 +++++++++++++++++++ tests/CMakeLists.txt | 2 +- tests/support/probeComponentThread.h | 64 +++-------------- 6 files changed, 110 insertions(+), 59 deletions(-) create mode 100644 probe/CMakeLists.txt rename {tests/support => probe}/probeComponentThread.cpp (96%) create mode 100644 probe/probeComponentThread.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e502e9..5561b0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,21 @@ endif() option(LIBSPINSCALE_BUILD_TESTS "Build libspinscale unit tests" ${_libspinscaleTestsDefault}) +option(LIBSPINSCALE_BUILD_PROBE_SUPPORT + "Build spinscale probe component-thread harness (tools and tests)" + OFF) + +# Tests always need the probe harness; tools may request it via cache/root. +if(LIBSPINSCALE_BUILD_TESTS) + set(LIBSPINSCALE_BUILD_PROBE_SUPPORT ON CACHE BOOL + "Build spinscale probe component-thread harness (tools and tests)" + FORCE) +endif() + +if(LIBSPINSCALE_BUILD_PROBE_SUPPORT) + add_subdirectory(probe) +endif() + if(LIBSPINSCALE_BUILD_TESTS) if(NOT TARGET gtest AND NOT TARGET gtest_main) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) diff --git a/probe/CMakeLists.txt b/probe/CMakeLists.txt new file mode 100644 index 0000000..0b20732 --- /dev/null +++ b/probe/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(spinscale_probe_support STATIC + probeComponentThread.cpp +) + +target_include_directories(spinscale_probe_support PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/.. +) + +target_link_libraries(spinscale_probe_support PUBLIC + spinscale +) diff --git a/tests/support/probeComponentThread.cpp b/probe/probeComponentThread.cpp similarity index 96% rename from tests/support/probeComponentThread.cpp rename to probe/probeComponentThread.cpp index a48c514..3487f44 100644 --- a/tests/support/probeComponentThread.cpp +++ b/probe/probeComponentThread.cpp @@ -1,10 +1,10 @@ -#include +#include #include #include -namespace sscl::tests { +namespace sscl::probe { namespace { @@ -115,4 +115,4 @@ void runNonViralNurseryOnComponentThread( nursery.syncAwaitAllSettlements(componentThread->getIoContext()); } -} // namespace sscl::tests +} // namespace sscl::probe diff --git a/probe/probeComponentThread.h b/probe/probeComponentThread.h new file mode 100644 index 0000000..4efed28 --- /dev/null +++ b/probe/probeComponentThread.h @@ -0,0 +1,71 @@ +#ifndef SPINSCALE_PROBE_COMPONENT_THREAD_H +#define SPINSCALE_PROBE_COMPONENT_THREAD_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace sscl::probe { + +constexpr std::chrono::milliseconds defaultProbeTaskTimeout{10000}; + +void runNonViralNurseryOnComponentThread( + const std::shared_ptr& componentThread, + std::function invokerFactory, + std::chrono::milliseconds timeout = defaultProbeTaskTimeout); + +/** Sync driver: run work on a temporary puppeteer ComponentThread. + * + * Shared by lcameraDev probe tools and HIL/unit tests. Not tied to gtest. + */ +class ProbeComponentThreadHarness +{ +public: + explicit ProbeComponentThreadHarness( + const char *threadName = "spinscale-probe"); + ~ProbeComponentThreadHarness(); + + ProbeComponentThreadHarness(const ProbeComponentThreadHarness &) = delete; + ProbeComponentThreadHarness &operator=( + const ProbeComponentThreadHarness &) = delete; + + std::shared_ptr componentThread() const; + + void runSync( + const std::function&)>& work); + + template + void runNonViralNurseryTask( + InvokerFactory &&invokerFactory, + std::chrono::milliseconds timeout = defaultProbeTaskTimeout) + { + runSync( + [this, &invokerFactory, timeout]( + const std::shared_ptr& componentThread) + { + sscl::probe::runNonViralNurseryOnComponentThread( + componentThread, + std::forward(invokerFactory), + timeout); + }); + } + +private: + std::string threadName; + std::shared_ptr dummyComponent; + std::shared_ptr lastComponentThread; +}; + +} // namespace sscl::probe + +#endif // SPINSCALE_PROBE_COMPONENT_THREAD_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a4869b7..4126572 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,5 @@ add_library(spinscale_test_support STATIC support/threadHarness.cpp - support/probeComponentThread.cpp ) target_include_directories(spinscale_test_support PUBLIC @@ -10,6 +9,7 @@ target_include_directories(spinscale_test_support PUBLIC target_link_libraries(spinscale_test_support PUBLIC spinscale + spinscale_probe_support gtest ) diff --git a/tests/support/probeComponentThread.h b/tests/support/probeComponentThread.h index cabc9d5..4598afb 100644 --- a/tests/support/probeComponentThread.h +++ b/tests/support/probeComponentThread.h @@ -1,65 +1,19 @@ #ifndef SPINSCALE_TEST_SUPPORT_PROBE_COMPONENT_THREAD_H #define SPINSCALE_TEST_SUPPORT_PROBE_COMPONENT_THREAD_H -#include -#include -#include -#include -#include -#include +/** EXPLANATION: + * Compatibility shim: probe harness lives in spinscale_probe_support under + * sscl::probe. Test code may keep including this path and using sscl::tests + * names; tools should include directly. + */ -#include -#include -#include +#include namespace sscl::tests { -constexpr std::chrono::milliseconds defaultProbeTaskTimeout{10000}; - -void runNonViralNurseryOnComponentThread( - const std::shared_ptr& componentThread, - std::function invokerFactory, - std::chrono::milliseconds timeout = defaultProbeTaskTimeout); - -class ProbeComponentThreadHarness -{ -public: - explicit ProbeComponentThreadHarness( - const char *threadName = "spinscale-probe"); - ~ProbeComponentThreadHarness(); - - ProbeComponentThreadHarness(const ProbeComponentThreadHarness &) = delete; - ProbeComponentThreadHarness &operator=( - const ProbeComponentThreadHarness &) = delete; - - std::shared_ptr componentThread() const; - - void runSync( - const std::function&)>& work); - - template - void runNonViralNurseryTask( - InvokerFactory &&invokerFactory, - std::chrono::milliseconds timeout = defaultProbeTaskTimeout) - { - runSync( - [this, &invokerFactory, timeout]( - const std::shared_ptr& componentThread) - { - sscl::tests::runNonViralNurseryOnComponentThread( - componentThread, - std::forward(invokerFactory), - timeout); - }); - } - -private: - std::string threadName; - std::shared_ptr dummyComponent; - std::shared_ptr lastComponentThread; -}; +using sscl::probe::defaultProbeTaskTimeout; +using sscl::probe::runNonViralNurseryOnComponentThread; +using sscl::probe::ProbeComponentThreadHarness; } // namespace sscl::tests