diff --git a/benches/alias.rs b/benches/alias.rs index 6fd1b43c3..ae1148951 100644 --- a/benches/alias.rs +++ b/benches/alias.rs @@ -48,7 +48,7 @@ fn wt_cmd(binary: &Path, repo: &Path, user_config: &Path, args: &[&str]) -> Comm fn bench_dispatch(c: &mut Criterion) { let mut group = c.benchmark_group("dispatch"); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); // Startup floor: `wt --version` exits before any repo discovery, so the // delta between this and the scaling rows is the parent-side dispatch diff --git a/benches/completion.rs b/benches/completion.rs index 59558ccfe..9149c59e0 100644 --- a/benches/completion.rs +++ b/benches/completion.rs @@ -73,7 +73,7 @@ fn assert_completion_candidates(binary: &Path, repo_path: &Path, expected: &BTre fn bench_completion_switch(c: &mut Criterion) { let mut group = c.benchmark_group("completion_switch"); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); let (linked_worktrees, branchless_branches) = (24, 120); group.bench_function("full_surface", |b| { diff --git a/benches/list.rs b/benches/list.rs index fcc7fdcf1..d3de98c75 100644 --- a/benches/list.rs +++ b/benches/list.rs @@ -58,7 +58,7 @@ fn run_benchmark( fn bench_skeleton(c: &mut Criterion) { let mut group = c.benchmark_group("skeleton"); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); for total_worktrees in WORKTREE_COUNTS { for cache in CacheState::WARM_AND_COLD { @@ -85,7 +85,7 @@ fn bench_skeleton(c: &mut Criterion) { fn bench_worktree_scaling(c: &mut Criterion) { let mut group = c.benchmark_group("worktree_scaling"); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); for total_worktrees in WORKTREE_COUNTS { for cache in CacheState::WARM_AND_COLD { @@ -120,7 +120,7 @@ fn bench_large_repository(c: &mut Criterion) { group.measurement_time(std::time::Duration::from_secs(20)); group.sample_size(10); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); let fixture = OnceCell::new(); // Cold goes last because it removes the commit graph. Each warm row has @@ -153,7 +153,7 @@ fn bench_divergent_branches(c: &mut Criterion) { group.measurement_time(std::time::Duration::from_secs(30)); group.sample_size(10); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); for cache in CacheState::WARM_AND_COLD { group.bench_function(cache.label(), |b| { @@ -218,7 +218,7 @@ fn bench_full(c: &mut Criterion) { group.measurement_time(std::time::Duration::from_secs(20)); group.sample_size(10); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); let (linked_worktrees, branchless_branches) = (24usize, 120usize); for cache in CacheState::WARM_AND_COLD { diff --git a/benches/picker_preview.rs b/benches/picker_preview.rs index a58a077b3..d8d361b6a 100644 --- a/benches/picker_preview.rs +++ b/benches/picker_preview.rs @@ -45,8 +45,6 @@ fn main() { #[cfg(unix)] use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main}; #[cfg(unix)] -use std::path::Path; -#[cfg(unix)] use wt_perf::{CacheState, FixtureRecipe, bench_wt, wt_command}; #[cfg(unix)] @@ -57,7 +55,7 @@ fn bench_picker_preview(c: &mut Criterion) { group.sample_size(10); group.measurement_time(std::time::Duration::from_secs(35)); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); let total_worktrees = 8; for cache in CacheState::WARM_AND_COLD { diff --git a/benches/prune.rs b/benches/prune.rs index 71dd45721..cadfed0b8 100644 --- a/benches/prune.rs +++ b/benches/prune.rs @@ -93,7 +93,7 @@ fn generated_prune_fixture() -> FixtureRepo { /// Build the `wt ` command for `repo`. fn wt_cmd(repo: &Path, args: &[&str]) -> Command { - let mut cmd = wt_command(Path::new(env!("CARGO_BIN_EXE_wt")), repo, None); + let mut cmd = wt_command(&worktrunk::testing::wt_bin(), repo, None); cmd.args(args); cmd } diff --git a/benches/remove.rs b/benches/remove.rs index 47017eb23..c5a5f603b 100644 --- a/benches/remove.rs +++ b/benches/remove.rs @@ -194,7 +194,7 @@ fn bench_variant( expect_hooks: bool, cache: CacheState, ) { - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); group.bench_function(name, |b| { b.iter_custom(|iterations| { diff --git a/benches/time_to_first_output.rs b/benches/time_to_first_output.rs index 6bddb4dcf..51a113e6f 100644 --- a/benches/time_to_first_output.rs +++ b/benches/time_to_first_output.rs @@ -14,14 +14,13 @@ // cargo bench --bench time_to_first_output -- switch # Just switch use criterion::{Criterion, criterion_group, criterion_main}; -use std::path::Path; use wt_perf::{ CacheState, FixtureRecipe, bench_wt, run_and_check, standard_benchmark_profile, wt_command, }; fn bench_first_output(c: &mut Criterion) { let mut group = c.benchmark_group("first_output"); - let binary = Path::new(env!("CARGO_BIN_EXE_wt")); + let binary = &worktrunk::testing::wt_bin(); let fixture = FixtureRecipe::generated(3).create(); diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 10e51eafd..eb250d5c9 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -108,9 +108,14 @@ pub fn wt_bin() -> PathBuf { /// by the observed binary's identity, keeping `src`'s basename. The hardlink /// pins the inode: cargo's uplift only unlinks the *path*, so the pinned entry /// keeps serving the observed binary through any number of concurrent -/// rebuilds. A link costs no space while the `deps/` artifact it shares an -/// inode with exists, and everything under `wt-test-bin/` dies with -/// `cargo clean`, so nothing sweeps it. +/// rebuilds. An entry's marginal disk cost is near zero — where cargo uplifts +/// by hardlink (Linux) the pin shares the `deps/` artifact's inode outright, +/// and where it uplifts by copy-on-write clone (macOS/APFS) the pin keeps the +/// clone, whose blocks stay shared with that artifact (measured: cloning the +/// 70 MB binary consumes 8 KB) — the bytes belong to `deps/`, which cargo +/// already retains. Everything under `wt-test-bin/` dies with `cargo clean`, +/// so nothing sweeps it; a sweeper could unlink a generation another live +/// suite pinned, re-creating the very window this exists to close. /// /// Two runs observing the same binary converge on the same entry (`link` /// returning `AlreadyExists` is success — the key names the content); a run diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 4341b1a8d..886f6c3da 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1419,7 +1419,7 @@ mod tests { let needle = ["CARGO_BIN_EXE_", "wt\""].concat(); let root = Path::new(env!("CARGO_MANIFEST_DIR")); let mut offenders = Vec::new(); - for dir in ["src", "tests"] { + for dir in ["src", "tests", "benches"] { scan_for_needle(&root.join(dir), &needle, root, &mut offenders); } assert_eq!(