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 <cursoragent@cursor.com>
This commit is contained in:
2026-07-11 22:03:19 -04:00
co-authored by Cursor
parent 7c9bec7b9c
commit 15ebf375ef
6 changed files with 110 additions and 59 deletions
+15
View File
@@ -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)
+11
View File
@@ -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
)
@@ -1,10 +1,10 @@
#include <support/probeComponentThread.h>
#include <probe/probeComponentThread.h>
#include <iostream>
#include <spinscale/component.h>
namespace sscl::tests {
namespace sscl::probe {
namespace {
@@ -115,4 +115,4 @@ void runNonViralNurseryOnComponentThread(
nursery.syncAwaitAllSettlements(componentThread->getIoContext());
}
} // namespace sscl::tests
} // namespace sscl::probe
+71
View File
@@ -0,0 +1,71 @@
#ifndef SPINSCALE_PROBE_COMPONENT_THREAD_H
#define SPINSCALE_PROBE_COMPONENT_THREAD_H
#include <chrono>
#include <exception>
#include <functional>
#include <future>
#include <memory>
#include <stdexcept>
#include <string>
#include <spinscale/componentThread.h>
#include <spinscale/co/invokers.h>
#include <spinscale/co/nonViralTaskNursery.h>
namespace sscl::probe {
constexpr std::chrono::milliseconds defaultProbeTaskTimeout{10000};
void runNonViralNurseryOnComponentThread(
const std::shared_ptr<sscl::ComponentThread>& componentThread,
std::function<sscl::co::NonViralNonPostingInvoker(
sscl::co::NonViralTaskNursery::Slot::Lease&)> 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<sscl::ComponentThread> componentThread() const;
void runSync(
const std::function<void(
const std::shared_ptr<sscl::ComponentThread>&)>& work);
template <typename InvokerFactory>
void runNonViralNurseryTask(
InvokerFactory &&invokerFactory,
std::chrono::milliseconds timeout = defaultProbeTaskTimeout)
{
runSync(
[this, &invokerFactory, timeout](
const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
sscl::probe::runNonViralNurseryOnComponentThread(
componentThread,
std::forward<InvokerFactory>(invokerFactory),
timeout);
});
}
private:
std::string threadName;
std::shared_ptr<sscl::pptr::PuppeteerComponent> dummyComponent;
std::shared_ptr<sscl::ComponentThread> lastComponentThread;
};
} // namespace sscl::probe
#endif // SPINSCALE_PROBE_COMPONENT_THREAD_H
+1 -1
View File
@@ -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
)
+9 -55
View File
@@ -1,65 +1,19 @@
#ifndef SPINSCALE_TEST_SUPPORT_PROBE_COMPONENT_THREAD_H
#define SPINSCALE_TEST_SUPPORT_PROBE_COMPONENT_THREAD_H
#include <chrono>
#include <exception>
#include <functional>
#include <future>
#include <memory>
#include <stdexcept>
/** 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 <probe/probeComponentThread.h> directly.
*/
#include <spinscale/componentThread.h>
#include <spinscale/co/invokers.h>
#include <spinscale/co/nonViralTaskNursery.h>
#include <probe/probeComponentThread.h>
namespace sscl::tests {
constexpr std::chrono::milliseconds defaultProbeTaskTimeout{10000};
void runNonViralNurseryOnComponentThread(
const std::shared_ptr<sscl::ComponentThread>& componentThread,
std::function<sscl::co::NonViralNonPostingInvoker(
sscl::co::NonViralTaskNursery::Slot::Lease&)> 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<sscl::ComponentThread> componentThread() const;
void runSync(
const std::function<void(
const std::shared_ptr<sscl::ComponentThread>&)>& work);
template <typename InvokerFactory>
void runNonViralNurseryTask(
InvokerFactory &&invokerFactory,
std::chrono::milliseconds timeout = defaultProbeTaskTimeout)
{
runSync(
[this, &invokerFactory, timeout](
const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
sscl::tests::runNonViralNurseryOnComponentThread(
componentThread,
std::forward<InvokerFactory>(invokerFactory),
timeout);
});
}
private:
std::string threadName;
std::shared_ptr<sscl::pptr::PuppeteerComponent> dummyComponent;
std::shared_ptr<sscl::ComponentThread> lastComponentThread;
};
using sscl::probe::defaultProbeTaskTimeout;
using sscl::probe::runNonViralNurseryOnComponentThread;
using sscl::probe::ProbeComponentThreadHarness;
} // namespace sscl::tests