use std::sync::Arc;
use std::time::Duration;
use mcpmesh::allowlist::{AllowlistGate, PeerEntry, PeerStore};
use mcpmesh::config::Config;
use mcpmesh::daemon::{self, MeshState, build_services_audited};
use mcpmesh::limits::MeshLimiters;
use mcpmesh::pairing::LiveInvites;
use mcpmesh::roster::gate::RosterGate;
use mcpmesh_net::registry::ConnRegistry;
use mcpmesh_net::{ALPN_MCP, ALPN_PING, TrustGate};
use tokio::time::timeout;
fn assemble(
endpoint: iroh::Endpoint,
store: Arc<PeerStore>,
config_path: std::path::PathBuf,
) -> Arc<MeshState> {
let gate: Arc<dyn TrustGate> = Arc::new(AllowlistGate::new(store.clone()));
MeshState::new(
endpoint,
gate,
store,
Arc::new(LiveInvites::new()),
"self".into(),
config_path,
Arc::new(RosterGate::empty()),
Arc::new(ConnRegistry::new()),
None,
None,
None,
None,
)
}
#[tokio::test(flavor = "multi_thread")]
async fn the_path_reports_the_route_data_actually_takes() {
timeout(Duration::from_secs(90), async {
let dir = tempfile::tempdir().unwrap();
let (relay_map, relay_url, _relay_guard) = iroh::test_utils::run_relay_server()
.await
.expect("run in-process relay");
let mk = || {
iroh::Endpoint::builder(iroh::endpoint::presets::Minimal)
.relay_mode(iroh::RelayMode::Custom(relay_map.clone()))
.ca_tls_config(iroh_relay::tls::CaTlsConfig::insecure_skip_verify())
.alpns(vec![ALPN_MCP.to_vec(), ALPN_PING.to_vec()])
.bind()
};
let peer_ep = mk().await.expect("bind peer");
let our_ep = mk().await.expect("bind ours");
let peer_id = *peer_ep.id().as_bytes();
let our_id = *our_ep.id().as_bytes();
let peer_store = Arc::new(PeerStore::open(&dir.path().join("peer.redb")).unwrap());
peer_store
.add(PeerEntry {
endpoint_id: our_id,
nickname: "us".into(),
services: vec![],
paired_at: None,
user_id: None,
last_addr: None,
})
.unwrap();
let our_store = Arc::new(PeerStore::open(&dir.path().join("our.redb")).unwrap());
our_store
.add(PeerEntry {
endpoint_id: peer_id,
nickname: "bob".into(),
services: vec![],
paired_at: None,
user_id: None,
last_addr: Some(
serde_json::to_string(
&iroh::EndpointAddr::new(iroh::EndpointId::from_bytes(&peer_id).unwrap())
.with_relay_url(relay_url.clone()),
)
.expect("serialize relay addr"),
),
})
.unwrap();
std::fs::write(dir.path().join("peer.toml"), "").unwrap();
let peer_mesh = assemble(peer_ep, peer_store, dir.path().join("peer.toml"));
let _peer_accept = daemon::spawn_accept_loop(
peer_mesh.clone(),
Arc::new(build_services_audited(
&Config::default(),
&mcpmesh::audit::AuditSink::disabled(),
&MeshLimiters::unlimited(),
)),
);
std::fs::write(dir.path().join("our.toml"), "").unwrap();
let mesh = assemble(our_ep, our_store, dir.path().join("our.toml"));
let mut seen = Vec::new();
let mut got_direct = false;
for _ in 0..12 {
let entry = daemon::probe_peer(&mesh, peer_id).await;
assert!(entry.reachable, "the peer must be reachable over the relay");
seen.push(entry.path.clone());
if entry.path == mcpmesh_local_api::PeerPath::Direct {
got_direct = true;
break;
}
tokio::time::sleep(Duration::from_millis(500)).await;
}
assert!(
got_direct,
"with a direct path available, the field must eventually report Direct — reporting \
Relay forever is the bug this suite exists to catch. Saw: {seen:?}"
);
let probe_conn = mesh_endpoint_dial(&mesh, peer_id, &relay_url).await;
let (mut relay_open, mut direct_selected) = (false, false);
for _ in 0..20 {
for path in &probe_conn.paths() {
if path.is_relay() {
relay_open = true;
}
if path.is_ip() && path.is_selected() {
direct_selected = true;
}
}
if relay_open && direct_selected {
break;
}
tokio::time::sleep(Duration::from_millis(150)).await;
}
assert!(
relay_open && direct_selected,
"setup: expected an OPEN relay path alongside a SELECTED direct one \
(relay_open={relay_open}, direct_selected={direct_selected}) — without that overlap \
this test cannot distinguish reading the selected path from reading open addresses"
);
for p in &seen {
assert!(
matches!(
p,
mcpmesh_local_api::PeerPath::Direct | mcpmesh_local_api::PeerPath::Relay { .. }
),
"a live connection must classify, got {p:?}"
);
}
for p in &seen {
if let mcpmesh_local_api::PeerPath::Relay { url: Some(u) } = p {
assert!(!u.contains('@'), "userinfo must never ship: {u}");
assert_eq!(u.matches('/').count(), 2, "scheme://host only, got {u}");
}
}
})
.await
.expect("peer path test timed out");
}
async fn mesh_endpoint_dial(
mesh: &Arc<MeshState>,
peer_id: [u8; 32],
relay_url: &iroh::RelayUrl,
) -> iroh::endpoint::Connection {
let addr = iroh::EndpointAddr::new(iroh::EndpointId::from_bytes(&peer_id).unwrap())
.with_relay_url(relay_url.clone());
mesh.endpoint_for_test()
.connect(addr, ALPN_PING)
.await
.expect("dial peer for path inspection")
}