test(cli): extract the shared demo-project fixture helpers into tests/common (#223)
built_project/project_lock/ScratchPath/ScratchGuard move from their three per-binary copies (cli_run.rs, research_docs.rs, project_load.rs's built_fixture near-copy) into tests/common/mod.rs; project_load's one shared-store-mutating test now takes the lock it previously lacked. The module doc states the boundary plainly: the Mutex serializes threads within one process only — process-parallel runners still race on the shared fixture store (documented, dormant under cargo test's sequential binaries; see the issue thread for the observed process-parallel repro). closes #223
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||
use std::sync::MutexGuard;
|
||||
|
||||
mod common;
|
||||
use common::{built_project, project_lock};
|
||||
|
||||
/// Path to the freshly-built `aura` binary (Cargo sets this env var for the test
|
||||
/// crate; the binary is named `aura` in `Cargo.toml`).
|
||||
@@ -19,35 +22,6 @@ fn temp_cwd(name: &str) -> std::path::PathBuf {
|
||||
dir
|
||||
}
|
||||
|
||||
/// The demo-project fixture (Aura.toml + a built cdylib present), built once —
|
||||
/// mirrors research_docs.rs's helper (a separate test binary, so it needs its
|
||||
/// own `OnceLock`); `cargo build` is idempotent, so a second binary building
|
||||
/// the same fixture is a no-op.
|
||||
fn built_project() -> &'static PathBuf {
|
||||
static BUILT: OnceLock<PathBuf> = OnceLock::new();
|
||||
BUILT.get_or_init(|| {
|
||||
let dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/demo-project");
|
||||
let out = std::process::Command::new("cargo")
|
||||
.arg("build")
|
||||
.current_dir(&dir)
|
||||
.output()
|
||||
.expect("spawn cargo build for the fixture project");
|
||||
assert!(
|
||||
out.status.success(),
|
||||
"fixture build failed:\n{}",
|
||||
String::from_utf8_lossy(&out.stderr)
|
||||
);
|
||||
dir
|
||||
})
|
||||
}
|
||||
|
||||
/// Serializes every test that runs a verb inside the shared fixture (they reset
|
||||
/// `<fixture>/runs`, so parallel threads would race). Poison-tolerant.
|
||||
fn project_lock() -> MutexGuard<'static, ()> {
|
||||
static LOCK: Mutex<()> = Mutex::new(());
|
||||
LOCK.lock().unwrap_or_else(|e| e.into_inner())
|
||||
}
|
||||
|
||||
/// Removes `<fixture>/runs` on drop (including mid-panic) so a migrated test never
|
||||
/// leaks its content-addressed store into the git-tracked fixture tree.
|
||||
struct RunsCleanup(PathBuf);
|
||||
|
||||
Reference in New Issue
Block a user