Skip to content

Commit de6c5f1

Browse files
gakonstemschwartz
authored andcommitted
test(three-nodes): check balances to ensure three nodes is not flaky
1 parent 6a2c7ac commit de6c5f1

File tree

1 file changed

+136
-67
lines changed

1 file changed

+136
-67
lines changed

crates/interledger/tests/three_nodes.rs

Lines changed: 136 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![recursion_limit = "128"]
22

33
use env_logger;
4-
use futures::{future::join_all, Future, Stream};
4+
use futures::{Future, Stream};
55
use interledger::{
66
cli,
77
node::{AccountDetails, InterledgerNode},
@@ -116,9 +116,10 @@ fn three_nodes() {
116116
secret_seed: cli::random_secret(),
117117
route_broadcast_interval: Some(200),
118118
};
119+
let node2_clone = node2.clone();
119120
runtime.spawn(
120-
join_all(vec![
121-
node2.insert_account(AccountDetails {
121+
node2_clone
122+
.insert_account(AccountDetails {
122123
ilp_address: Address::from_str("example.one").unwrap(),
123124
asset_code: "XYZ".to_string(),
124125
asset_scale: 9,
@@ -138,44 +139,45 @@ fn three_nodes() {
138139
packets_per_minute_limit: None,
139140
amount_per_minute_limit: None,
140141
settlement_engine_url: None,
141-
}),
142-
node2.insert_account(AccountDetails {
143-
ilp_address: Address::from_str("example.two.three").unwrap(),
144-
asset_code: "ABC".to_string(),
145-
asset_scale: 6,
146-
btp_incoming_token: Some("three".to_string()),
147-
btp_uri: None,
148-
http_endpoint: None,
149-
http_incoming_token: None,
150-
http_outgoing_token: None,
151-
max_packet_amount: u64::max_value(),
152-
min_balance: Some(-1_000_000_000),
153-
settle_threshold: None,
154-
settle_to: None,
155-
send_routes: true,
156-
receive_routes: false,
157-
routing_relation: Some("Child".to_string()),
158-
round_trip_time: None,
159-
packets_per_minute_limit: None,
160-
amount_per_minute_limit: None,
161-
settlement_engine_url: None,
162-
}),
163-
])
164-
.and_then(move |_| node2.serve())
165-
.and_then(move |_| {
166-
let client = reqwest::r#async::Client::new();
167-
client
168-
.put(&format!("http://localhost:{}/rates", node2_http))
169-
.header("Authorization", "Bearer admin")
170-
.json(&json!({"ABC": 2, "XYZ": 1}))
171-
.send()
172-
.map_err(|err| panic!(err))
173-
.and_then(|res| {
174-
res.error_for_status()
175-
.expect("Error setting exchange rates");
176-
Ok(())
142+
})
143+
.and_then(move |_| {
144+
node2_clone.insert_account(AccountDetails {
145+
ilp_address: Address::from_str("example.two.three").unwrap(),
146+
asset_code: "ABC".to_string(),
147+
asset_scale: 6,
148+
btp_incoming_token: Some("three".to_string()),
149+
btp_uri: None,
150+
http_endpoint: None,
151+
http_incoming_token: Some("three".to_string()),
152+
http_outgoing_token: None,
153+
max_packet_amount: u64::max_value(),
154+
min_balance: Some(-1_000_000_000),
155+
settle_threshold: None,
156+
settle_to: None,
157+
send_routes: true,
158+
receive_routes: false,
159+
routing_relation: Some("Child".to_string()),
160+
round_trip_time: None,
161+
packets_per_minute_limit: None,
162+
amount_per_minute_limit: None,
163+
settlement_engine_url: None,
177164
})
178-
}),
165+
})
166+
.and_then(move |_| node2.serve())
167+
.and_then(move |_| {
168+
let client = reqwest::r#async::Client::new();
169+
client
170+
.put(&format!("http://localhost:{}/rates", node2_http))
171+
.header("Authorization", "Bearer admin")
172+
.json(&json!({"ABC": 2, "XYZ": 1}))
173+
.send()
174+
.map_err(|err| panic!(err))
175+
.and_then(|res| {
176+
res.error_for_status()
177+
.expect("Error setting exchange rates");
178+
Ok(())
179+
})
180+
}),
179181
);
180182

181183
let node3 = InterledgerNode {
@@ -193,8 +195,8 @@ fn three_nodes() {
193195
runtime.spawn(
194196
// Wait a bit to make sure the other node's BTP server is listening
195197
delay(50).map_err(|err| panic!(err)).and_then(move |_| {
196-
join_all(vec![
197-
node3_clone.insert_account(AccountDetails {
198+
node3_clone
199+
.insert_account(AccountDetails {
198200
ilp_address: Address::from_str("example.two.three").unwrap(),
199201
asset_code: "ABC".to_string(),
200202
asset_scale: 6,
@@ -214,30 +216,31 @@ fn three_nodes() {
214216
packets_per_minute_limit: None,
215217
amount_per_minute_limit: None,
216218
settlement_engine_url: None,
217-
}),
218-
node3_clone.insert_account(AccountDetails {
219-
ilp_address: Address::from_str("example.two").unwrap(),
220-
asset_code: "ABC".to_string(),
221-
asset_scale: 6,
222-
btp_incoming_token: None,
223-
btp_uri: Some(format!("btp+ws://:three@localhost:{}", node2_btp)),
224-
http_endpoint: None,
225-
http_incoming_token: None,
226-
http_outgoing_token: None,
227-
max_packet_amount: u64::max_value(),
228-
min_balance: Some(-1_000_000_000),
229-
settle_threshold: None,
230-
settle_to: None,
231-
send_routes: false,
232-
receive_routes: true,
233-
routing_relation: Some("Parent".to_string()),
234-
round_trip_time: None,
235-
packets_per_minute_limit: None,
236-
amount_per_minute_limit: None,
237-
settlement_engine_url: None,
238-
}),
239-
])
240-
.and_then(move |_| node3.serve())
219+
})
220+
.and_then(move |_| {
221+
node3_clone.insert_account(AccountDetails {
222+
ilp_address: Address::from_str("example.two").unwrap(),
223+
asset_code: "ABC".to_string(),
224+
asset_scale: 6,
225+
btp_incoming_token: None,
226+
btp_uri: Some(format!("btp+ws://:three@localhost:{}", node2_btp)),
227+
http_endpoint: None,
228+
http_incoming_token: None,
229+
http_outgoing_token: None,
230+
max_packet_amount: u64::max_value(),
231+
min_balance: Some(-1_000_000_000),
232+
settle_threshold: None,
233+
settle_to: None,
234+
send_routes: false,
235+
receive_routes: true,
236+
routing_relation: Some("Parent".to_string()),
237+
round_trip_time: None,
238+
packets_per_minute_limit: None,
239+
amount_per_minute_limit: None,
240+
settlement_engine_url: None,
241+
})
242+
})
243+
.and_then(move |_| node3.serve())
241244
}),
242245
);
243246

@@ -278,16 +281,82 @@ fn three_nodes() {
278281
Ok(())
279282
});
280283

284+
let get_balance = |account_id, node_port, admin_token| {
285+
let client = reqwest::r#async::Client::new();
286+
client
287+
.get(&format!(
288+
"http://localhost:{}/accounts/{}/balance",
289+
node_port, account_id
290+
))
291+
.header("Authorization", format!("Bearer {}", admin_token))
292+
.send()
293+
.map_err(|err| {
294+
eprintln!("Error getting account data: {:?}", err);
295+
err
296+
})
297+
.and_then(|res| res.error_for_status())
298+
.and_then(|res| res.into_body().concat2())
299+
};
300+
301+
// Node 1 sends 1000 to Node 3. However, Node1's scale is 9,
302+
// while Node 3's scale is 6. This means that Node 3 will
303+
// see 1000x less. In addition, the conversion rate is 2:1
304+
// for 3's asset, so he will receive 2 total.
281305
send_1_to_3
282306
.map_err(|err| {
283307
eprintln!("Error sending from node 1 to node 3: {:?}", err);
284308
err
285309
})
286-
.and_then(|_| send_3_to_1
310+
.and_then(move |_| {
311+
get_balance(0, node1_http, "default account holder")
312+
.and_then(move |ret| {
313+
let ret = str::from_utf8(&ret).unwrap();
314+
assert_eq!(ret, "{\"balance\":\"-1000\"}");
315+
Ok(())
316+
}).and_then(move |_| {
317+
// Node 2 updates Node 3's balance properly.
318+
get_balance(1, node2_http, "three").and_then(move |ret| {
319+
let ret = str::from_utf8(&ret).unwrap();
320+
assert_eq!(ret, "{\"balance\":\"2\"}");
321+
Ok(())
322+
})
323+
}).and_then(move |_| {
324+
// Node 3's balance is properly adjusted after
325+
// it's received the message from node 2
326+
get_balance(0, node3_http, "default account holder").and_then(move |ret| {
327+
let ret = str::from_utf8(&ret).unwrap();
328+
assert_eq!(ret, "{\"balance\":\"2\"}");
329+
Ok(())
330+
})
331+
})
332+
})
333+
.and_then(move |_| send_3_to_1
287334
.map_err(|err| {
288335
eprintln!("Error sending from node 3 to node 1: {:?}", err);
289336
err
290337
}))
338+
.and_then(move |_| {
339+
get_balance(0, node1_http, "default account holder").and_then(move |ret| {
340+
let ret = str::from_utf8(&ret).unwrap();
341+
assert_eq!(ret, "{\"balance\":\"499000\"}");
342+
Ok(())
343+
}).and_then(move |_| {
344+
// Node 2 updates Node 3's balance properly.
345+
get_balance(1, node2_http, "three").and_then(move |ret| {
346+
let ret = str::from_utf8(&ret).unwrap();
347+
assert_eq!(ret, "{\"balance\":\"-998\"}");
348+
Ok(())
349+
})
350+
}).and_then(move |_| {
351+
// Node 3's balance is properly adjusted after
352+
// it's received the message from node 2
353+
get_balance(0, node3_http, "default account holder").and_then(move |ret| {
354+
let ret = str::from_utf8(&ret).unwrap();
355+
assert_eq!(ret, "{\"balance\":\"-998\"}");
356+
Ok(())
357+
})
358+
})
359+
})
291360
}),
292361
)
293362
.unwrap();

0 commit comments

Comments
 (0)