Skip to content

Commit b4f7080

Browse files
Merge branch 'worktree-agent-a8539afe05ba22c1b' into codex/tracedecay-total-redesign-plan
2 parents 1553457 + ea9b2d5 commit b4f7080

2 files changed

Lines changed: 21 additions & 74 deletions

File tree

crates/tracedecay-runtime-core/src/config.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,17 @@ pub fn is_generated_dir_segment(segment: &str) -> bool {
212212
GENERATED_DIR_SEGMENTS.contains(&segment)
213213
}
214214

215-
#[cfg(any(test, feature = "test-helpers"))]
215+
// Deliberately unconditional (not gated behind `cfg(test)` /
216+
// `feature = "test-helpers"`): some non-test call sites — e.g. the root
217+
// crate's `src/sessions/session_temporal_benchmark.rs`, which backs
218+
// `cargo bench` and is always compiled as part of the lib — need this lock
219+
// outside a test build. The mutex and accessor are trivial and side-effect
220+
// free, so keeping them unconditional costs nothing while guaranteeing every
221+
// consumer, test or not, serializes on the same lock.
216222
static USER_DATA_DIR_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
217223

218-
/// Serializes tests that mutate process-wide profile discovery variables.
219-
#[cfg(any(test, feature = "test-helpers"))]
224+
/// Serializes tests (and benchmark harnesses) that mutate process-wide
225+
/// profile discovery variables.
220226
pub fn lock_user_data_dir_test_env() -> std::sync::MutexGuard<'static, ()> {
221227
USER_DATA_DIR_TEST_LOCK
222228
.lock()

src/config.rs

Lines changed: 12 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,81 +2207,22 @@ fn any_pattern_matches(patterns: &[String], candidates: &[&str]) -> bool {
22072207

22082208
/// Serializes test and benchmark code that mutates process-wide storage env
22092209
/// vars (`TRACEDECAY_DATA_DIR` and related HOME/profile pins).
2210-
static USER_DATA_DIR_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
2211-
2212-
/// Acquires [`USER_DATA_DIR_TEST_LOCK`], recovering even when poisoned.
2213-
pub(crate) fn lock_user_data_dir_test_env() -> std::sync::MutexGuard<'static, ()> {
2214-
USER_DATA_DIR_TEST_LOCK
2215-
.lock()
2216-
.unwrap_or_else(std::sync::PoisonError::into_inner)
2217-
}
2210+
///
2211+
/// Single source of truth: [`tracedecay_runtime_core::config`] owns the lock,
2212+
/// [`lock_user_data_dir_test_env`], and `PinnedUserDataDir`; this module only
2213+
/// re-exports them so every historical `crate::config::…` call site keeps
2214+
/// resolving. The lock and its accessor are unconditional there (not gated
2215+
/// behind `cfg(test)` / `feature = "test-helpers"`) because non-test code —
2216+
/// `src/sessions/session_temporal_benchmark.rs`, which is always compiled and
2217+
/// backs `cargo bench` — takes this lock outside a test build.
2218+
pub(crate) use tracedecay_runtime_core::config::lock_user_data_dir_test_env;
22182219

22192220
/// Pins [`USER_DATA_DIR_ENV`] and agent home discovery to an isolated temp
2220-
/// profile while holding [`USER_DATA_DIR_TEST_LOCK`], so parallel lib tests
2221-
/// cannot race profile resolution or scan live host transcripts during
2221+
/// profile while holding the shared user-data-dir test lock, so parallel lib
2222+
/// tests cannot race profile resolution or scan live host transcripts during
22222223
/// `TraceDecay::init` / indexing.
22232224
#[cfg(test)]
2224-
pub struct PinnedUserDataDir {
2225-
_lock: std::sync::MutexGuard<'static, ()>,
2226-
_root: tempfile::TempDir,
2227-
previous: Option<OsString>,
2228-
previous_home: Option<OsString>,
2229-
previous_userprofile: Option<OsString>,
2230-
}
2231-
2232-
#[cfg(test)]
2233-
impl PinnedUserDataDir {
2234-
pub fn new() -> Self {
2235-
let lock = lock_user_data_dir_test_env();
2236-
let root = tempfile::TempDir::new()
2237-
.unwrap_or_else(|err| panic!("failed to create temp profile dir: {err}"));
2238-
let profile = root.path().join(TRACEDECAY_DIR);
2239-
crate::storage::PrivateStoreIo::create_dir_all(&profile)
2240-
.unwrap_or_else(|err| panic!("failed to create isolated profile root: {err}"));
2241-
let previous = std::env::var_os(USER_DATA_DIR_ENV);
2242-
let previous_home = std::env::var_os("HOME");
2243-
let previous_userprofile = std::env::var_os("USERPROFILE");
2244-
unsafe {
2245-
std::env::set_var(USER_DATA_DIR_ENV, &profile);
2246-
std::env::set_var("HOME", root.path());
2247-
std::env::set_var("USERPROFILE", root.path());
2248-
}
2249-
Self {
2250-
_lock: lock,
2251-
_root: root,
2252-
previous,
2253-
previous_home,
2254-
previous_userprofile,
2255-
}
2256-
}
2257-
}
2258-
2259-
#[cfg(test)]
2260-
impl Default for PinnedUserDataDir {
2261-
fn default() -> Self {
2262-
Self::new()
2263-
}
2264-
}
2265-
2266-
#[cfg(test)]
2267-
impl Drop for PinnedUserDataDir {
2268-
fn drop(&mut self) {
2269-
unsafe {
2270-
match self.previous.take() {
2271-
Some(previous) => std::env::set_var(USER_DATA_DIR_ENV, previous),
2272-
None => std::env::remove_var(USER_DATA_DIR_ENV),
2273-
}
2274-
match self.previous_home.take() {
2275-
Some(previous) => std::env::set_var("HOME", previous),
2276-
None => std::env::remove_var("HOME"),
2277-
}
2278-
match self.previous_userprofile.take() {
2279-
Some(previous) => std::env::set_var("USERPROFILE", previous),
2280-
None => std::env::remove_var("USERPROFILE"),
2281-
}
2282-
}
2283-
}
2284-
}
2225+
pub(crate) use tracedecay_runtime_core::config::PinnedUserDataDir;
22852226

22862227
#[cfg(test)]
22872228
#[allow(clippy::unwrap_used, clippy::expect_used)]

0 commit comments

Comments
 (0)