Skip to content

Commit 56badbd

Browse files
committed
Adding a test for the error shutdown case
1 parent f38f2e1 commit 56badbd

File tree

1 file changed

+80
-3
lines changed

1 file changed

+80
-3
lines changed

simln-lib/src/lib.rs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ mod tests {
19431943
// Set up test nodes
19441944
let ((node_1, node_2), clients) = setup_test_nodes();
19451945

1946-
// Define an activity that would make many payments (but we will shut down early)
1946+
// Define an activity that would make payments (but we will shut down early)
19471947
let activity_definition = crate::ActivityDefinition {
19481948
source: node_1,
19491949
destination: node_2,
@@ -1997,11 +1997,88 @@ mod tests {
19971997
elapsed
19981998
);
19991999

2000-
// We expect fewer than the total 100 payments to be attempted
2000+
// We expect fewer than the total 10 payments to be attempted
20012001
let total_payments = simulation.get_total_payments().await;
20022002
assert!(
20032003
total_payments > 0 && total_payments < 10,
2004-
"Expected between 1 and 99 payments to be attempted, got {}",
2004+
"Expected between 1 and 9 payments to be attempted, got {}",
2005+
total_payments
2006+
);
2007+
}
2008+
2009+
#[tokio::test]
2010+
async fn test_shutdown_on_error() {
2011+
// Set up test nodes with one that will produce a permanent error
2012+
let ((node_1, node_2), mut clients) = setup_test_nodes();
2013+
let mut mock_node_1 = MockLightningNode::new();
2014+
2015+
// Set up node 1 expectations
2016+
let node_1_clone = node_1.clone();
2017+
mock_node_1.expect_get_info().return_const(node_1.clone());
2018+
mock_node_1
2019+
.expect_get_network()
2020+
.returning(|| Ok(Network::Regtest));
2021+
mock_node_1
2022+
.expect_list_channels()
2023+
.returning(|| Ok(vec![100_000]));
2024+
mock_node_1
2025+
.expect_get_node_info()
2026+
.returning(move |_| Ok(node_1_clone.clone()));
2027+
mock_node_1.expect_track_payment().returning(|_, _| {
2028+
Ok(crate::PaymentResult {
2029+
htlc_count: 1,
2030+
payment_outcome: crate::PaymentOutcome::Success,
2031+
})
2032+
});
2033+
mock_node_1.expect_send_payment().returning(|_, _| {
2034+
Err(LightningError::PermanentError(
2035+
"Simulated permanent error".to_string(),
2036+
))
2037+
});
2038+
2039+
clients.insert(node_1.pubkey, Arc::new(Mutex::new(mock_node_1)));
2040+
2041+
// Define an activity that attempts to send a payment from node_1 to node_2
2042+
let activity_definition = crate::ActivityDefinition {
2043+
source: node_1,
2044+
destination: node_2,
2045+
start_secs: None, // Start immediately
2046+
count: Some(5), // Would try multiple payments if no error occurred
2047+
interval_secs: crate::ValueOrRange::Value(1), // 1 second interval
2048+
amount_msat: crate::ValueOrRange::Value(2000), // 2000 msats
2049+
};
2050+
2051+
// Create simulation with a long timeout that we don't expect to be reached
2052+
let simulation = Simulation::new(
2053+
SimulationCfg::new(
2054+
Some(30), // 30 second timeout (shouldn't matter)
2055+
1000, // Expected payment size
2056+
0.1, // Activity multiplier
2057+
None, // No result writing
2058+
Some(42), // Seed for determinism
2059+
),
2060+
clients,
2061+
vec![activity_definition],
2062+
TaskTracker::new(),
2063+
);
2064+
2065+
// Run the simulation (should be interrupted by the error)
2066+
let start = std::time::Instant::now();
2067+
let _ = simulation.run().await;
2068+
let elapsed = start.elapsed();
2069+
2070+
// Check that simulation ran for a short time (less than our expected 5 seconds)
2071+
assert!(
2072+
elapsed < Duration::from_secs(5),
2073+
"Simulation should have shut down quickly after encountering the error, took {:?}",
2074+
elapsed
2075+
);
2076+
2077+
// We expect no successful payments to be recorded
2078+
let total_payments = simulation.get_total_payments().await;
2079+
assert_eq!(
2080+
total_payments, 0,
2081+
"Expected no payments to be recorded, got {}",
20052082
total_payments
20062083
);
20072084
}

0 commit comments

Comments
 (0)