use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use crate::{Builder, KoiHandle, ServiceMode};
pub struct TestNode {
handle: KoiHandle,
data_dir: PathBuf,
}
impl std::ops::Deref for TestNode {
type Target = KoiHandle;
fn deref(&self) -> &KoiHandle {
&self.handle
}
}
impl TestNode {
pub async fn shutdown(self) {
let _ = self.handle.shutdown().await;
let _ = std::fs::remove_dir_all(&self.data_dir);
}
}
fn unique_dir(tag: &str) -> PathBuf {
static COUNTER: AtomicU64 = AtomicU64::new(0);
let n = COUNTER.fetch_add(1, Ordering::Relaxed);
let dir = std::env::temp_dir().join(format!("koi-testkit-{tag}-{}-{n}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
dir
}
async fn build(tag: &str) -> TestNode {
let data_dir = unique_dir(tag);
let koi = Builder::new()
.data_dir(&data_dir)
.service_mode(ServiceMode::EmbeddedOnly)
.mdns(false)
.dns_enabled(false)
.health(false)
.certmesh(true)
.proxy(false)
.build()
.expect("testkit: build embedded");
let handle = koi.start().await.expect("testkit: start embedded");
TestNode { handle, data_dir }
}
pub async fn open() -> TestNode {
build("open").await
}
pub async fn secured() -> TestNode {
std::env::set_var("KOI_NO_CREDENTIAL_STORE", "1");
let node = build("secured").await;
let core = node
.certmesh()
.expect("testkit: certmesh enabled")
.core()
.expect("testkit: embedded certmesh core");
core.create(koi_certmesh::protocol::CreateCaRequest {
passphrase: "testkit-passphrase".to_string(),
entropy_hex: "2a".repeat(32), operator: None,
enrollment_open: false,
requires_approval: false,
auto_unlock: false,
totp_secret_hex: None,
})
.await
.expect("testkit: create CA");
node
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn open_node_is_open_and_secured_node_is_authenticated() {
let open = open().await;
assert!(
!open.certmesh().unwrap().posture().unwrap().signed,
"open() must yield an Open node"
);
open.shutdown().await;
let secured = secured().await;
assert!(
secured.certmesh().unwrap().posture().unwrap().signed,
"secured() must yield an Authenticated node"
);
secured.shutdown().await;
}
}