hive-agent: compact tests set the harness dir like the other Bus tests
The two report_compact tests build a Bus, which resolves the events db under HYPERHIVE_HARNESS_DIR and panics when it is unset, as in the nix test sandbox. Add a test-only paths::with_harness_dir that points the variable at a temp dir under a lock, and use it in both the new tests and the existing swarm_inference Bus test, which set the variable unguarded.
This commit is contained in:
parent
2c4a3c2fa7
commit
3c03d82858
3 changed files with 69 additions and 37 deletions
|
|
@ -131,3 +131,38 @@ pub fn claude_dir() -> PathBuf {
|
||||||
}
|
}
|
||||||
PathBuf::from("/root/.claude")
|
PathBuf::from("/root/.claude")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run `f` with `HYPERHIVE_HARNESS_DIR` pointing at a fresh temp dir, then
|
||||||
|
/// restore the previous value. Tests that build a `Bus` or read the harness
|
||||||
|
/// state files go through this: the variable is process-wide, so the calls
|
||||||
|
/// are serialised on a lock.
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn with_harness_dir<T>(f: impl FnOnce() -> T) -> T {
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
static LOCK: Mutex<()> = Mutex::new(());
|
||||||
|
|
||||||
|
struct Restore(Option<OsString>);
|
||||||
|
impl Drop for Restore {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// SAFETY: still holding `LOCK`, the only writer of this variable.
|
||||||
|
unsafe {
|
||||||
|
match self.0.take() {
|
||||||
|
Some(v) => std::env::set_var("HYPERHIVE_HARNESS_DIR", v),
|
||||||
|
None => std::env::remove_var("HYPERHIVE_HARNESS_DIR"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _lock = LOCK
|
||||||
|
.lock()
|
||||||
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
// Declared after `_lock` so the variable is restored before the lock drops.
|
||||||
|
let _restore = Restore(std::env::var_os("HYPERHIVE_HARNESS_DIR"));
|
||||||
|
// SAFETY: serialised by `LOCK`.
|
||||||
|
unsafe { std::env::set_var("HYPERHIVE_HARNESS_DIR", dir.path()) };
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -320,34 +320,29 @@ mod tests {
|
||||||
/// persisted files, so clearing it, or a restart, finds the local value.
|
/// persisted files, so clearing it, or a restart, finds the local value.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_swarm_value_is_not_persisted_over_the_local_one() {
|
fn the_swarm_value_is_not_persisted_over_the_local_one() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let (swarm, swarm_sources, files, cleared, cleared_sources) =
|
||||||
let prev = std::env::var_os("HYPERHIVE_HARNESS_DIR");
|
crate::paths::with_harness_dir(|| {
|
||||||
// SAFETY: no other test in this crate reads or sets this variable.
|
let bus = Bus::new();
|
||||||
unsafe { std::env::set_var("HYPERHIVE_HARNESS_DIR", dir.path()) };
|
bus.set_model("sonnet");
|
||||||
let bus = Bus::new();
|
bus.set_effort("low");
|
||||||
bus.set_model("sonnet");
|
let target = Harness {
|
||||||
bus.set_effort("low");
|
bus: bus.clone(),
|
||||||
let target = Harness {
|
nix_model: None,
|
||||||
bus: bus.clone(),
|
nix_effort: None,
|
||||||
nix_model: None,
|
};
|
||||||
nix_effort: None,
|
let mut o = Overridden::default();
|
||||||
};
|
o.apply(&set(Some("opus"), Some(Effort::Max)), &target);
|
||||||
let mut o = Overridden::default();
|
let swarm = (bus.model(), bus.effort());
|
||||||
o.apply(&set(Some("opus"), Some(Effort::Max)), &target);
|
let swarm_sources = (bus.model_source(), bus.effort_source());
|
||||||
let swarm = (bus.model(), bus.effort());
|
let files = (
|
||||||
let swarm_sources = (bus.model_source(), bus.effort_source());
|
crate::harness_state::load_model(),
|
||||||
let files = (
|
crate::harness_state::load_effort(),
|
||||||
crate::harness_state::load_model(),
|
);
|
||||||
crate::harness_state::load_effort(),
|
o.apply(&AgentInference::default(), &target);
|
||||||
);
|
let cleared = (bus.model(), bus.effort());
|
||||||
o.apply(&AgentInference::default(), &target);
|
let cleared_sources = (bus.model_source(), bus.effort_source());
|
||||||
let cleared = (bus.model(), bus.effort());
|
(swarm, swarm_sources, files, cleared, cleared_sources)
|
||||||
let cleared_sources = (bus.model_source(), bus.effort_source());
|
});
|
||||||
match prev {
|
|
||||||
// SAFETY: as above.
|
|
||||||
Some(v) => unsafe { std::env::set_var("HYPERHIVE_HARNESS_DIR", v) },
|
|
||||||
None => unsafe { std::env::remove_var("HYPERHIVE_HARNESS_DIR") },
|
|
||||||
}
|
|
||||||
assert_eq!(swarm, pair("opus", "max"));
|
assert_eq!(swarm, pair("opus", "max"));
|
||||||
assert_eq!(files, (Some("sonnet".to_owned()), Some("low".to_owned())));
|
assert_eq!(files, (Some("sonnet".to_owned()), Some("low".to_owned())));
|
||||||
assert_eq!(cleared, pair("sonnet", "low"));
|
assert_eq!(cleared, pair("sonnet", "low"));
|
||||||
|
|
|
||||||
|
|
@ -983,16 +983,18 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compact_report(result: Result<(), &str>) -> (bool, Vec<String>) {
|
fn compact_report(result: Result<(), &str>) -> (bool, Vec<String>) {
|
||||||
let bus = Bus::new();
|
crate::paths::with_harness_dir(|| {
|
||||||
let mut rx = bus.subscribe();
|
let bus = Bus::new();
|
||||||
let ok = report_compact(&bus, result);
|
let mut rx = bus.subscribe();
|
||||||
let mut notes = Vec::new();
|
let ok = report_compact(&bus, result);
|
||||||
while let Ok(ev) = rx.try_recv() {
|
let mut notes = Vec::new();
|
||||||
if let LiveEvent::Note { text } = ev.event {
|
while let Ok(ev) = rx.try_recv() {
|
||||||
notes.push(text);
|
if let LiveEvent::Note { text } = ev.event {
|
||||||
|
notes.push(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
(ok, notes)
|
||||||
(ok, notes)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue