Skip to content

Commit 4e301c5

Browse files
committed
test(e2e): three-nodes and exchange rates tests pass
1 parent d316689 commit 4e301c5

File tree

13 files changed

+136
-166
lines changed

13 files changed

+136
-166
lines changed

crates/ilp-node/src/node.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ impl InterledgerNode {
249249
// Err(())
250250
// }
251251
// } else {
252-
self.serve_node().await
252+
self.serve_node().await
253253
// }
254254
}
255255

@@ -394,7 +394,7 @@ impl InterledgerNode {
394394
let incoming_service = Router::new(
395395
store.clone(),
396396
// Add tracing to add the outgoing request details to the incoming span
397-
outgoing_service.clone() // .wrap(trace_forwarding),
397+
outgoing_service.clone(), // .wrap(trace_forwarding),
398398
);
399399

400400
// Add tracing to track the outgoing request details
@@ -491,10 +491,10 @@ impl InterledgerNode {
491491
store.clone(),
492492
)
493493
.as_filter())
494-
.or(btp_service_as_filter(
495-
btp_server_service_clone,
496-
store.clone(),
497-
))
494+
// .or(btp_service_as_filter(
495+
// btp_server_service_clone,
496+
// store.clone(),
497+
// ))
498498
.recover(default_rejection_handler)
499499
.with(warp::log("interledger-api"))
500500
.boxed();
@@ -514,9 +514,9 @@ impl InterledgerNode {
514514
exchange_rate_poll_failure_tolerance,
515515
store.clone(),
516516
);
517-
// This function does not compile on 1.39 for some reason.
518-
// exchange_rate_fetcher
519-
// .spawn_interval(Duration::from_millis(exchange_rate_poll_interval));
517+
// This function does not compile on 1.39 for some reason.
518+
exchange_rate_fetcher
519+
.spawn_interval(Duration::from_millis(exchange_rate_poll_interval));
520520
} else {
521521
debug!(target: "interledger-node", "Not using exchange rate provider. Rates must be set via the HTTP API");
522522
}

crates/ilp-node/tests/redis/exchange_rates.rs

+41-90
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,20 @@ use crate::redis_helpers::*;
22
use crate::test_helpers::*;
33
use futures::Future;
44
use ilp_node::InterledgerNode;
5-
use reqwest::r#async::Client;
5+
use reqwest::Client;
66
use secrecy::SecretString;
77
use serde_json::{self, json, Value};
88
use std::env;
9+
use std::time::Duration;
910
use tokio::runtime::Builder as RuntimeBuilder;
1011
use tokio_retry::{strategy::FibonacciBackoff, Retry};
1112
use tracing::error;
1213
use tracing_subscriber;
1314

14-
#[test]
15-
fn coincap() {
16-
install_tracing_subscriber();
15+
#[tokio::test]
16+
async fn coincap() {
1717
let context = TestContext::new();
1818

19-
let mut runtime = RuntimeBuilder::new()
20-
.panic_handler(|err| std::panic::resume_unwind(err))
21-
.build()
22-
.unwrap();
23-
2419
let http_port = get_open_port(None);
2520

2621
let node: InterledgerNode = serde_json::from_value(json!({
@@ -33,56 +28,38 @@ fn coincap() {
3328
"secret_seed": random_secret(),
3429
"route_broadcast_interval": 200,
3530
"exchange_rate": {
36-
"poll_interval": 60000,
31+
"poll_interval": 100,
3732
"provider": "coincap",
3833
},
3934
}))
4035
.unwrap();
41-
runtime.spawn(node.serve());
36+
node.serve().await.unwrap();
4237

43-
let get_rates = move || {
44-
Client::new()
45-
.get(&format!("http://localhost:{}/rates", http_port))
46-
.send()
47-
.map_err(|_| panic!("Error getting rates"))
48-
.and_then(|mut res| res.json().map_err(|_| panic!("Error getting body")))
49-
.and_then(|body: Value| {
50-
if let Value::Object(obj) = body {
51-
if obj.is_empty() {
52-
error!("Rates are empty");
53-
return Err(());
54-
}
55-
assert_eq!(
56-
format!("{}", obj.get("USD").expect("Should have USD rate")).as_str(),
57-
"1.0"
58-
);
59-
assert!(obj.contains_key("EUR"));
60-
assert!(obj.contains_key("JPY"));
61-
assert!(obj.contains_key("BTC"));
62-
assert!(obj.contains_key("ETH"));
63-
assert!(obj.contains_key("XRP"));
64-
} else {
65-
panic!("Not an object");
66-
}
38+
// Wait a few seconds so our node can poll the API
39+
tokio::time::delay_for(Duration::from_millis(1000)).await;
6740

68-
Ok(())
69-
})
70-
};
71-
72-
runtime
73-
.block_on(
74-
delay(1000)
75-
.map_err(|_| panic!("Something strange happened"))
76-
.and_then(move |_| {
77-
Retry::spawn(FibonacciBackoff::from_millis(1000).take(5), get_rates)
78-
}),
79-
)
41+
let ret = Client::new()
42+
.get(&format!("http://localhost:{}/rates", http_port))
43+
.send()
44+
.await
8045
.unwrap();
46+
let txt = ret.text().await.unwrap();
47+
let obj: Value = serde_json::from_str(&txt).unwrap();
48+
49+
assert_eq!(
50+
format!("{}", obj.get("USD").expect("Should have USD rate")).as_str(),
51+
"1.0"
52+
);
53+
assert!(obj.get("EUR").is_some());
54+
assert!(obj.get("JPY").is_some());
55+
assert!(obj.get("BTC").is_some());
56+
assert!(obj.get("ETH").is_some());
57+
assert!(obj.get("XRP").is_some());
8158
}
8259

8360
// TODO can we disable this with conditional compilation?
84-
#[test]
85-
fn cryptocompare() {
61+
#[tokio::test]
62+
async fn cryptocompare() {
8663
tracing_subscriber::fmt::try_init().unwrap_or(());
8764
let context = TestContext::new();
8865

@@ -93,11 +70,6 @@ fn cryptocompare() {
9370
}
9471
let api_key = SecretString::new(api_key.unwrap());
9572

96-
let mut runtime = RuntimeBuilder::new()
97-
.panic_handler(|err| std::panic::resume_unwind(err))
98-
.build()
99-
.unwrap();
100-
10173
let http_port = get_open_port(Some(3011));
10274

10375
let node: InterledgerNode = serde_json::from_value(json!({
@@ -118,42 +90,21 @@ fn cryptocompare() {
11890
},
11991
}))
12092
.unwrap();
121-
runtime.spawn(node.serve());
122-
123-
let get_rates = move || {
124-
Client::new()
125-
.get(&format!("http://localhost:{}/rates", http_port))
126-
.send()
127-
.map_err(|_| panic!("Error getting rates"))
128-
.and_then(|mut res| res.json().map_err(|_| panic!("Error getting body")))
129-
.and_then(|body: Value| {
130-
if let Value::Object(obj) = body {
131-
if obj.is_empty() {
132-
error!("Rates are empty");
133-
return Err(());
134-
}
135-
assert_eq!(
136-
format!("{}", obj.get("USD").expect("Should have USD rate")).as_str(),
137-
"1.0"
138-
);
139-
assert!(obj.contains_key("BTC"));
140-
assert!(obj.contains_key("ETH"));
141-
assert!(obj.contains_key("XRP"));
142-
} else {
143-
panic!("Not an object");
144-
}
93+
node.serve().await.unwrap();
14594

146-
Ok(())
147-
})
148-
};
149-
150-
runtime
151-
.block_on(
152-
delay(1000)
153-
.map_err(|_| panic!("Something strange happened"))
154-
.and_then(move |_| {
155-
Retry::spawn(FibonacciBackoff::from_millis(1000).take(5), get_rates)
156-
}),
157-
)
95+
let ret = Client::new()
96+
.get(&format!("http://localhost:{}/rates", http_port))
97+
.send()
98+
.await
15899
.unwrap();
100+
let txt = ret.text().await.unwrap();
101+
let obj: Value = serde_json::from_str(&txt).unwrap();
102+
103+
assert_eq!(
104+
format!("{}", obj.get("USD").expect("Should have USD rate")).as_str(),
105+
"1.0"
106+
);
107+
assert!(obj.get("BTC").is_some());
108+
assert!(obj.get("ETH").is_some());
109+
assert!(obj.get("XRP").is_some());
159110
}

crates/ilp-node/tests/redis/redis_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#![type_length_limit="3000000"]
1+
#![type_length_limit = "3000000"]
22
// mod btp;
3-
// mod exchange_rates;
3+
mod exchange_rates;
44
// mod prometheus;
55
mod three_nodes;
66

crates/ilp-node/tests/redis/test_helpers.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub async fn create_account_on_node<T: Serialize>(
3737
api_port: u16,
3838
data: T,
3939
auth: &str,
40-
) -> Result<String, ()> {
40+
) -> Result<Account, ()> {
4141
let client = reqwest::Client::new();
4242
let res = client
4343
.post(&format!("http://localhost:{}/accounts", api_port))
@@ -50,9 +50,7 @@ pub async fn create_account_on_node<T: Serialize>(
5050

5151
let res = res.error_for_status().map_err(|_| ())?;
5252

53-
let data: bytes05::Bytes = res.bytes().map_err(|_| ()).await?;
54-
55-
Ok(str::from_utf8(&data).unwrap().to_string())
53+
Ok(res.json::<Account>().map_err(|_| ()).await.unwrap())
5654
}
5755

5856
#[allow(unused)]
@@ -101,7 +99,6 @@ pub async fn send_money_to_username<T: Display + Debug>(
10199
.await?;
102100

103101
let res = res.error_for_status().map_err(|_| ())?;
104-
// does this work?
105102
Ok(res.json::<StreamDelivery>().await.unwrap())
106103
}
107104

crates/ilp-node/tests/redis/three_nodes.rs

+36-13
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ async fn three_nodes() {
6565
"username": "charlie_on_b",
6666
"asset_code": "ABC",
6767
"asset_scale": 6,
68-
"ilp_over_btp_incoming_token" : "three",
68+
// "ilp_over_btp_incoming_token" : "three",
69+
// TODO: remove these and replace with BTP once it's solved
70+
"ilp_over_http_outgoing_token": "two",
71+
"ilp_over_http_incoming_token": "three",
72+
"ilp_over_http_url": format!("http://localhost:{}/accounts/{}/ilp", node3_http, "bob_on_c"),
6973
"min_balance": -1_000_000_000,
7074
"routing_relation": "Child",
7175
});
@@ -81,13 +85,15 @@ async fn three_nodes() {
8185
"username": "bob_on_c",
8286
"asset_code": "ABC",
8387
"asset_scale": 6,
84-
"ilp_over_http_incoming_token" : "two",
8588
"ilp_over_http_outgoing_token": "three",
86-
"ilp_over_btp_url": format!("btp+ws://localhost:{}/accounts/{}/ilp/btp", node2_http, "charlie_on_b"),
87-
"ilp_over_btp_outgoing_token": "three",
89+
"ilp_over_http_incoming_token" : "two",
90+
"ilp_over_http_url": format!("http://localhost:{}/accounts/{}/ilp", node2_http, "charlie_on_b"),
8891
"min_balance": -1_000_000_000,
8992
"routing_relation": "Parent",
9093
});
94+
// json! does not take comments into account!
95+
// "ilp_over_btp_url": format!("btp+ws://localhost:{}/accounts/{}/ilp/btp", node2_http, "charlie_on_b"),
96+
// "ilp_over_btp_outgoing_token": "three",
9197

9298
let node1: InterledgerNode = serde_json::from_value(json!({
9399
"ilp_address": "example.alice",
@@ -133,24 +139,37 @@ async fn three_nodes() {
133139
.expect("Error creating node3.");
134140

135141
node1.serve().await.unwrap(); // .instrument(error_span!(target: "interledger", "node1")).await.unwrap();
136-
create_account_on_node(node1_http, alice_on_alice, "admin").await.unwrap();
137-
create_account_on_node(node1_http, bob_on_alice, "admin").await.unwrap();
142+
create_account_on_node(node1_http, alice_on_alice, "admin")
143+
.await
144+
.unwrap();
145+
create_account_on_node(node1_http, bob_on_alice, "admin")
146+
.await
147+
.unwrap();
138148

139149
node2.serve().await.unwrap(); // .instrument(error_span!(target: "interledger", "node2")).await.unwrap();
140-
create_account_on_node(node2_http, alice_on_bob, "admin").await.unwrap();
141-
create_account_on_node(node2_http, charlie_on_bob, "admin").await.unwrap();
150+
create_account_on_node(node2_http, alice_on_bob, "admin")
151+
.await
152+
.unwrap();
153+
create_account_on_node(node2_http, charlie_on_bob, "admin")
154+
.await
155+
.unwrap();
142156
// Also set exchange rates
143157
let client = reqwest::Client::new();
144158
client
145159
.put(&format!("http://localhost:{}/rates", node2_http))
146160
.header("Authorization", "Bearer admin")
147161
.json(&json!({"ABC": 1, "XYZ": 2}))
148162
.send()
149-
.await.unwrap();
163+
.await
164+
.unwrap();
150165

151166
node3.serve().await.unwrap(); // .instrument(error_span!(target: "interledger", "node3")).await.unwrap();
152-
create_account_on_node(node3_http, charlie_on_charlie, "admin").await.unwrap();
153-
create_account_on_node(node3_http, bob_on_charlie, "admin").await.unwrap();
167+
let acc = create_account_on_node(node3_http, charlie_on_charlie, "admin")
168+
.await
169+
.unwrap();
170+
create_account_on_node(node3_http, bob_on_charlie, "admin")
171+
.await
172+
.unwrap();
154173

155174
delay(1000).await;
156175

@@ -173,7 +192,9 @@ async fn three_nodes() {
173192
"charlie_on_c",
174193
"alice_on_a",
175194
"default account holder",
176-
).await.unwrap();
195+
)
196+
.await
197+
.unwrap();
177198

178199
assert_eq!(
179200
receipt.from,
@@ -225,7 +246,9 @@ async fn three_nodes() {
225246
"alice_on_a",
226247
"charlie_on_c",
227248
"default account holder",
228-
).await.unwrap();
249+
)
250+
.await
251+
.unwrap();
229252

230253
assert_eq!(
231254
receipt.from,

crates/interledger-api/src/routes/accounts.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ where
7373
let admin_auth_header = admin_auth_header_clone.clone();
7474
async move {
7575
if authorization.expose_secret() == &admin_auth_header {
76-
println!("autorized!");
7776
Ok::<(), Rejection>(())
7877
} else {
79-
println!("unautorized!");
8078
Err(Rejection::from(ApiError::unauthorized()))
8179
}
8280
}
@@ -398,6 +396,7 @@ where
398396
// GET /accounts/:username/spsp
399397
let server_secret_clone = server_secret.clone();
400398
let get_spsp = warp::get()
399+
.and(warp::path("accounts"))
401400
.and(account_username_to_id)
402401
.and(warp::path("spsp"))
403402
.and(warp::path::end())
@@ -676,6 +675,7 @@ pub fn deserialize_json<T: DeserializeOwned + Send>(
676675
#[cfg(test)]
677676
mod tests {
678677
use crate::routes::test_helpers::*;
678+
// TODO: Add test for GET /accounts/:username/spsp and /.well_known
679679

680680
#[tokio::test]
681681
async fn only_admin_can_create_account() {

crates/interledger-api/src/routes/node_settings.rs

-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ where
197197
.and(with_store.clone())
198198
.and_then(|prefix: String, body: bytes05::Bytes, store: S| {
199199
async move {
200-
println!("TRYING TO PARSE USERNAEME");
201200
let username_str =
202201
str::from_utf8(&body).map_err(|_| Rejection::from(ApiError::bad_request()))?;
203202
let username = Username::from_str(username_str)

0 commit comments

Comments
 (0)