yams/tests/unit/daemon/tune_advisor_threshold_test.cpp
Trevon 0dd3985db4
refactor: simplify runtime paths and harden retrieval (#61)
* refactor(tuning): prune dormant runtime knobs

Remove unused tuning controls and adaptive search budget state. Extract testable ONNX slot reconciliation and search telemetry hydration seams, and correct the Apple Silicon sysctl value width.

* refactor(vector): retire dormant backends

Remove unused FAISS, model-infrastructure, VectorIndexManager, and TurboQuant paths while keeping Simeon PQ and float-vector storage.

Migrate unused V2.2 quantized schemas transactionally to V2.3. Databases containing non-default quantized formats or packed-code blobs fail closed with recovery guidance and no mutation.

* refactor(plugins): remove legacy SDK tooling

Remove the Ghidra and SDK submodules, their bespoke tests, and stale scan exclusions. Retain generic PluginProcess coverage against the repository mock fixture.

* build(vector): remove stale FAISS overrides

* refactor(ipc): remove dormant FSM snapshots

* refactor(ingest): unify bounded KG enqueue

* fix(plugins): harden allocation contracts

Keep ABI outputs null or fully initialized when allocations fail, and represent empty object payloads without relying on malloc(0).

* fix(storage): define empty object reads

Return a null buffer with zero length for successful empty-object reads instead of treating malloc(0) as an allocation contract.

* refactor(storage): trim through string views

* test: prune dormant harness helpers

Remove unused readiness and fixture helpers, and keep benchmark client-count doubling in a wide integer domain.

* chore(cpp): initialize analyzer-facing locals

* build(simeon): advance analyzer cleanup

* refactor(config): drop dead daemon client keys

* refactor(ipc): inject daemon client transport

Socket and in-process execution now share DaemonClient request dispatch, so CLI fallbacks do not need alternate service paths.

* refactor(retrieval): route CLI through daemon

Search and grep now use the same daemon handlers over socket or in-process transport. Live grep remains an explicit freshness inspection.

* refactor(graph): move CLI scope into daemon

Graph CLI requests now share daemon handlers across socket and in-process transports. CWD filtering occurs before pagination so scoped totals and pages stay correct.

* build: isolate test-only runtime controls

* refactor(metadata): decouple lock telemetry

* fix(services): return on request timeout

* fix(retrieval): enforce workspace scope

* fix(graph): scope nodes before pagination

* fix(grep): drop binary result lines

* fix(daemon): bound checkpoint wait

* fix(repair): use KG health checks

* fix(storage): always verify compressed CRC

* perf(vector): skip unchanged PQ snapshots

* build(zyp): exclude bench from default build

* build: protect Meson files from formatter

* refactor: remove unreachable production APIs

* refactor(daemon): remove dormant runtime state

* fix(vector): harden daemon provider calls

Timed-out coroutines must own their client and requests. Provider discovery must also fail instead of returning synthetic embeddings in production.

* refactor(storage): remove unusable adapters

* fix(cli): unify in-process add requests

* fix(tsan): preserve async worker progress

* test(cli): isolate daemon-dependent suites

* fix(repair): expose queue backoff progress
2026-07-31 14:16:45 -04:00

1004 lines
39 KiB
C++

// TuneAdvisor model eviction threshold tests (Catch2)
// Tests profile defaults, env var overrides, programmatic setters, and validation
#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>
#include <yams/daemon/components/TuneAdvisor.h>
#include <yams/daemon/resource/gpu_info.h>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <string>
#include "../../common/env_compat.h"
#include "../../common/test_helpers_catch2.h"
#include <yams/compat/unistd.h>
using namespace yams::daemon;
// =============================================================================
// Test Helpers
// =============================================================================
namespace {
/// RAII guard for TuneAdvisor profile restoration
class ProfileGuard {
TuneAdvisor::Profile prev_;
public:
explicit ProfileGuard(TuneAdvisor::Profile profile) : prev_(TuneAdvisor::tuningProfile()) {
TuneAdvisor::setTuningProfile(profile);
}
~ProfileGuard() { TuneAdvisor::setTuningProfile(prev_); }
ProfileGuard(const ProfileGuard&) = delete;
ProfileGuard& operator=(const ProfileGuard&) = delete;
};
using yams::test::ScopedEnvVar;
class HardwareGuard {
unsigned prev_;
public:
explicit HardwareGuard(unsigned hw) : prev_(TuneAdvisor::hardwareConcurrency()) {
TuneAdvisor::setHardwareConcurrencyForTests(hw);
}
~HardwareGuard() { TuneAdvisor::setHardwareConcurrencyForTests(prev_); }
HardwareGuard(const HardwareGuard&) = delete;
HardwareGuard& operator=(const HardwareGuard&) = delete;
};
/// Reset all eviction threshold overrides to default (unset)
void resetEvictionOverrides() {
TuneAdvisor::resetModelEvictThresholdOverrides();
}
} // namespace
// =============================================================================
// Profile Default Tests
// =============================================================================
TEST_CASE("Model eviction threshold profile defaults", "[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
SECTION("Efficient profile thresholds") {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.30));
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.50));
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.70));
}
SECTION("Balanced profile thresholds") {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.75));
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.90));
}
SECTION("Aggressive profile thresholds") {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.75));
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.85));
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.95));
}
}
// =============================================================================
// Environment Variable Override Tests
// =============================================================================
TEST_CASE("Model eviction threshold env var overrides", "[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
ProfileGuard profileGuard(TuneAdvisor::Profile::Balanced);
SECTION("Valid warning threshold env var overrides profile default") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "0.45");
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.45));
}
SECTION("Valid critical threshold env var overrides profile default") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_CRITICAL_THRESHOLD", "0.80");
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.80));
}
SECTION("Valid emergency threshold env var overrides profile default") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_EMERGENCY_THRESHOLD", "0.92");
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.92));
}
SECTION("Invalid env var (non-numeric) falls back to profile default") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "invalid");
// Should return profile default (0.60 for Balanced), not crash
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
}
SECTION("Env var exactly 1.0 is rejected (must be < 1.0)") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "1.0");
// 1.0 should be rejected, falls back to profile default
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
}
SECTION("Env var exactly 0.0 is rejected (must be > 0.0)") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "0.0");
// 0.0 should be rejected, falls back to profile default
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
}
SECTION("Negative env var is rejected") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "-0.5");
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
}
SECTION("Env var > 1.0 is rejected") {
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "1.5");
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.60));
}
}
// =============================================================================
// Programmatic Setter Tests
// =============================================================================
TEST_CASE("Model eviction threshold setter validation", "[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
ProfileGuard profileGuard(TuneAdvisor::Profile::Balanced);
SECTION("Valid values are accepted") {
TuneAdvisor::setModelEvictWarningThreshold(0.5);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.5));
TuneAdvisor::setModelEvictCriticalThreshold(0.7);
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.7));
TuneAdvisor::setModelEvictEmergencyThreshold(0.85);
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.85));
}
SECTION("Boundary values near 0 and 1 are handled correctly") {
// Just above 0 should be accepted
TuneAdvisor::setModelEvictWarningThreshold(0.001);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.001));
// Just below 1 should be accepted
TuneAdvisor::setModelEvictCriticalThreshold(0.999);
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.999));
}
SECTION("Negative values are rejected") {
double prev = TuneAdvisor::modelEvictWarningThreshold();
TuneAdvisor::setModelEvictWarningThreshold(-0.5);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(prev));
}
SECTION("Zero is rejected") {
double prev = TuneAdvisor::modelEvictCriticalThreshold();
TuneAdvisor::setModelEvictCriticalThreshold(0.0);
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(prev));
}
SECTION("Values >= 1.0 are rejected") {
double prev = TuneAdvisor::modelEvictEmergencyThreshold();
TuneAdvisor::setModelEvictEmergencyThreshold(1.0);
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(prev));
TuneAdvisor::setModelEvictEmergencyThreshold(1.5);
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(prev));
TuneAdvisor::setModelEvictEmergencyThreshold(100.0);
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(prev));
}
SECTION("NaN is rejected") {
double prev = TuneAdvisor::modelEvictWarningThreshold();
TuneAdvisor::setModelEvictWarningThreshold(std::numeric_limits<double>::quiet_NaN());
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(prev));
}
SECTION("Positive infinity is rejected") {
double prev = TuneAdvisor::modelEvictCriticalThreshold();
TuneAdvisor::setModelEvictCriticalThreshold(std::numeric_limits<double>::infinity());
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(prev));
}
SECTION("Negative infinity is rejected") {
double prev = TuneAdvisor::modelEvictEmergencyThreshold();
TuneAdvisor::setModelEvictEmergencyThreshold(-std::numeric_limits<double>::infinity());
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(prev));
}
}
// =============================================================================
// Override Precedence Tests
// =============================================================================
TEST_CASE("Model eviction threshold override precedence", "[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
SECTION("Programmatic setter takes precedence over env var") {
ProfileGuard profileGuard(TuneAdvisor::Profile::Balanced);
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_WARNING_THRESHOLD", "0.45");
// Env var would give 0.45, but setter should override
TuneAdvisor::setModelEvictWarningThreshold(0.55);
CHECK(TuneAdvisor::modelEvictWarningThreshold() == Catch::Approx(0.55));
}
SECTION("Env var takes precedence over profile default") {
ProfileGuard profileGuard(TuneAdvisor::Profile::Efficient);
ScopedEnvVar envGuard("YAMS_MODEL_EVICT_CRITICAL_THRESHOLD", "0.65");
// Efficient profile default is 0.50, but env var overrides to 0.65
CHECK(TuneAdvisor::modelEvictCriticalThreshold() == Catch::Approx(0.65));
}
SECTION("Profile default is used when no overrides set") {
ProfileGuard profileGuard(TuneAdvisor::Profile::Aggressive);
CHECK(TuneAdvisor::modelEvictEmergencyThreshold() == Catch::Approx(0.95));
}
}
TEST_CASE("Governor warning scale percent tuning", "[daemon][tune][advisor][catch2]") {
TuneAdvisor::resetGovernorWarningScalePercentOverride();
SECTION("Default value is 85 percent") {
CHECK(TuneAdvisor::governorWarningScalePercent() == 85u);
}
SECTION("Valid env var overrides default") {
ScopedEnvVar envGuard("YAMS_GOV_WARNING_SCALE_PCT", "92");
CHECK(TuneAdvisor::governorWarningScalePercent() == 92u);
}
SECTION("Invalid env var falls back to default") {
ScopedEnvVar envGuard("YAMS_GOV_WARNING_SCALE_PCT", "invalid");
CHECK(TuneAdvisor::governorWarningScalePercent() == 85u);
}
SECTION("Out-of-range env var falls back to default") {
ScopedEnvVar envGuard("YAMS_GOV_WARNING_SCALE_PCT", "9");
CHECK(TuneAdvisor::governorWarningScalePercent() == 85u);
}
SECTION("Programmatic setter overrides env var") {
ScopedEnvVar envGuard("YAMS_GOV_WARNING_SCALE_PCT", "90");
TuneAdvisor::setGovernorWarningScalePercent(77u);
CHECK(TuneAdvisor::governorWarningScalePercent() == 77u);
}
SECTION("Setter clamps values into allowed range") {
TuneAdvisor::setGovernorWarningScalePercent(5u);
CHECK(TuneAdvisor::governorWarningScalePercent() == 10u);
TuneAdvisor::setGovernorWarningScalePercent(150u);
CHECK(TuneAdvisor::governorWarningScalePercent() == 100u);
}
SECTION("Setter zero resets override") {
TuneAdvisor::setGovernorWarningScalePercent(72u);
CHECK(TuneAdvisor::governorWarningScalePercent() == 72u);
TuneAdvisor::setGovernorWarningScalePercent(0u);
CHECK(TuneAdvisor::governorWarningScalePercent() == 85u);
}
TuneAdvisor::resetGovernorWarningScalePercentOverride();
}
TEST_CASE("Connection lifetime seconds env var", "[daemon][tune][advisor][catch2]") {
TuneAdvisor::resetConnectionLifetimeSecondsOverride();
SECTION("Default value is 300 seconds") {
CHECK(TuneAdvisor::connectionLifetimeSeconds() == 300);
}
SECTION("Valid env var overrides default") {
ScopedEnvVar envGuard("YAMS_CONNECTION_LIFETIME_S", "1800");
CHECK(TuneAdvisor::connectionLifetimeSeconds() == 1800);
}
SECTION("Zero env var disables lifetime enforcement") {
ScopedEnvVar envGuard("YAMS_CONNECTION_LIFETIME_S", "0");
CHECK(TuneAdvisor::connectionLifetimeSeconds() == 0);
}
SECTION("Out-of-range env var falls back to default") {
ScopedEnvVar envGuard("YAMS_CONNECTION_LIFETIME_S", "90000");
CHECK(TuneAdvisor::connectionLifetimeSeconds() == 300);
}
SECTION("Programmatic setter overrides env") {
ScopedEnvVar envGuard("YAMS_CONNECTION_LIFETIME_S", "1800");
TuneAdvisor::setConnectionLifetimeSeconds(42);
CHECK(TuneAdvisor::connectionLifetimeSeconds() == 42);
TuneAdvisor::resetConnectionLifetimeSecondsOverride();
}
TuneAdvisor::resetConnectionLifetimeSecondsOverride();
}
// =============================================================================
// Threshold Ordering Invariant Tests
// =============================================================================
TEST_CASE("Threshold ordering invariant: warning < critical < emergency",
"[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
SECTION("Efficient profile maintains ordering") {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
CHECK(TuneAdvisor::modelEvictWarningThreshold() <
TuneAdvisor::modelEvictCriticalThreshold());
CHECK(TuneAdvisor::modelEvictCriticalThreshold() <
TuneAdvisor::modelEvictEmergencyThreshold());
}
SECTION("Balanced profile maintains ordering") {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
CHECK(TuneAdvisor::modelEvictWarningThreshold() <
TuneAdvisor::modelEvictCriticalThreshold());
CHECK(TuneAdvisor::modelEvictCriticalThreshold() <
TuneAdvisor::modelEvictEmergencyThreshold());
}
SECTION("Aggressive profile maintains ordering") {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
CHECK(TuneAdvisor::modelEvictWarningThreshold() <
TuneAdvisor::modelEvictCriticalThreshold());
CHECK(TuneAdvisor::modelEvictCriticalThreshold() <
TuneAdvisor::modelEvictEmergencyThreshold());
}
}
// =============================================================================
// Repair Batch Size Profile Tests
// =============================================================================
TEST_CASE("Repair batch sizes are profile-aware", "[daemon][tune][advisor][catch2]") {
SECTION("Efficient profile uses smaller batch sizes") {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
// Efficient profile scale is 0.0
// repairMaxBatch: 8 + 24*0.0 = 8
// repairStartupBatchSize: 25 + 75*0.0 = 25
CHECK(TuneAdvisor::repairMaxBatch() == 8u);
CHECK(TuneAdvisor::repairStartupBatchSize() == 25u);
}
SECTION("Balanced profile uses default batch sizes") {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
// Balanced profile scale is 0.5
// repairMaxBatch: 8 + 24*0.5 = 20
// repairStartupBatchSize: 25 + 75*0.5 = 62
CHECK(TuneAdvisor::repairMaxBatch() == 20u);
CHECK(TuneAdvisor::repairStartupBatchSize() == 62u);
}
SECTION("Aggressive profile uses larger batch sizes") {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
// Aggressive profile scale is 1.0
// repairMaxBatch: 8 + 24*1.0 = 32
// repairStartupBatchSize: 25 + 75*1.0 = 100
CHECK(TuneAdvisor::repairMaxBatch() == 32u);
CHECK(TuneAdvisor::repairStartupBatchSize() == 100u);
}
}
TEST_CASE("Repair batch size env var overrides", "[daemon][tune][advisor][catch2]") {
ProfileGuard profileGuard(TuneAdvisor::Profile::Balanced);
SECTION("YAMS_REPAIR_MAX_BATCH env var overrides profile") {
ScopedEnvVar envGuard("YAMS_REPAIR_MAX_BATCH", "64");
CHECK(TuneAdvisor::repairMaxBatch() == 64u);
}
SECTION("YAMS_REPAIR_STARTUP_BATCH env var overrides profile") {
ScopedEnvVar envGuard("YAMS_REPAIR_STARTUP_BATCH", "200");
CHECK(TuneAdvisor::repairStartupBatchSize() == 200u);
}
SECTION("Invalid env var falls back to profile default") {
ScopedEnvVar envGuard("YAMS_REPAIR_MAX_BATCH", "invalid");
// Should fall back to profile default (20 for Balanced at 0.5 scale)
CHECK(TuneAdvisor::repairMaxBatch() == 20u);
}
SECTION("Zero env var falls back to profile default") {
ScopedEnvVar envGuard("YAMS_REPAIR_MAX_BATCH", "0");
// 0 is rejected, should fall back to profile default
CHECK(TuneAdvisor::repairMaxBatch() == 20u);
}
SECTION("Env var > 1000 falls back to profile default") {
ScopedEnvVar envGuard("YAMS_REPAIR_MAX_BATCH", "1001");
// > 1000 is rejected, should fall back to profile default
CHECK(TuneAdvisor::repairMaxBatch() == 20u);
}
}
TEST_CASE("Embed doc cap resolves to safe default when unset",
"[daemon][tune][advisor][embed][catch2]") {
struct EmbedCapGuard {
std::size_t prev{TuneAdvisor::getEmbedDocCap()};
~EmbedCapGuard() { TuneAdvisor::setEmbedDocCap(prev); }
} guard;
SECTION("Unset cap uses built-in default (no singleton fallback)") {
// Ensure no explicit override is active.
TuneAdvisor::setEmbedDocCap(0);
// Invalid env value should be ignored and still resolve to default.
ScopedEnvVar envGuard("YAMS_EMBED_DOC_CAP", "0");
CHECK(TuneAdvisor::getEmbedDocCap() == 0u);
CHECK(TuneAdvisor::resolvedEmbedDocCap() == TuneAdvisor::kDefaultEmbedDocCap);
CHECK(TuneAdvisor::resolvedEmbedDocCap() == 64u);
}
SECTION("Explicit cap overrides default") {
TuneAdvisor::setEmbedDocCap(128);
CHECK(TuneAdvisor::resolvedEmbedDocCap() == 128u);
}
}
// =============================================================================
// Worker poll cadence overrides
// =============================================================================
TEST_CASE("Worker poll cadence overrides", "[daemon][tune][advisor][catch2]") {
SECTION("Dynamic updates apply when not pinned") {
ScopedEnvVar envGuard("YAMS_WORKER_POLL_MS", "0");
TuneAdvisor::setWorkerPollMs(0);
TuneAdvisor::setWorkerPollMsDynamic(200);
CHECK(TuneAdvisor::workerPollMs() == 200u);
TuneAdvisor::setWorkerPollMs(0);
TuneAdvisor::setWorkerPollMsDynamic(120);
CHECK(TuneAdvisor::workerPollMs() == 120u);
}
SECTION("Dynamic updates ignored when pinned by setter") {
ScopedEnvVar envGuard("YAMS_WORKER_POLL_MS", "0");
TuneAdvisor::setWorkerPollMs(250);
CHECK(TuneAdvisor::workerPollMs() == 250u);
TuneAdvisor::setWorkerPollMsDynamic(100);
CHECK(TuneAdvisor::workerPollMs() == 250u);
TuneAdvisor::setWorkerPollMs(0);
}
SECTION("Dynamic updates ignored when env pins cadence") {
ScopedEnvVar envGuard("YAMS_WORKER_POLL_MS", "300");
TuneAdvisor::setWorkerPollMs(0);
TuneAdvisor::setWorkerPollMsDynamic(100);
CHECK(TuneAdvisor::workerPollMs() == 300u);
}
}
TEST_CASE("Model maintenance thresholds use bounded environment overrides",
"[daemon][tune][advisor][catch2]") {
ProfileGuard profile(TuneAdvisor::Profile::Balanced);
ScopedEnvVar connectionThreshold("YAMS_MODEL_MAINT_CONN_THRESHOLD", "17");
ScopedEnvVar searchThreshold("YAMS_MODEL_MAINT_SEARCH_THRESHOLD", "19");
ScopedEnvVar queueThreshold("YAMS_MODEL_MAINT_QUEUE_THRESHOLD", "23");
CHECK(TuneAdvisor::modelMaintenanceConnThreshold() == 17);
CHECK(TuneAdvisor::modelMaintenanceSearchThreshold() == 19);
CHECK(TuneAdvisor::modelMaintenanceQueueThreshold() == 23);
connectionThreshold.set("101");
searchThreshold.set("101");
queueThreshold.set("10001");
CHECK(TuneAdvisor::modelMaintenanceConnThreshold() == 1);
CHECK(TuneAdvisor::modelMaintenanceSearchThreshold() == 1);
CHECK(TuneAdvisor::modelMaintenanceQueueThreshold() == 10);
}
TEST_CASE("Default-enabled tuning flags use explicit boolean overrides",
"[daemon][tune][advisor][catch2]") {
ScopedEnvVar proactiveEviction("YAMS_PROACTIVE_EVICTION", "off");
ScopedEnvVar semanticBackfill("YAMS_ENABLE_SEMANTIC_NEIGHBOR_BACKFILL", "no");
ScopedEnvVar gradientLimiters("YAMS_ENABLE_GRADIENT_LIMITERS", "false");
CHECK_FALSE(TuneAdvisor::enableProactiveEviction());
CHECK_FALSE(TuneAdvisor::enableSemanticNeighborBackfill());
CHECK_FALSE(TuneAdvisor::enableGradientLimiters());
proactiveEviction.set("invalid");
semanticBackfill.set("invalid");
gradientLimiters.set("invalid");
CHECK(TuneAdvisor::enableProactiveEviction());
CHECK(TuneAdvisor::enableSemanticNeighborBackfill());
CHECK(TuneAdvisor::enableGradientLimiters());
}
// =============================================================================
// GPU Detection Tests (Apple Silicon sysctl path)
// =============================================================================
TEST_CASE("detectGpu returns consistent cached result", "[daemon][gpu][catch2]") {
using namespace yams::daemon::resource;
const auto& first = detectGpu();
const auto& second = detectGpu();
// std::call_once caching: same static object returned each time
CHECK(&first == &second);
// Basic structural sanity: fields are default-initialized or populated
CHECK(first.detected == second.detected);
CHECK(first.name == second.name);
CHECK(first.vramBytes == second.vramBytes);
CHECK(first.provider == second.provider);
CHECK(first.unifiedMemory == second.unifiedMemory);
}
TEST_CASE("effectiveGpuBatchBudgetBytes applies unified-memory safety defaults",
"[daemon][gpu][batch-budget][catch2]") {
using namespace yams::daemon::resource;
constexpr uint64_t GiB = 1024ULL * 1024ULL * 1024ULL;
SECTION("Dedicated memory uses full detected budget by default") {
ScopedEnvVar clear1("YAMS_GPU_BATCH_BUDGET_MB", "");
ScopedEnvVar clear2("YAMS_GPU_UNIFIED_BUDGET_MB", "");
ScopedEnvVar clear3("YAMS_GPU_UNIFIED_BUDGET_FRACTION", "");
GpuInfo gpu;
gpu.detected = true;
gpu.unifiedMemory = false;
gpu.provider = "migraphx";
gpu.vramBytes = 12ULL * GiB;
CHECK(effectiveGpuBatchBudgetBytes(gpu) == 12ULL * GiB);
}
SECTION("Unified memory defaults to conservative 4 GiB cap") {
ScopedEnvVar clear1("YAMS_GPU_BATCH_BUDGET_MB", "");
ScopedEnvVar clear2("YAMS_GPU_UNIFIED_BUDGET_MB", "");
ScopedEnvVar clear3("YAMS_GPU_UNIFIED_BUDGET_FRACTION", "");
GpuInfo gpu;
gpu.detected = true;
gpu.unifiedMemory = true;
gpu.provider = "coreml";
gpu.vramBytes = 24ULL * GiB;
CHECK(effectiveGpuBatchBudgetBytes(gpu) == 4ULL * GiB);
}
SECTION("Unified memory MB override is honored") {
ScopedEnvVar clear1("YAMS_GPU_BATCH_BUDGET_MB", "");
ScopedEnvVar envMb("YAMS_GPU_UNIFIED_BUDGET_MB", "6144");
ScopedEnvVar clear3("YAMS_GPU_UNIFIED_BUDGET_FRACTION", "");
GpuInfo gpu;
gpu.detected = true;
gpu.unifiedMemory = true;
gpu.provider = "coreml";
gpu.vramBytes = 24ULL * GiB;
CHECK(effectiveGpuBatchBudgetBytes(gpu) == 6ULL * GiB);
}
SECTION("Global budget override takes precedence") {
ScopedEnvVar envGlobal("YAMS_GPU_BATCH_BUDGET_MB", "2048");
ScopedEnvVar envMb("YAMS_GPU_UNIFIED_BUDGET_MB", "6144");
ScopedEnvVar envFrac("YAMS_GPU_UNIFIED_BUDGET_FRACTION", "0.5");
GpuInfo gpu;
gpu.detected = true;
gpu.unifiedMemory = true;
gpu.provider = "coreml";
gpu.vramBytes = 24ULL * GiB;
CHECK(effectiveGpuBatchBudgetBytes(gpu) == 2ULL * GiB);
}
}
#if defined(__APPLE__) && defined(__aarch64__)
TEST_CASE("detectAppleSiliconGpu populates all fields", "[daemon][gpu][catch2]") {
using namespace yams::daemon::resource;
GpuInfo info;
bool result = detail::detectAppleSiliconGpu(info);
CHECK(result == true);
CHECK(info.detected == true);
CHECK(info.provider == "coreml");
CHECK(info.unifiedMemory == true);
// Brand string should contain "Apple" (e.g. "Apple M3 Max")
CHECK(info.name.find("Apple") != std::string::npos);
// VRAM should be populated
CHECK(info.vramBytes > 0);
// Cross-check: read hw.memsize via sysctl, verify vramBytes ≈ 75% of memsize
uint64_t memsize = 0;
size_t len = sizeof(memsize);
REQUIRE(detail::sysctlbyname("hw.memsize", &memsize, &len, nullptr, 0) == 0);
REQUIRE(memsize > 0);
uint64_t expected = static_cast<uint64_t>(static_cast<double>(memsize) * 0.75);
double ratio = static_cast<double>(info.vramBytes) / static_cast<double>(expected);
CHECK(ratio == Catch::Approx(1.0).margin(0.01));
// Sanity bounds: > 1 GB and < 1 TB
constexpr uint64_t oneGB = 1024ULL * 1024ULL * 1024ULL;
constexpr uint64_t oneTB = 1024ULL * oneGB;
CHECK(info.vramBytes > oneGB);
CHECK(info.vramBytes < oneTB);
}
#endif // __APPLE__ && __aarch64__
#if defined(__APPLE__)
TEST_CASE("sysctlString returns values for valid keys", "[daemon][gpu][catch2]") {
using namespace yams::daemon::resource::detail;
CHECK_FALSE(sysctlString("hw.machine").empty());
CHECK_FALSE(sysctlString("machdep.cpu.brand_string").empty());
// Invalid key should return empty gracefully (no crash)
CHECK(sysctlString("totally.invalid.key.xyz").empty());
}
#endif // __APPLE__
#if defined(__APPLE__) && !defined(__aarch64__)
TEST_CASE("detectAppleSiliconGpu returns false on non-ARM64", "[daemon][gpu][catch2]") {
using namespace yams::daemon::resource;
GpuInfo info;
bool result = detail::detectAppleSiliconGpu(info);
CHECK(result == false);
CHECK(info.detected == false);
}
#endif // __APPLE__ && !__aarch64__
// =============================================================================
// PostIngestQueue Profile-Aware Concurrency Tests
// =============================================================================
TEST_CASE("PostIngestQueue methods are profile-aware", "[daemon][tune][advisor][catch2]") {
resetEvictionOverrides();
auto setHardwareConcurrency = [](unsigned value) {
yams::daemon::TuneAdvisor::setHardwareConcurrencyForTests(value);
};
SECTION("Efficient profile uses 0.0 scaling") {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
ScopedEnvVar maxThreadsGuard("YAMS_MAX_THREADS", "0");
ScopedEnvVar postIngestGuard("YAMS_POST_INGEST_TOTAL_CONCURRENT", "0");
setHardwareConcurrency(8);
// With hw=8, all 6 stages active: totalBudget = max(formula, 6) = 6.
// Each stage gets exactly 1 slot (budget distributed evenly).
CHECK(TuneAdvisor::postExtractionConcurrent() == 1u);
CHECK(TuneAdvisor::postKgConcurrent() == 1u);
CHECK(TuneAdvisor::postSymbolConcurrent() == 1u);
CHECK(TuneAdvisor::postEntityConcurrent() == 1u);
CHECK(TuneAdvisor::postTitleConcurrent() == 1u);
CHECK(TuneAdvisor::postEmbedConcurrent() == 1u);
}
SECTION("Balanced profile uses 0.5 scaling") {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
ScopedEnvVar maxThreadsGuard("YAMS_MAX_THREADS", "0");
ScopedEnvVar postIngestGuard("YAMS_POST_INGEST_TOTAL_CONCURRENT", "0");
setHardwareConcurrency(8);
// With hw=8, all 6 stages active: totalBudget = max(3, 6) = 6.
// Each stage gets exactly 1 slot.
CHECK(TuneAdvisor::postExtractionConcurrent() == 1u);
CHECK(TuneAdvisor::postKgConcurrent() == 1u);
CHECK(TuneAdvisor::postSymbolConcurrent() == 1u);
CHECK(TuneAdvisor::postEntityConcurrent() == 1u);
CHECK(TuneAdvisor::postTitleConcurrent() == 1u);
CHECK(TuneAdvisor::postEmbedConcurrent() == 1u);
}
SECTION("Aggressive profile uses 1.0x (defaults)") {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
ScopedEnvVar maxThreadsGuard("YAMS_MAX_THREADS", "0");
ScopedEnvVar postIngestGuard("YAMS_POST_INGEST_TOTAL_CONCURRENT", "0");
setHardwareConcurrency(8);
// With hw=8, round-up division: base=max(2,2)=2, scaleRange=max(1,2)=2.
// total=2+2=4. But 6 active stages, total=max(4,6)=6. Each gets 1.
CHECK(TuneAdvisor::postExtractionConcurrent() == 1u);
CHECK(TuneAdvisor::postKgConcurrent() == 1u);
CHECK(TuneAdvisor::postSymbolConcurrent() == 1u);
CHECK(TuneAdvisor::postEntityConcurrent() == 1u);
CHECK(TuneAdvisor::postTitleConcurrent() == 1u);
CHECK(TuneAdvisor::postEmbedConcurrent() == 1u);
}
}
// =============================================================================
// statusTickMs Default and Override Tests
// =============================================================================
TEST_CASE("statusTickMs defaults to 5", "[daemon][governance][catch2]") {
CHECK(TuneAdvisor::statusTickMs() == 5);
}
TEST_CASE("statusTickMs remains fixed at 5ms", "[daemon][governance][catch2]") {
CHECK(TuneAdvisor::statusTickMs() == 5);
}
TEST_CASE("Thread reserve is profile-aware", "[daemon][governance][catch2]") {
for (unsigned hw : {8u, 16u}) {
const auto effReserve = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::testing_reservedHostThreads(hw);
}();
const auto balReserve = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::testing_reservedHostThreads(hw);
}();
const auto aggReserve = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::testing_reservedHostThreads(hw);
}();
INFO("hw=" << hw << " eff=" << effReserve << " bal=" << balReserve
<< " agg=" << aggReserve);
CHECK(effReserve >= balReserve);
CHECK(balReserve >= aggReserve);
CHECK(effReserve < hw);
CHECK(aggReserve < hw);
}
}
TEST_CASE("recommendedThreads remains profile-aware while leaving host headroom",
"[daemon][governance][catch2]") {
ScopedEnvVar maxThreadsGuard("YAMS_MAX_THREADS", "0");
HardwareGuard hwGuard(16);
const auto effThreads = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::recommendedThreads(1.0);
}();
const auto balThreads = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::recommendedThreads(1.0);
}();
const auto aggThreads = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::recommendedThreads(1.0);
}();
INFO("eff=" << effThreads << " bal=" << balThreads << " agg=" << aggThreads);
CHECK(effThreads <= balThreads);
CHECK(balThreads <= aggThreads);
CHECK(aggThreads < 16u);
CHECK(effThreads >= 1u);
}
TEST_CASE("Auto memory budget is profile-aware", "[daemon][governance][catch2]") {
constexpr uint64_t kSystemMem = 8ull * 1024ull * 1024ull * 1024ull;
const auto effBudget = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::testing_autoMemoryBudgetBytes(kSystemMem);
}();
const auto balBudget = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::testing_autoMemoryBudgetBytes(kSystemMem);
}();
const auto aggBudget = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::testing_autoMemoryBudgetBytes(kSystemMem);
}();
INFO("eff=" << effBudget << " bal=" << balBudget << " agg=" << aggBudget);
CHECK(effBudget < balBudget);
CHECK(balBudget < aggBudget);
CHECK(aggBudget < kSystemMem);
CHECK(effBudget == (kSystemMem * 45ull) / 100ull);
CHECK(balBudget == (kSystemMem * 60ull) / 100ull);
CHECK(aggBudget == (kSystemMem * 75ull) / 100ull);
}
TEST_CASE("WorkCoordinator defaults are io-biased", "[daemon][governance][catch2]") {
ScopedEnvVar workThreadsGuard("YAMS_WORK_COORDINATOR_THREADS", "0");
HardwareGuard hwGuard(16);
const auto efficientWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::workCoordinatorThreads();
}();
const auto balancedWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::workCoordinatorThreads();
}();
const auto aggressiveWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::workCoordinatorThreads();
}();
const auto efficientExpectedWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return std::max(4u, TuneAdvisor::recommendedThreads(1.0));
}();
const auto balancedExpectedWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return std::max(4u, TuneAdvisor::recommendedThreads(1.5));
}();
const auto aggressiveExpectedWorkers = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return std::max(4u, TuneAdvisor::recommendedThreads(1.75));
}();
CHECK(efficientWorkers == efficientExpectedWorkers);
CHECK(balancedWorkers == balancedExpectedWorkers);
CHECK(aggressiveWorkers == aggressiveExpectedWorkers);
CHECK(efficientWorkers <= balancedWorkers);
CHECK(balancedWorkers <= aggressiveWorkers);
}
TEST_CASE("Search concurrency limit has a balanced floor", "[daemon][governance][catch2]") {
ScopedEnvVar searchOverrideGuard("YAMS_SEARCH_MAX_CONCURRENT", "0");
HardwareGuard hwGuard(10);
const auto efficientLimit = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::searchConcurrencyLimit();
}();
const auto balancedLimit = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::searchConcurrencyLimit();
}();
const auto aggressiveLimit = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::searchConcurrencyLimit();
}();
const auto efficientExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return std::max<uint32_t>(2, TuneAdvisor::recommendedThreads(0.5)) * 2;
}();
const auto balancedExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return std::max<uint32_t>(5u,
std::max<uint32_t>(2, TuneAdvisor::recommendedThreads(0.5)) * 2);
}();
const auto aggressiveExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return std::max<uint32_t>(6u,
std::max<uint32_t>(2, TuneAdvisor::recommendedThreads(0.5)) * 2);
}();
CHECK(efficientLimit == efficientExpected);
CHECK(balancedLimit == balancedExpected);
CHECK(aggressiveLimit == aggressiveExpected);
}
TEST_CASE("Read pool max connections follow centralized capacity model",
"[daemon][governance][catch2]") {
HardwareGuard hwGuard(16);
const auto efficientCap = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
return TuneAdvisor::readPoolMaxConnections(32);
}();
const auto balancedCap = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::readPoolMaxConnections(32);
}();
const auto aggressiveCap = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
return TuneAdvisor::readPoolMaxConnections(32);
}();
const auto efficientExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
const auto derived = std::max<uint32_t>({4u, TuneAdvisor::workCoordinatorThreads(),
TuneAdvisor::searchConcurrencyLimit(),
TuneAdvisor::listInflightLimit()});
return std::min<uint32_t>(8u, derived);
}();
const auto balancedExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
const auto derived = std::max<uint32_t>({4u, TuneAdvisor::workCoordinatorThreads(),
TuneAdvisor::searchConcurrencyLimit(),
TuneAdvisor::listInflightLimit()});
return std::min<uint32_t>(8u, derived);
}();
const auto aggressiveExpected = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
const auto derived = std::max<uint32_t>({4u, TuneAdvisor::workCoordinatorThreads(),
TuneAdvisor::searchConcurrencyLimit(),
TuneAdvisor::listInflightLimit()});
return std::min<uint32_t>(8u, derived);
}();
CHECK(efficientCap == efficientExpected);
CHECK(balancedCap == balancedExpected);
CHECK(aggressiveCap == aggressiveExpected);
const auto cappedConfiguredMax = [&]() {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
return TuneAdvisor::readPoolMaxConnections(6);
}();
CHECK(cappedConfiguredMax <= 6u);
CHECK(cappedConfiguredMax >= 1u);
}
// =============================================================================
// computeCpuThrottleDelayMs Tests
// =============================================================================
TEST_CASE("computeCpuThrottleDelayMs returns 0 below threshold", "[daemon][governance][catch2]") {
ProfileGuard guard(TuneAdvisor::Profile::Balanced);
// Balanced threshold = 50 + 0.5*35 = 67.5%
CHECK(TuneAdvisor::computeCpuThrottleDelayMs(60.0) == 0);
CHECK(TuneAdvisor::computeCpuThrottleDelayMs(0.0) == 0);
}
TEST_CASE("computeCpuThrottleDelayMs returns clamped delay above threshold",
"[daemon][governance][catch2]") {
ProfileGuard guard(TuneAdvisor::Profile::Aggressive);
// Aggressive threshold = 50 + 1.0*35 = 85%
double threshold = TuneAdvisor::cpuHighThresholdPercent();
int32_t delay = TuneAdvisor::computeCpuThrottleDelayMs(threshold + 10.0);
CHECK(delay >= 2);
CHECK(delay <= 25);
}
TEST_CASE("computeCpuThrottleDelayMs clamps to max 25ms", "[daemon][governance][catch2]") {
// Even at 100% CPU, delay should not exceed 25ms
int32_t delay = TuneAdvisor::computeCpuThrottleDelayMs(100.0);
CHECK(delay <= 25);
}
TEST_CASE("cpuHighThresholdPercent setter overrides profile and env",
"[daemon][governance][catch2]") {
TuneAdvisor::resetCpuHighThresholdPercentOverride();
SECTION("setter overrides profile default") {
ProfileGuard guard(TuneAdvisor::Profile::Efficient);
TuneAdvisor::setCpuHighThresholdPercent(72.0);
CHECK(TuneAdvisor::cpuHighThresholdPercent() == Catch::Approx(72.0));
TuneAdvisor::resetCpuHighThresholdPercentOverride();
}
SECTION("setter overrides env var") {
ScopedEnvVar envGuard("YAMS_CPU_HIGH_PCT", "55");
CHECK(TuneAdvisor::cpuHighThresholdPercent() == Catch::Approx(55.0));
TuneAdvisor::setCpuHighThresholdPercent(68.0);
CHECK(TuneAdvisor::cpuHighThresholdPercent() == Catch::Approx(68.0));
TuneAdvisor::resetCpuHighThresholdPercentOverride();
}
}