use std::net::{SocketAddr, TcpListener as StdTcpListener};
use serde_json::Value;
use tempfile::TempDir;
use tokio::net::TcpListener;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let std_listener = StdTcpListener::bind("127.0.0.1:0")?;
let addr: SocketAddr = std_listener.local_addr()?;
drop(std_listener);
let td = TempDir::new()?;
let opts = mnem_http::AppOptions {
allow_labels: Some(true),
in_memory: true,
metrics_enabled: false,
};
let repo_path = td.path().to_path_buf();
let server_handle = std::thread::spawn(
move || -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(async move {
let app = mnem_http::app_with_options(&repo_path, opts)?;
let listener = TcpListener::bind(addr).await?;
axum::serve(listener, app).await?;
Ok::<_, Box<dyn std::error::Error + Send + Sync>>(())
})
},
);
std::thread::sleep(std::time::Duration::from_millis(200));
let base = format!("http://{addr}");
println!("server up at {base}");
let body: String = ureq::get(&format!("{base}/v1/healthz"))
.call()?
.into_string()?;
let j: Value = serde_json::from_str(&body)?;
assert_eq!(j["schema"], "mnem.v1.healthz");
assert_eq!(j["ok"], true);
println!("GET /v1/healthz: ok=true schema=mnem.v1.healthz");
let post = ureq::post(&format!("{base}/v1/nodes"))
.set("content-type", "application/json")
.send_string(
r#"{"author":"smoke","message":"seed","label":"Memory","summary":"hello from the smoke-client example"}"#,
)?;
assert_eq!(post.status(), 200);
let post_body: Value = serde_json::from_str(&post.into_string()?)?;
assert_eq!(post_body["schema"], "mnem.v1.post-node");
let node_id = post_body["id"].as_str().unwrap().to_string();
println!("POST /v1/nodes: id={node_id}");
let ret = ureq::get(&format!("{base}/v1/retrieve?label=Memory&limit=5"))
.call()?
.into_string()?;
let rj: Value = serde_json::from_str(&ret)?;
assert!(
rj["items"].is_array(),
"retrieve response must carry items[]"
);
assert_eq!(rj["schema"], "mnem.v1.retrieve");
println!(
"GET /v1/retrieve: {} item(s) returned",
rj["items"].as_array().map_or(0, Vec::len)
);
drop(server_handle);
println!("OK");
Ok(())
}