Skip to content

Commit d10a5e1

Browse files
committed
simln-lib/test: Add unit tests for validate_activity(), validate_node_network()
1 parent a45993d commit d10a5e1

File tree

2 files changed

+370
-53
lines changed

2 files changed

+370
-53
lines changed

simln-lib/src/lib.rs

Lines changed: 174 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,19 +1417,19 @@ async fn track_payment_result(
14171417

14181418
#[cfg(test)]
14191419
mod tests {
1420+
// use crate::test_utils::TestNetworkBuilder;
14201421
use crate::{
1421-
get_payment_delay, test_utils, LightningError, LightningNode, MutRng, NodeInfo,
1422-
PaymentGenerationError, PaymentGenerator, Simulation,
1422+
get_payment_delay, test_utils, test_utils::LightningTestNodeBuilder, LightningError,
1423+
LightningNode, MutRng, PaymentGenerationError, PaymentGenerator,
14231424
};
1424-
use async_trait::async_trait;
14251425
use bitcoin::secp256k1::PublicKey;
1426+
use bitcoin::Network;
14261427
use mockall::mock;
14271428
use std::collections::HashMap;
14281429
use std::fmt;
14291430
use std::sync::Arc;
14301431
use std::time::Duration;
14311432
use tokio::sync::Mutex;
1432-
use tokio_util::task::TaskTracker;
14331433

14341434
#[test]
14351435
fn create_seeded_mut_rng() {
@@ -1472,27 +1472,6 @@ mod tests {
14721472
}
14731473
}
14741474

1475-
mock! {
1476-
pub LightningNode {}
1477-
#[async_trait]
1478-
impl crate::LightningNode for LightningNode {
1479-
fn get_info(&self) -> &NodeInfo;
1480-
async fn get_network(&mut self) -> Result<bitcoin::Network, LightningError>;
1481-
async fn send_payment(
1482-
&mut self,
1483-
dest: bitcoin::secp256k1::PublicKey,
1484-
amount_msat: u64,
1485-
) -> Result<lightning::ln::PaymentHash, LightningError>;
1486-
async fn track_payment(
1487-
&mut self,
1488-
hash: &lightning::ln::PaymentHash,
1489-
shutdown: triggered::Listener,
1490-
) -> Result<crate::PaymentResult, LightningError>;
1491-
async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError>;
1492-
async fn list_channels(&mut self) -> Result<Vec<u64>, LightningError>;
1493-
}
1494-
}
1495-
14961475
#[test]
14971476
fn test_no_payment_delay() {
14981477
let node = test_utils::create_nodes(1, 100_000)
@@ -1548,33 +1527,178 @@ mod tests {
15481527
);
15491528
}
15501529

1530+
// Tests for validate_activity()
1531+
1532+
/// Verifies that an empty activity (for random generation) is valid when two nodes with keysend
1533+
/// support are present, expecting an `Ok` result.
1534+
#[tokio::test]
1535+
async fn test_validate_activity_empty_with_sufficient_nodes() {
1536+
let (_, clients) = LightningTestNodeBuilder::setup_test_nodes(2, &[0, 1, 2]);
1537+
let simulation = test_utils::create_simulation(clients, vec![]);
1538+
let result = simulation.validate_activity().await;
1539+
assert!(result.is_ok());
1540+
}
1541+
1542+
/// Verifies that an empty activity fails validation with only one keysend-enabled node,
1543+
/// expecting a `ValidationError` with "At least two nodes required".
1544+
#[tokio::test]
1545+
async fn test_validate_activity_empty_with_insufficient_nodes() {
1546+
let (_, clients) = LightningTestNodeBuilder::setup_test_nodes(1, &[0]);
1547+
let simulation = test_utils::create_simulation(clients, vec![]);
1548+
let result = simulation.validate_activity().await;
1549+
1550+
assert!(result.is_err());
1551+
assert!(matches!(result,
1552+
Err(LightningError::ValidationError(msg)) if msg.contains("At least two nodes required")));
1553+
}
1554+
1555+
/// Verifies that an empty activity fails when one of two nodes doesn’t support keysend,
1556+
/// expecting a `ValidationError` with "must support keysend".
1557+
#[tokio::test]
1558+
async fn test_validate_activity_empty_with_non_keysend_node() {
1559+
let (_, clients) = LightningTestNodeBuilder::setup_test_nodes(2, &[0]);
1560+
let simulation = test_utils::create_simulation(clients, vec![]);
1561+
let result = simulation.validate_activity().await;
1562+
1563+
assert!(result.is_err());
1564+
assert!(matches!(result,
1565+
Err(LightningError::ValidationError(msg)) if msg.contains("must support keysend")));
1566+
}
1567+
1568+
/// Verifies that an activity fails when the source node isn’t in the clients map,
1569+
/// expecting a `ValidationError` with "Source node not found".
1570+
#[tokio::test]
1571+
async fn test_validate_activity_with_missing_source_node() {
1572+
let (nodes, clients) = LightningTestNodeBuilder::setup_test_nodes(1, &[0]);
1573+
let missing_nodes = test_utils::create_nodes(1, 100_000);
1574+
let missing_node = missing_nodes.first().unwrap().0.clone();
1575+
let dest_node = nodes[0].clone();
1576+
1577+
let activity = test_utils::create_activity(missing_node, dest_node, 1000);
1578+
let simulation = test_utils::create_simulation(clients, vec![activity]);
1579+
let result = simulation.validate_activity().await;
1580+
1581+
assert!(result.is_err());
1582+
assert!(matches!(result,
1583+
Err(LightningError::ValidationError(msg)) if msg.contains("Source node not found")));
1584+
}
1585+
1586+
/// Verifies that an activity fails when the destination lacks keysend support,
1587+
/// expecting a `ValidationError` with "does not support keysend".
1588+
#[tokio::test]
1589+
async fn test_validate_activity_with_non_keysend_destination() {
1590+
let (nodes, clients) = LightningTestNodeBuilder::setup_test_nodes(1, &[0]);
1591+
let dest_nodes = test_utils::create_nodes(1, 100_000);
1592+
let dest_node = dest_nodes.first().unwrap().0.clone();
1593+
1594+
let activity = test_utils::create_activity(nodes[0].clone(), dest_node, 1000);
1595+
let simulation = test_utils::create_simulation(clients, vec![activity]);
1596+
let result = simulation.validate_activity().await;
1597+
1598+
assert!(result.is_err());
1599+
assert!(matches!(result,
1600+
Err(LightningError::ValidationError(msg)) if msg.contains("does not support keysend")));
1601+
}
1602+
1603+
/// Verifies that an activity with a non-zero amount between two keysend-enabled nodes
1604+
/// passes validation, expecting an `Ok` result.
1605+
#[tokio::test]
1606+
async fn test_validate_activity_valid_payment_flow() {
1607+
let (nodes, clients) = LightningTestNodeBuilder::setup_test_nodes(1, &[0]);
1608+
let dest_nodes = test_utils::create_nodes(1, 100_000);
1609+
let mut dest_node = dest_nodes.first().unwrap().0.clone();
1610+
dest_node.features.set_keysend_optional();
1611+
1612+
let activity = test_utils::create_activity(nodes[0].clone(), dest_node, 1000);
1613+
let simulation = test_utils::create_simulation(clients, vec![activity]);
1614+
let result = simulation.validate_activity().await;
1615+
1616+
assert!(result.is_ok());
1617+
}
1618+
1619+
/// Verifies that an activity with a zero amount between two keysend-enabled nodes fails,
1620+
/// expecting a `ValidationError` with "zero values".
15511621
#[tokio::test]
15521622
async fn test_validate_zero_amount_no_valid() {
1553-
let nodes = test_utils::create_nodes(2, 100_000);
1554-
let mut node_1 = nodes.first().unwrap().0.clone();
1555-
let mut node_2 = nodes.get(1).unwrap().0.clone();
1556-
node_1.features.set_keysend_optional();
1557-
node_2.features.set_keysend_optional();
1558-
1559-
let mock_node_1 = MockLightningNode::new();
1560-
let mock_node_2 = MockLightningNode::new();
1561-
let mut clients: HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>> = HashMap::new();
1562-
clients.insert(node_1.pubkey, Arc::new(Mutex::new(mock_node_1)));
1563-
clients.insert(node_2.pubkey, Arc::new(Mutex::new(mock_node_2)));
1564-
let activity_definition = crate::ActivityDefinition {
1565-
source: node_1,
1566-
destination: node_2,
1567-
start_secs: None,
1568-
count: None,
1569-
interval_secs: crate::ValueOrRange::Value(0),
1570-
amount_msat: crate::ValueOrRange::Value(0),
1571-
};
1572-
let simulation = Simulation::new(
1573-
crate::SimulationCfg::new(Some(0), 0, 0.0, None, None),
1574-
clients,
1575-
vec![activity_definition],
1576-
TaskTracker::new(),
1623+
let (nodes, clients) = LightningTestNodeBuilder::setup_test_nodes(2, &[0, 1]);
1624+
1625+
let activity = test_utils::create_activity(nodes[0].clone(), nodes[1].clone(), 0);
1626+
let simulation = test_utils::create_simulation(clients, vec![activity]);
1627+
let result = simulation.validate_activity().await;
1628+
1629+
assert!(result.is_err());
1630+
assert!(matches!(result,
1631+
Err(LightningError::ValidationError(msg)) if msg.contains("zero values")));
1632+
}
1633+
1634+
// tests for validate_node_network()
1635+
1636+
/// Verifies that validation fails with no nodes, expecting a `ValidationError` with
1637+
/// "we don't control any nodes".
1638+
#[tokio::test]
1639+
async fn test_validate_node_network_empty_nodes() {
1640+
let empty_nodes: HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>> = HashMap::new();
1641+
1642+
let simulation = test_utils::create_simulation(empty_nodes, vec![]);
1643+
let result = simulation.validate_node_network().await;
1644+
1645+
assert!(result.is_err());
1646+
assert!(matches!(result,
1647+
Err(LightningError::ValidationError(msg)) if msg.contains("we don't control any nodes")));
1648+
}
1649+
1650+
/// Verifies that a node on Bitcoin mainnet fails validation, expecting a `ValidationError`
1651+
/// with "mainnet is not supported".
1652+
#[tokio::test]
1653+
async fn test_validate_node_network_mainnet_not_supported() {
1654+
let clients = LightningTestNodeBuilder::setup_network_test_nodes(1, vec![Network::Bitcoin]);
1655+
1656+
let simulation = test_utils::create_simulation(clients, vec![]);
1657+
let result = simulation.validate_node_network().await;
1658+
1659+
assert!(result.is_err());
1660+
assert!(matches!(result,
1661+
Err(LightningError::ValidationError(msg)) if msg.contains("mainnet is not supported")));
1662+
}
1663+
1664+
/// Verifies that nodes on Testnet and Regtest fail validation, expecting a
1665+
/// `ValidationError` with "nodes are not on the same network".
1666+
#[tokio::test]
1667+
async fn test_validate_node_network_mixed_networks() {
1668+
let clients = LightningTestNodeBuilder::setup_network_test_nodes(
1669+
2,
1670+
vec![Network::Testnet, Network::Regtest],
15771671
);
1578-
assert!(simulation.validate_activity().await.is_err());
1672+
1673+
let simulation = test_utils::create_simulation(clients, vec![]);
1674+
let result = simulation.validate_node_network().await;
1675+
1676+
assert!(result.is_err());
1677+
assert!(matches!(result,
1678+
Err(LightningError::ValidationError(msg)) if msg.contains("nodes are not on the same network")));
1679+
}
1680+
1681+
/// Verifies that three Testnet nodes pass validation, expecting an `Ok` result.
1682+
#[tokio::test]
1683+
async fn test_validate_node_network_multiple_nodes_same_network() {
1684+
let clients = LightningTestNodeBuilder::setup_network_test_nodes(
1685+
3,
1686+
vec![Network::Testnet, Network::Testnet, Network::Testnet],
1687+
);
1688+
1689+
let simulation = test_utils::create_simulation(clients, vec![]);
1690+
let result = simulation.validate_node_network().await;
1691+
1692+
assert!(result.is_ok());
1693+
}
1694+
1695+
#[tokio::test]
1696+
async fn test_validate_node_network_single_node_valid_network() {
1697+
let clients = LightningTestNodeBuilder::setup_network_test_nodes(1, vec![Network::Testnet]);
1698+
1699+
let simulation = test_utils::create_simulation(clients, vec![]);
1700+
let result = simulation.validate_node_network().await;
1701+
1702+
assert!(result.is_ok());
15791703
}
15801704
}

0 commit comments

Comments
 (0)