test(cli): RED — sweep --real --trace refuses instead of writing tap series
Pins the #224 delivery headline: the #168 refusal lifts and at least one non-empty tap-series file lands under runs/traces/. Layout-agnostic on purpose — the per-member key convention is the GREEN slice's call. refs #224
This commit is contained in:
@@ -1225,6 +1225,82 @@ fn sweep_real_blueprint_member_lines_pin_the_dissolved_contract() {
|
|||||||
assert_eq!(count("campaigns"), 1, "second identical run dedupes the campaign doc");
|
assert_eq!(count("campaigns"), 1, "second identical run dedupes the campaign doc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True iff `root` contains, at any depth, a regular file of non-zero length —
|
||||||
|
/// the layout-agnostic "traces actually landed on disk" probe. #224 does not yet
|
||||||
|
/// pin the per-member trace-directory naming (the sweep sugar's cell has no
|
||||||
|
/// nominee and `persist_campaign_traces` keys by `<trace_name>/<cell_key>`), so
|
||||||
|
/// this walks the tree rather than hard-coding a path, keeping the headline about
|
||||||
|
/// *that* traces are written, not *where*.
|
||||||
|
fn any_nonempty_file(root: &Path) -> bool {
|
||||||
|
let mut stack = vec![root.to_path_buf()];
|
||||||
|
while let Some(p) = stack.pop() {
|
||||||
|
let Ok(entries) = std::fs::read_dir(&p) else { continue };
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
stack.push(path);
|
||||||
|
} else if std::fs::metadata(&path).map(|m| m.len() > 0).unwrap_or(false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Property (#224): `aura sweep <blueprint.json> --real SYM --axis … --trace <fam>`
|
||||||
|
/// DELIVERS the advertised trace-writing capability instead of the #168
|
||||||
|
/// refuse-with-pointer. Two things must hold once the capability ships:
|
||||||
|
/// (1) the run no longer refuses (`aura: --trace is not yet available on sweep;
|
||||||
|
/// see #224`, exit 2) but succeeds, and (2) the tap series actually land on disk
|
||||||
|
/// under `runs/traces/` — at least one non-empty tap file is written, the honest
|
||||||
|
/// inverse of the #168 no-op where the `--real` sugar set `persist_taps: vec![]`
|
||||||
|
/// (verb_sugar.rs) and `run_blueprint_sweep` did `let _ = persist`, so nothing was
|
||||||
|
/// ever written. The exact on-disk layout (trace name + per-member/nominee key)
|
||||||
|
/// is deliberately NOT pinned here: this headline pins that traces are written at
|
||||||
|
/// all — not how many dirs, nor under what member key — because that naming is
|
||||||
|
/// the GREEN slice's open design point (the selection-free sweep cell has no
|
||||||
|
/// nominee for the existing per-cell `persist_campaign_traces` mechanism, #224).
|
||||||
|
/// Gated on the local GER40 archive (the project skip-on-no-data convention);
|
||||||
|
/// the refused status quo makes it RED on a data-ful host today.
|
||||||
|
#[test]
|
||||||
|
fn sweep_real_with_trace_writes_tap_series_to_disk() {
|
||||||
|
if !local_data_present() {
|
||||||
|
eprintln!("skip: no local data at {}", data_server::DEFAULT_DATA_PATH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (dir, _g) = fresh_project();
|
||||||
|
let fixture = format!("{}/examples/r_sma_open.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
let out = std::process::Command::new(BIN)
|
||||||
|
.args([
|
||||||
|
"sweep", &fixture,
|
||||||
|
"--real", "GER40",
|
||||||
|
"--from", GER40_SEPT2024_FROM_MS,
|
||||||
|
"--to", GER40_SEPT2024_TO_MS,
|
||||||
|
"--axis", "sma_signal.fast.length=2,4",
|
||||||
|
"--trace", "brp",
|
||||||
|
])
|
||||||
|
.current_dir(dir)
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
// (1) the #168 refusal is lifted: the advertised flag runs instead of exit 2.
|
||||||
|
assert!(
|
||||||
|
out.status.success(),
|
||||||
|
"sweep --trace must no longer refuse (#224); exit {:?}, stderr: {}",
|
||||||
|
out.status.code(),
|
||||||
|
String::from_utf8_lossy(&out.stderr),
|
||||||
|
);
|
||||||
|
// (2) the tap series actually land on disk under runs/traces/ (non-empty) —
|
||||||
|
// the honest inverse of the #168 `persist_taps: vec![]` no-op.
|
||||||
|
let traces_root = dir.join("runs").join("traces");
|
||||||
|
assert!(
|
||||||
|
any_nonempty_file(&traces_root),
|
||||||
|
"sweep --trace must write at least one non-empty tap file under {} \
|
||||||
|
(found none — the #168 no-op wrote nothing); stderr: {}",
|
||||||
|
traces_root.display(),
|
||||||
|
String::from_utf8_lossy(&out.stderr),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Extract the first persisted family whose `kind` matches `want` from
|
/// Extract the first persisted family whose `kind` matches `want` from
|
||||||
/// `aura runs families` stdout (one JSON object per line), returning its
|
/// `aura runs families` stdout (one JSON object per line), returning its
|
||||||
/// `family_id` — the id `aura reproduce` addresses. Panics if none matches so a
|
/// `family_id` — the id `aura reproduce` addresses. Panics if none matches so a
|
||||||
|
|||||||
Reference in New Issue
Block a user