Skip to content

Commit cb1054f

Browse files
committed
test(electrum): split monolithic test into focused per-scenario tests
Break test_electrum() into individual test functions (balance, history, payment, raw), each covering a specific scenario, and extract shared setup into a WalletTester struct.
1 parent d100fc7 commit cb1054f

File tree

1 file changed

+107
-63
lines changed

1 file changed

+107
-63
lines changed

tests/electrum.rs

Lines changed: 107 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,51 @@ use electrumd::jsonrpc::serde_json::json;
99
use electrumd::ElectrumD;
1010

1111
use electrs::chain::Address;
12+
use electrs::electrum::RPC as ElectrumRPC;
1213

1314
#[cfg(not(feature = "liquid"))]
1415
use bitcoin::address;
1516

16-
/// Test the Electrum RPC server using an headless Electrum wallet
17-
/// This only runs on Bitcoin (non-Liquid) mode.
18-
#[cfg_attr(not(feature = "liquid"), test)]
19-
#[cfg_attr(feature = "liquid", allow(dead_code))]
20-
fn test_electrum() -> Result<()> {
21-
// Spawn an Electrs Electrum RPC server
22-
let (electrum_server, electrum_addr, mut tester) = common::init_electrum_tester().unwrap();
23-
24-
// Spawn an headless Electrum wallet RPC daemon, connected to Electrs
25-
let mut electrum_wallet_conf = electrumd::Conf::default();
26-
let server_arg = format!("{}:t", electrum_addr.to_string());
27-
electrum_wallet_conf.args = if std::env::var_os("RUST_LOG").is_some() {
28-
vec!["-v", "--server", &server_arg]
29-
} else {
30-
vec!["--server", &server_arg]
31-
};
32-
electrum_wallet_conf.view_stdout = true;
33-
let electrum_wallet = ElectrumD::with_conf(electrumd::exe_path()?, &electrum_wallet_conf)?;
34-
35-
let notify_wallet = || {
36-
electrum_server.notify();
17+
struct WalletTester {
18+
electrum_server: ElectrumRPC,
19+
electrum_wallet: ElectrumD,
20+
tester: common::TestRunner,
21+
}
22+
23+
impl WalletTester {
24+
fn new() -> Result<Self> {
25+
let (electrum_server, electrum_addr, tester) = common::init_electrum_tester().unwrap();
26+
27+
let mut electrum_wallet_conf = electrumd::Conf::default();
28+
let server_arg = format!("{}:t", electrum_addr);
29+
electrum_wallet_conf.args = if std::env::var_os("RUST_LOG").is_some() {
30+
vec!["-v", "--server", &server_arg]
31+
} else {
32+
vec!["--server", &server_arg]
33+
};
34+
electrum_wallet_conf.view_stdout = true;
35+
let electrum_wallet =
36+
ElectrumD::with_conf(electrumd::exe_path()?, &electrum_wallet_conf)?;
37+
38+
log::info!(
39+
"Electrum wallet version: {:?}",
40+
electrum_wallet.call("version", &json!([]))?
41+
);
42+
43+
Ok(WalletTester {
44+
electrum_server,
45+
electrum_wallet,
46+
tester,
47+
})
48+
}
49+
50+
fn notify_wallet(&self) {
51+
self.electrum_server.notify();
3752
std::thread::sleep(std::time::Duration::from_millis(200));
38-
};
53+
}
3954

40-
let assert_balance = |confirmed: f64, unconfirmed: f64| {
41-
let balance = electrum_wallet.call("getbalance", &json!([])).unwrap();
55+
fn assert_balance(&self, confirmed: f64, unconfirmed: f64) {
56+
let balance = self.electrum_wallet.call("getbalance", &json!([])).unwrap();
4257
log::info!("balance: {}", balance);
4358

4459
assert_eq!(
@@ -53,15 +68,16 @@ fn test_electrum() -> Result<()> {
5368
} else {
5469
assert!(balance["unconfirmed"].is_null())
5570
}
56-
};
71+
}
5772

58-
let newaddress = || -> Address {
73+
fn newaddress(&self) -> Address {
5974
#[cfg(not(feature = "liquid"))]
6075
type ParseAddrType = Address<address::NetworkUnchecked>;
6176
#[cfg(feature = "liquid")]
6277
type ParseAddrType = Address;
6378

64-
let addr = electrum_wallet
79+
let addr = self
80+
.electrum_wallet
6581
.call("createnewaddress", &json!([]))
6682
.unwrap()
6783
.as_str()
@@ -73,37 +89,55 @@ fn test_electrum() -> Result<()> {
7389
let addr = addr.assume_checked();
7490

7591
addr
76-
};
92+
}
93+
}
7794

78-
log::info!(
79-
"Electrum wallet version: {:?}",
80-
electrum_wallet.call("version", &json!([]))?
81-
);
95+
/// Test balance tracking with confirmed and unconfirmed transactions
96+
#[cfg_attr(not(feature = "liquid"), test)]
97+
#[cfg_attr(feature = "liquid", allow(dead_code))]
98+
fn test_electrum_balance() -> Result<()> {
99+
let mut wt = WalletTester::new()?;
100+
101+
let addr1 = wt.newaddress();
102+
let addr2 = wt.newaddress();
103+
104+
wt.assert_balance(0.0, 0.0);
105+
106+
wt.tester.send(&addr1, "0.1 BTC".parse().unwrap())?;
107+
wt.notify_wallet();
108+
wt.assert_balance(0.0, 0.1);
82109

83-
// Send some funds and verify that the balance checks out
84-
let addr1 = newaddress();
85-
let addr2 = newaddress();
110+
wt.tester.mine()?;
111+
wt.notify_wallet();
112+
wt.assert_balance(0.1, 0.0);
86113

87-
assert_balance(0.0, 0.0);
114+
wt.tester.send(&addr2, "0.2 BTC".parse().unwrap())?;
115+
wt.notify_wallet();
116+
wt.assert_balance(0.1, 0.2);
88117

89-
let txid1 = tester.send(&addr1, "0.1 BTC".parse().unwrap())?;
90-
notify_wallet();
91-
assert_balance(0.0, 0.1);
118+
wt.tester.mine()?;
119+
wt.notify_wallet();
120+
wt.assert_balance(0.3, 0.0);
92121

93-
tester.mine()?;
94-
notify_wallet();
95-
assert_balance(0.1, 0.0);
122+
Ok(())
123+
}
124+
125+
/// Test transaction history via onchain_history
126+
#[cfg_attr(not(feature = "liquid"), test)]
127+
#[cfg_attr(feature = "liquid", allow(dead_code))]
128+
fn test_electrum_history() -> Result<()> {
129+
let mut wt = WalletTester::new()?;
96130

97-
let txid2 = tester.send(&addr2, "0.2 BTC".parse().unwrap())?;
98-
notify_wallet();
99-
assert_balance(0.1, 0.2);
131+
let addr1 = wt.newaddress();
132+
let addr2 = wt.newaddress();
100133

101-
tester.mine()?;
102-
notify_wallet();
103-
assert_balance(0.3, 0.0);
134+
let txid1 = wt.tester.send(&addr1, "0.1 BTC".parse().unwrap())?;
135+
wt.tester.mine()?;
136+
let txid2 = wt.tester.send(&addr2, "0.2 BTC".parse().unwrap())?;
137+
wt.tester.mine()?;
138+
wt.notify_wallet();
104139

105-
// Verify that the transaction history checks out
106-
let history = electrum_wallet.call("onchain_history", &json!([]))?;
140+
let history = wt.electrum_wallet.call("onchain_history", &json!([]))?;
107141
log::debug!("history = {:#?}", history);
108142
assert_eq!(
109143
history["transactions"][0]["txid"].as_str(),
@@ -119,37 +153,47 @@ fn test_electrum() -> Result<()> {
119153
assert_eq!(history["transactions"][1]["height"].as_u64(), Some(103));
120154
assert_eq!(history["transactions"][1]["bc_value"].as_str(), Some("0.2"));
121155

122-
// Send an outgoing payment
123-
electrum_wallet.call(
156+
Ok(())
157+
}
158+
159+
/// Test sending an outgoing payment
160+
#[cfg_attr(not(feature = "liquid"), test)]
161+
#[cfg_attr(feature = "liquid", allow(dead_code))]
162+
fn test_electrum_payment() -> Result<()> {
163+
let mut wt = WalletTester::new()?;
164+
165+
let addr1 = wt.newaddress();
166+
wt.tester.send(&addr1, "0.3 BTC".parse().unwrap())?;
167+
wt.tester.mine()?;
168+
wt.notify_wallet();
169+
wt.assert_balance(0.3, 0.0);
170+
171+
wt.electrum_wallet.call(
124172
"broadcast",
125-
&json!([electrum_wallet.call(
173+
&json!([wt.electrum_wallet.call(
126174
"payto",
127175
&json!({
128-
"destination": tester.node_client().get_new_address(None, None)?,
176+
"destination": wt.tester.node_client().get_new_address(None, None)?,
129177
"amount": 0.16,
130178
"fee": 0.001,
131179
}),
132180
)?]),
133181
)?;
134-
notify_wallet();
135-
assert_balance(0.139, 0.0);
182+
wt.notify_wallet();
183+
wt.assert_balance(0.139, 0.0);
136184

137-
tester.mine()?;
138-
notify_wallet();
139-
assert_balance(0.139, 0.0);
185+
wt.tester.mine()?;
186+
wt.notify_wallet();
187+
wt.assert_balance(0.139, 0.0);
140188

141189
Ok(())
142190
}
143191

144192
/// Test the Electrum RPC server using a raw TCP socket
145-
/// This only runs on Bitcoin (non-Liquid) mode.
146193
#[cfg_attr(not(feature = "liquid"), test)]
147194
#[cfg_attr(feature = "liquid", allow(dead_code))]
148-
#[ignore = "must be launched singularly, otherwise conflict with the other server"]
149195
fn test_electrum_raw() {
150-
// Spawn an Electrs Electrum RPC server
151196
let (_electrum_server, electrum_addr, mut _tester) = common::init_electrum_tester().unwrap();
152-
std::thread::sleep(std::time::Duration::from_millis(1000));
153197

154198
let mut stream = TcpStream::connect(electrum_addr).unwrap();
155199
let write = "{\"jsonrpc\": \"2.0\", \"method\": \"server.version\", \"id\": 0}";

0 commit comments

Comments
 (0)