From 1ccce9ad32691070dec3ce122a7b2c7f084518e8 Mon Sep 17 00:00:00 2001 From: claude Date: Mon, 13 Jul 2026 20:15:31 +0200 Subject: [PATCH] fix(test): anchor all test sandboxes on reclaimable pid-free names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every hand-rolled test-sandbox helper keyed its directory on std::process::id() under env::temp_dir(), so the pre-create wipe never matched a prior run's path: one directory stranded per helper site per test-binary invocation, >50k dirs / 15.5 GiB on the 16 GiB tmpfs by 2026-07-13. The remedy extends commit 84e1075's knob-lab pattern to every site: fixed, tag-keyed, PID-FREE names under the build-tree tmp anchor, each site keeping its pre-create remove_dir_all — which now genuinely reclaims the previous run. Integration/bench targets use env!("CARGO_TARGET_TMPDIR"); src-internal unit-test helpers (cargo sets that var only for integration/bench targets) derive the same anchor from env!("CARGO_MANIFEST_DIR") + ../../target/tmp. Residue is bounded to one directory per site, on disk instead of the tmpfs, per checkout. One deliberate exception: project_new.rs's tmp() stays under env::temp_dir() because two of its tests (new_outside_a_work_tree_*) need a base genuinely detached from any git work tree, and target/ lives inside the checkout's work tree. Its name carries a per-checkout hash discriminator instead, so concurrently running checkouts (which share /tmp) cannot race on the fixed name while each run still reclaims its predecessor. tempfile-RAII was considered and rejected (issue #258 decision log): it cannot cover the process-lifetime OnceLock scaffolds (statics never drop), adds a dependency, and still strands kill-leftovers on the tmpfs. Verified: full workspace suite green (incl. the new RED regression test temp_cwd_sandbox_does_not_leak_under_env_temp_dir), clippy clean, sandboxes observed under target/tmp with stable names across runs. Stale pre-fix PID-keyed dirs in /tmp are not swept by this change and age out only by manual cleanup. closes #258 --- crates/aura-campaign/src/lib.rs | 6 +++-- crates/aura-campaign/tests/execute.rs | 4 ++-- crates/aura-cli/src/main.rs | 15 ++++++++---- crates/aura-cli/src/project.rs | 24 ++++++++++++++----- crates/aura-cli/src/scaffold.rs | 8 +++++-- crates/aura-cli/src/verb_sugar.rs | 21 +++++++--------- crates/aura-cli/tests/cli_broken_pipe.rs | 2 +- crates/aura-cli/tests/cli_run.rs | 2 +- crates/aura-cli/tests/common/mod.rs | 9 +++++++ crates/aura-cli/tests/graph_construct.rs | 2 +- crates/aura-cli/tests/project_load.rs | 6 +++-- crates/aura-cli/tests/project_new.rs | 13 +++++++++- crates/aura-cli/tests/project_nodes.rs | 2 +- crates/aura-cli/tests/research_docs.rs | 2 +- crates/aura-ingest/src/lib.rs | 6 +++++ crates/aura-registry/src/lib.rs | 13 ++++++---- crates/aura-registry/src/trace_store.rs | 6 +++-- .../tests/campaign_run_store_e2e.rs | 4 ++-- 18 files changed, 100 insertions(+), 45 deletions(-) diff --git a/crates/aura-campaign/src/lib.rs b/crates/aura-campaign/src/lib.rs index 0907e87..9229ee1 100644 --- a/crates/aura-campaign/src/lib.rs +++ b/crates/aura-campaign/src/lib.rs @@ -885,8 +885,10 @@ mod wf_tests { /// A per-test registry in a fresh temp dir (a Registry's family store /// isolates per DIRECTORY, not per filename — see Registry::open). fn wf_registry(name: &str) -> Registry { - let dir = std::env::temp_dir() - .join(format!("aura-campaign-wf-{}-{}", std::process::id(), name)); + // fixed, tag-keyed, pid-free name under the build-tree tmp anchor (#258): the + // pre-create wipe below then genuinely reclaims the previous run. + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join(format!("aura-campaign-wf-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); Registry::open(dir.join("runs.jsonl")) diff --git a/crates/aura-campaign/tests/execute.rs b/crates/aura-campaign/tests/execute.rs index abab2d6..84d976b 100644 --- a/crates/aura-campaign/tests/execute.rs +++ b/crates/aura-campaign/tests/execute.rs @@ -219,8 +219,8 @@ fn strategies() -> Vec<(String, String)> { /// Per-test registry DIRECTORY (family/campaign stores are per-directory /// siblings of the runs path — the aura-registry temp-dir idiom). fn temp_registry(name: &str) -> Registry { - let dir = std::env::temp_dir() - .join(format!("aura-campaign-exec-{}-{}", std::process::id(), name)); + let dir = std::path::Path::new(env!("CARGO_TARGET_TMPDIR")) + .join(format!("aura-campaign-exec-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("create temp registry dir"); Registry::open(dir.join("runs.jsonl")) diff --git a/crates/aura-cli/src/main.rs b/crates/aura-cli/src/main.rs index 6a5b17e..daf2356 100644 --- a/crates/aura-cli/src/main.rs +++ b/crates/aura-cli/src/main.rs @@ -5321,7 +5321,8 @@ mod tests { #[test] fn reproduce_family_re_derives_every_member_bit_identically() { // a unique temp runs store so the on-disk family + blueprint store do not collide. - let dir = std::env::temp_dir().join(format!("aura-repro-{}", std::process::id())); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-repro"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); let reg = Registry::open(dir.join("runs.jsonl")); @@ -5366,7 +5367,8 @@ mod tests { // under a NON-default vol-stop regime (a campaign risk-regime cell, or wf/mc/ // generalize with --stop-length/--stop-k) must still reproduce bit-identically; // silently re-running it under the default Vol{3,2.0} reports a spurious DIVERGED. - let dir = std::env::temp_dir().join(format!("aura-repro-stop-{}", std::process::id())); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-repro-stop"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); let reg = Registry::open(dir.join("runs.jsonl")); @@ -5434,7 +5436,8 @@ mod tests { /// vol proxy). #[test] fn reproduce_family_re_derives_a_costed_member_bit_identically() { - let dir = std::env::temp_dir().join(format!("aura-repro-cost-{}", std::process::id())); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-repro-cost"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); let reg = Registry::open(dir.join("runs.jsonl")); @@ -5489,7 +5492,8 @@ mod tests { #[test] fn reproduce_family_re_derives_every_mc_member_bit_identically() { - let dir = std::env::temp_dir().join(format!("aura-repro-mc-{}", std::process::id())); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-repro-mc"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); let reg = Registry::open(dir.join("runs.jsonl")); @@ -5590,7 +5594,8 @@ mod tests { /// must show. Sweep / walk-forward labels still echo their params (covered elsewhere). #[test] fn reproduce_mc_member_labels_carry_the_seed() { - let dir = std::env::temp_dir().join(format!("aura-repro-mc-seed-{}", std::process::id())); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-repro-mc-seed"); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("temp dir"); let reg = Registry::open(dir.join("runs.jsonl")); diff --git a/crates/aura-cli/src/project.rs b/crates/aura-cli/src/project.rs index d4c026d..182aa0f 100644 --- a/crates/aura-cli/src/project.rs +++ b/crates/aura-cli/src/project.rs @@ -588,7 +588,9 @@ mod tests { #[test] fn discover_walks_up_to_aura_toml() { - let tmp = std::env::temp_dir().join(format!("aura-disc-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-disc"); + let _ = std::fs::remove_dir_all(&tmp); let nested = tmp.join("a/b/c"); std::fs::create_dir_all(&nested).unwrap(); assert_eq!(discover_from(&nested), None); @@ -611,7 +613,9 @@ mod tests { /// and stamps commit-only provenance. #[test] fn data_only_project_loads_without_a_crate() { - let tmp = std::env::temp_dir().join(format!("aura-dataonly-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-dataonly"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); std::fs::write(tmp.join("Aura.toml"), "[paths]\nruns = \"runs\"\n").unwrap(); let p = load(&tmp, false).expect("data-only load"); @@ -632,7 +636,9 @@ mod tests { /// changes the data location depending on the caller's working directory. #[test] fn data_path_resolves_a_relative_paths_data_against_the_project_root() { - let tmp = std::env::temp_dir().join(format!("aura-datarel-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-datarel"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); std::fs::write(tmp.join("Aura.toml"), "[paths]\ndata = \"data\"\n").unwrap(); let p = load(&tmp, false).expect("data-only load"); @@ -643,7 +649,9 @@ mod tests { #[test] fn two_nodes_pointers_refuse_with_multi_crate() { - let tmp = std::env::temp_dir().join(format!("aura-multi-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-multi"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); std::fs::write(tmp.join("Aura.toml"), "[nodes]\ncrates = [\"a\", \"b\"]\n").unwrap(); let e = load(&tmp, false).unwrap_err(); @@ -653,7 +661,9 @@ mod tests { #[test] fn a_broken_nodes_pointer_names_the_pointer() { - let tmp = std::env::temp_dir().join(format!("aura-badptr-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-badptr"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); std::fs::write(tmp.join("Aura.toml"), "[nodes]\ncrates = [\"../nope\"]\n").unwrap(); let e = load(&tmp, false).unwrap_err(); @@ -671,7 +681,9 @@ mod tests { /// that (`load` still refuses → CLI exit 1). #[test] fn a_missing_nodes_pointer_dir_refuses_without_the_cargo_metadata_leak() { - let tmp = std::env::temp_dir().join(format!("aura-missingptr-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-missingptr"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); // `missing-node-crate` is never created — the pointer target is absent. std::fs::write( diff --git a/crates/aura-cli/src/scaffold.rs b/crates/aura-cli/src/scaffold.rs index 4ad85de..324794c 100644 --- a/crates/aura-cli/src/scaffold.rs +++ b/crates/aura-cli/src/scaffold.rs @@ -488,7 +488,9 @@ mod tests { #[test] fn scaffold_project_refuses_existing_destination() { - let tmp = std::env::temp_dir().join(format!("aura-pscaf-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-pscaf"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(tmp.join("x")).unwrap(); let spec = project_scaffold_spec("x", &tmp).unwrap(); let e = scaffold_project(&spec).unwrap_err(); @@ -498,7 +500,9 @@ mod tests { #[test] fn scaffold_node_crate_refuses_existing_dir_and_missing_engine() { - let tmp = std::env::temp_dir().join(format!("aura-scaf-{}", std::process::id())); + let tmp = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-scaf"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); // existing destination let mut spec = scaffold_spec("x", None, None, &tmp).unwrap(); diff --git a/crates/aura-cli/src/verb_sugar.rs b/crates/aura-cli/src/verb_sugar.rs index cd327cf..b7537b9 100644 --- a/crates/aura-cli/src/verb_sugar.rs +++ b/crates/aura-cli/src/verb_sugar.rs @@ -895,10 +895,9 @@ mod tests { /// that silently, before the dispatch rewire ever exercises the path live. #[test] fn register_generated_g_stores_documents_the_campaign_can_actually_resolve() { - let dir = std::env::temp_dir().join(format!( - "aura-verb-sugar-generalize-registry-test-{}", - std::process::id() - )); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-verb-sugar-generalize-registry-test"); + let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).unwrap(); let reg = aura_registry::Registry::open(dir.join("runs.jsonl")); @@ -1047,10 +1046,9 @@ mod tests { #[test] fn register_generated_wf_stores_documents_the_campaign_can_actually_resolve() { - let dir = std::env::temp_dir().join(format!( - "aura-verb-sugar-walkforward-registry-test-{}", - std::process::id() - )); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-verb-sugar-walkforward-registry-test"); + let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).unwrap(); let reg = aura_registry::Registry::open(dir.join("runs.jsonl")); let ax = wf_axes(); @@ -1140,10 +1138,9 @@ mod tests { #[test] fn register_generated_mc_stores_documents_the_campaign_can_actually_resolve() { - let dir = std::env::temp_dir().join(format!( - "aura-verb-sugar-mc-registry-test-{}", - std::process::id() - )); + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join("aura-verb-sugar-mc-registry-test"); + let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).unwrap(); let reg = aura_registry::Registry::open(dir.join("runs.jsonl")); let ax = wf_axes(); diff --git a/crates/aura-cli/tests/cli_broken_pipe.rs b/crates/aura-cli/tests/cli_broken_pipe.rs index 2942e3a..cbdd9c4 100644 --- a/crates/aura-cli/tests/cli_broken_pipe.rs +++ b/crates/aura-cli/tests/cli_broken_pipe.rs @@ -15,7 +15,7 @@ const BIN: &str = env!("CARGO_BIN_EXE_aura"); /// `./runs/runs.jsonl` into a throwaway dir, never dirtying the repo. Unique /// per test + per process; no external tempfile dependency (mirrors `cli_run.rs`). fn temp_cwd(name: &str) -> std::path::PathBuf { - let dir = std::env::temp_dir().join(format!("aura-cli-{}-{}", std::process::id(), name)); + let dir = std::path::Path::new(env!("CARGO_TARGET_TMPDIR")).join(format!("aura-cli-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("create temp cwd"); dir diff --git a/crates/aura-cli/tests/cli_run.rs b/crates/aura-cli/tests/cli_run.rs index 0b34354..13cb19a 100644 --- a/crates/aura-cli/tests/cli_run.rs +++ b/crates/aura-cli/tests/cli_run.rs @@ -15,7 +15,7 @@ const BIN: &str = env!("CARGO_BIN_EXE_aura"); /// records (so `aura sweep`'s `./runs/runs.jsonl` never dirties the repo). /// Unique per test + per process; no external tempfile dependency. fn temp_cwd(name: &str) -> std::path::PathBuf { - let dir = std::env::temp_dir().join(format!("aura-cli-{}-{}", std::process::id(), name)); + let dir = Path::new(env!("CARGO_TARGET_TMPDIR")).join(format!("aura-cli-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("create temp cwd"); dir diff --git a/crates/aura-cli/tests/common/mod.rs b/crates/aura-cli/tests/common/mod.rs index 7ac6fff..ad139ff 100644 --- a/crates/aura-cli/tests/common/mod.rs +++ b/crates/aura-cli/tests/common/mod.rs @@ -55,6 +55,15 @@ impl Drop for FreshProject { /// Mints a unique, empty tempdir under `std::env::temp_dir()`, named /// `aura-e2e--` so concurrent test threads (same process) and /// concurrent `cargo test` processes never collide. +/// +/// #258 sweep note: this site keeps `std::process::id()` deliberately, unlike +/// the fixed, pid-free sandbox names the rest of #258's fix uses — it has no +/// pre-create wipe to defeat in the first place. `FreshProject::drop` (above) +/// unconditionally removes the returned root when the owning test ends (pass, +/// fail, or panic-unwind), so nothing strands across runs; the pid instead +/// disambiguates concurrent `cargo test` *processes* racing this one function +/// from dozens of call sites, which a fixed tag-keyed name cannot do without +/// plumbing a unique tag through every one of them. fn mint_tempdir() -> PathBuf { static COUNTER: AtomicUsize = AtomicUsize::new(0); let root = std::env::temp_dir().join(format!( diff --git a/crates/aura-cli/tests/graph_construct.rs b/crates/aura-cli/tests/graph_construct.rs index bbc3e28..ea02399 100644 --- a/crates/aura-cli/tests/graph_construct.rs +++ b/crates/aura-cli/tests/graph_construct.rs @@ -382,7 +382,7 @@ fn graph_introspect_no_flag_is_usage_exit_2() { /// A fresh, unique working directory for a test that persists content-addressed /// blueprints under `./runs/` (mirrors `research_docs.rs`'s `temp_cwd`). fn temp_cwd(name: &str) -> std::path::PathBuf { - let dir = std::env::temp_dir().join(format!("aura-graph-{}-{}", std::process::id(), name)); + let dir = std::path::Path::new(env!("CARGO_TARGET_TMPDIR")).join(format!("aura-graph-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("create temp cwd"); dir diff --git a/crates/aura-cli/tests/project_load.rs b/crates/aura-cli/tests/project_load.rs index f979325..46023b8 100644 --- a/crates/aura-cli/tests/project_load.rs +++ b/crates/aura-cli/tests/project_load.rs @@ -368,7 +368,8 @@ fn nodes_pointer_crate_resolves_and_stamps_its_namespace() { /// "binds no node crate" hint (not the outside-project "no Aura.toml" text). #[test] fn data_only_project_hints_attach_for_namespaced_ids() { - let tmp = std::env::temp_dir().join(format!("aura-dataonly-hint-{}", std::process::id())); + let tmp = Path::new(env!("CARGO_TARGET_TMPDIR")).join("aura-dataonly-hint"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(&tmp).unwrap(); std::fs::write(tmp.join("Aura.toml"), "").unwrap(); let bp = tmp.join("bp.json"); @@ -388,7 +389,8 @@ fn data_only_project_hints_attach_for_namespaced_ids() { #[test] fn missing_artifact_refuses_with_build_hint() { // A minimal never-built project: valid cargo metadata, no dylib on disk. - let tmp = std::env::temp_dir().join(format!("aura-nobuild-{}", std::process::id())); + let tmp = Path::new(env!("CARGO_TARGET_TMPDIR")).join("aura-nobuild"); + let _ = std::fs::remove_dir_all(&tmp); std::fs::create_dir_all(tmp.join("src")).unwrap(); std::fs::write(tmp.join("Aura.toml"), "").unwrap(); std::fs::write(tmp.join("src/lib.rs"), "").unwrap(); diff --git a/crates/aura-cli/tests/project_new.rs b/crates/aura-cli/tests/project_new.rs index 6fbae50..a7f3da9 100644 --- a/crates/aura-cli/tests/project_new.rs +++ b/crates/aura-cli/tests/project_new.rs @@ -14,8 +14,19 @@ fn aura(args: &[&str], cwd: &Path) -> Output { .expect("run aura") } +/// Fixed, tag-keyed, pid-free name (#258) — kept under `env::temp_dir()` +/// rather than the `CARGO_TARGET_TMPDIR` build-tree anchor used by the other +/// sandbox helpers: two of this file's tests (`new_outside_a_work_tree_*`) +/// require a base genuinely detached from any git work tree, and +/// `CARGO_TARGET_TMPDIR` resolves inside this very checkout's `target/`. +/// The checkout discriminator keeps concurrently running checkouts/worktrees +/// (which share `env::temp_dir()`) off each other's fixed names while the +/// name stays deterministic per checkout, so each run still reclaims the last. fn tmp(tag: &str) -> PathBuf { - let d = std::env::temp_dir().join(format!("aura-new-{tag}-{}", std::process::id())); + use std::hash::{Hash, Hasher}; + let mut h = std::collections::hash_map::DefaultHasher::new(); + env!("CARGO_MANIFEST_DIR").hash(&mut h); + let d = std::env::temp_dir().join(format!("aura-new-{tag}-{:08x}", h.finish() as u32)); let _ = std::fs::remove_dir_all(&d); std::fs::create_dir_all(&d).unwrap(); d diff --git a/crates/aura-cli/tests/project_nodes.rs b/crates/aura-cli/tests/project_nodes.rs index 561bdd1..ba2bcb8 100644 --- a/crates/aura-cli/tests/project_nodes.rs +++ b/crates/aura-cli/tests/project_nodes.rs @@ -4,7 +4,7 @@ use std::path::Path; use std::process::Command; fn temp_cwd(tag: &str) -> std::path::PathBuf { - let d = std::env::temp_dir().join(format!("aura-nodes-{tag}-{}", std::process::id())); + let d = Path::new(env!("CARGO_TARGET_TMPDIR")).join(format!("aura-nodes-{tag}")); let _ = std::fs::remove_dir_all(&d); std::fs::create_dir_all(&d).unwrap(); d diff --git a/crates/aura-cli/tests/research_docs.rs b/crates/aura-cli/tests/research_docs.rs index 4318fb4..1691215 100644 --- a/crates/aura-cli/tests/research_docs.rs +++ b/crates/aura-cli/tests/research_docs.rs @@ -12,7 +12,7 @@ use common::{ScratchGuard, ScratchPath, fresh_project}; /// never dirties the repo). Unique per test + per process; no external /// tempfile dependency (mirrors `cli_run.rs` / `cli_broken_pipe.rs`). fn temp_cwd(name: &str) -> PathBuf { - let dir = std::env::temp_dir().join(format!("aura-cli-{}-{}", std::process::id(), name)); + let dir = Path::new(env!("CARGO_TARGET_TMPDIR")).join(format!("aura-cli-{name}")); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).expect("create temp cwd"); dir diff --git a/crates/aura-ingest/src/lib.rs b/crates/aura-ingest/src/lib.rs index ceb3dcf..ba766aa 100644 --- a/crates/aura-ingest/src/lib.rs +++ b/crates/aura-ingest/src/lib.rs @@ -551,6 +551,12 @@ mod tests { /// mirrors `aura-cli`'s own `tests/common::mint_tempdir` pattern (unique /// name via pid + an atomic counter) so this crate's tests need no /// `tempfile` dev-dependency for a handful of throwaway fixture dirs. + /// + /// #258 sweep note: deliberately kept pid-suffixed like the sibling it + /// mirrors — there is no pre-create wipe here for a stale pid to defeat; + /// `Drop` (below) unconditionally reclaims the directory when the owning + /// test ends, so nothing strands across runs. The pid instead + /// disambiguates concurrent `cargo test` processes. struct ScratchDir(std::path::PathBuf); impl ScratchDir { diff --git a/crates/aura-registry/src/lib.rs b/crates/aura-registry/src/lib.rs index 22048d8..f075604 100644 --- a/crates/aura-registry/src/lib.rs +++ b/crates/aura-registry/src/lib.rs @@ -909,8 +909,11 @@ mod tests { } fn temp_path(name: &str) -> PathBuf { - // unique per test + per process; no external tempfile dependency - std::env::temp_dir().join(format!("aura-registry-{}-{}.jsonl", std::process::id(), name)) + // fixed, tag-keyed, pid-free name under the build-tree tmp anchor (#258): + // no external tempfile dependency, and every call site already wipes + // before use, so the fixed name genuinely reclaims the previous run. + std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join(format!("aura-registry-{name}.jsonl")) } #[test] @@ -1081,8 +1084,10 @@ mod tests { fn temp_family_dir(name: &str) -> PathBuf { // a unique per-test directory so the families.jsonl sibling never collides // across tests sharing the temp dir; the registry binds to runs.jsonl inside. - let dir = - std::env::temp_dir().join(format!("aura-registry-fam-{}-{}", std::process::id(), name)); + // Fixed, tag-keyed, pid-free name under the build-tree tmp anchor (#258): the + // pre-create wipe below then genuinely reclaims the previous run. + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join(format!("aura-registry-fam-{name}")); let _ = fs::remove_dir_all(&dir); fs::create_dir_all(&dir).expect("create temp family dir"); dir.join("runs.jsonl") diff --git a/crates/aura-registry/src/trace_store.rs b/crates/aura-registry/src/trace_store.rs index 4bade17..01e14df 100644 --- a/crates/aura-registry/src/trace_store.rs +++ b/crates/aura-registry/src/trace_store.rs @@ -288,8 +288,10 @@ mod tests { use aura_core::{Scalar, ScalarKind, Timestamp}; fn temp_traces_root(name: &str) -> PathBuf { - let dir = - std::env::temp_dir().join(format!("aura-tracestore-{}-{}", std::process::id(), name)); + // fixed, tag-keyed, pid-free name under the build-tree tmp anchor (#258): the + // pre-create wipe below then genuinely reclaims the previous run. + let dir = std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tmp")) + .join(format!("aura-tracestore-{name}")); let _ = fs::remove_dir_all(&dir); fs::create_dir_all(&dir).expect("create temp traces root"); dir diff --git a/crates/aura-registry/tests/campaign_run_store_e2e.rs b/crates/aura-registry/tests/campaign_run_store_e2e.rs index 1cf01a8..6752f27 100644 --- a/crates/aura-registry/tests/campaign_run_store_e2e.rs +++ b/crates/aura-registry/tests/campaign_run_store_e2e.rs @@ -18,8 +18,8 @@ use aura_registry::{ }; fn temp_dir(name: &str) -> PathBuf { - let dir = std::env::temp_dir() - .join(format!("aura-registry-campaign-e2e-{}-{}", std::process::id(), name)); + let dir = std::path::Path::new(env!("CARGO_TARGET_TMPDIR")) + .join(format!("aura-registry-campaign-e2e-{name}")); let _ = fs::remove_dir_all(&dir); fs::create_dir_all(&dir).expect("create temp dir"); dir.join("runs.jsonl")