The three values that differ per host (deploy.hive-controller.dashboardPort, claudeCodePackage and otel.extraResourceAttributes) no longer go into the meta flake. hive-priv writes them into the container's /etc/hyperhive-hive-facts with the hive name and domain, and the agent reads them at boot: - HIVE_DASHBOARD_PORT reaches every unit through the hive-facts generator; the web UI still defaults to 7000 without it. - `claude` on PATH is a wrapper that runs HYPERHIVE_CLAUDE_CODE_PATH's claude when it is there, and the container's own claude-code otherwise. The host's serve.json keeps gc-rooting the pinned build. - OTEL_RESOURCE_ATTRIBUTES moves out of the units' Environment= into a boot-time generator, which appends HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES. The agent options services.hyperhive.agent.claudeCodePath (now a removed option) and otel.extraResourceAttributes go; only the meta render set them. render_flake takes no HiveEnv any more, so the memory-cap render test and render_hive_flake_at, which only existed to vary HiveEnv into the render, go with it. Refs #4857
39 lines
2.1 KiB
Rust
39 lines
2.1 KiB
Rust
//! Test-only: the crate's single lock for tests that mutate process
|
|
//! environment variables.
|
|
//!
|
|
//! Environment variables are one process-global, and every `#[test]` in this
|
|
//! crate lands in the *same* test binary, run on parallel threads. A test that
|
|
//! sets a variable, asserts, then restores it is only safe against a *concurrent*
|
|
//! test if both take the same lock — so any test here that touches the
|
|
//! environment must route through [`lock`] rather than rolling its own
|
|
//! save/restore.
|
|
//!
|
|
//! ⚠️ **The lock has to be crate-wide, not per-module.** `hive-bash-mcp`'s
|
|
//! sibling helper records why: two separate per-module mutexes serialise
|
|
//! nothing against each other, and that produced a CI-only flake. The pair that
|
|
//! motivated this one is `meta::tests` (which renders a flake with
|
|
//! `HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES` set) and `stats::otel_metrics::tests` (which asserts which
|
|
//! variable enables the exporter) — different modules, same process env, same
|
|
//! binary.
|
|
//!
|
|
//! ⚠️ **A green local run is weak evidence for this class.** An agent container
|
|
//! has the hyperhive variables ambient-set, so a losing race still finds a
|
|
//! plausible value; the nix sandbox strips them, so there the race can delete a
|
|
//! variable out from under another thread. Reproduce the sandbox shape with
|
|
//! `env -u OTEL_EXPORTER_OTLP_ENDPOINT cargo test -p hive-c0re`.
|
|
|
|
use std::sync::{Mutex, MutexGuard, PoisonError};
|
|
|
|
static ENV_LOCK: Mutex<()> = Mutex::new(());
|
|
|
|
/// Serialise this test against every other environment-mutating test in the
|
|
/// crate. Hold the returned guard for as long as the variables are perturbed —
|
|
/// bind it (`let _env = lock();`), never discard it with `let _ = lock();`,
|
|
/// which drops the guard immediately and serialises nothing.
|
|
///
|
|
/// Recovers from poisoning: a test that panicked mid-mutation has already
|
|
/// failed and reported, and refusing to run every later test on top of that
|
|
/// turns one failure into a cascade that hides which test actually broke.
|
|
pub fn lock() -> MutexGuard<'static, ()> {
|
|
ENV_LOCK.lock().unwrap_or_else(PoisonError::into_inner)
|
|
}
|