Skip to content

Commit a15d442

Browse files
committed
refactor(memtrack): extract shared test helpers for compile and track
Move `compile_rust_crate` from rust_tests.rs to shared.rs as `compile_rust_binary` and generalize `track_binary_with_opts` into `track_command` which accepts a Command and a flag to skip system-wide allocator discovery.
1 parent d0de2ed commit a15d442

2 files changed

Lines changed: 44 additions & 31 deletions

File tree

crates/memtrack/tests/rust_tests.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,6 @@ mod shared;
44
use memtrack::AllocatorLib;
55
use rstest::rstest;
66
use std::path::Path;
7-
use std::process::Command;
8-
9-
fn compile_rust_crate(
10-
crate_dir: &Path,
11-
name: &str,
12-
features: &[&str],
13-
) -> anyhow::Result<std::path::PathBuf> {
14-
let mut cmd = Command::new("cargo");
15-
cmd.current_dir(crate_dir)
16-
.args(["build", "--release", "--bin", name]);
17-
18-
if !features.is_empty() {
19-
cmd.arg("--features").arg(features.join(","));
20-
}
21-
22-
let output = cmd.output()?;
23-
if !output.status.success() {
24-
eprintln!("cargo stderr: {}", String::from_utf8_lossy(&output.stderr));
25-
eprintln!("cargo stdout: {}", String::from_utf8_lossy(&output.stdout));
26-
return Err(anyhow::anyhow!("Failed to compile Rust crate"));
27-
}
28-
29-
let binary_path = crate_dir.join(format!("target/release/{name}"));
30-
Ok(binary_path)
31-
}
327

338
#[test_with::env(GITHUB_ACTIONS)]
349
#[rstest]
@@ -41,7 +16,7 @@ fn test_rust_alloc_tracking(
4116
#[case] features: &[&str],
4217
) -> Result<(), Box<dyn std::error::Error>> {
4318
let crate_path = Path::new("testdata/alloc_rust");
44-
let binary = compile_rust_crate(crate_path, "alloc_rust", features)?;
19+
let binary = shared::compile_rust_binary(crate_path, "alloc_rust", features)?;
4520

4621
// Try to find a static allocator in the binary, then attach to it as well
4722
// This is needed because the CWD is different, which breaks the heuristics.

crates/memtrack/tests/shared.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,49 @@ macro_rules! assert_events_with_marker {
100100
}};
101101
}
102102

103-
pub fn track_binary_with_opts(binary: &Path, extra_allocators: &[AllocatorLib]) -> TrackResult {
103+
/// Compile a Rust binary from a test crate directory.
104+
pub fn compile_rust_binary(
105+
crate_dir: &Path,
106+
name: &str,
107+
features: &[&str],
108+
) -> anyhow::Result<std::path::PathBuf> {
109+
let mut cmd = Command::new("cargo");
110+
cmd.current_dir(crate_dir)
111+
.args(["build", "--release", "--bin", name]);
112+
113+
if !features.is_empty() {
114+
cmd.arg("--features").arg(features.join(","));
115+
}
116+
117+
let output = cmd.output()?;
118+
if !output.status.success() {
119+
eprintln!("cargo stderr: {}", String::from_utf8_lossy(&output.stderr));
120+
eprintln!("cargo stdout: {}", String::from_utf8_lossy(&output.stdout));
121+
return Err(anyhow::anyhow!("Failed to compile Rust crate"));
122+
}
123+
124+
Ok(crate_dir.join(format!("target/release/{name}")))
125+
}
126+
127+
/// Track a spawned command, collecting all memory events.
128+
///
129+
/// When `discover_system_allocators` is true, the tracker will scan for all
130+
/// allocators on the system (slower). When false, only `extra_allocators` are used.
131+
pub fn track_command(
132+
mut command: Command,
133+
extra_allocators: &[AllocatorLib],
134+
discover_system_allocators: bool,
135+
) -> TrackResult {
104136
// IMPORTANT: Always initialize the tracker BEFORE spawning the binary, as it can take some time to
105137
// attach to all the allocator libraries (especially when using NixOS).
106-
let mut tracker = memtrack::Tracker::new()?;
138+
let mut tracker = if discover_system_allocators {
139+
memtrack::Tracker::new()?
140+
} else {
141+
memtrack::Tracker::new_without_allocators()?
142+
};
107143
tracker.attach_allocators(extra_allocators)?;
108144

109-
let child = Command::new(binary)
110-
.spawn()
111-
.context("Failed to spawn command")?;
145+
let child = command.spawn().context("Failed to spawn command")?;
112146
let root_pid = child.id() as i32;
113147

114148
tracker.enable()?;
@@ -128,6 +162,10 @@ pub fn track_binary_with_opts(binary: &Path, extra_allocators: &[AllocatorLib])
128162
Ok((events, thread_handle))
129163
}
130164

165+
pub fn track_binary_with_opts(binary: &Path, extra_allocators: &[AllocatorLib]) -> TrackResult {
166+
track_command(Command::new(binary), extra_allocators, true)
167+
}
168+
131169
pub fn track_binary(binary: &Path) -> TrackResult {
132170
track_binary_with_opts(binary, &[])
133171
}

0 commit comments

Comments
 (0)