|
|
|
@@ -5,7 +5,7 @@
|
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
|
|
|
|
|
|
mod common;
|
|
|
|
|
use common::{ScratchGuard, ScratchPath, built_project, project_lock};
|
|
|
|
|
use common::{ScratchGuard, ScratchPath, fresh_project};
|
|
|
|
|
|
|
|
|
|
/// A fresh, unique working directory for a process test that persists
|
|
|
|
|
/// content-addressed documents under `./runs/` (so `aura process register`
|
|
|
|
@@ -304,8 +304,7 @@ fn process_register_stores_content_addressed_under_runs_root() {
|
|
|
|
|
/// them together end to end.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_validate_in_project_reports_referential_tier_end_to_end() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -321,7 +320,7 @@ fn campaign_validate_in_project_reports_referential_tier_end_to_end() {
|
|
|
|
|
// test).
|
|
|
|
|
let closed_bp = format!("{}/examples/r_sma.json", env!("CARGO_MANIFEST_DIR"));
|
|
|
|
|
let (sweep_out, sweep_code) = run_code_in(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
&[
|
|
|
|
|
"sweep",
|
|
|
|
|
&closed_bp,
|
|
|
|
@@ -360,8 +359,8 @@ fn campaign_validate_in_project_reports_referential_tier_end_to_end() {
|
|
|
|
|
// overfit_probability (not per-member) flip to a per-member scalar.
|
|
|
|
|
.replacen("\"overfit_probability\", \"cmp\": \"lt\", \"value\": 0.1", "\"win_rate\", \"cmp\": \"lt\", \"value\": 1.1", 1);
|
|
|
|
|
assert_ne!(exec_process, PROCESS_DOC, "replacen must match the sweep stage");
|
|
|
|
|
write_doc(dir, "seed.process.json", &exec_process);
|
|
|
|
|
let (proc_out, proc_code) = run_code_in(dir, &["process", "register", "seed.process.json"]);
|
|
|
|
|
write_doc(&dir, "seed.process.json", &exec_process);
|
|
|
|
|
let (proc_out, proc_code) = run_code_in(&dir, &["process", "register", "seed.process.json"]);
|
|
|
|
|
assert_eq!(proc_code, Some(0), "seed process register failed: {proc_out}");
|
|
|
|
|
let proc_id = proc_out
|
|
|
|
|
.lines()
|
|
|
|
@@ -394,8 +393,8 @@ fn campaign_validate_in_project_reports_referential_tier_end_to_end() {
|
|
|
|
|
bp = bp_id,
|
|
|
|
|
proc = proc_id
|
|
|
|
|
);
|
|
|
|
|
write_doc(dir, "ref-ok.campaign.json", &campaign);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "validate", "ref-ok.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "ref-ok.campaign.json", &campaign);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "validate", "ref-ok.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(0), "stdout/stderr: {out}");
|
|
|
|
|
assert!(out.contains(
|
|
|
|
|
"campaign document valid (referential): all references resolve, axes are in the param space"
|
|
|
|
@@ -404,8 +403,8 @@ fn campaign_validate_in_project_reports_referential_tier_end_to_end() {
|
|
|
|
|
// An unresolved process reference: the fault block + `ref_fault_prose`
|
|
|
|
|
// mapping, prose exit 1, at the same CLI seam.
|
|
|
|
|
let bad = campaign.replace(&proc_id, "0000000000000000000000000000000000000000000000000000000000000000");
|
|
|
|
|
write_doc(dir, "ref-bad.campaign.json", &bad);
|
|
|
|
|
let (out2, code2) = run_code_in(dir, &["campaign", "validate", "ref-bad.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "ref-bad.campaign.json", &bad);
|
|
|
|
|
let (out2, code2) = run_code_in(&dir, &["campaign", "validate", "ref-bad.campaign.json"]);
|
|
|
|
|
assert_eq!(code2, Some(1));
|
|
|
|
|
assert!(out2.contains("campaign references do not resolve:"), "stdout/stderr: {out2}");
|
|
|
|
|
assert!(out2.contains("not found in the project store"), "stdout/stderr: {out2}");
|
|
|
|
@@ -1129,9 +1128,8 @@ fn campaign_run_outside_project_refuses() {
|
|
|
|
|
/// both readings (inside the project, past the project gate).
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_bogus_target_refuses() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "no-such-target"]);
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "no-such-target"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("'no-such-target' is neither a readable .json file nor a 64-hex content id"),
|
|
|
|
@@ -1142,10 +1140,9 @@ fn campaign_run_bogus_target_refuses() {
|
|
|
|
|
/// A well-formed but unknown content id refuses with the store-miss prose.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_unknown_id_refuses() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let id = "0".repeat(64);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", &id]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", &id]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains(&format!("no campaign {id} in the project store")),
|
|
|
|
@@ -1169,8 +1166,7 @@ fn campaign_run_unknown_id_refuses() {
|
|
|
|
|
/// bare-store-line contract exactly.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_runs_lists_and_dumps_the_bare_stored_record() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
std::fs::create_dir_all(&runs_dir).expect("create runs dir");
|
|
|
|
@@ -1185,7 +1181,7 @@ fn campaign_runs_lists_and_dumps_the_bare_stored_record() {
|
|
|
|
|
|
|
|
|
|
// LIST mode: one scannable line per stored record, carrying the campaign
|
|
|
|
|
// id (bare 64-hex or a prefix), exit 0.
|
|
|
|
|
let (list_out, list_code) = run_code_in(dir, &["campaign", "runs"]);
|
|
|
|
|
let (list_out, list_code) = run_code_in(&dir, &["campaign", "runs"]);
|
|
|
|
|
assert_eq!(list_code, Some(0), "list exits 0: {list_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
list_out.contains(&campaign_id[..8]),
|
|
|
|
@@ -1195,7 +1191,7 @@ fn campaign_runs_lists_and_dumps_the_bare_stored_record() {
|
|
|
|
|
// DUMP mode: addressed by the campaign content id, prints the BARE stored
|
|
|
|
|
// record line — the store form, NOT the `{{"campaign_run": …}}` run-emit
|
|
|
|
|
// wrapper (F10) — byte-identical to the seeded line, exit 0.
|
|
|
|
|
let (dump_out, dump_code) = run_code_in(dir, &["campaign", "runs", &campaign_id]);
|
|
|
|
|
let (dump_out, dump_code) = run_code_in(&dir, &["campaign", "runs", &campaign_id]);
|
|
|
|
|
assert_eq!(dump_code, Some(0), "dump exits 0: {dump_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
!dump_out.contains("\"campaign_run\""),
|
|
|
|
@@ -1221,8 +1217,7 @@ fn campaign_runs_lists_and_dumps_the_bare_stored_record() {
|
|
|
|
|
/// depends on.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_runs_dump_round_trips_a_populated_trace_name() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
std::fs::create_dir_all(&runs_dir).expect("create runs dir");
|
|
|
|
@@ -1235,7 +1230,7 @@ fn campaign_runs_dump_round_trips_a_populated_trace_name() {
|
|
|
|
|
std::fs::write(runs_dir.join("campaign_runs.jsonl"), format!("{record_line}\n"))
|
|
|
|
|
.expect("seed the campaign-run store");
|
|
|
|
|
|
|
|
|
|
let (dump_out, dump_code) = run_code_in(dir, &["campaign", "runs", &campaign_id]);
|
|
|
|
|
let (dump_out, dump_code) = run_code_in(&dir, &["campaign", "runs", &campaign_id]);
|
|
|
|
|
assert_eq!(dump_code, Some(0), "dump exits 0: {dump_out}");
|
|
|
|
|
assert_eq!(
|
|
|
|
|
dump_out.trim(),
|
|
|
|
@@ -1254,8 +1249,7 @@ fn campaign_runs_dump_round_trips_a_populated_trace_name() {
|
|
|
|
|
/// runs, with Debug-free PipelineShape prose.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_mc_before_walk_forward() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1263,10 +1257,10 @@ fn campaign_run_refuses_mc_before_walk_forward() {
|
|
|
|
|
ScratchPath::File(dir.join("mcwf.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("mcwf.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-mcwf-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "mcwf.process.json", MC_BEFORE_WF_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "mcwf.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "mcwf.campaign.json"]);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-mcwf-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "mcwf.process.json", MC_BEFORE_WF_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "mcwf.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "mcwf.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(out.contains("process pipeline is not executable:"), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
@@ -1304,8 +1298,7 @@ const SELECTION_FREE_SWEEP_THEN_GATE_PROCESS_DOC: &str = r#"{
|
|
|
|
|
/// nothing for a following stage to consume).
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_a_non_terminal_selection_free_sweep() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1313,11 +1306,11 @@ fn campaign_run_refuses_a_non_terminal_selection_free_sweep() {
|
|
|
|
|
ScratchPath::File(dir.join("selfree.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("selfree.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-selfree-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-selfree-seed");
|
|
|
|
|
let proc_id =
|
|
|
|
|
register_process_doc(dir, "selfree.process.json", SELECTION_FREE_SWEEP_THEN_GATE_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "selfree.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "selfree.campaign.json"]);
|
|
|
|
|
register_process_doc(&dir, "selfree.process.json", SELECTION_FREE_SWEEP_THEN_GATE_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "selfree.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "selfree.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains(
|
|
|
|
@@ -1344,8 +1337,7 @@ const SELECTION_FREE_SWEEP_ONLY_PROCESS_DOC: &str = r#"{
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_validate_accepts_a_terminal_selection_free_sweep() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1353,15 +1345,15 @@ fn campaign_validate_accepts_a_terminal_selection_free_sweep() {
|
|
|
|
|
ScratchPath::File(dir.join("selfreeonly.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("selfreeonly.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-validate-selfreeonly-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-validate-selfreeonly-seed");
|
|
|
|
|
let proc_id =
|
|
|
|
|
register_process_doc(dir, "selfreeonly.process.json", SELECTION_FREE_SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "selfreeonly.process.json", SELECTION_FREE_SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"selfreeonly.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "validate", "selfreeonly.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "validate", "selfreeonly.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(0), "a terminal selection-free sweep validates as executable: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("campaign document valid (executable): pipeline shape and static guards pass"),
|
|
|
|
@@ -1378,8 +1370,7 @@ fn campaign_validate_accepts_a_terminal_selection_free_sweep() {
|
|
|
|
|
/// single-instrument, and this refusal is data-free by construction).
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_single_instrument_generalize() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1387,10 +1378,10 @@ fn campaign_run_refuses_single_instrument_generalize() {
|
|
|
|
|
ScratchPath::File(dir.join("gen1.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("gen1.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-gen1-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "gen1.process.json", GENERALIZE_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "gen1.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "gen1.campaign.json"]);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-gen1-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "gen1.process.json", GENERALIZE_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "gen1.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "gen1.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("std::generalize needs at least 2"),
|
|
|
|
@@ -1423,8 +1414,7 @@ const GENERALIZE_NON_R_PROCESS_DOC: &str = r#"{
|
|
|
|
|
/// would silently accept a pip-denominated `std::generalize`.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_generalize_non_r_metric() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1432,8 +1422,8 @@ fn campaign_run_refuses_generalize_non_r_metric() {
|
|
|
|
|
ScratchPath::File(dir.join("genpip.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("genpip.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-genpip-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "genpip.process.json", GENERALIZE_NON_R_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-genpip-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "genpip.process.json", GENERALIZE_NON_R_PROCESS_DOC);
|
|
|
|
|
// Two instruments (arity passes), so the metric guard is the one that
|
|
|
|
|
// actually fires. The [1, 2] 1970 window never matters: this refusal is
|
|
|
|
|
// data-free, before any member runs.
|
|
|
|
@@ -1451,8 +1441,8 @@ fn campaign_run_refuses_generalize_non_r_metric() {
|
|
|
|
|
"presentation": {{ "persist_taps": [], "emit": [] }}
|
|
|
|
|
}}"#
|
|
|
|
|
);
|
|
|
|
|
write_doc(dir, "genpip.campaign.json", &campaign_doc);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "genpip.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "genpip.campaign.json", &campaign_doc);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "genpip.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
// #207 (fieldtest 0108 F8): the refusal names the REAL rule (the rankable
|
|
|
|
|
// R-expectancy family), never the mislabel "pip metric" — max_r_drawdown is
|
|
|
|
@@ -1505,8 +1495,7 @@ fn process_validate_permits_wf_after_mc_but_campaign_run_refuses_it() {
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// executor tier: campaign run's v2 preflight refuses the same shape.
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1514,10 +1503,10 @@ fn process_validate_permits_wf_after_mc_but_campaign_run_refuses_it() {
|
|
|
|
|
ScratchPath::File(dir.join("wfmc.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("wfmc.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-wfmc-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "wfmc.process.json", WF_AFTER_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "wfmc.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "wfmc.campaign.json"]);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-wfmc-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "wfmc.process.json", WF_AFTER_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "wfmc.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "wfmc.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("std::walk_forward cannot follow std::monte_carlo"),
|
|
|
|
@@ -1545,8 +1534,7 @@ fn process_validate_permits_wf_after_mc_but_campaign_run_refuses_it() {
|
|
|
|
|
/// shape validate clean (exit 0), the F6 friction.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_validate_runs_the_executor_preflight_as_a_third_tier() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1556,15 +1544,15 @@ fn campaign_validate_runs_the_executor_preflight_as_a_third_tier() {
|
|
|
|
|
ScratchPath::File(dir.join("wfmc.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("wfmc.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-validate-3tier-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-validate-3tier-seed");
|
|
|
|
|
|
|
|
|
|
// Face 1 — the happy path: an executable pipeline shape (a bare
|
|
|
|
|
// std::sweep). Intrinsic + referential pass today (exit 0), but the
|
|
|
|
|
// executor tier is invisible; after #205 validate gains the third
|
|
|
|
|
// "valid (executable)" line while staying exit 0.
|
|
|
|
|
let ok_proc = register_process_doc(dir, "runnable.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "runnable.campaign.json", &campaign_doc_json(&bp_id, &ok_proc, (1, 2), "", ""));
|
|
|
|
|
let (ok_out, ok_code) = run_code_in(dir, &["campaign", "validate", "runnable.campaign.json"]);
|
|
|
|
|
let ok_proc = register_process_doc(&dir, "runnable.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "runnable.campaign.json", &campaign_doc_json(&bp_id, &ok_proc, (1, 2), "", ""));
|
|
|
|
|
let (ok_out, ok_code) = run_code_in(&dir, &["campaign", "validate", "runnable.campaign.json"]);
|
|
|
|
|
assert_eq!(ok_code, Some(0), "an executable campaign validates clean: {ok_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
ok_out.contains("campaign document valid (referential): all references resolve"),
|
|
|
|
@@ -1583,9 +1571,9 @@ fn campaign_validate_runs_the_executor_preflight_as_a_third_tier() {
|
|
|
|
|
// reaches the third tier — which refuses the non-executable shape at
|
|
|
|
|
// validate time (data-free: the [1, 2] 1970-epoch-ms window is never
|
|
|
|
|
// reached), exit 1, with the executor fault header + the shape prose.
|
|
|
|
|
let bad_proc = register_process_doc(dir, "wfmc.process.json", WF_AFTER_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "wfmc.campaign.json", &campaign_doc_json(&bp_id, &bad_proc, (1, 2), "", ""));
|
|
|
|
|
let (bad_out, bad_code) = run_code_in(dir, &["campaign", "validate", "wfmc.campaign.json"]);
|
|
|
|
|
let bad_proc = register_process_doc(&dir, "wfmc.process.json", WF_AFTER_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "wfmc.campaign.json", &campaign_doc_json(&bp_id, &bad_proc, (1, 2), "", ""));
|
|
|
|
|
let (bad_out, bad_code) = run_code_in(&dir, &["campaign", "validate", "wfmc.campaign.json"]);
|
|
|
|
|
assert_eq!(bad_code, Some(1), "an executor-unrunnable shape refuses at validate: {bad_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
bad_out.contains("campaign is not executable:"),
|
|
|
|
@@ -1639,8 +1627,7 @@ const WF_PLATEAU_GATED_PROCESS_DOC: &str = r#"{
|
|
|
|
|
/// exit 0 — either direction goes red here.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_validate_narrows_plateau_in_wf_refusal_to_gate_preceded_stages() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1650,19 +1637,19 @@ fn campaign_validate_narrows_plateau_in_wf_refusal_to_gate_preceded_stages() {
|
|
|
|
|
ScratchPath::File(dir.join("wf-plateau-gated.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("wf-plateau-gated.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-validate-wf-plateau-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-validate-wf-plateau-seed");
|
|
|
|
|
|
|
|
|
|
// Face 1 — gate-free: sweep -> walk_forward(plateau:worst). The lattice
|
|
|
|
|
// is intact, so the executor tier accepts it (exit 0).
|
|
|
|
|
let free_id =
|
|
|
|
|
register_process_doc(dir, "wf-plateau-free.process.json", WF_PLATEAU_GATE_FREE_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "wf-plateau-free.process.json", WF_PLATEAU_GATE_FREE_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"wf-plateau-free.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &free_id, (1, 2), "", ""),
|
|
|
|
|
);
|
|
|
|
|
let (free_out, free_code) =
|
|
|
|
|
run_code_in(dir, &["campaign", "validate", "wf-plateau-free.campaign.json"]);
|
|
|
|
|
run_code_in(&dir, &["campaign", "validate", "wf-plateau-free.campaign.json"]);
|
|
|
|
|
assert_eq!(free_code, Some(0), "gate-free plateau walk_forward validates clean: {free_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
free_out.contains(
|
|
|
|
@@ -1675,14 +1662,14 @@ fn campaign_validate_narrows_plateau_in_wf_refusal_to_gate_preceded_stages() {
|
|
|
|
|
// The gate can break the lattice, so the executor tier still refuses it
|
|
|
|
|
// (exit 1), naming the offending stage.
|
|
|
|
|
let gated_id =
|
|
|
|
|
register_process_doc(dir, "wf-plateau-gated.process.json", WF_PLATEAU_GATED_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "wf-plateau-gated.process.json", WF_PLATEAU_GATED_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"wf-plateau-gated.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &gated_id, (1, 2), "", ""),
|
|
|
|
|
);
|
|
|
|
|
let (gated_out, gated_code) =
|
|
|
|
|
run_code_in(dir, &["campaign", "validate", "wf-plateau-gated.campaign.json"]);
|
|
|
|
|
run_code_in(&dir, &["campaign", "validate", "wf-plateau-gated.campaign.json"]);
|
|
|
|
|
assert_eq!(gated_code, Some(1), "gate-preceded plateau walk_forward still refuses: {gated_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
gated_out.contains("campaign is not executable:"),
|
|
|
|
@@ -1717,8 +1704,7 @@ const ZERO_RESAMPLES_MC_PROCESS_DOC: &str = r#"{
|
|
|
|
|
/// would let this refusal disappear or drift to a different message.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_zero_resamples_monte_carlo_before_any_member_runs() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1726,10 +1712,10 @@ fn campaign_run_refuses_zero_resamples_monte_carlo_before_any_member_runs() {
|
|
|
|
|
ScratchPath::File(dir.join("zeromc.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("zeromc.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-zeromc-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "zeromc.process.json", ZERO_RESAMPLES_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "zeromc.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "zeromc.campaign.json"]);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-zeromc-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "zeromc.process.json", ZERO_RESAMPLES_MC_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "zeromc.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "zeromc.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("process stage 1: monte_carlo resamples must be > 0"),
|
|
|
|
@@ -1749,8 +1735,7 @@ fn campaign_run_refuses_zero_resamples_monte_carlo_before_any_member_runs() {
|
|
|
|
|
/// pinned here.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_refuses_unknown_tap_at_validate() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1758,14 +1743,14 @@ fn campaign_run_refuses_unknown_tap_at_validate() {
|
|
|
|
|
ScratchPath::File(dir.join("badtap.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("badtap.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-badtap-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "badtap.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-badtap-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "badtap.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"badtap.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &proc_id, (1, 2), "\"r_record\"", ""),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "badtap.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "badtap.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(out.contains("campaign document invalid:"), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
@@ -1794,8 +1779,7 @@ fn campaign_run_refuses_unknown_tap_at_validate() {
|
|
|
|
|
/// tightens this test to pin its absence.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_valid_tap_reaches_the_member_data_seam() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1803,14 +1787,14 @@ fn campaign_run_valid_tap_reaches_the_member_data_seam() {
|
|
|
|
|
ScratchPath::File(dir.join("taps.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("taps.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-taps-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "taps.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-taps-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "taps.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"taps.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &proc_id, (1, 2), "\"equity\"", ""),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "taps.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "taps.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
!out.contains("unknown tap"),
|
|
|
|
@@ -1849,8 +1833,7 @@ fn campaign_run_valid_tap_reaches_the_member_data_seam() {
|
|
|
|
|
/// stays green on a data-less machine.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_sweep_gate_walkforward() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -1858,12 +1841,12 @@ fn campaign_run_real_e2e_sweep_gate_walkforward() {
|
|
|
|
|
ScratchPath::File(dir.join("wf.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("wf.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-e2e-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "wf.process.json", WF_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-e2e-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "wf.process.json", WF_PROCESS_DOC);
|
|
|
|
|
// The GER40 Sept-2024 window (inclusive Unix-ms) — the same gated window
|
|
|
|
|
// cli_run.rs drives; ~30 days, so the (14d, 7d, 7d) roller tiles it.
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"wf.campaign.json",
|
|
|
|
|
&campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
@@ -1873,7 +1856,7 @@ fn campaign_run_real_e2e_sweep_gate_walkforward() {
|
|
|
|
|
"\"family_table\", \"selection_report\"",
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "wf.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "wf.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -1999,7 +1982,7 @@ fn campaign_run_real_e2e_sweep_gate_walkforward() {
|
|
|
|
|
// The shipped viewer reads the member back (the cli_run.rs chart
|
|
|
|
|
// idiom): exit 0 and an HTML page carrying both persisted tap series.
|
|
|
|
|
let (chart_out, chart_code) =
|
|
|
|
|
run_code_in(dir, &["chart", &format!("{trace_name}/{cell_key}")]);
|
|
|
|
|
run_code_in(&dir, &["chart", &format!("{trace_name}/{cell_key}")]);
|
|
|
|
|
assert_eq!(chart_code, Some(0), "aura chart reads the persisted member: {chart_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
chart_out.contains("\"equity\"") && chart_out.contains("\"r_equity\""),
|
|
|
|
@@ -2015,8 +1998,7 @@ fn campaign_run_real_e2e_sweep_gate_walkforward() {
|
|
|
|
|
/// Gated on the local GER40 archive; skips cleanly when absent.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_bindings_override_rebinds_price_to_open() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2025,8 +2007,8 @@ fn campaign_run_real_e2e_bindings_override_rebinds_price_to_open() {
|
|
|
|
|
ScratchPath::File(dir.join("close.campaign.json")),
|
|
|
|
|
ScratchPath::File(dir.join("open.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "binding-override-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "sweep.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "binding-override-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "sweep.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2039,10 +2021,10 @@ fn campaign_run_real_e2e_bindings_override_rebinds_price_to_open() {
|
|
|
|
|
r#""data": { "bindings": { "price": "open" }, "instruments": ["GER40"],"#,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(rebound, base, "the override splice must hit the data section");
|
|
|
|
|
write_doc(dir, "close.campaign.json", &base);
|
|
|
|
|
write_doc(dir, "open.campaign.json", &rebound);
|
|
|
|
|
write_doc(&dir, "close.campaign.json", &base);
|
|
|
|
|
write_doc(&dir, "open.campaign.json", &rebound);
|
|
|
|
|
|
|
|
|
|
let (out_close, code_close) = run_code_in(dir, &["campaign", "run", "close.campaign.json"]);
|
|
|
|
|
let (out_close, code_close) = run_code_in(&dir, &["campaign", "run", "close.campaign.json"]);
|
|
|
|
|
if code_close == Some(1)
|
|
|
|
|
&& (out_close.contains("no recorded geometry") || out_close.contains("no data for instrument"))
|
|
|
|
|
{
|
|
|
|
@@ -2050,7 +2032,7 @@ fn campaign_run_real_e2e_bindings_override_rebinds_price_to_open() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(code_close, Some(0), "stdout/stderr: {out_close}");
|
|
|
|
|
let (out_open, code_open) = run_code_in(dir, &["campaign", "run", "open.campaign.json"]);
|
|
|
|
|
let (out_open, code_open) = run_code_in(&dir, &["campaign", "run", "open.campaign.json"]);
|
|
|
|
|
assert_eq!(code_open, Some(0), "stdout/stderr: {out_open}");
|
|
|
|
|
|
|
|
|
|
let first_member = |out: &str| -> serde_json::Value {
|
|
|
|
@@ -2081,8 +2063,7 @@ fn campaign_run_real_e2e_bindings_override_rebinds_price_to_open() {
|
|
|
|
|
/// above; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_non_default_regime_stamps_its_own_stop() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2090,8 +2071,8 @@ fn campaign_run_real_e2e_non_default_regime_stamps_its_own_stop() {
|
|
|
|
|
ScratchPath::File(dir.join("regime.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("regime.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-regime-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "regime.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-regime-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "regime.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2105,8 +2086,8 @@ fn campaign_run_real_e2e_non_default_regime_stamps_its_own_stop() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_regime, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "regime.campaign.json", &with_regime);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "regime.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "regime.campaign.json", &with_regime);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "regime.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
if code == Some(1)
|
|
|
|
|
&& (out.contains("no recorded geometry") || out.contains("no data for instrument"))
|
|
|
|
@@ -2151,8 +2132,7 @@ fn campaign_run_real_e2e_non_default_regime_stamps_its_own_stop() {
|
|
|
|
|
/// on the local GER40 archive like its siblings; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_two_regimes_each_stamp_their_own_stop() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2160,8 +2140,8 @@ fn campaign_run_real_e2e_two_regimes_each_stamp_their_own_stop() {
|
|
|
|
|
ScratchPath::File(dir.join("tworegimes.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("tworegimes.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-two-regimes-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "tworegimes.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-two-regimes-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "tworegimes.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2176,8 +2156,8 @@ fn campaign_run_real_e2e_two_regimes_each_stamp_their_own_stop() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_regimes, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "tworegimes.campaign.json", &with_regimes);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "tworegimes.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "tworegimes.campaign.json", &with_regimes);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "tworegimes.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
if code == Some(1)
|
|
|
|
|
&& (out.contains("no recorded geometry") || out.contains("no data for instrument"))
|
|
|
|
@@ -2236,8 +2216,7 @@ fn campaign_run_real_e2e_two_regimes_each_stamp_their_own_stop() {
|
|
|
|
|
/// archive like its siblings; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_persist_non_default_regime_does_not_false_fail_c1() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2245,9 +2224,9 @@ fn campaign_persist_non_default_regime_does_not_false_fail_c1() {
|
|
|
|
|
ScratchPath::File(dir.join("regime-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("regime-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-regime-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-regime-seed");
|
|
|
|
|
let proc_id =
|
|
|
|
|
register_process_doc(dir, "regime-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "regime-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2264,8 +2243,8 @@ fn campaign_persist_non_default_regime_does_not_false_fail_c1() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_regime, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "regime-persist.campaign.json", &with_regime);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "regime-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "regime-persist.campaign.json", &with_regime);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "regime-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2321,8 +2300,7 @@ fn campaign_persist_non_default_regime_does_not_false_fail_c1() {
|
|
|
|
|
/// the local GER40 archive; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_costed_campaign_persists_without_drift_alarm() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2330,8 +2308,8 @@ fn campaign_run_real_e2e_costed_campaign_persists_without_drift_alarm() {
|
|
|
|
|
ScratchPath::File(dir.join("cost-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("cost-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-cost-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "cost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-cost-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "cost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2345,8 +2323,8 @@ fn campaign_run_real_e2e_costed_campaign_persists_without_drift_alarm() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_cost, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "cost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "cost-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "cost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "cost-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2417,8 +2395,7 @@ fn campaign_run_real_e2e_costed_campaign_persists_without_drift_alarm() {
|
|
|
|
|
/// archive; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_net_r_equity_tap_persists_the_cost_adjusted_curve() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2426,8 +2403,8 @@ fn campaign_run_real_e2e_net_r_equity_tap_persists_the_cost_adjusted_curve() {
|
|
|
|
|
ScratchPath::File(dir.join("net-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("net-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-net-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "net-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-net-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "net-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2441,8 +2418,8 @@ fn campaign_run_real_e2e_net_r_equity_tap_persists_the_cost_adjusted_curve() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_cost, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "net-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "net-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "net-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "net-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2531,8 +2508,7 @@ fn campaign_run_real_e2e_net_r_equity_tap_persists_the_cost_adjusted_curve() {
|
|
|
|
|
/// wired). Gated on the local GER40 archive; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_vol_slippage_cost_persists_without_drift_alarm() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2540,9 +2516,9 @@ fn campaign_run_real_e2e_vol_slippage_cost_persists_without_drift_alarm() {
|
|
|
|
|
ScratchPath::File(dir.join("volcost-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("volcost-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-volcost-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-volcost-seed");
|
|
|
|
|
let proc_id =
|
|
|
|
|
register_process_doc(dir, "volcost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "volcost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2556,8 +2532,8 @@ fn campaign_run_real_e2e_vol_slippage_cost_persists_without_drift_alarm() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_cost, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "volcost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "volcost-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "volcost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "volcost-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2617,8 +2593,7 @@ fn campaign_run_real_e2e_vol_slippage_cost_persists_without_drift_alarm() {
|
|
|
|
|
/// into one dir. Gated on the local GER40 archive; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_persist_two_regimes_land_in_distinct_trace_dirs() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2626,9 +2601,9 @@ fn campaign_persist_two_regimes_land_in_distinct_trace_dirs() {
|
|
|
|
|
ScratchPath::File(dir.join("tworegimes-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("tworegimes-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-two-regimes-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-two-regimes-seed");
|
|
|
|
|
let proc_id = register_process_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"tworegimes-persist.process.json",
|
|
|
|
|
SWEEP_ONLY_PROCESS_DOC,
|
|
|
|
|
);
|
|
|
|
@@ -2646,8 +2621,8 @@ fn campaign_persist_two_regimes_land_in_distinct_trace_dirs() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_regimes, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "tworegimes-persist.campaign.json", &with_regimes);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "tworegimes-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "tworegimes-persist.campaign.json", &with_regimes);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "tworegimes-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2704,8 +2679,7 @@ fn campaign_persist_two_regimes_land_in_distinct_trace_dirs() {
|
|
|
|
|
/// host like its siblings.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_skips_unproducible_tap_gracefully() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2713,10 +2687,10 @@ fn campaign_run_real_e2e_skips_unproducible_tap_gracefully() {
|
|
|
|
|
ScratchPath::File(dir.join("mixedtap.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("mixedtap.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-mixedtap-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "mixedtap.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-mixedtap-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "mixedtap.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"mixedtap.campaign.json",
|
|
|
|
|
&campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
@@ -2726,7 +2700,7 @@ fn campaign_run_real_e2e_skips_unproducible_tap_gracefully() {
|
|
|
|
|
"",
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "mixedtap.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "mixedtap.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -2781,8 +2755,7 @@ fn campaign_run_real_e2e_skips_unproducible_tap_gracefully() {
|
|
|
|
|
/// manifests). Skips on a data-less host like its siblings.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2791,8 +2764,8 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
ScratchPath::File(dir.join("costless.campaign.json")),
|
|
|
|
|
ScratchPath::File(dir.join("costnet.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-costnet-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "costnet.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-costnet-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "costnet.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2809,8 +2782,8 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_cost, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "costless.campaign.json", &base);
|
|
|
|
|
write_doc(dir, "costnet.campaign.json", &with_cost);
|
|
|
|
|
write_doc(&dir, "costless.campaign.json", &base);
|
|
|
|
|
write_doc(&dir, "costnet.campaign.json", &with_cost);
|
|
|
|
|
|
|
|
|
|
// Per-member (axis-params key -> (expectancy_r, net_expectancy_r)),
|
|
|
|
|
// parsed from the emitted family_table member lines. Cost stamps are
|
|
|
|
@@ -2843,7 +2816,7 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
|
|
|
|
|
// (a) the cost-less baseline: net == gross, and net_r_equity skips with
|
|
|
|
|
// the remedy notice while equity still persists.
|
|
|
|
|
let (out_gross, code_gross) = run_code_in(dir, &["campaign", "run", "costless.campaign.json"]);
|
|
|
|
|
let (out_gross, code_gross) = run_code_in(&dir, &["campaign", "run", "costless.campaign.json"]);
|
|
|
|
|
if code_gross == Some(1)
|
|
|
|
|
&& (out_gross.contains("no recorded geometry") || out_gross.contains("no data for instrument"))
|
|
|
|
|
{
|
|
|
|
@@ -2865,7 +2838,7 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
|
|
|
|
|
// (b) the costed run: gross identical member-for-member, net strictly
|
|
|
|
|
// below gross, no skip notice, net_r_equity persisted on disk.
|
|
|
|
|
let (out_net, code_net) = run_code_in(dir, &["campaign", "run", "costnet.campaign.json"]);
|
|
|
|
|
let (out_net, code_net) = run_code_in(&dir, &["campaign", "run", "costnet.campaign.json"]);
|
|
|
|
|
assert_eq!(code_net, Some(0), "costed run: {out_net}");
|
|
|
|
|
assert!(
|
|
|
|
|
!out_net.contains("skipped"),
|
|
|
|
@@ -2916,7 +2889,7 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
.to_string()
|
|
|
|
|
})
|
|
|
|
|
.expect("a costed member line carries the family id");
|
|
|
|
|
let (rep_out, rep_code) = run_code_in(dir, &["reproduce", &family_id]);
|
|
|
|
|
let (rep_out, rep_code) = run_code_in(&dir, &["reproduce", &family_id]);
|
|
|
|
|
assert_eq!(rep_code, Some(0), "reproduce: {rep_out}");
|
|
|
|
|
assert!(
|
|
|
|
|
rep_out.contains("reproduced 4/4 members bit-identically"),
|
|
|
|
@@ -2939,8 +2912,7 @@ fn campaign_run_real_e2e_cost_block_nets_members_and_persists_net_r_equity() {
|
|
|
|
|
/// local GER40 archive; skips on a data-less host.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_carry_cost_persists_without_drift_alarm() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -2948,9 +2920,9 @@ fn campaign_run_real_e2e_carry_cost_persists_without_drift_alarm() {
|
|
|
|
|
ScratchPath::File(dir.join("carrycost-persist.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("carrycost-persist.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-persist-carrycost-seed");
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-persist-carrycost-seed");
|
|
|
|
|
let proc_id =
|
|
|
|
|
register_process_doc(dir, "carrycost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
register_process_doc(&dir, "carrycost-persist.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
let base = campaign_doc_json(
|
|
|
|
|
&bp_id,
|
|
|
|
|
&proc_id,
|
|
|
|
@@ -2964,8 +2936,8 @@ fn campaign_run_real_e2e_carry_cost_persists_without_drift_alarm() {
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(with_cost, base, "replacen must actually match the fixture's seed field");
|
|
|
|
|
write_doc(dir, "carrycost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "carrycost-persist.campaign.json"]);
|
|
|
|
|
write_doc(&dir, "carrycost-persist.campaign.json", &with_cost);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "carrycost-persist.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -3021,8 +2993,7 @@ fn campaign_run_real_e2e_carry_cost_persists_without_drift_alarm() {
|
|
|
|
|
/// data-free refusal fixture).
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_real_e2e_sweep_monte_carlo_per_survivor() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -3030,15 +3001,15 @@ fn campaign_run_real_e2e_sweep_monte_carlo_per_survivor() {
|
|
|
|
|
ScratchPath::File(dir.join("mc.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("mc.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-mc-persurvivor-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "mc.process.json", MC_PROCESS_DOC);
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-mc-persurvivor-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "mc.process.json", MC_PROCESS_DOC);
|
|
|
|
|
// Same GER40 Sept-2024 window as the gated wf e2e above.
|
|
|
|
|
write_doc(
|
|
|
|
|
dir,
|
|
|
|
|
&dir,
|
|
|
|
|
"mc.campaign.json",
|
|
|
|
|
&campaign_doc_json(&bp_id, &proc_id, (1725148800000, 1727740799999), "", ""),
|
|
|
|
|
);
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "mc.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "mc.campaign.json"]);
|
|
|
|
|
|
|
|
|
|
// Skip on a data-less machine: the member-data refusal, never a panic.
|
|
|
|
|
if code == Some(1)
|
|
|
|
@@ -3095,8 +3066,7 @@ fn campaign_run_real_e2e_sweep_monte_carlo_per_survivor() {
|
|
|
|
|
/// prose either way (the message depends only on env/instrument/window).
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_by_content_id_matches_file_sugar_refusal() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -3104,14 +3074,14 @@ fn campaign_run_by_content_id_matches_file_sugar_refusal() {
|
|
|
|
|
ScratchPath::File(dir.join("mc2.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("mc2.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-id-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "mc2.process.json", MC_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "mc2.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-id-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "mc2.process.json", MC_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "mc2.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
|
|
|
|
|
let (file_out, file_code) = run_code_in(dir, &["campaign", "run", "mc2.campaign.json"]);
|
|
|
|
|
let (file_out, file_code) = run_code_in(&dir, &["campaign", "run", "mc2.campaign.json"]);
|
|
|
|
|
assert_eq!(file_code, Some(1), "stdout/stderr: {file_out}");
|
|
|
|
|
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(dir, &["campaign", "register", "mc2.campaign.json"]);
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(&dir, &["campaign", "register", "mc2.campaign.json"]);
|
|
|
|
|
assert_eq!(reg_code, Some(0), "register failed: {reg_out}");
|
|
|
|
|
let id = reg_out
|
|
|
|
|
.lines()
|
|
|
|
@@ -3123,7 +3093,7 @@ fn campaign_run_by_content_id_matches_file_sugar_refusal() {
|
|
|
|
|
.expect("id")
|
|
|
|
|
.trim_start_matches("content:")
|
|
|
|
|
.to_string();
|
|
|
|
|
let (id_out, id_code) = run_code_in(dir, &["campaign", "run", &id]);
|
|
|
|
|
let (id_out, id_code) = run_code_in(&dir, &["campaign", "run", &id]);
|
|
|
|
|
assert_eq!(id_code, Some(1), "stdout/stderr: {id_out}");
|
|
|
|
|
|
|
|
|
|
let file_line = file_out.lines().find(|l| l.starts_with("aura: ")).expect("file refusal line");
|
|
|
|
@@ -3146,8 +3116,7 @@ fn campaign_run_by_content_id_matches_file_sugar_refusal() {
|
|
|
|
|
/// needed.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_tolerates_content_prefix_on_target() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -3155,11 +3124,11 @@ fn campaign_run_tolerates_content_prefix_on_target() {
|
|
|
|
|
ScratchPath::File(dir.join("prefix.process.json")),
|
|
|
|
|
ScratchPath::File(dir.join("prefix.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let bp_id = seed_blueprint(dir, "campaign-run-prefix-seed");
|
|
|
|
|
let proc_id = register_process_doc(dir, "prefix.process.json", MC_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "prefix.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let bp_id = seed_blueprint(&dir, "campaign-run-prefix-seed");
|
|
|
|
|
let proc_id = register_process_doc(&dir, "prefix.process.json", MC_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "prefix.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(dir, &["campaign", "register", "prefix.campaign.json"]);
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(&dir, &["campaign", "register", "prefix.campaign.json"]);
|
|
|
|
|
assert_eq!(reg_code, Some(0), "register failed: {reg_out}");
|
|
|
|
|
let id = reg_out
|
|
|
|
|
.lines()
|
|
|
|
@@ -3172,8 +3141,8 @@ fn campaign_run_tolerates_content_prefix_on_target() {
|
|
|
|
|
.trim_start_matches("content:")
|
|
|
|
|
.to_string();
|
|
|
|
|
|
|
|
|
|
let (bare_out, _) = run_code_in(dir, &["campaign", "run", &id]);
|
|
|
|
|
let (pfx_out, _) = run_code_in(dir, &["campaign", "run", &format!("content:{id}")]);
|
|
|
|
|
let (bare_out, _) = run_code_in(&dir, &["campaign", "run", &id]);
|
|
|
|
|
let (pfx_out, _) = run_code_in(&dir, &["campaign", "run", &format!("content:{id}")]);
|
|
|
|
|
|
|
|
|
|
let pfx_line = pfx_out.lines().find(|l| l.starts_with("aura: ")).expect("prefixed refusal line");
|
|
|
|
|
assert!(
|
|
|
|
@@ -3201,8 +3170,7 @@ fn campaign_run_tolerates_content_prefix_on_target() {
|
|
|
|
|
/// data-free refusal) rather than failing earlier at referencing or binding.
|
|
|
|
|
#[test]
|
|
|
|
|
fn campaign_run_accepts_a_graph_register_seeded_strategy() {
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let _cleanup = ScratchGuard(vec![
|
|
|
|
@@ -3211,7 +3179,7 @@ fn campaign_run_accepts_a_graph_register_seeded_strategy() {
|
|
|
|
|
ScratchPath::File(dir.join("onramp.campaign.json")),
|
|
|
|
|
]);
|
|
|
|
|
let closed_bp = format!("{}/examples/r_sma.json", env!("CARGO_MANIFEST_DIR"));
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(dir, &["graph", "register", &closed_bp]);
|
|
|
|
|
let (reg_out, reg_code) = run_code_in(&dir, &["graph", "register", &closed_bp]);
|
|
|
|
|
assert_eq!(reg_code, Some(0), "graph register failed: {reg_out}");
|
|
|
|
|
let bp_id = reg_out
|
|
|
|
|
.lines()
|
|
|
|
@@ -3224,9 +3192,9 @@ fn campaign_run_accepts_a_graph_register_seeded_strategy() {
|
|
|
|
|
.trim_start_matches("content:")
|
|
|
|
|
.to_string();
|
|
|
|
|
|
|
|
|
|
let proc_id = register_process_doc(dir, "onramp.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(dir, "onramp.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "onramp.campaign.json"]);
|
|
|
|
|
let proc_id = register_process_doc(&dir, "onramp.process.json", SWEEP_ONLY_PROCESS_DOC);
|
|
|
|
|
write_doc(&dir, "onramp.campaign.json", &campaign_doc_json(&bp_id, &proc_id, (1, 2), "", ""));
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "onramp.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("no recorded geometry") || out.contains("no data for instrument"),
|
|
|
|
@@ -3248,15 +3216,14 @@ fn campaign_run_invalid_file_refuses_before_touching_store() {
|
|
|
|
|
// Run inside the built project (campaign run needs one, per the project
|
|
|
|
|
// gate); the document fails intrinsic validation before any store or
|
|
|
|
|
// referential check is reached, so the project's own store is untouched.
|
|
|
|
|
let _fixture = project_lock();
|
|
|
|
|
let dir = built_project();
|
|
|
|
|
let (dir, _fixture) = fresh_project();
|
|
|
|
|
let runs_dir = dir.join("runs");
|
|
|
|
|
std::fs::remove_dir_all(&runs_dir).ok();
|
|
|
|
|
let bad = CAMPAIGN_DOC.replacen(r#""values": [8]"#, r#""values": []"#, 1);
|
|
|
|
|
let bad_path = write_doc(dir, "bad.campaign.json", &bad);
|
|
|
|
|
let bad_path = write_doc(&dir, "bad.campaign.json", &bad);
|
|
|
|
|
let _cleanup = ScratchGuard(vec![ScratchPath::Dir(runs_dir.clone()), ScratchPath::File(bad_path)]);
|
|
|
|
|
|
|
|
|
|
let (out, code) = run_code_in(dir, &["campaign", "run", "bad.campaign.json"]);
|
|
|
|
|
let (out, code) = run_code_in(&dir, &["campaign", "run", "bad.campaign.json"]);
|
|
|
|
|
assert_eq!(code, Some(1), "stdout/stderr: {out}");
|
|
|
|
|
assert!(
|
|
|
|
|
out.contains("aura: campaign document invalid:"),
|
|
|
|
|