use super::*;
use crate::boundary::answer::answer;
use crate::boundary::config::{Read, Write};
use crate::boundary::dispatch::{Caller, Deps, dispatch};
use crate::boundary::reply::{ConfigAnswer, Reply};
use crate::boundary::{Action, Query};
use crate::cli_outbound::Cli;
use crate::model_pick::{Effort, Tuning};
use crate::ui_state::UiState;
use std::sync::Arc;
fn deps_on(root: &Path, litany: &Path) -> Deps {
let places = Places::under(root);
let world = crate::world::compose(&crate::xdg::Env::from_pairs([(
"XDG_DATA_HOME",
root.display().to_string(),
)]));
assert_eq!(
world.yog_state_root(),
places.state,
"the engine's own fold"
);
Deps {
litany: Cli::new(litany),
bl: Cli::new(Path::new("/definitely/not/a/bl-xyz")),
state_root: places.state.clone(),
yog_binary: root.join("yog"),
world,
home: root.join("home"),
yog_data_root: places.data.clone(),
snapshot: Arc::new(crate::boundary::tests::snapshot(
&places.workspace(roster::WORKSPACE),
roster::WORKSPACE,
vec![],
vec![],
)),
caller: Caller::default(),
}
}
fn recorder(bin: &Path, log: &Path) -> PathBuf {
let path = bin.join("litany");
crate::test_support::write_exec(
&path,
&format!(
"#!/bin/sh\ncat \"$YOG_EDIT_SRC/providers.yaml\" > {}\nexit 0\n",
log.display()
),
);
path
}
fn tune(tuning: Tuning) -> Action {
Action::Config(Write::Tune(tuning))
}
fn fire(deps: &Deps, action: &Action) -> Result<Reply, String> {
let mut ui = UiState::open(PathBuf::from("/nonexistent/ui.json"));
dispatch(deps, &mut ui, "T0", action)
}
#[test]
fn every_laid_world_declares_its_roles_to_the_config_read() {
let mut swept = 0;
for (state, recipe) in roster::ROSTER {
if recipe.workspaces.is_empty() {
continue;
}
let (tmp, _places, _) = laid(state, 2_000_000_000);
let deps = deps_on(tmp.path(), Path::new("/definitely/not/a/litany-xyz"));
let ui = UiState::open(PathBuf::from("/nonexistent/ui.json"));
let rows = match answer(
&Query::Config(Read::Roles {
workspace: roster::WORKSPACE.to_owned(),
}),
&deps,
&ui,
0,
) {
Ok(Reply::Config(ConfigAnswer::Roles(rows))) => rows,
other => panic!("{state}: roles answers roles: {other:?}"),
};
assert_eq!(rows.len(), 2, "{state}");
assert_eq!(rows[0].role, "worker", "{state}");
assert!(!rows[0].provider.is_empty(), "{state}: a row is named");
assert!(!rows[0].model.is_empty(), "{state}: a model is bound");
assert_eq!(rows[0].effort, None, "{state}");
assert!(!rows[0].priority, "{state}");
swept += 1;
}
assert!(swept > 0, "the roster laid no workspace at all");
}
#[test]
fn the_tuning_pair_takes_against_a_laid_world() {
let (tmp, _places, _) = laid("busy", 2_000_000_000);
let bin = TempDir::new().expect("bin");
let log = bin.path().join("staged");
let deps = deps_on(tmp.path(), &recorder(bin.path(), &log));
let ws = roster::WORKSPACE.to_owned();
let knobs = [
(
Tuning::Effort {
workspace: ws.clone(),
role: "worker".to_owned(),
level: Some(Effort::High),
},
"effort: high",
),
(
Tuning::Priority {
workspace: ws.clone(),
role: "worker".to_owned(),
on: true,
},
"priority: true",
),
];
for (tuning, line) in knobs {
let reply = fire(&deps, &tune(tuning));
assert!(
matches!(&reply, Ok(Reply::Outcome(o)) if o.ok()),
"{line}: {reply:?}"
);
let staged = std::fs::read_to_string(&log).expect("staged");
assert!(staged.contains(line), "{line} missing from {staged}");
}
let refused = fire(
&deps,
&tune(Tuning::Effort {
workspace: ws,
role: "nobody".to_owned(),
level: Some(Effort::Low),
}),
);
assert!(
matches!(&refused, Err(e) if e.contains("nobody")),
"{refused:?}"
);
}