#![allow(clippy::unwrap_used, clippy::expect_used)]
use tempfile::TempDir;
use x0x::{network::NetworkConfig, Agent};
#[tokio::test]
async fn test_machine_id_non_zero() {
let dir = TempDir::new().unwrap();
let agent = Agent::builder()
.with_machine_key(dir.path().join("machine.key"))
.with_agent_key_path(dir.path().join("agent.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
assert_ne!(
agent.machine_id().as_bytes(),
&[0u8; 32],
"machine_id must be non-zero"
);
}
#[tokio::test]
async fn test_machine_id_stable_across_restarts() {
let dir = TempDir::new().unwrap();
let key_path = dir.path().join("machine.key");
let agent1 = Agent::builder()
.with_machine_key(key_path.clone())
.with_agent_key_path(dir.path().join("agent1.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let machine_id1 = agent1.machine_id();
let agent2 = Agent::builder()
.with_machine_key(key_path.clone())
.with_agent_key_path(dir.path().join("agent2.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let machine_id2 = agent2.machine_id();
assert_eq!(
machine_id1, machine_id2,
"same key file must produce the same machine_id"
);
}
#[tokio::test]
async fn test_different_key_files_different_machine_ids() {
let dir = TempDir::new().unwrap();
let agent1 = Agent::builder()
.with_machine_key(dir.path().join("machine1.key"))
.with_agent_key_path(dir.path().join("agent1.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let agent2 = Agent::builder()
.with_machine_key(dir.path().join("machine2.key"))
.with_agent_key_path(dir.path().join("agent2.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
assert_ne!(
agent1.machine_id(),
agent2.machine_id(),
"different key files must yield different machine IDs"
);
}
#[tokio::test]
async fn test_agent_id_portable_across_machines() {
let dir = TempDir::new().unwrap();
let agent_key = dir.path().join("portable_agent.key");
let agent1 = Agent::builder()
.with_machine_key(dir.path().join("machineA.key"))
.with_agent_key_path(agent_key.clone())
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let agent2 = Agent::builder()
.with_machine_key(dir.path().join("machineB.key"))
.with_agent_key_path(agent_key.clone())
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
assert_eq!(
agent1.agent_id(),
agent2.agent_id(),
"same agent key must produce the same agent_id regardless of machine"
);
assert_ne!(
agent1.machine_id(),
agent2.machine_id(),
"different machine keys must produce different machine_ids"
);
}
#[tokio::test]
async fn test_announcement_machine_id_matches_agent() {
let dir = TempDir::new().unwrap();
let agent = Agent::builder()
.with_machine_key(dir.path().join("machine.key"))
.with_agent_key_path(dir.path().join("agent.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let ann = agent.build_announcement(false, false).unwrap();
assert_eq!(
ann.machine_id,
agent.machine_id(),
"announcement machine_id must match agent.machine_id()"
);
assert_eq!(
ann.agent_id,
agent.agent_id(),
"announcement agent_id must match agent.agent_id()"
);
}
#[tokio::test]
async fn test_announcement_verifies() {
let dir = TempDir::new().unwrap();
let agent = Agent::builder()
.with_machine_key(dir.path().join("machine.key"))
.with_agent_key_path(dir.path().join("agent.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let ann = agent.build_announcement(false, false).unwrap();
ann.verify()
.expect("freshly built announcement should verify");
}
#[tokio::test]
async fn test_machine_public_key_derives_machine_id() {
let dir = TempDir::new().unwrap();
let agent = Agent::builder()
.with_machine_key(dir.path().join("machine.key"))
.with_agent_key_path(dir.path().join("agent.key"))
.with_network_config(NetworkConfig::default())
.build()
.await
.unwrap();
let ann = agent.build_announcement(false, false).unwrap();
let machine_pub = ant_quic::MlDsaPublicKey::from_bytes(&ann.machine_public_key)
.expect("machine_public_key bytes should be a valid ML-DSA-65 public key");
let derived = x0x::identity::MachineId::from_public_key(&machine_pub);
assert_eq!(
derived,
agent.machine_id(),
"SHA-256(machine_public_key) must equal agent.machine_id()"
);
}