use std::collections::HashMap;
use std::path::PathBuf;
use ant_core::node::binary::NoopProgress;
use ant_core::node::registry::NodeRegistry;
use ant_core::node::types::{AddNodeOpts, BinarySource, PortRange};
const TEST_ADDR: &str = "0x1234567890abcdef1234567890abcdef12345678";
fn create_fake_binary(dir: &std::path::Path) -> PathBuf {
#[cfg(unix)]
{
let binary_path = dir.join("fake-antnode");
std::fs::write(&binary_path, "#!/bin/sh\necho \"antnode 0.1.0-test\"\n").unwrap();
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(&binary_path, std::fs::Permissions::from_mode(0o755)).unwrap();
binary_path
}
#[cfg(windows)]
{
let binary_path = dir.join("fake-antnode.cmd");
std::fs::write(&binary_path, "@echo off\r\necho antnode 0.1.0-test\r\n").unwrap();
binary_path
}
}
#[tokio::test]
async fn add_nodes_creates_registry_and_directories() {
let tmp = tempfile::tempdir().unwrap();
let binary = create_fake_binary(tmp.path());
let reg_path = tmp.path().join("registry.json");
let opts = AddNodeOpts {
count: 2,
rewards_address: TEST_ADDR.to_string(),
node_port: Some(PortRange::Range(12000, 12001)),
metrics_port: Some(PortRange::Range(13000, 13001)),
data_dir_path: Some(tmp.path().join("data")),
log_dir_path: Some(tmp.path().join("logs")),
binary_source: BinarySource::LocalPath(binary),
..Default::default()
};
let result = ant_core::node::add_nodes(opts, ®_path, &NoopProgress)
.await
.unwrap();
assert_eq!(result.nodes_added.len(), 2);
assert_eq!(result.nodes_added[0].id, 1);
assert_eq!(result.nodes_added[1].id, 2);
assert_eq!(result.nodes_added[0].node_port, Some(12000));
assert_eq!(result.nodes_added[1].node_port, Some(12001));
assert_eq!(result.nodes_added[0].metrics_port, Some(13000));
assert_eq!(result.nodes_added[1].metrics_port, Some(13001));
for node in &result.nodes_added {
assert!(
node.data_dir.exists(),
"data dir should exist: {:?}",
node.data_dir
);
let log_dir = node.log_dir.as_ref().expect("log_dir should be set");
assert!(log_dir.exists(), "log dir should exist: {:?}", log_dir);
}
assert!(reg_path.exists());
let reg = NodeRegistry::load(®_path).unwrap();
assert_eq!(reg.len(), 2);
assert_eq!(reg.next_id, 3);
}
#[tokio::test]
async fn add_then_remove_node() {
let tmp = tempfile::tempdir().unwrap();
let binary = create_fake_binary(tmp.path());
let reg_path = tmp.path().join("registry.json");
let opts = AddNodeOpts {
count: 1,
rewards_address: TEST_ADDR.to_string(),
data_dir_path: Some(tmp.path().join("data")),
log_dir_path: Some(tmp.path().join("logs")),
binary_source: BinarySource::LocalPath(binary),
..Default::default()
};
let result = ant_core::node::add_nodes(opts, ®_path, &NoopProgress)
.await
.unwrap();
let node_id = result.nodes_added[0].id;
let remove_result = ant_core::node::remove_node(node_id, ®_path).unwrap();
assert_eq!(remove_result.removed.rewards_address, TEST_ADDR);
let reg = NodeRegistry::load(®_path).unwrap();
assert!(reg.is_empty());
}
#[tokio::test]
async fn add_nodes_with_env_variables() {
let tmp = tempfile::tempdir().unwrap();
let binary = create_fake_binary(tmp.path());
let reg_path = tmp.path().join("registry.json");
let opts = AddNodeOpts {
count: 1,
rewards_address: TEST_ADDR.to_string(),
data_dir_path: Some(tmp.path().join("data")),
log_dir_path: Some(tmp.path().join("logs")),
binary_source: BinarySource::LocalPath(binary),
env_variables: vec![
("FOO".to_string(), "bar".to_string()),
("BAZ".to_string(), "qux".to_string()),
],
bootstrap_peers: vec!["1.2.3.4:5000".to_string()],
..Default::default()
};
let result = ant_core::node::add_nodes(opts, ®_path, &NoopProgress)
.await
.unwrap();
let node = &result.nodes_added[0];
let expected_env: HashMap<String, String> = [
("FOO".to_string(), "bar".to_string()),
("BAZ".to_string(), "qux".to_string()),
]
.into_iter()
.collect();
assert_eq!(node.env_variables, expected_env);
assert_eq!(node.bootstrap_peers, vec!["1.2.3.4:5000"]);
}