pub fn run_merged_vs_parents(
program: &str,
args: &[String],
parent_a: &Path,
parent_b: &Path,
merged: &Path,
env: &BTreeMap<String, String>,
timeout: Option<Duration>,
) -> Result<DifferentialReport, String>Expand description
Runs one explicit command in both parent trees and the merged tree.
env is the complete environment every run sees; nothing is inherited
from this process. That closes the reproducibility gap where “same
command” enforced same argv while an ambient variable (a leaked
CARGO_TARGET_DIR, a changed RUSTFLAGS) silently changed what the
three runs measured. Callers building the map from a command file should
use crate::differential_ledger::effective_environment, which is what
the ledger’s recorded environment hash is computed over.
The three runs happen concurrently, one thread each. They are
independent by construction — three separate checkouts, and the caller
owns their isolation — so this is a straight 3x on the dominant cost
without touching what is measured: every run is still really run, which
is what the calibration’s declared independent_runs assumption needs.
A result cache would be faster still and would quietly void that
assumption, since determinism is the property under test.
The one thing to know before pointing a command at this: if the command
writes to a location the three trees share — an absolute
--target-dir, say — they will serialize on that tool’s own lock
rather than run in parallel. Correctness is unaffected either way; the
speedup is not. Keeping such state per-tree is what makes this pay.
timeout bounds each of the three runs individually; None waits
forever, which was the only behavior before the parameter existed. A
run that exceeds it is killed and reported as an error, never as a
verdict — a timeout cannot distinguish a hung command from a slow one,
so it must not become evidence about the merge. Unattended corpus
walks (choir-bridge harvest, D27) are the reason it exists: one hung
test run must not stall a multi-hour walk forever.
§Errors
The program could not be spawned in one of the three directories, or a
run exceeded timeout. All
three are attempted before reporting: unlike the previous sequential
form, a spawn failure in parent_a no longer prevents the other two
from running. The reported error is still the earliest in
parent_a, parent_b, merged order, so the message a caller sees
for a given failure is unchanged.
§Panics
If one of the three worker threads panics, this propagates that panic rather than reporting a verdict computed from two runs.