use gunnar_core::txlog::Kind;
use gunnar_core::{Principal, PrincipalKind};
use gunnar_server::stores::ServerStores;
const ACCOUNTS: usize = 30;
fn key_line() -> String {
let key = gunnar_core::ssh_key::PrivateKey::from_openssh(gunnar_core::mint_ed25519().unwrap())
.unwrap();
key.public_key().to_openssh().unwrap()
}
#[test]
fn a_control_change_on_main_costs_one_log_fsync_and_one_redb_fsync() {
let dir = tempfile::tempdir().unwrap();
let stores = ServerStores::open(dir.path()).unwrap();
let log = stores.txlog();
let db = stores.control_db();
let (h0, s0, c0) = (log.head_seq(), log.frame_syncs(), db.durable_commits());
for i in 0..ACCOUNTS {
let id = format!("u{i:05}");
stores
.auth()
.add_principal(Principal::new(&id, &id, PrincipalKind::User).unwrap())
.unwrap();
stores.auth().register_key(&id, &key_line(), None).unwrap();
stores.catalog().create_namespace(&id).unwrap();
}
let (h1, s1, c1) = (log.head_seq(), log.frame_syncs(), db.durable_commits());
let (mut docs, mut blobs, mut other) = (0u64, 0u64, 0u64);
for seq in h0 + 1..=h1 {
match gunnar_core::txlog::Kind::from_u16(log.locate_blob(seq).unwrap().kind) {
Some(Kind::ControlDoc) => docs += 1,
Some(Kind::ControlBlob) => blobs += 1,
_ => other += 1,
}
}
let (syncs, commits) = (s1 - s0, c1 - c0);
let line = format!(
"{ACCOUNTS} sign-ups on main: {} frames ({docs} documents, {blobs} blobs, {other} other) cost {syncs} log fsyncs and {commits} redb durable commits — {:.2} and {:.2} per document change",
h1 - h0,
syncs as f64 / docs as f64,
commits as f64 / docs as f64
);
eprintln!("{line}");
assert!(
docs > 0 && blobs > docs,
"the workload is document changes with their shards: {line}"
);
assert!(
syncs <= docs + other,
"one log fsync per document change (its blobs ride on it): {line}"
);
assert!(
commits <= docs + other,
"one redb durable commit per document change (its blobs ride on it): {line}"
);
}