plugins/native/znippy-plugin-git/tests/twin_runtime_limits_env_wins.rs
//! **An explicit environment variable still wins over a code-set default.**
//!
//! The precedence rule [`znippy_plugin_git::arms::set_graph_cache_default`] already keeps, kept
//! by its four new siblings, asserted rather than assumed. It is not a detail: an operator who
//! types `ZNIPPY_GIT_EXPLODE=full` on a box that also calls `set_explode_default(Off)` must get
//! `full`, or the variable they set is a lie and the next measurement taken under it is wrong.
//!
//! A separate binary from `twin_runtime_limits.rs` because the resolver's two doors are read
//! **once per process**: this binary sets the variables before any of them is read, and that
//! one sets none at all. Neither can be folded into the other without the first read deciding
//! the answer for both.
use std::sync::atomic::AtomicBool;
use znippy_plugin_git::exploded_arrow::ExplodePolicy;
use znippy_plugin_git::resolve::ResolveLimits;
use znippy_plugin_git::{
ENV_EXPLODE, ENV_EXPLODE_BUDGET, ENV_GRAPH_CACHE, ENV_RESOLVE_LOOKAHEAD_BYTES,
ENV_RESOLVE_WORKERS, set_explode_budget_default, set_explode_default,
set_graph_cache_default, set_resolve_lookahead_default, set_resolve_workers_default,
};
/// What the operator typed…
const OP_WORKERS: usize = 7;
const OP_LOOKAHEAD: u64 = 99 << 20;
const OP_BUDGET: u64 = 5 << 20;
/// …against what the code asked for, which must lose every time.
const CODE_WORKERS: usize = 2;
const CODE_LOOKAHEAD: u64 = 16 << 20;
const CODE_BUDGET: u64 = 16 << 20;
/// The environment goes up once, before any door is read, and the code-set defaults go up with
/// it — every test below is the same question about a different key.
fn an_operator_and_an_embedder_disagree() {
static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| {
// SAFETY (edition 2024): set before the first thread of this test binary reads the
// environment, and no thread of this crate writes it.
unsafe {
std::env::set_var(ENV_RESOLVE_WORKERS, OP_WORKERS.to_string());
std::env::set_var(ENV_RESOLVE_LOOKAHEAD_BYTES, OP_LOOKAHEAD.to_string());
std::env::set_var(ENV_EXPLODE, "full");
std::env::set_var(ENV_EXPLODE_BUDGET, OP_BUDGET.to_string());
std::env::set_var(ENV_GRAPH_CACHE, "on");
}
set_explode_default(ExplodePolicy::Off);
set_explode_budget_default(Some(CODE_BUDGET));
set_resolve_workers_default(CODE_WORKERS);
set_resolve_lookahead_default(CODE_LOOKAHEAD);
set_graph_cache_default(false);
});
}
/// ★ **The resolver runs at the operator's width and lookahead, not the embedder's.**
#[test]
fn the_environment_beats_the_resolver_setters() {
an_operator_and_an_embedder_disagree();
let cancel = AtomicBool::new(false);
let progress = znippy_plugin_git::progress::IndexProgress::new("env-wins");
let dog = std::sync::Arc::new(znippy_plugin_git::memguard::MemWatchdog::from_env());
let spill = || 0u64;
let limits = ResolveLimits::for_indexer("env-wins", &cancel, &progress, dog, &spill);
assert_eq!(limits.workers, OP_WORKERS, "a set ZNIPPY_GIT_RESOLVE_WORKERS was overruled by code");
assert_eq!(
limits.lookahead_bytes, OP_LOOKAHEAD,
"a set ZNIPPY_GIT_RESOLVE_LOOKAHEAD_BYTES was overruled by code"
);
}
/// ★ **The explode policy and its budget answer to the variable too.**
#[test]
fn the_environment_beats_the_explode_setters() {
an_operator_and_an_embedder_disagree();
assert_eq!(
ExplodePolicy::from_env().unwrap(),
ExplodePolicy::Full,
"a set ZNIPPY_GIT_EXPLODE was overruled by set_explode_default"
);
assert_eq!(
znippy_plugin_git::exploded_cache::budget_from_env(&std::env::temp_dir()).unwrap(),
OP_BUDGET,
"a set ZNIPPY_GIT_EXPLODE_BUDGET was overruled by set_explode_budget_default"
);
}
/// ★ **And the door this crate already had keeps behaving the way the new ones copy** — the
/// rule is asserted on its source, so a change to it goes red here beside its siblings.
#[test]
fn the_environment_beats_the_graph_cache_setter() {
an_operator_and_an_embedder_disagree();
assert!(
znippy_plugin_git::arms::graph_cache_from_env().unwrap(),
"a set ZNIPPY_GIT_GRAPH_CACHE was overruled by set_graph_cache_default"
);
}