Skip to content

Commit ad7773e

Browse files
benthecarmanclaude
andcommitted
Reduce test slowness and flakiness
- Use exponential backoff (50ms→1s) in wait_for_condition instead of fixed 1s polling, preserving the same total timeout budget - Make wait_for_tx_broadcast async to avoid blocking the tokio runtime - Replace hardcoded sleep(5) and sleep(1) sync waits with wallet.sync_ln_wallet() for deterministic synchronization - Batch initial 101-block generation into 2 RPC calls instead of 101 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d74dfef commit ad7773e

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

orange-sdk/tests/integration_tests.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -441,9 +441,9 @@ async fn test_receive_onchain() {
441441
// a rebalance should be initiated, we need to mine the channel opening transaction
442442
// for it to be confirmed and reflected in the wallet's history
443443
generate_blocks(&bitcoind, &electrsd, 6).await;
444-
tokio::time::sleep(Duration::from_secs(5)).await; // wait for sync
444+
wallet.sync_ln_wallet().unwrap();
445445
generate_blocks(&bitcoind, &electrsd, 6).await; // confirm the channel opening transaction
446-
tokio::time::sleep(Duration::from_secs(5)).await; // wait for sync
446+
wallet.sync_ln_wallet().unwrap();
447447

448448
// wait for rebalance to be initiated
449449
println!("waiting for channel opened event");
@@ -553,7 +553,7 @@ async fn test_receive_to_onchain_with_channel() {
553553

554554
// confirm splice
555555
generate_blocks(&bitcoind, &electrsd, 6).await;
556-
tokio::time::sleep(Duration::from_secs(5)).await;
556+
wallet.sync_ln_wallet().unwrap();
557557

558558
let event = wait_next_event(&wallet).await;
559559
match event {
@@ -563,8 +563,6 @@ async fn test_receive_to_onchain_with_channel() {
563563
ev => panic!("Expected ChannelOpened event, got {ev:?}"),
564564
}
565565

566-
wallet.sync_ln_wallet().unwrap();
567-
568566
let txs = wallet.list_transactions().await.unwrap();
569567
assert_eq!(txs.len(), 2);
570568
let tx = txs.into_iter().last().unwrap();
@@ -839,14 +837,9 @@ async fn test_pay_onchain_from_self_custody() {
839837
let info = PaymentInfo::build(instr, Some(send_amount)).unwrap();
840838
wallet.pay(&info).await.unwrap();
841839

842-
// sleep for a second to wait for proper broadcast
843-
tokio::time::sleep(Duration::from_secs(1)).await;
844-
845840
// confirm the tx
846841
generate_blocks(&bitcoind, &electrsd, 6).await;
847-
848-
// sleep for a second to wait for sync
849-
tokio::time::sleep(Duration::from_secs(1)).await;
842+
wallet.sync_ln_wallet().unwrap();
850843

851844
// wait for payment to complete
852845
test_utils::wait_for_condition("on-chain payment completion", || async {
@@ -945,14 +938,9 @@ async fn test_pay_onchain_from_channel() {
945938
let info = PaymentInfo::build(instr, Some(send_amount)).unwrap();
946939
wallet.pay(&info).await.unwrap();
947940

948-
// sleep for a second to wait for proper broadcast
949-
tokio::time::sleep(Duration::from_secs(1)).await;
950-
951941
// confirm the tx
952942
generate_blocks(&bitcoind, &electrsd, 6).await;
953-
954-
// sleep for a second to wait for sync
955-
tokio::time::sleep(Duration::from_secs(1)).await;
943+
wallet.sync_ln_wallet().unwrap();
956944

957945
// wait for payment to complete
958946
test_utils::wait_for_condition("on-chain payment completion", || async {

orange-sdk/tests/test_utils.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,30 @@ use std::sync::Arc;
3333
use std::time::Duration;
3434
use uuid::Uuid;
3535

36-
/// Waits for an async condition to be true, polling at a specified interval until a timeout.
36+
/// Waits for an async condition to be true, polling with exponential backoff until a timeout.
3737
pub async fn wait_for_condition<F, Fut>(condition_name: &str, mut condition: F)
3838
where
3939
F: FnMut() -> Fut,
4040
Fut: Future<Output = bool>,
4141
{
42-
// longer timeout if running in CI as things can be slower there
43-
let iterations = if std::env::var("CI").is_ok() { 120 } else { 20 };
44-
for _ in 0..iterations {
42+
let timeout = if std::env::var("CI").is_ok() {
43+
Duration::from_secs(120)
44+
} else {
45+
Duration::from_secs(20)
46+
};
47+
let start = tokio::time::Instant::now();
48+
let mut delay = Duration::from_millis(50);
49+
loop {
4550
if condition().await {
4651
return;
4752
}
48-
tokio::time::sleep(Duration::from_secs(1)).await;
53+
if start.elapsed() >= timeout {
54+
panic!("Timeout waiting for condition: {condition_name}");
55+
}
56+
tokio::time::sleep(delay).await;
57+
// Exponential backoff, cap at 1 second
58+
delay = (delay * 2).min(Duration::from_secs(1));
4959
}
50-
panic!("Timeout waiting for condition: {condition_name}");
5160
}
5261

5362
/// Waits for the next event from the wallet, polling every second for up to 20 seconds.
@@ -84,11 +93,11 @@ async fn create_bitcoind(uuid: Uuid) -> (Arc<Bitcoind>, Arc<ElectrsD>) {
8493
ElectrsD::with_conf(electrsd::downloaded_exe_path().unwrap(), &bitcoind, &electrsd_conf)
8594
.unwrap_or_else(|_| panic!("Failed to start electrsd for test {uuid}"));
8695

87-
// mine 101 blocks to get some spendable funds, split it up into multiple calls
96+
// mine 101 blocks to get some spendable funds, split it up into batches
8897
// to avoid potentially hitting RPC timeouts on slower CI systems
8998
let address = bitcoind.client.new_address().unwrap();
90-
for _ in 0..101 {
91-
let _block_hashes = bitcoind.client.generate_to_address(1, &address).unwrap();
99+
for batch_size in [50, 51] {
100+
let _block_hashes = bitcoind.client.generate_to_address(batch_size, &address).unwrap();
92101
}
93102

94103
wait_for_block(&electrsd.client, 101).await;
@@ -305,7 +314,7 @@ async fn build_test_nodes() -> TestParams {
305314

306315
// open a channel from payer to LSP
307316
third_party.open_channel(lsp.node_id(), lsp_listen.clone(), 10_000_000, None, None).unwrap();
308-
wait_for_tx_broadcast(&bitcoind);
317+
wait_for_tx_broadcast(&bitcoind).await;
309318
generate_blocks(&bitcoind, &electrsd, 6).await;
310319

311320
// wait for channel ready (needs blocking wait as we are not in async context here)
@@ -457,7 +466,7 @@ async fn build_test_nodes() -> TestParams {
457466
None,
458467
)
459468
.unwrap();
460-
wait_for_tx_broadcast(&bitcoind_clone);
469+
wait_for_tx_broadcast(&bitcoind_clone).await;
461470
generate_blocks(&bitcoind_clone, &electrsd, 6).await;
462471

463472
// wait for sync/channel ready
@@ -542,14 +551,24 @@ pub async fn open_channel_from_lsp(wallet: &orange_sdk::Wallet, payer: Arc<Node>
542551
recv_amt
543552
}
544553

545-
fn wait_for_tx_broadcast(bitcoind: &Bitcoind) {
546-
let iterations = if std::env::var("CI").is_ok() { 120 } else { 10 };
547-
for _ in 0..iterations {
554+
async fn wait_for_tx_broadcast(bitcoind: &Bitcoind) {
555+
let timeout = if std::env::var("CI").is_ok() {
556+
Duration::from_secs(30)
557+
} else {
558+
Duration::from_millis(2500)
559+
};
560+
let start = tokio::time::Instant::now();
561+
let mut delay = Duration::from_millis(50);
562+
loop {
548563
let num_txs = bitcoind.client.get_mempool_info().unwrap().size;
549564
if num_txs > 0 {
550565
break;
551566
}
552-
std::thread::sleep(Duration::from_millis(250));
567+
if start.elapsed() >= timeout {
568+
panic!("Timeout waiting for tx broadcast");
569+
}
570+
tokio::time::sleep(delay).await;
571+
delay = (delay * 2).min(Duration::from_millis(500));
553572
}
554573
}
555574

0 commit comments

Comments
 (0)