From 537d05e01edfb5e1fe7e9168a1e11d15e41da40f Mon Sep 17 00:00:00 2001 From: rishflab <rishflab@hotmail.com> Date: Fri, 15 Jan 2021 11:26:32 +1100 Subject: [PATCH] Add reusable test function We introduce a reusable test function to make it easier to add new tests and make our existing tests more readable. --- swap/tests/happy_path.rs | 149 +++++++++--------------------------- swap/tests/testutils/mod.rs | 133 ++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 111 deletions(-) diff --git a/swap/tests/happy_path.rs b/swap/tests/happy_path.rs index c1e12e0e..200c1fbe 100644 --- a/swap/tests/happy_path.rs +++ b/swap/tests/happy_path.rs @@ -1,21 +1,9 @@ -use crate::testutils::{init_alice, init_bob}; -use futures::{ - future::{join, select}, - FutureExt, -}; -use get_port::get_port; -use libp2p::Multiaddr; use rand::rngs::OsRng; use swap::{ bitcoin, - config::Config, - monero, - protocol::{alice, bob}, - seed::Seed, + protocol::{alice, alice::AliceState, bob, bob::BobState}, }; -use testcontainers::clients::Cli; -use testutils::init_tracing; -use uuid::Uuid; +use tokio::join; pub mod testutils; @@ -23,108 +11,47 @@ pub mod testutils; #[tokio::test] async fn happy_path() { - let _guard = init_tracing(); + testutils::test(|alice, bob, swap_amounts| async move { + let alice_swap_fut = alice::swap( + alice.state, + alice.event_loop_handle, + alice.bitcoin_wallet.clone(), + alice.monero_wallet.clone(), + alice.config, + alice.swap_id, + alice.db, + ); + let bob_swap_fut = bob::swap( + bob.state, + bob.event_loop_handle, + bob.db, + bob.bitcoin_wallet.clone(), + bob.monero_wallet.clone(), + OsRng, + bob.swap_id, + ); + let (alice_state, bob_state) = join!(alice_swap_fut, bob_swap_fut); - let cli = Cli::default(); - let ( - monero, - testutils::Containers { - bitcoind, - monerods: _monerods, - }, - ) = testutils::init_containers(&cli).await; + let btc_alice_final = alice.bitcoin_wallet.as_ref().balance().await.unwrap(); + let btc_bob_final = bob.bitcoin_wallet.as_ref().balance().await.unwrap(); - let btc_to_swap = bitcoin::Amount::from_sat(1_000_000); - let btc_alice = bitcoin::Amount::ZERO; - let btc_bob = btc_to_swap * 10; + let xmr_alice_final = alice.monero_wallet.as_ref().get_balance().await.unwrap(); - // this xmr value matches the logic of alice::calculate_amounts i.e. btc * - // 10_000 * 100 - let xmr_to_swap = monero::Amount::from_piconero(1_000_000_000_000); - let xmr_alice = xmr_to_swap * 10; - let xmr_bob = monero::Amount::ZERO; + bob.monero_wallet.as_ref().inner.refresh().await.unwrap(); + let xmr_bob_final = bob.monero_wallet.as_ref().get_balance().await.unwrap(); - let port = get_port().expect("Failed to find a free port"); - let alice_multiaddr: Multiaddr = format!("/ip4/127.0.0.1/tcp/{}", port) - .parse() - .expect("failed to parse Alice's address"); + assert!(matches!(alice_state.unwrap(), AliceState::BtcRedeemed)); + assert!(matches!(bob_state.unwrap(), BobState::XmrRedeemed)); - let config = Config::regtest(); + assert_eq!( + btc_alice_final, + alice.btc_starting_balance + swap_amounts.btc + - bitcoin::Amount::from_sat(bitcoin::TX_FEE) + ); + assert!(btc_bob_final <= bob.btc_starting_balance - swap_amounts.btc); - let ( - alice_state, - mut alice_event_loop, - alice_event_loop_handle, - alice_btc_wallet, - alice_xmr_wallet, - alice_db, - ) = init_alice( - &bitcoind, - &monero, - btc_to_swap, - xmr_to_swap, - xmr_alice, - alice_multiaddr.clone(), - config, - Seed::random().unwrap(), - ) + assert!(xmr_alice_final <= alice.xmr_starting_balance - swap_amounts.xmr); + assert_eq!(xmr_bob_final, bob.xmr_starting_balance + swap_amounts.xmr); + }) .await; - - let (bob_state, bob_event_loop, bob_event_loop_handle, bob_btc_wallet, bob_xmr_wallet, bob_db) = - init_bob( - alice_multiaddr.clone(), - alice_event_loop.peer_id(), - &bitcoind, - &monero, - btc_to_swap, - btc_bob, - xmr_to_swap, - config, - ) - .await; - - let alice_swap_fut = alice::swap::swap( - alice_state, - alice_event_loop_handle, - alice_btc_wallet.clone(), - alice_xmr_wallet.clone(), - config, - Uuid::new_v4(), - alice_db, - ) - .boxed(); - - let alice_fut = select(alice_swap_fut, alice_event_loop.run().boxed()); - - let bob_swap_fut = bob::swap::swap( - bob_state, - bob_event_loop_handle, - bob_db, - bob_btc_wallet.clone(), - bob_xmr_wallet.clone(), - OsRng, - Uuid::new_v4(), - ) - .boxed(); - - let bob_fut = select(bob_swap_fut, bob_event_loop.run().boxed()); - - join(alice_fut, bob_fut).await; - - let btc_alice_final = alice_btc_wallet.as_ref().balance().await.unwrap(); - let btc_bob_final = bob_btc_wallet.as_ref().balance().await.unwrap(); - - let xmr_alice_final = alice_xmr_wallet.as_ref().get_balance().await.unwrap(); - - bob_xmr_wallet.as_ref().inner.refresh().await.unwrap(); - let xmr_bob_final = bob_xmr_wallet.as_ref().get_balance().await.unwrap(); - - assert_eq!( - btc_alice_final, - btc_alice + btc_to_swap - bitcoin::Amount::from_sat(bitcoin::TX_FEE) - ); - assert!(btc_bob_final <= btc_bob - btc_to_swap); - - assert!(xmr_alice_final <= xmr_alice - xmr_to_swap); - assert_eq!(xmr_bob_final, xmr_bob + xmr_to_swap); } diff --git a/swap/tests/testutils/mod.rs b/swap/tests/testutils/mod.rs index 4b1bad00..9fb9b20b 100644 --- a/swap/tests/testutils/mod.rs +++ b/swap/tests/testutils/mod.rs @@ -1,4 +1,7 @@ +use crate::testutils; use bitcoin_harness::Bitcoind; +use futures::Future; +use get_port::get_port; use libp2p::{core::Multiaddr, PeerId}; use monero_harness::{image, Monero}; use rand::rngs::OsRng; @@ -17,6 +20,136 @@ use tempfile::tempdir; use testcontainers::{clients::Cli, Container}; use tracing_core::dispatcher::DefaultGuard; use tracing_log::LogTracer; +use uuid::Uuid; + +pub struct Alice { + pub state: AliceState, + pub event_loop_handle: alice::EventLoopHandle, + pub bitcoin_wallet: Arc<bitcoin::Wallet>, + pub monero_wallet: Arc<monero::Wallet>, + pub config: Config, + pub swap_id: Uuid, + pub db: Database, + pub xmr_starting_balance: monero::Amount, + pub btc_starting_balance: bitcoin::Amount, +} + +pub struct Bob { + pub state: BobState, + pub event_loop_handle: bob::EventLoopHandle, + pub db: Database, + pub bitcoin_wallet: Arc<bitcoin::Wallet>, + pub monero_wallet: Arc<monero::Wallet>, + pub swap_id: Uuid, + pub btc_starting_balance: bitcoin::Amount, + pub xmr_starting_balance: monero::Amount, +} + +pub async fn test<T, F>(testfn: T) +where + T: Fn(Alice, Bob, SwapAmounts) -> F, + F: Future<Output = ()>, +{ + let cli = Cli::default(); + + let _guard = init_tracing(); + + let (monero, containers) = testutils::init_containers(&cli).await; + + let swap_amounts = SwapAmounts { + btc: bitcoin::Amount::from_sat(1_000_000), + xmr: monero::Amount::from_piconero(1_000_000_000_000), + }; + + let bob_btc_starting_balance = swap_amounts.btc * 10; + let alice_xmr_starting_balance = swap_amounts.xmr * 10; + + let port = get_port().expect("Failed to find a free port"); + + let alice_multiaddr: Multiaddr = format!("/ip4/127.0.0.1/tcp/{}", port) + .parse() + .expect("failed to parse Alice's address"); + + let config = Config::regtest(); + + let alice_seed = Seed::random().unwrap(); + + let (alice_btc_wallet, alice_xmr_wallet) = init_wallets( + "alice", + &containers.bitcoind, + &monero, + None, + Some(alice_xmr_starting_balance), + config, + ) + .await; + + let alice_state = init_alice_state( + swap_amounts.btc, + swap_amounts.xmr, + alice_btc_wallet.clone(), + config, + ) + .await; + + let (mut alice_event_loop, alice_event_loop_handle) = + init_alice_event_loop(alice_multiaddr.clone(), alice_seed); + + let alice_db_datadir = tempdir().unwrap(); + let alice_db = Database::open(alice_db_datadir.path()).unwrap(); + + let (bob_btc_wallet, bob_xmr_wallet) = init_wallets( + "bob", + &containers.bitcoind, + &monero, + Some(bob_btc_starting_balance), + None, + config, + ) + .await; + + let bob_state = init_bob_state( + swap_amounts.btc, + swap_amounts.xmr, + bob_btc_wallet.clone(), + config, + ) + .await; + + let (bob_event_loop, bob_event_loop_handle) = + init_bob_event_loop(alice_event_loop.peer_id(), alice_multiaddr); + + let bob_db_dir = tempdir().unwrap(); + let bob_db = Database::open(bob_db_dir.path()).unwrap(); + + tokio::spawn(async move { alice_event_loop.run().await }); + tokio::spawn(async move { bob_event_loop.run().await }); + + let alice = Alice { + state: alice_state, + event_loop_handle: alice_event_loop_handle, + bitcoin_wallet: alice_btc_wallet, + monero_wallet: alice_xmr_wallet, + config, + swap_id: Uuid::new_v4(), + db: alice_db, + xmr_starting_balance: alice_xmr_starting_balance, + btc_starting_balance: bitcoin::Amount::ZERO, + }; + + let bob = Bob { + state: bob_state, + event_loop_handle: bob_event_loop_handle, + db: bob_db, + bitcoin_wallet: bob_btc_wallet, + monero_wallet: bob_xmr_wallet, + swap_id: Uuid::new_v4(), + xmr_starting_balance: monero::Amount::ZERO, + btc_starting_balance: bob_btc_starting_balance, + }; + + testfn(alice, bob, swap_amounts).await +} pub async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) { let bitcoind = Bitcoind::new(&cli, "0.19.1").unwrap();