chore: rustfmt, clippy lints and code tidying

This commit is contained in:
Riz Ashraf committed 2026-09-17 15:35:41 +01:00
1 parent 3716c3e698
commit 1752753fcc
19 files changed
+1273 -738

No files matched your search

+14 -9
View File
@@ -2,19 +2,24 @@ use std::process::Command;
fn main() {
let git_hash = Command::new("git")
.args(&["rev-parse", "--short", "HEAD"])
.output()
.ok()
.and_then(|out| String::from_utf8(out.stdout).ok())
.unwrap_or_else(|| "unknown".to_string());
let git_date = Command::new("git")
.args(&["log", "-1", "--format=%cd", "--date=format:%Y.%m.%d"])
.args(["rev-parse", "--short", "HEAD"])
.output()
.ok()
.and_then(|out| String::from_utf8(out.stdout).ok())
.unwrap_or_else(|| "unknown".to_string());
let version = format!("{} ({} {})", env!("CARGO_PKG_VERSION"), git_date.trim(), git_hash.trim());
let git_date = Command::new("git")
.args(["log", "-1", "--format=%cd", "--date=format:%Y.%m.%d"])
.output()
.ok()
.and_then(|out| String::from_utf8(out.stdout).ok())
.unwrap_or_else(|| "unknown".to_string());
let version = format!(
"{} ({} {})",
env!("CARGO_PKG_VERSION"),
git_date.trim(),
git_hash.trim()
);
println!("cargo:rustc-env=APP_VERSION={}", version);
}
+12 -13
View File
@@ -1,14 +1,15 @@
use futures_util::StreamExt;
use reqwest::Client;
use std::env;
use std::time::Duration;
use futures_util::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let target = env::var("MCP_TARGET").unwrap_or_else(|_| "https://127.0.0.1:3000".to_string());
let token = env::var("MCP_AUTH_TOKEN").unwrap_or_else(|_| "jP76lUJ5DtFRZmcvXH8LKdCTIkp29eAf".to_string());
let token = env::var("MCP_AUTH_TOKEN")
.unwrap_or_else(|_| "jP76lUJ5DtFRZmcvXH8LKdCTIkp29eAf".to_string());
tracing::info!("Starting skeletal client to {}", target);
@@ -17,13 +18,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.build()?;
let sse_url = format!("{}/sse", target);
tracing::info!("Connecting to SSE: {}", sse_url);
let res = client.get(&sse_url)
.bearer_auth(&token)
.send()
.await?;
let res = client.get(&sse_url).bearer_auth(&token).send().await?;
if !res.status().is_success() {
tracing::error!("Failed to connect to SSE: {}", res.status());
@@ -40,15 +38,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
while let Some(chunk) = stream.next().await {
let bytes = chunk?;
buffer.extend_from_slice(&bytes);
while let Some(pos) = buffer.windows(2).position(|w| w == b"\n\n" || w == b"\r\n") {
let msg_bytes = buffer.drain(..pos).collect::<Vec<_>>();
buffer.drain(..2);
let text = String::from_utf8_lossy(&msg_bytes);
let mut is_endpoint = false;
let mut data_content = String::new();
for line in text.lines() {
if line.starts_with("event: endpoint") {
is_endpoint = true;
@@ -78,7 +76,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::info!("Sending test payload to {}", post_url);
tracing::info!("Payload: {}", payload);
let post_res = client.post(&post_url)
let post_res = client
.post(&post_url)
.bearer_auth(&token)
.header("Content-Type", "application/json")
.body(payload.to_string())
@@ -91,7 +90,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Wait for the SSE stream to deliver the response
tracing::info!("Waiting 2 seconds for SSE response delivery...");
let mut timeout = tokio::time::interval(Duration::from_secs(2));
timeout.tick().await; // first tick is immediate
+7 -9
View File
@@ -1,6 +1,6 @@
use std::sync::Arc;
use clap::Parser;
use futures_util::{SinkExt, StreamExt};
use std::sync::Arc;
use tokio::io::AsyncBufReadExt;
use tokio::sync::mpsc;
@@ -23,11 +23,11 @@ async fn read_mcp_message(stdin: &mut tokio::io::BufReader<tokio::io::Stdin>) ->
return None;
}
tracing::info!("Read {} bytes from stdin: {:?}", bytes_read, line);
if line.starts_with('{') {
return Some(line.trim_end().to_string());
}
let line = line.trim_end();
if line.is_empty() {
break;
@@ -51,16 +51,16 @@ fn init_logging(app_name: &str) -> Option<tracing_appender::non_blocking::Worker
let mut base_dir = dirs::home_dir().unwrap_or_else(|| std::path::PathBuf::from("."));
base_dir.push(".gemini/mcp_memory/logs");
std::fs::create_dir_all(&base_dir).unwrap_or_default();
let file_appender = tracing_appender::rolling::daily(base_dir, format!("{}.log", app_name));
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
let _ = tracing_subscriber::fmt()
.with_writer(non_blocking)
.with_ansi(false)
.with_max_level(tracing::Level::TRACE)
.try_init();
Some(guard)
}
@@ -94,7 +94,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::info!("Attempting to connect to {}", ws_url);
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
let mut request = match ws_url.clone().into_client_request() {
let request = match ws_url.clone().into_client_request() {
Ok(req) => req,
Err(e) => {
tracing::error!("Failed to parse target URL {}: {}", ws_url, e);
@@ -165,5 +165,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
})
}
+40 -25
View File
@@ -1,5 +1,5 @@
use serde_json::{json, Value};
use std::io::{BufRead, BufReader, Read, Write};
use serde_json::{Value, json};
use std::io::{BufRead, BufReader, Write};
use std::process::{Command, Stdio};
use std::time::Duration;
@@ -18,21 +18,26 @@ fn read_message(reader: &mut impl BufRead) -> Option<Value> {
serde_json::from_str(line.trim()).ok()
}
#[tokio::test]
async fn test_full_system_e2e_performance() {
let temp_dir = std::env::temp_dir().join(format!("mcp_e2e_{}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs()));
let temp_dir = std::env::temp_dir().join(format!(
"mcp_e2e_{}",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs()
));
std::fs::create_dir_all(&temp_dir).unwrap();
let test_port = "3042"; // Use a distinct port
let test_auth_token = "test-token-12345";
// Since tests run from inside `target/debug/deps`, and `cargo test` does not guarantee
// Since tests run from inside `target/debug/deps`, and `cargo test` does not guarantee
// `env!("CARGO_BIN_EXE_name")` works correctly for binaries compiled in other crates without build dependencies,
// we use `CARGO_MANIFEST_DIR` (which points to `stub`) to reliably locate the workspace `target/debug`.
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let debug_dir = manifest_dir.parent().unwrap().join("target").join("debug");
let server_exe = debug_dir.join(format!("mcp-memory-server{}", std::env::consts::EXE_SUFFIX));
let nvim_name = if cfg!(windows) {
"mcp-memory-win-nvim"
@@ -41,21 +46,24 @@ async fn test_full_system_e2e_performance() {
};
let nvim_exe = debug_dir.join(format!("{}{}", nvim_name, std::env::consts::EXE_SUFFIX));
let stub_exe = debug_dir.join(format!("mcp-memory-stub{}", std::env::consts::EXE_SUFFIX));
assert!(server_exe.exists(), "Server not found at {:?}", server_exe);
assert!(nvim_exe.exists(), "Nvim not found at {:?}", nvim_exe);
assert!(stub_exe.exists(), "Stub not found at {:?}", stub_exe);
// 1. Start Server
let mut server = Command::new(&server_exe).arg("--daemon")
.env("MCP_PORT", test_port).env("RUST_LOG", "debug")
let mut server = Command::new(&server_exe)
.arg("--daemon")
.env("MCP_PORT", test_port)
.env("RUST_LOG", "debug")
.env("MCP_MEMORY_STORE_DIR", temp_dir.to_str().unwrap())
.env("MCP_AUTH_TOKEN", test_auth_token).env("RUST_LOG", "debug")
.env("MCP_AUTH_TOKEN", test_auth_token)
.env("RUST_LOG", "debug")
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to start server");
// Give server time to generate TLS cert and start
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
@@ -63,28 +71,32 @@ async fn test_full_system_e2e_performance() {
.unwrap();
let mut started = false;
for _ in 0..30 {
if let Ok(resp) = client.get(format!("http://127.0.0.1:{}/health", test_port)).send().await {
if resp.status().is_success() {
started = true;
break;
}
if let Ok(resp) = client
.get(format!("http://127.0.0.1:{}/health", test_port))
.send()
.await
&& resp.status().is_success()
{
started = true;
break;
}
tokio::time::sleep(Duration::from_millis(500)).await;
}
assert!(started, "Server failed to start in time");
// 2. Start Stub
let mut stub = Command::new(&stub_exe)
.arg("--target")
.arg(format!("http://127.0.0.1:{}", test_port))
.env("MCP_MEMORY_STORE_DIR", temp_dir.to_str().unwrap())
.env("MCP_AUTH_TOKEN", test_auth_token).env("RUST_LOG", "debug")
.env("MCP_AUTH_TOKEN", test_auth_token)
.env("RUST_LOG", "debug")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn()
.expect("Failed to start stub");
let mut stub_stdin = stub.stdin.take().unwrap();
let mut stub_stdout = BufReader::new(stub.stdout.take().unwrap());
@@ -111,7 +123,7 @@ async fn test_full_system_e2e_performance() {
"params": {},
"id": i
});
// Alternate between LSP header format and JSONL format
if i % 2 == 0 {
send_message(&mut stub_stdin, tools_req);
@@ -121,7 +133,8 @@ async fn test_full_system_e2e_performance() {
stub_stdin.flush().unwrap();
}
let mut resp = read_message(&mut stub_stdout).expect("Failed to read rapid response from stub");
let mut resp =
read_message(&mut stub_stdout).expect("Failed to read rapid response from stub");
while resp.get("id").is_none() || resp["id"].is_null() {
resp = read_message(&mut stub_stdout).expect("Failed to read rapid response from stub");
}
@@ -140,7 +153,7 @@ async fn test_full_system_e2e_performance() {
"params": {},
"id": i
});
if i % 2 == 0 {
send_message(&mut nvim_stdin, tools_req);
} else {
@@ -149,9 +162,11 @@ async fn test_full_system_e2e_performance() {
nvim_stdin.flush().unwrap();
}
let mut resp = read_message(&mut nvim_stdout).expect("Failed to read rapid response from win-nvim");
let mut resp =
read_message(&mut nvim_stdout).expect("Failed to read rapid response from win-nvim");
while resp.get("id").is_none() || resp["id"].is_null() {
resp = read_message(&mut nvim_stdout).expect("Failed to read rapid response from win-nvim");
resp = read_message(&mut nvim_stdout)
.expect("Failed to read rapid response from win-nvim");
}
assert_eq!(resp["id"], i);
}
+36 -16
View File
@@ -10,10 +10,14 @@ fn get_stub_exe() -> std::path::PathBuf {
#[tokio::test]
async fn test_stub_connection_refused() {
let _ = std::process::Command::new("cargo").arg("build").arg("--bin").arg("mcp-memory-stub").status();
let _ = std::process::Command::new("cargo")
.arg("build")
.arg("--bin")
.arg("mcp-memory-stub")
.status();
let target = "http://127.0.0.1:49999";
let start = Instant::now();
let mut child = Command::new(get_stub_exe())
.arg("--target")
@@ -21,19 +25,27 @@ async fn test_stub_connection_refused() {
.stdin(Stdio::null()) // close stdin immediately to simulate EOF
.spawn()
.expect("Failed to execute stub");
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
let elapsed = start.elapsed();
assert!(res.is_ok(), "Stub hung on connection refused! Took {:?}", elapsed);
assert!(
res.is_ok(),
"Stub hung on connection refused! Took {:?}",
elapsed
);
}
#[tokio::test]
async fn test_stub_handles_eof_cleanly() {
let _ = std::process::Command::new("cargo").arg("build").arg("--bin").arg("mcp-memory-stub").status();
let _ = std::process::Command::new("cargo")
.arg("build")
.arg("--bin")
.arg("mcp-memory-stub")
.status();
let target = "http://127.0.0.1:49998";
let mut child = Command::new(get_stub_exe())
.arg("--target")
.arg(target)
@@ -42,28 +54,32 @@ async fn test_stub_handles_eof_cleanly() {
.stderr(Stdio::piped())
.spawn()
.expect("Failed to execute stub");
if let Some(mut stdin) = child.stdin.take() {
use tokio::io::AsyncWriteExt;
let msg = "Content-Length: 51\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"params\":{},\"id\":1}";
stdin.write_all(msg.as_bytes()).await.unwrap();
} // stdin dropped here
let start = Instant::now();
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
let elapsed = start.elapsed();
assert!(res.is_ok(), "Stub hung after EOF! Took {:?}", elapsed);
}
#[tokio::test]
async fn test_stub_sse_fallback_failure() {
let _ = std::process::Command::new("cargo").arg("build").arg("--bin").arg("mcp-memory-stub").status();
let _ = std::process::Command::new("cargo")
.arg("build")
.arg("--bin")
.arg("mcp-memory-stub")
.status();
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let local_addr = listener.local_addr().unwrap();
let target = format!("http://127.0.0.1:{}", local_addr.port());
tokio::spawn(async move {
while let Ok((mut socket, _)) = listener.accept().await {
use tokio::io::AsyncReadExt;
@@ -77,12 +93,16 @@ async fn test_stub_sse_fallback_failure() {
let mut child = Command::new(get_stub_exe())
.arg("--target")
.arg(target)
.stdin(Stdio::null())
.stdin(Stdio::null())
.spawn()
.expect("Failed to execute stub");
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
let elapsed = start.elapsed();
assert!(res.is_ok(), "Stub hung on fallback failure! Took {:?}", elapsed);
assert!(
res.is_ok(),
"Stub hung on fallback failure! Took {:?}",
elapsed
);
}