mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 14:38:12 +02:00
Lot 25 : Strata tenu par la façade (LOKI_STRATA=rust)
Port de backend_strata.go (rust/loki-rs/src/strata) : la machine (cartes par nvidia-smi, Python 3.10+ et venv, RAM totale et disponible, RAM du moteur Strata en marche, place libre), ce qui y tient et la recommandation, la configuration de lancement en clair des modèles installés (placement des experts drop/ram/arena/disk, carte d'aide, réglages du preset), les réglages d'un modèle installé et l'installation (job des moteurs : paquet figé vérifié par SHA-256, installeur lancé et journalisé comme le sinkWriter du Go, preset écrit puis activé par le Go). Tenu seulement avec LOKI_BACKENDS=rust ; le lancement (loki serve) reste au Go, qui relaie les routes du tunnel. Correction du Go : /api/strata/settings décidait « en service » après avoir écrit les nouveaux réglages, donc jamais pour un réglage changé ; décidé désormais avant l'écriture, comme SavePresetApplying. Le port suit. Parité : parity_strata_test.go (crochets de test : release, meminfo, place libre, action de service) tire du Go un journal rejoué par tests/strata.rs ; les tests du Go portés dans strata/tests.rs ; TestFacadeStrata côté Go. Mutations : 71 tuées sur 71. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
22 files changed
+9079
-19
No files matched your search
@@ -0,0 +1,485 @@
|
||||
//! Les tests du Go (`backend_strata_test.go`), portés.
|
||||
|
||||
use super::*;
|
||||
|
||||
fn cfg(kv: &[(&str, &str)]) -> Cfg {
|
||||
kv.iter()
|
||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn args_of(v: &Value) -> Vec<String> {
|
||||
arg_list(v)
|
||||
}
|
||||
|
||||
fn arg_after(args: &[String], flag: &str) -> String {
|
||||
args.windows(2)
|
||||
.find(|w| w[0] == flag)
|
||||
.map(|w| w[1].clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reglages_valides_appliques() {
|
||||
let base = json!({
|
||||
"exe": "/x/engine-cuda12/strata",
|
||||
"args": ["--pack", "/p", "--prefill", "8192", "--max-context", "131072"],
|
||||
"port": 8080.0,
|
||||
});
|
||||
let out = build_config(
|
||||
&base,
|
||||
&cfg(&[("PORT", "8081"), ("CTX", "65536")]),
|
||||
"k",
|
||||
"ram",
|
||||
)
|
||||
.unwrap();
|
||||
let a = args_of(&out);
|
||||
for (flag, want) in [
|
||||
("--prefill", "16384"),
|
||||
("--short-read", "150"),
|
||||
("--prompt-cache-root", "256"),
|
||||
("--max-context", "65536"),
|
||||
("--pack", "/p"),
|
||||
] {
|
||||
assert_eq!(arg_after(&a, flag), want, "{flag} : {a:?}");
|
||||
}
|
||||
assert_eq!(a.join(" ").matches("--prefill").count(), 1);
|
||||
assert!(!has_arg(&a, "--remote-expert-opt") && !has_arg(&a, "--expert-cache-device1"));
|
||||
assert_eq!(out["port"], 8081);
|
||||
assert_eq!(out["api_key"], "k");
|
||||
assert_eq!(out["host"], "127.0.0.1");
|
||||
assert_eq!(base["args"][3], "8192", "la config de base est modifiée");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn carte_d_aide() {
|
||||
let base = json!({
|
||||
"args": ["--pack", "/p", "--mmap-experts", "--vram-reserve-mib", "700"],
|
||||
"gpu": 1.0,
|
||||
"vision": { "exe": "v", "gpu": true },
|
||||
});
|
||||
let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "0")]), "", "ram").unwrap();
|
||||
let a = args_of(&out);
|
||||
assert_eq!(arg_after(&a, "--expert-cache-device1"), "auto");
|
||||
assert!(has_arg(&a, "--remote-expert-opt"));
|
||||
assert!(!has_arg(&a, "--vram-reserve-mib") && !has_arg(&a, "700"));
|
||||
assert!(out.get("api_key").is_none());
|
||||
assert!(out.get("gpu").is_none());
|
||||
assert_eq!(out["vision"]["cuda_device"], 0);
|
||||
assert_eq!(out["env"]["STRATA_PLE_BATCH"], "0");
|
||||
assert!(build_config(&json!({}), &Cfg::new(), "", "ram").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cartes_cuda() {
|
||||
for (main, helper, want) in [
|
||||
("1", "0", "1,0"),
|
||||
("0", "-1", "0"),
|
||||
("0", "", "0"),
|
||||
("", "", ""),
|
||||
("-1", "0", ""),
|
||||
] {
|
||||
assert_eq!(
|
||||
cuda_devices(&cfg(&[
|
||||
("STRATA_MAIN_GPU", main),
|
||||
("STRATA_HELPER_GPU", helper)
|
||||
])),
|
||||
want
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn machine() -> Env {
|
||||
Env {
|
||||
supported: true,
|
||||
main: 1,
|
||||
helper: 0,
|
||||
ram_gb: 47.0,
|
||||
avail_gb: 47.0,
|
||||
disk_free_gb: 400.0,
|
||||
gpus: vec![
|
||||
Gpu {
|
||||
index: 0,
|
||||
name: String::new(),
|
||||
vram_gb: 8.0,
|
||||
arch: 86,
|
||||
},
|
||||
Gpu {
|
||||
index: 1,
|
||||
name: String::new(),
|
||||
vram_gb: 16.0,
|
||||
arch: 120,
|
||||
},
|
||||
],
|
||||
..Env::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recommandation() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
let p = Paths {
|
||||
home: d.path().to_path_buf(),
|
||||
};
|
||||
let mut env = machine();
|
||||
assert_eq!(recommend(&p, "swift", &env), "IQ3_XXS");
|
||||
assert_eq!(recommend(&p, "qwen", &env), "IQ3_XXS");
|
||||
assert_eq!(recommend(&p, "autre", &env), "");
|
||||
let f = fit_for(quant("IQ3_XXS").unwrap(), &env, 0.0);
|
||||
assert!(f.ok && f.mmap && !f.drop);
|
||||
env.ram_gb = 64.0;
|
||||
env.avail_gb = 64.0;
|
||||
assert_eq!(recommend(&p, "qwen", &env), "IQ3_S");
|
||||
let small = Env {
|
||||
supported: true,
|
||||
main: 0,
|
||||
helper: -1,
|
||||
ram_gb: 16.0,
|
||||
disk_free_gb: 400.0,
|
||||
gpus: vec![Gpu {
|
||||
index: 0,
|
||||
name: String::new(),
|
||||
vram_gb: 8.0,
|
||||
arch: 86,
|
||||
}],
|
||||
..Env::default()
|
||||
};
|
||||
assert_eq!(recommend(&p, "swift", &small), "");
|
||||
env.disk_free_gb = 50.0;
|
||||
assert!(!fit_for(quant("Q2_0").unwrap(), &env, 0.0).ok);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn noms() {
|
||||
assert_eq!(
|
||||
preset_name("swift", "IQ3_XXS"),
|
||||
"STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS"
|
||||
);
|
||||
assert_eq!(
|
||||
preset_name("qwen", "Q2_0"),
|
||||
"STRATA FLASH NEXT CLASSIQUE Q2_0"
|
||||
);
|
||||
assert_eq!(family_label("qwen"), "Qwen3.8 Flash Next");
|
||||
assert_eq!(family_label("swift"), "Qwen3.8 Flash Next Swift 1.5");
|
||||
assert_eq!(family_label("x"), "x");
|
||||
assert_eq!(config_tag("/a/strata-swift-iq3_xxs.json"), "swift-iq3_xxs");
|
||||
assert_eq!(config_tag("autre.json"), "autre");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn donnees_deja_la() {
|
||||
let mut env = machine();
|
||||
env.avail_gb = 0.0;
|
||||
env.disk_free_gb = 32.0;
|
||||
assert!(fit_for(quant("IQ3_XXS").unwrap(), &env, 120.0).ok);
|
||||
assert!(!fit_for(quant("IQ3_XXS").unwrap(), &env, 0.0).ok);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reglages_du_preset() {
|
||||
let base = json!({ "args": ["--kv", "int8", "--spec", "4"] });
|
||||
let out = build_config(
|
||||
&base,
|
||||
&cfg(&[("STRATA_KV", "fp16"), ("STRATA_SPEC", "3")]),
|
||||
"",
|
||||
"ram",
|
||||
)
|
||||
.unwrap();
|
||||
let a = args_of(&out);
|
||||
assert_eq!(arg_after(&a, "--kv"), "fp16");
|
||||
assert_eq!(arg_after(&a, "--spec"), "3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deja_sur_le_disque() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
let p = Paths {
|
||||
home: d.path().to_path_buf(),
|
||||
};
|
||||
let write = |rel: &str, n: usize| {
|
||||
let f = p.data_dir().join(rel);
|
||||
std::fs::create_dir_all(f.parent().unwrap()).unwrap();
|
||||
std::fs::write(f, vec![0u8; n]).unwrap();
|
||||
};
|
||||
write("models/swift-IQ3_XXS/a.gguf", 3000);
|
||||
write("packs/swift-iq3_xxs/experts.bin", 2000);
|
||||
write("mtp/rt/x", 500);
|
||||
write("models/IQ2_XS/b.gguf", 7000);
|
||||
assert_eq!((have_gb(&p, "swift", "IQ3_XXS") * 1e9).round(), 5500.0);
|
||||
assert_eq!((have_gb(&p, "swift", "IQ2_XS") * 1e9).round(), 500.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reglages() {
|
||||
let input =
|
||||
"# NAME=x\nENGINE=strata\nCTX=131072\nSTRATA_KV=fp16\nSTRATA_SPEC=3\nSTRATA_HELPER_GPU=0\n";
|
||||
let r = SettingsReq {
|
||||
ctx: 65536,
|
||||
kv: "int8".into(),
|
||||
spec: 4,
|
||||
..SettingsReq::default()
|
||||
};
|
||||
let out = apply_settings(input, &r).unwrap();
|
||||
let c = crate::presets::parse_env(&out);
|
||||
for (k, v) in [
|
||||
("CTX", "65536"),
|
||||
("STRATA_KV", "int8"),
|
||||
("STRATA_SPEC", "4"),
|
||||
("STRATA_VISION", "0"),
|
||||
("STRATA_HELPER", "0"),
|
||||
("STRATA_HELPER_GPU", "0"),
|
||||
("ENGINE", "strata"),
|
||||
] {
|
||||
assert_eq!(c.get(k).map(String::as_str), Some(v), "{k} : {out:?}");
|
||||
}
|
||||
assert_eq!(out.matches("CTX=").count(), 1);
|
||||
// Les bornes acceptées.
|
||||
for (ctx, spec) in [(32768, 2), (MAX_CTX, 4)] {
|
||||
let ok = SettingsReq {
|
||||
ctx,
|
||||
kv: "fp16".into(),
|
||||
spec,
|
||||
..SettingsReq::default()
|
||||
};
|
||||
assert!(apply_settings(input, &ok).is_ok(), "{ctx} {spec}");
|
||||
}
|
||||
assert!(!helper_on(&c));
|
||||
assert_eq!(
|
||||
cuda_devices(&cfg(&[
|
||||
("STRATA_MAIN_GPU", "1"),
|
||||
("STRATA_HELPER_GPU", "0"),
|
||||
("STRATA_HELPER", "0")
|
||||
])),
|
||||
"1"
|
||||
);
|
||||
let base = json!({ "args": ["--vision", "--pack", "/p"], "vision": { "exe": "v" } });
|
||||
let b = build_config(&base, &c, "", "ram").unwrap();
|
||||
let a = args_of(&b);
|
||||
assert!(!has_arg(&a, "--vision") && b.get("vision").is_none());
|
||||
assert!(!has_arg(&a, "--expert-cache-device1"));
|
||||
for (ctx, kv, spec, why) in [
|
||||
(1000, "fp16", 3, "contexte hors limites : 1000"),
|
||||
(32768, "q2", 3, "cache KV inconnu : q2"),
|
||||
(32768, "fp16", 9, "MTP hors limites : 9"),
|
||||
(36864 + 1, "fp16", 3, "contexte hors limites : 36865"),
|
||||
(MAX_CTX + 4096, "fp16", 3, "contexte hors limites : 266240"),
|
||||
(32768, "fp16", 1, "MTP hors limites : 1"),
|
||||
(32768, "fp16", 5, "MTP hors limites : 5"),
|
||||
(28672, "fp16", 3, "contexte hors limites : 28672"),
|
||||
] {
|
||||
let bad = SettingsReq {
|
||||
ctx,
|
||||
kv: kv.into(),
|
||||
spec,
|
||||
..SettingsReq::default()
|
||||
};
|
||||
assert_eq!(apply_settings(input, &bad).unwrap_err(), why);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn moteur_du_preset() {
|
||||
for (v, want) in [
|
||||
("", ENGINE_LLAMACPP),
|
||||
("llamacpp", ENGINE_LLAMACPP),
|
||||
("strata", ENGINE_STRATA),
|
||||
(" Strata ", ENGINE_STRATA),
|
||||
("moe", ENGINE_STRATA),
|
||||
("autre", ENGINE_LLAMACPP),
|
||||
] {
|
||||
assert_eq!(engine_of(&cfg(&[("ENGINE", v)])), want, "{v:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placement_des_experts() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
let p = Paths {
|
||||
home: d.path().to_path_buf(),
|
||||
};
|
||||
let pack = d.path().join("pack");
|
||||
std::fs::create_dir_all(&pack).unwrap();
|
||||
let args = vec!["--pack".to_string(), pack.to_string_lossy().into_owned()];
|
||||
let mut c = cfg(&[
|
||||
("STRATA_CONFIG", "/x/strata-swift-iq3_xxs.json"),
|
||||
("STRATA_HELPER_GPU", "1"),
|
||||
("STRATA_DROP", "1"),
|
||||
]);
|
||||
for (experts, avail, want) in [
|
||||
("", 44.0, "disk"),
|
||||
("", 60.0, "ram"),
|
||||
("auto", 52.8, "disk"),
|
||||
("disk", 60.0, "disk"),
|
||||
("ram", 20.0, "ram"),
|
||||
] {
|
||||
c.insert("STRATA_EXPERTS".into(), experts.into());
|
||||
assert_eq!(
|
||||
resolve_experts(&p, &c, &args, avail, 12.0),
|
||||
want,
|
||||
"{experts} {avail}"
|
||||
);
|
||||
}
|
||||
std::fs::write(pack.join("experts.bin"), "x").unwrap();
|
||||
std::fs::create_dir_all(p.src_dir().join("engine-cuda12")).unwrap();
|
||||
std::fs::write(p.engine_marker(), format!("{ENGINE_ASSET}\n")).unwrap();
|
||||
c.insert("STRATA_EXPERTS".into(), String::new());
|
||||
assert_eq!(resolve_experts(&p, &c, &args, 44.0, 12.0), "drop");
|
||||
assert_eq!(resolve_experts(&p, &c, &args, 30.0, 12.0), "arena");
|
||||
c.insert("STRATA_HELPER".into(), "0".into());
|
||||
assert_eq!(resolve_experts(&p, &c, &args, 44.0, 12.0), "arena");
|
||||
c.insert("STRATA_EXPERTS".into(), "disk".into());
|
||||
assert_eq!(resolve_experts(&p, &c, &args, 60.0, 12.0), "arena");
|
||||
assert_eq!(
|
||||
resolve_experts(
|
||||
&p,
|
||||
&cfg(&[("STRATA_CONFIG", "/x/autre.json")]),
|
||||
&[],
|
||||
500.0,
|
||||
0.0
|
||||
),
|
||||
"disk"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modes_des_experts() {
|
||||
let base = json!({
|
||||
"args": ["--pack", "/p", "--resident-experts", "--pcie-frac", "0.3"],
|
||||
"env": { "X": "1" },
|
||||
});
|
||||
let c = cfg(&[("STRATA_HELPER_GPU", "1")]);
|
||||
let out = build_config(&base, &c, "", "disk").unwrap();
|
||||
let a = args_of(&out);
|
||||
assert!(has_arg(&a, "--mmap-experts") && !has_arg(&a, "--resident-experts"));
|
||||
assert_eq!(arg_after(&a, "--pcie-frac"), "0");
|
||||
assert!(out["env"].get("STRATA_ARENA_MMAP").is_none());
|
||||
assert_eq!(out["env"]["X"], "1");
|
||||
let out = build_config(&base, &c, "", "ram").unwrap();
|
||||
let a = args_of(&out);
|
||||
assert!(!has_arg(&a, "--mmap-experts") && !has_arg(&a, "--resident-experts"));
|
||||
assert!(out["env"].get("STRATA_REMOTE_DROP").is_none());
|
||||
let out = build_config(&base, &c, "", "arena").unwrap();
|
||||
assert_eq!(arg_after(&args_of(&out), "--pcie-frac"), "0");
|
||||
assert_eq!(out["env"]["STRATA_ARENA_MMAP"], "1");
|
||||
let out = build_config(&base, &c, "", "drop").unwrap();
|
||||
assert!(!has_arg(&args_of(&out), "--pcie-frac"));
|
||||
assert_eq!(out["env"]["STRATA_REMOTE_DROP"], "1");
|
||||
assert_eq!(out["env"]["STRATA_STAGER_THREADS"], "8");
|
||||
let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "-1")]), "", "drop").unwrap();
|
||||
assert!(out["env"].get("STRATA_REMOTE_DROP").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reglages_des_experts() {
|
||||
let input = "ENGINE=strata\nSTRATA_EXPERTS=auto\n";
|
||||
let mut r = SettingsReq {
|
||||
ctx: 131072,
|
||||
kv: "fp16".into(),
|
||||
spec: 3,
|
||||
experts: "disk".into(),
|
||||
..SettingsReq::default()
|
||||
};
|
||||
let out = apply_settings(input, &r).unwrap();
|
||||
assert_eq!(crate::presets::parse_env(&out)["STRATA_EXPERTS"], "disk");
|
||||
r.experts = "nvme".into();
|
||||
assert_eq!(
|
||||
apply_settings(input, &r).unwrap_err(),
|
||||
"placement des experts inconnu : nvme"
|
||||
);
|
||||
r.experts = String::new();
|
||||
let out = apply_settings(input, &r).unwrap();
|
||||
assert_eq!(crate::presets::parse_env(&out)["STRATA_EXPERTS"], "auto");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nombres_a_la_go() {
|
||||
assert_eq!(go_g(8192.0), "8192");
|
||||
assert_eq!(go_g(123456.0), "123456");
|
||||
assert_eq!(go_g(1e6), "1e+06");
|
||||
assert_eq!(go_g(1234567.0), "1.234567e+06");
|
||||
assert_eq!(go_g(0.3), "0.3");
|
||||
assert_eq!(go_g(0.0001), "0.0001");
|
||||
assert_eq!(go_g(0.00001), "1e-05");
|
||||
assert_eq!(go_g(-2.5), "-2.5");
|
||||
assert_eq!(go_sprint(&json!("x")), "x");
|
||||
assert_eq!(go_sprint(&json!(true)), "true");
|
||||
assert_eq!(go_num(34.0), json!(34));
|
||||
assert_eq!(go_num(35.5), json!(35.5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ligne_par_ligne() {
|
||||
let mut s = api::SinkWriter::default();
|
||||
assert_eq!(s.write(b"a\nb"), vec!["a"]);
|
||||
assert_eq!(s.write(b"c\r"), Vec::<String>::new());
|
||||
assert_eq!(s.write(b"\n10%\r20%\r"), vec!["bc", "10%"]);
|
||||
assert_eq!(s.write(b"fin\r\n"), vec!["fin"]);
|
||||
}
|
||||
|
||||
/// La RAM du moteur Strata en marche : l'arbre du service, lu dans /proc.
|
||||
#[test]
|
||||
fn ram_du_moteur_en_marche() {
|
||||
let home = tempfile::tempdir().unwrap();
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let probe = crate::backends::probe::Probe {
|
||||
path: Some(vec![]),
|
||||
root: root.path().to_path_buf(),
|
||||
};
|
||||
let st = api::Strata::new(home.path().to_path_buf(), probe);
|
||||
let status = |pid: &str, ppid: i64, kb: i64| {
|
||||
let d = root.path().join("proc").join(pid);
|
||||
std::fs::create_dir_all(&d).unwrap();
|
||||
std::fs::write(
|
||||
d.join("status"),
|
||||
format!("Name:\tx\nPPid:\t{ppid}\nVmRSS:\t {kb} kB\n"),
|
||||
)
|
||||
.unwrap();
|
||||
};
|
||||
status("100", 1, 1_048_576);
|
||||
status("101", 100, 2048);
|
||||
status("102", 101, 1024);
|
||||
status("200", 1, 999_999);
|
||||
std::fs::create_dir_all(root.path().join("proc/self")).unwrap();
|
||||
let strata = cfg(&[("ENGINE", "strata")]);
|
||||
assert_eq!(st.engine_rss_gb(&strata), 0.0, "sans fichier de PID");
|
||||
std::fs::write(home.path().join("loki-engine.pid"), "100\n").unwrap();
|
||||
let want = (1_048_576.0 + 2048.0 + 1024.0) * 1024.0 / 1e9;
|
||||
assert!((st.engine_rss_gb(&strata) - want).abs() < 1e-9);
|
||||
assert_eq!(st.engine_rss_gb(&Cfg::new()), 0.0, "llama.cpp actif");
|
||||
std::fs::write(
|
||||
root.path().join("proc/meminfo"),
|
||||
"MemTotal: 8388608 kB\nMemAvailable: 4194304 kB\n",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(st.total_ram_gb(), 8.0);
|
||||
assert!((st.mem_available_gb() - 4194304.0 * 1024.0 / 1e9).abs() < 1e-9);
|
||||
}
|
||||
|
||||
/// Les drapeaux posés une seule fois, où qu'ils soient dans la liste.
|
||||
#[test]
|
||||
fn drapeaux_uniques() {
|
||||
let v = |a: &[&str]| a.iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
set_arg(v(&["--a", "1", "--kv", "int8"]), "--kv", "fp16"),
|
||||
v(&["--a", "1", "--kv", "fp16"])
|
||||
);
|
||||
assert_eq!(
|
||||
set_arg(v(&["--kv"]), "--kv", "x"),
|
||||
v(&["--kv", "--kv", "x"])
|
||||
);
|
||||
assert_eq!(
|
||||
drop_flag_value(v(&["--a", "1", "--b", "2"]), "--b"),
|
||||
v(&["--a", "1"])
|
||||
);
|
||||
assert_eq!(drop_flag(v(&["--a", "--b", "--a"]), "--a"), v(&["--b"]));
|
||||
let base = json!({ "args": ["--remote-expert-opt", "--pack", "/p"] });
|
||||
let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "1")]), "", "drop").unwrap();
|
||||
let a = args_of(&out);
|
||||
assert_eq!(
|
||||
a.iter().filter(|x| *x == "--remote-expert-opt").count(),
|
||||
1,
|
||||
"{a:?}"
|
||||
);
|
||||
assert_eq!(out["env"]["STRATA_STAGER_RING"], "32");
|
||||
assert_eq!(out["env"]["STRATA_NO_LARGEPAGES"], "1");
|
||||
}
|
||||
Reference in new issue
Block a user