#include #include #include #include #include #include using namespace std::chrono_literals; TEST_CASE("DaemonClientPool pruning thread exits promptly on shutdown", "[cli][daemon][pool]") { yams::daemon::ClientConfig clientCfg; clientCfg.transportMode = yams::daemon::ClientTransportMode::InProcess; yams::cli::DaemonClientPool::Config poolCfg; poolCfg.min_clients = 1; poolCfg.max_clients = 1; poolCfg.idle_timeout = std::chrono::seconds(60); poolCfg.client_config = clientCfg; std::chrono::milliseconds worst{0}; for (int i = 0; i < 3; ++i) { auto pool = std::make_unique(poolCfg); // Let the pruning thread enter its wait state before destruction. std::this_thread::sleep_for(80ms); const auto start = std::chrono::steady_clock::now(); pool.reset(); const auto elapsed = std::chrono::duration_cast( std::chrono::steady_clock::now() - start); worst = std::max(worst, elapsed); } CHECK(worst < 1100ms); } TEST_CASE("is_transport_failure classifies 'Daemon not ready yet' as transport", "[cli][daemon][transport]") { using yams::Error; using yams::ErrorCode; yams::Error notReady{ErrorCode::InvalidState, "Daemon not ready yet for list (status=initializing)"}; CHECK(yams::cli::is_transport_failure(notReady)); yams::Error timeout{ErrorCode::Timeout, "deadline exceeded"}; CHECK(yams::cli::is_transport_failure(timeout)); yams::Error otherInvalid{ErrorCode::InvalidState, "unrelated invalid state"}; CHECK_FALSE(yams::cli::is_transport_failure(otherInvalid)); yams::Error notFound{ErrorCode::NotFound, "missing key"}; CHECK_FALSE(yams::cli::is_transport_failure(notFound)); }