use super::*;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::time::Duration;
use trusty_memory::project_root::{write_project_pin, ProjectPin};
struct EnvGuard {
key: &'static str,
prev: Option<OsString>,
}
impl EnvGuard {
fn set<V: AsRef<OsStr>>(key: &'static str, value: V) -> Self {
let prev = std::env::var_os(key);
unsafe { std::env::set_var(key, value) };
Self { key, prev }
}
fn clear(key: &'static str) -> Self {
let prev = std::env::var_os(key);
unsafe { std::env::remove_var(key) };
Self { key, prev }
}
}
impl Drop for EnvGuard {
fn drop(&mut self) {
unsafe {
match self.prev.take() {
Some(v) => std::env::set_var(self.key, v),
None => std::env::remove_var(self.key),
}
}
}
}
#[serial_test::serial]
#[test]
fn spawn_startup_tasks_populates_pin_map() {
trusty_common::memory_core::retrieval::seed_shared_embedder_with_mock();
let tmp = tempfile::tempdir().expect("tempdir");
let search_root = tmp.path().join("Projects");
let project_dir = search_root.join("my-project");
fs::create_dir_all(&project_dir).expect("create project dir");
write_project_pin(&project_dir, &ProjectPin::new("my-palace".to_string())).expect("write pin");
let _home = EnvGuard::set("HOME", tmp.path());
let _enforcement = EnvGuard::set("TRUSTY_SKIP_PALACE_ENFORCEMENT", "1");
let _data_dir = EnvGuard::clear(trusty_common::DATA_DIR_OVERRIDE_ENV);
let _update = EnvGuard::set(trusty_common::update::NO_UPDATE_CHECK_ENV, "1");
let state_root = tmp.path().join("data");
fs::create_dir_all(&state_root).expect("create data dir");
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("build test runtime");
let found = rt.block_on(async {
let state = AppState::new(state_root);
spawn_startup_tasks(&state);
let deadline = std::time::Instant::now() + Duration::from_millis(500);
loop {
if let Some(entry) = state.pin_project_map.get("my-palace") {
return Some(entry.clone());
}
if std::time::Instant::now() >= deadline {
return None;
}
tokio::time::sleep(Duration::from_millis(10)).await;
}
});
rt.shutdown_timeout(Duration::ZERO);
let found = found.expect(
"pin_project_map must contain 'my-palace' after spawn_startup_tasks; \
the scan did not populate it within 500 ms",
);
let actual = fs::canonicalize(found).expect("canonicalize actual");
let expected = fs::canonicalize(&project_dir).expect("canonicalize expected");
assert_eq!(
actual, expected,
"pin_project_map entry must point to the project directory"
);
}