use std::path::Path;
pub(crate) struct BaseDirGuard {
old: Option<std::ffi::OsString>,
_dir: tempfile::TempDir,
}
impl BaseDirGuard {
pub(crate) fn new() -> Self {
let dir = tempfile::TempDir::new().unwrap();
let old = std::env::var_os("SYNAPS_BASE_DIR");
agent_core::config::set_base_dir_for_tests(dir.path().to_path_buf());
Self { old, _dir: dir }
}
pub(crate) fn path(&self) -> &Path {
self._dir.path()
}
}
impl Drop for BaseDirGuard {
fn drop(&mut self) {
match self.old.take() {
Some(v) => std::env::set_var("SYNAPS_BASE_DIR", v),
None => std::env::remove_var("SYNAPS_BASE_DIR"),
}
}
}
pub(crate) struct EnvVarGuard {
key: &'static str,
old: Option<std::ffi::OsString>,
}
impl EnvVarGuard {
pub(crate) fn set(key: &'static str, value: &str) -> Self {
let old = std::env::var_os(key);
std::env::set_var(key, value);
Self { key, old }
}
pub(crate) fn remove(key: &'static str) -> Self {
let old = std::env::var_os(key);
std::env::remove_var(key);
Self { key, old }
}
}
impl Drop for EnvVarGuard {
fn drop(&mut self) {
match self.old.take() {
Some(v) => std::env::set_var(self.key, v),
None => std::env::remove_var(self.key),
}
}
}
pub(crate) struct OfflineProviderEnv {
_guards: [EnvVarGuard; 4],
}
impl OfflineProviderEnv {
pub(crate) fn new() -> Self {
Self {
_guards: [
EnvVarGuard::remove("ANTHROPIC_API_KEY"),
EnvVarGuard::remove("SYNAPS_AUTH_ENDPOINT"),
EnvVarGuard::remove("SYNAPS_MACHINE_TOKEN"),
EnvVarGuard::set("SYNAPS_ANTHROPIC_BASE_URL", "http://127.0.0.1:9"),
],
}
}
}
#[cfg(all(test, unix))]
mod tests {
use super::EnvVarGuard;
use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStrExt;
const KEY: &str = "SYNAPS_TEST_ENV_GUARD_NON_UTF8";
fn non_utf8() -> OsString {
OsStr::from_bytes(b"/var/run/syn\xffaps").to_os_string()
}
#[test]
#[serial_test::serial(synaps_base_dir)]
fn remove_restores_a_non_utf8_value() {
std::env::set_var(KEY, non_utf8());
{
let _guard = EnvVarGuard::remove(KEY);
assert_eq!(std::env::var_os(KEY), None);
}
assert_eq!(std::env::var_os(KEY), Some(non_utf8()));
std::env::remove_var(KEY);
}
#[test]
#[serial_test::serial(synaps_base_dir)]
fn the_base_dir_guard_restores_a_non_utf8_value() {
let outer = std::env::var_os("SYNAPS_BASE_DIR");
std::env::set_var("SYNAPS_BASE_DIR", non_utf8());
{
let guard = super::BaseDirGuard::new();
assert_eq!(
std::env::var_os("SYNAPS_BASE_DIR").as_deref(),
Some(guard.path().as_os_str())
);
}
let restored = std::env::var_os("SYNAPS_BASE_DIR");
match outer {
Some(v) => std::env::set_var("SYNAPS_BASE_DIR", v),
None => std::env::remove_var("SYNAPS_BASE_DIR"),
}
assert_eq!(restored, Some(non_utf8()));
}
#[test]
#[serial_test::serial(synaps_base_dir)]
fn set_restores_a_non_utf8_value() {
std::env::set_var(KEY, non_utf8());
{
let _guard = EnvVarGuard::set(KEY, "plain");
assert_eq!(std::env::var_os(KEY), Some(OsString::from("plain")));
}
assert_eq!(std::env::var_os(KEY), Some(non_utf8()));
std::env::remove_var(KEY);
}
}