Files
boxmaker/crates/memoryd/tests/support/worker.rs
T

134 lines
4.4 KiB
Rust

//! A Honcho worker for tests, stepped by hand: a home with session logs and a ledger, the fake
//! Honcho, `brokerd` as a closure whose answer the test sets, and the log lines collected. Do not
//! edit.
#![allow(dead_code)] // each test file uses a different part of this module
use std::collections::BTreeMap;
use std::ffi::OsString;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use bxcore::{LogRecord, SessionStateReply, Timestamp};
use memoryd::honcho::client::{Clients, Timeouts};
use memoryd::honcho::config::HonchoConfig;
use memoryd::honcho::ledger::{Ledger, Record};
use memoryd::honcho::turns::{LEDGER, TurnSync};
use memoryd::honcho::worker::{Tuning, Wake, Worker};
use memoryd::serve::Log;
use crate::honcho::FakeHoncho;
use crate::tmp::TempDir;
use crate::turns::{clean, sid, write_turns};
pub const FAST: Tuning = Tuning {
backoff: Duration::from_millis(1),
backoff_max: Duration::from_millis(8),
idle: Duration::from_millis(1),
};
pub fn config(url: &str) -> HonchoConfig {
HonchoConfig {
url: url.to_string(),
agent: "boxmaker0".to_string(),
owner: "kyle".to_string(),
trusted: "boxmaker0-trusted".to_string(),
untrusted: "boxmaker0-untrusted".to_string(),
fleet: "fleet".to_string(),
read: Vec::new(),
keys: BTreeMap::new(),
}
}
pub struct Home {
pub sync: Arc<Mutex<TurnSync>>,
/// What `brokerd` answers.
pub answer: Arc<Mutex<Result<SessionStateReply, String>>>,
pub lines: Arc<Mutex<Vec<String>>>,
pub dir: TempDir,
}
impl Home {
pub fn new(tag: &str) -> Home {
let dir = TempDir::new(tag);
std::fs::create_dir_all(dir.path().join("memory")).unwrap();
Home {
sync: Arc::new(Mutex::new(TurnSync::new(
Ledger::open(&dir.path().join("memory").join(LEDGER)).unwrap(),
"boxmaker0",
&dir.path().join("sessions"),
))),
answer: Arc::new(Mutex::new(Ok(clean()))),
lines: Arc::new(Mutex::new(Vec::new())),
dir,
}
}
pub fn ledger_path(&self) -> PathBuf {
self.dir.path().join("memory").join(LEDGER)
}
/// A new `TurnSync` over the ledger as it is on disk, resumed: what a restart makes.
pub fn restart(&mut self) {
let mut sync = TurnSync::new(
Ledger::open(&self.ledger_path()).unwrap(),
"boxmaker0",
&self.dir.path().join("sessions"),
);
sync.resume();
self.sync = Arc::new(Mutex::new(sync));
}
pub fn log(&self, session: &str, turns: &[Vec<LogRecord>]) {
write_turns(self.dir.path(), session, turns);
}
/// `loopd` reports turn `turn` of `session`: decided now, with `answer`.
pub fn report(&self, session: &str, turn: u64) {
let answer = Arc::clone(&self.answer);
let ask = move |_: &bxcore::SessionId| answer.lock().unwrap().clone();
let lines = Arc::clone(&self.lines);
let log = move |line: &str| lines.lock().unwrap().push(line.to_string());
let now = Timestamp::parse("2026-09-28T10:00:00.000Z").unwrap();
self.sync
.lock()
.unwrap()
.updated(&sid(session), turn, &ask, now, &log);
}
pub fn worker(&self, fake: &FakeHoncho, tuning: Tuning) -> Worker {
let no_env = |_: &str| -> Option<OsString> { None };
let timeouts = Timeouts {
connect: Duration::from_secs(5),
read: Duration::from_millis(300),
};
let (clients, _) = Clients::new(&config(&fake.url), &no_env, timeouts).unwrap();
let answer = Arc::clone(&self.answer);
let lines = Arc::clone(&self.lines);
let log: Log = Arc::new(move |line: &str| lines.lock().unwrap().push(line.to_string()));
Worker::new(
Arc::clone(&self.sync),
clients,
Arc::new(Wake::default()),
Box::new(move |_: &bxcore::SessionId| answer.lock().unwrap().clone()),
log,
tuning,
"boxmaker0",
)
}
/// Every record of the ledger on disk, in order.
pub fn records(&self) -> Vec<Record> {
std::fs::read_to_string(self.ledger_path())
.unwrap_or_default()
.lines()
.map(|l| serde_json::from_str(l).unwrap())
.collect()
}
pub fn lines(&self) -> Vec<String> {
self.lines.lock().unwrap().clone()
}
}