Browse Source

Merge #458

458: Roll-out usage of a mocking framework in actor tests r=klochowicz a=klochowicz

Mockall is a mocking framework that removes the need for writing more actors,
making tests easier to write.

Summary:
- add one more layer of indirection (a trait per actor type: Wallet, Oracle, Monitor)
- Mocks implementing the actor traits (with default stubbed implementations if no extra
  behaviour needed)
- references to the mocks are being passed into the tests (via Arc<Mutex>>), allowing
  for dynamically changing the behaviour and adding assertions. This also
    aids readability, as the mock setup can be collocated with a particular
    test, if the test needs something extra

Co-authored-by: Mariusz Klochowicz <mariusz@klochowicz.com>
burn-down-handle
bors[bot] 3 years ago
committed by GitHub
parent
commit
9ea131cd4e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 97
      Cargo.lock
  2. 2
      daemon/Cargo.toml
  3. 99
      daemon/tests/happy_path.rs
  4. 54
      daemon/tests/harness/mocks/mod.rs
  5. 52
      daemon/tests/harness/mocks/monitor.rs
  6. 68
      daemon/tests/harness/mocks/oracle.rs
  7. 124
      daemon/tests/harness/mocks/wallet.rs
  8. 69
      daemon/tests/harness/mod.rs

97
Cargo.lock

@ -528,6 +528,8 @@ dependencies = [
"hex",
"hkdf",
"itertools",
"mockall",
"mockall_derive",
"nalgebra",
"ndarray",
"ndarray_einsum_beta",
@ -634,6 +636,12 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
version = "0.9.0"
@ -655,6 +663,12 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "downcast"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
[[package]]
name = "either"
version = "1.6.1"
@ -741,6 +755,15 @@ dependencies = [
"version_check",
]
[[package]]
name = "float-cmp"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
dependencies = [
"num-traits",
]
[[package]]
name = "flume"
version = "0.10.9"
@ -769,6 +792,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fragile"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -1365,6 +1394,33 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "mockall"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ab571328afa78ae322493cacca3efac6a0f2e0a67305b4df31fd439ef129ac0"
dependencies = [
"cfg-if 1.0.0",
"downcast",
"fragile",
"lazy_static",
"mockall_derive",
"predicates",
"predicates-tree",
]
[[package]]
name = "mockall_derive"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e25b214433f669161f414959594216d8e6ba83b6679d3db96899c0b4639033"
dependencies = [
"cfg-if 1.0.0",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "multer"
version = "2.0.1"
@ -1437,6 +1493,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "ntapi"
version = "0.3.6"
@ -1675,6 +1737,35 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "predicates"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df"
dependencies = [
"difference",
"float-cmp",
"normalize-line-endings",
"predicates-core",
"regex",
]
[[package]]
name = "predicates-core"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
[[package]]
name = "predicates-tree"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7"
dependencies = [
"predicates-core",
"termtree",
]
[[package]]
name = "pretty_assertions"
version = "1.0.0"
@ -2838,6 +2929,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "termtree"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16"
[[package]]
name = "textwrap"
version = "0.14.2"

2
daemon/Cargo.toml

@ -53,6 +53,8 @@ name = "maker"
path = "src/maker.rs"
[dev-dependencies]
mockall = "0.10.2"
mockall_derive = "0.10.2"
pretty_assertions = "1"
serde_test = "1"
time = { version = "0.3", features = ["std"] }

99
daemon/tests/happy_path.rs

@ -1,6 +1,6 @@
use crate::harness::mocks::monitor::Monitor;
use crate::harness::mocks::oracle::Oracle;
use crate::harness::mocks::wallet::Wallet;
use crate::harness::bdk::dummy_partially_signed_transaction;
use crate::harness::mocks::oracle::dummy_announcement;
use crate::harness::mocks::wallet::build_party_params;
use crate::harness::start_both;
use anyhow::Context;
use cfd_protocol::secp256k1_zkp::schnorrsig;
@ -8,9 +8,10 @@ use daemon::maker_cfd;
use daemon::model::cfd::{Cfd, CfdState, Order, Origin};
use daemon::model::{Price, Usd};
use daemon::tokio_ext::FutureExt;
use harness::bdk::dummy_tx_id;
use rust_decimal_macros::dec;
use std::time::Duration;
use tokio::sync::watch;
use tokio::sync::{watch, MutexGuard};
use tracing::subscriber::DefaultGuard;
use tracing_subscriber::filter::LevelFilter;
use tracing_subscriber::util::SubscriberInitExt;
@ -20,15 +21,7 @@ mod harness;
#[tokio::test]
async fn taker_receives_order_from_maker_on_publication() {
let _guard = init_tracing();
let (mut maker, mut taker) = start_both(
Oracle::default(),
Monitor,
Wallet::default(),
Oracle::default(),
Monitor,
Wallet::default(),
)
.await;
let (mut maker, mut taker) = start_both().await;
assert!(is_next_none(&mut taker.order_feed).await);
@ -45,15 +38,7 @@ async fn taker_receives_order_from_maker_on_publication() {
#[tokio::test]
async fn taker_takes_order_and_maker_rejects() {
let _guard = init_tracing();
let (mut maker, mut taker) = start_both(
Oracle::default(),
Monitor,
Wallet::default().with_wallet_info(),
Oracle::default(),
Monitor,
Wallet::default().with_wallet_info(),
)
.await;
let (mut maker, mut taker) = start_both().await;
// TODO: Why is this needed? For the cfd stream it is not needed
is_next_none(&mut taker.order_feed).await;
@ -86,28 +71,25 @@ async fn taker_takes_order_and_maker_rejects() {
assert!(matches!(maker_cfd.state, CfdState::Rejected { .. }));
}
// Helper function setting up a "happy path" wallet mock
fn mock_wallet_sign_and_broadcast(wallet: &mut MutexGuard<'_, harness::mocks::wallet::MockWallet>) {
let mut seq = mockall::Sequence::new();
wallet
.expect_sign()
.times(1)
.returning(|_| Ok(dummy_partially_signed_transaction()))
.in_sequence(&mut seq);
wallet
.expect_broadcast()
.times(1)
.returning(|_| Ok(dummy_tx_id()))
.in_sequence(&mut seq);
}
#[tokio::test]
async fn taker_takes_order_and_maker_accepts_and_contract_setup() {
let _guard = init_tracing();
let (mut maker, mut taker) = start_both(
Oracle::default()
.with_dummy_announcement(harness::cfd_protocol::OliviaData::example_0().announcement()),
Monitor,
Wallet::default()
.with_wallet_info()
.with_party_params()
.with_psbt(harness::bdk::dummy_partially_signed_transaction())
.with_txid(harness::bdk::dummy_tx_id()),
Oracle::default()
.with_dummy_announcement(harness::cfd_protocol::OliviaData::example_0().announcement()),
Monitor,
Wallet::default()
.with_wallet_info()
.with_party_params()
.with_psbt(harness::bdk::dummy_partially_signed_transaction())
.with_txid(harness::bdk::dummy_tx_id()),
)
.await;
let (mut maker, mut taker) = start_both().await;
is_next_none(&mut taker.order_feed).await;
@ -118,8 +100,40 @@ async fn taker_takes_order_and_maker_accepts_and_contract_setup() {
taker.take_order(received.clone(), Usd::new(dec!(5)));
let (_, _) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await;
maker
.mocks
.oracle()
.await
.expect_get_announcement()
.returning(|_| Some(dummy_announcement()));
taker
.mocks
.oracle()
.await
.expect_get_announcement()
.returning(|_| Some(dummy_announcement()));
maker.accept_take_request(received.clone());
#[allow(clippy::redundant_closure)] // clippy is in the wrong here
maker
.mocks
.wallet()
.await
.expect_build_party_params()
.times(1)
.returning(|msg| build_party_params(msg));
#[allow(clippy::redundant_closure)] // clippy is in the wrong here
taker
.mocks
.wallet()
.await
.expect_build_party_params()
.times(1)
.returning(|msg| build_party_params(msg));
let (taker_cfd, maker_cfd) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await;
// TODO: More elaborate Cfd assertions
assert_eq!(taker_cfd.order.id, received.id);
@ -127,6 +141,9 @@ async fn taker_takes_order_and_maker_accepts_and_contract_setup() {
assert!(matches!(taker_cfd.state, CfdState::ContractSetup { .. }));
assert!(matches!(maker_cfd.state, CfdState::ContractSetup { .. }));
mock_wallet_sign_and_broadcast(&mut maker.mocks.wallet().await);
mock_wallet_sign_and_broadcast(&mut taker.mocks.wallet().await);
let (taker_cfd, maker_cfd) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await;
// TODO: More elaborate Cfd assertions
assert_eq!(taker_cfd.order.id, received.id);

54
daemon/tests/harness/mocks/mod.rs

@ -1,3 +1,57 @@
use std::sync::Arc;
use tokio::sync::{Mutex, MutexGuard};
use self::monitor::MonitorActor;
use self::oracle::OracleActor;
use self::wallet::WalletActor;
pub mod monitor;
pub mod oracle;
pub mod wallet;
#[derive(Clone)]
pub struct Mocks {
pub wallet: Arc<Mutex<wallet::MockWallet>>,
pub monitor: Arc<Mutex<monitor::MockMonitor>>,
pub oracle: Arc<Mutex<oracle::MockOracle>>,
}
impl Mocks {
pub async fn wallet(&mut self) -> MutexGuard<'_, wallet::MockWallet> {
self.wallet.lock().await
}
#[allow(dead_code)] // will be used soon
pub async fn monitor(&mut self) -> MutexGuard<'_, monitor::MockMonitor> {
self.monitor.lock().await
}
pub async fn oracle(&mut self) -> MutexGuard<'_, oracle::MockOracle> {
self.oracle.lock().await
}
}
impl Default for Mocks {
fn default() -> Self {
Self {
oracle: Arc::new(Mutex::new(oracle::MockOracle::new())),
monitor: Arc::new(Mutex::new(monitor::MockMonitor::new())),
wallet: Arc::new(Mutex::new(wallet::MockWallet::new())),
}
}
}
/// Creates actors with embedded mock handlers
pub fn create_actors(mocks: &Mocks) -> (OracleActor, MonitorActor, WalletActor) {
let oracle = OracleActor {
mock: mocks.oracle.clone(),
};
let monitor = MonitorActor {
mock: mocks.monitor.clone(),
};
let wallet = WalletActor {
mock: mocks.wallet.clone(),
};
(oracle, monitor, wallet)
}

52
daemon/tests/harness/mocks/monitor.rs

@ -1,29 +1,53 @@
use std::sync::Arc;
use daemon::{monitor, oracle};
use mockall::*;
use tokio::sync::Mutex;
use xtra_productivity::xtra_productivity;
/// Test Stub simulating the Monitor actor
pub struct Monitor;
impl xtra::Actor for Monitor {}
/// Test Stub simulating the Monitor actor.
/// Serves as an entrypoint for injected mock handlers.
pub struct MonitorActor {
pub mock: Arc<Mutex<dyn Monitor + Send>>,
}
impl xtra::Actor for MonitorActor {}
impl Monitor for MonitorActor {}
#[xtra_productivity(message_impl = false)]
impl Monitor {
async fn handle(&mut self, _msg: monitor::Sync) {}
impl MonitorActor {
async fn handle(&mut self, msg: monitor::Sync) {
self.mock.lock().await.sync(msg)
}
async fn handle(&mut self, _msg: monitor::StartMonitoring) {
todo!("stub this if needed")
async fn handle(&mut self, msg: monitor::StartMonitoring) {
self.mock.lock().await.start_monitoring(msg)
}
async fn handle(&mut self, _msg: monitor::CollaborativeSettlement) {
todo!("stub this if needed")
async fn handle(&mut self, msg: monitor::CollaborativeSettlement) {
self.mock.lock().await.collaborative_settlement(msg)
}
async fn handle(&mut self, _msg: oracle::Attestation) {
todo!("stub this if needed")
async fn handle(&mut self, msg: oracle::Attestation) {
self.mock.lock().await.oracle_attestation(msg)
}
}
impl Default for Monitor {
fn default() -> Self {
Monitor
#[automock]
pub trait Monitor {
fn sync(&mut self, _msg: monitor::Sync) {
unreachable!("mockall will reimplement this method")
}
fn start_monitoring(&mut self, _msg: monitor::StartMonitoring) {
unreachable!("mockall will reimplement this method")
}
fn collaborative_settlement(&mut self, _msg: monitor::CollaborativeSettlement) {
unreachable!("mockall will reimplement this method")
}
fn oracle_attestation(&mut self, _msg: oracle::Attestation) {
unreachable!("mockall will reimplement this method")
}
}

68
daemon/tests/harness/mocks/oracle.rs

@ -1,45 +1,57 @@
use crate::harness::cfd_protocol::OliviaData;
use daemon::model::BitMexPriceEventId;
use daemon::oracle;
use mockall::*;
use std::sync::Arc;
use time::OffsetDateTime;
use tokio::sync::Mutex;
use xtra_productivity::xtra_productivity;
pub struct Oracle {
announcement: Option<oracle::Announcement>,
/// Test Stub simulating the Oracle actor.
/// Serves as an entrypoint for injected mock handlers.
pub struct OracleActor {
pub mock: Arc<Mutex<dyn Oracle + Send>>,
}
impl Oracle {
pub fn with_dummy_announcement(
mut self,
dummy_announcement: cfd_protocol::Announcement,
) -> Self {
self.announcement = Some(oracle::Announcement {
id: BitMexPriceEventId::new(OffsetDateTime::UNIX_EPOCH, 0),
expected_outcome_time: OffsetDateTime::now_utc(),
nonce_pks: dummy_announcement.nonce_pks,
});
self
impl xtra::Actor for OracleActor {}
impl Oracle for OracleActor {}
#[xtra_productivity(message_impl = false)]
impl OracleActor {
async fn handle(&mut self, msg: oracle::GetAnnouncement) -> Option<oracle::Announcement> {
self.mock.lock().await.get_announcement(msg)
}
}
impl xtra::Actor for Oracle {}
async fn handle(&mut self, msg: oracle::MonitorAttestation) {
self.mock.lock().await.monitor_attestation(msg)
}
#[xtra_productivity(message_impl = false)]
impl Oracle {
async fn handle_get_announcement(
&mut self,
_msg: oracle::GetAnnouncement,
) -> Option<oracle::Announcement> {
self.announcement.clone()
async fn handle(&mut self, msg: oracle::Sync) {
self.mock.lock().await.sync(msg)
}
}
async fn handle(&mut self, _msg: oracle::MonitorAttestation) {}
#[automock]
pub trait Oracle {
fn get_announcement(&mut self, _msg: oracle::GetAnnouncement) -> Option<oracle::Announcement> {
unreachable!("mockall will reimplement this method")
}
fn monitor_attestation(&mut self, _msg: oracle::MonitorAttestation) {
unreachable!("mockall will reimplement this method")
}
async fn handle(&mut self, _msg: oracle::Sync) {}
fn sync(&mut self, _msg: oracle::Sync) {
unreachable!("mockall will reimplement this method")
}
}
impl Default for Oracle {
fn default() -> Self {
Oracle { announcement: None }
pub fn dummy_announcement() -> oracle::Announcement {
let announcement = OliviaData::example_0().announcement();
oracle::Announcement {
id: BitMexPriceEventId::new(OffsetDateTime::UNIX_EPOCH, 0),
expected_outcome_time: OffsetDateTime::now_utc(),
nonce_pks: announcement.nonce_pks,
}
}

124
daemon/tests/harness/mocks/wallet.rs

@ -1,93 +1,81 @@
use crate::harness::cfd_protocol::dummy_wallet;
use anyhow::{anyhow, Result};
use anyhow::Result;
use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
use bdk::bitcoin::{ecdsa, Amount, Txid};
use cfd_protocol::secp256k1_zkp::Secp256k1;
use cfd_protocol::{PartyParams, WalletExt};
use daemon::model::{Timestamp, WalletInfo};
use daemon::wallet;
use daemon::wallet::{self};
use mockall::*;
use rand::thread_rng;
use std::sync::Arc;
use tokio::sync::Mutex;
use xtra_productivity::xtra_productivity;
pub struct Wallet {
party_params: bool,
wallet_info: Option<WalletInfo>,
psbt: Option<PartiallySignedTransaction>,
txid: Option<Txid>,
/// Test Stub simulating the Wallet actor.
/// Serves as an entrypoint for injected mock handlers.
pub struct WalletActor {
pub mock: Arc<Mutex<dyn Wallet + Send>>,
}
impl Wallet {
pub fn with_party_params(mut self) -> Self {
self.party_params = true;
self
}
impl xtra::Actor for WalletActor {}
pub fn with_wallet_info(mut self) -> Self {
let s = Secp256k1::new();
let public_key = ecdsa::PublicKey::new(s.generate_keypair(&mut thread_rng()).1);
let address = bdk::bitcoin::Address::p2pkh(&public_key, bdk::bitcoin::Network::Testnet);
#[xtra_productivity(message_impl = false)]
impl WalletActor {
async fn handle(&mut self, msg: wallet::BuildPartyParams) -> Result<PartyParams> {
self.mock.lock().await.build_party_params(msg)
}
async fn handle(&mut self, msg: wallet::Sync) -> Result<WalletInfo> {
tracing::info!("We are handling the wallet sync msg");
self.mock.lock().await.sync(msg)
}
async fn handle(&mut self, msg: wallet::Sign) -> Result<PartiallySignedTransaction> {
self.mock.lock().await.sign(msg)
}
async fn handle(&mut self, msg: wallet::TryBroadcastTransaction) -> Result<Txid> {
self.mock.lock().await.broadcast(msg)
}
}
self.wallet_info = Some(WalletInfo {
balance: bdk::bitcoin::Amount::ONE_BTC,
address,
last_updated_at: Timestamp::now().unwrap(),
});
#[automock]
pub trait Wallet {
fn build_party_params(&mut self, _msg: wallet::BuildPartyParams) -> Result<PartyParams> {
unreachable!("mockall will reimplement this method")
}
self
fn sign(&mut self, _msg: wallet::Sign) -> Result<PartiallySignedTransaction> {
unreachable!("mockall will reimplement this method")
}
pub fn with_psbt(mut self, psbt: PartiallySignedTransaction) -> Self {
self.psbt = Some(psbt);
self
fn broadcast(&mut self, _msg: wallet::TryBroadcastTransaction) -> Result<Txid> {
unreachable!("mockall will reimplement this method")
}
pub fn with_txid(mut self, txid: Txid) -> Self {
self.txid = Some(txid);
self
fn sync(&mut self, _msg: wallet::Sync) -> Result<WalletInfo> {
unreachable!("mockall will reimplement this method")
}
}
impl xtra::Actor for Wallet {}
#[xtra_productivity(message_impl = false)]
impl Wallet {
async fn handle(&mut self, msg: wallet::BuildPartyParams) -> Result<PartyParams> {
if self.party_params {
let mut rng = thread_rng();
let wallet = dummy_wallet(&mut rng, Amount::from_btc(0.4).unwrap(), 5).unwrap();
let party_params = wallet
.build_party_params(msg.amount, msg.identity_pk)
.unwrap();
#[allow(dead_code)]
/// tells the user they have plenty of moneys
fn dummy_wallet_info() -> Result<WalletInfo> {
let s = Secp256k1::new();
let public_key = ecdsa::PublicKey::new(s.generate_keypair(&mut thread_rng()).1);
let address = bdk::bitcoin::Address::p2pkh(&public_key, bdk::bitcoin::Network::Testnet);
return Ok(party_params);
}
panic!("Stub not configured to return party params")
}
async fn handle(&mut self, _msg: wallet::Sync) -> Result<WalletInfo> {
self.wallet_info
.clone()
.ok_or_else(|| anyhow!("Stub not configured to return WalletInfo"))
}
async fn handle(&mut self, _msg: wallet::Sign) -> Result<PartiallySignedTransaction> {
self.psbt
.clone()
.ok_or_else(|| anyhow!("Stub not configured to return PartiallySignedTransaction"))
}
async fn handle(&mut self, _msg: wallet::TryBroadcastTransaction) -> Result<Txid> {
self.txid
.ok_or_else(|| anyhow!("Stub not configured to return Txid"))
}
Ok(WalletInfo {
balance: bdk::bitcoin::Amount::ONE_BTC,
address,
last_updated_at: Timestamp::now()?,
})
}
impl Default for Wallet {
fn default() -> Self {
Wallet {
party_params: false,
wallet_info: None,
psbt: None,
txid: None,
}
}
pub fn build_party_params(msg: wallet::BuildPartyParams) -> Result<PartyParams> {
let mut rng = thread_rng();
let wallet = dummy_wallet(&mut rng, Amount::from_btc(0.4).unwrap(), 5).unwrap();
let party_params = wallet
.build_party_params(msg.amount, msg.identity_pk)
.unwrap();
Ok(party_params)
}

69
daemon/tests/harness/mod.rs

@ -1,6 +1,6 @@
use crate::harness::mocks::monitor::Monitor;
use crate::harness::mocks::oracle::Oracle;
use crate::harness::mocks::wallet::Wallet;
use crate::harness::mocks::monitor::MonitorActor;
use crate::harness::mocks::oracle::OracleActor;
use crate::harness::mocks::wallet::WalletActor;
use crate::schnorrsig;
use daemon::maker_cfd::CfdAction;
use daemon::model::cfd::{Cfd, Order};
@ -18,54 +18,43 @@ pub mod bdk;
pub mod cfd_protocol;
pub mod mocks;
// TODO: Remove all these parameters once we have the mock framework (because we have
// Arcs then and can just default inside)
pub async fn start_both(
taker_oracle: Oracle,
taker_monitor: Monitor,
taker_wallet: Wallet,
maker_oracle: Oracle,
maker_monitor: Monitor,
maker_wallet: Wallet,
) -> (Maker, Taker) {
pub async fn start_both() -> (Maker, Taker) {
let oracle_pk: schnorrsig::PublicKey = schnorrsig::PublicKey::from_str(
"ddd4636845a90185991826be5a494cde9f4a6947b1727217afedc6292fa4caf7",
)
.unwrap();
let maker = Maker::start(oracle_pk, maker_oracle, maker_monitor, maker_wallet).await;
let taker = Taker::start(
oracle_pk,
maker.listen_addr,
taker_oracle,
taker_monitor,
taker_wallet,
)
.await;
let maker = Maker::start(oracle_pk).await;
let taker = Taker::start(oracle_pk, maker.listen_addr).await;
(maker, taker)
}
/// Maker Test Setup
#[derive(Clone)]
pub struct Maker {
pub cfd_actor_addr:
xtra::Address<maker_cfd::Actor<Oracle, Monitor, maker_inc_connections::Actor, Wallet>>,
pub cfd_actor_addr: xtra::Address<
maker_cfd::Actor<OracleActor, MonitorActor, maker_inc_connections::Actor, WalletActor>,
>,
pub order_feed: watch::Receiver<Option<Order>>,
pub cfd_feed: watch::Receiver<Vec<Cfd>>,
#[allow(dead_code)] // we need to keep the xtra::Address for refcounting
pub inc_conn_actor_addr: xtra::Address<maker_inc_connections::Actor>,
pub listen_addr: SocketAddr,
pub mocks: mocks::Mocks,
}
impl Maker {
pub async fn start(
oracle_pk: schnorrsig::PublicKey,
oracle: Oracle,
monitor: Monitor,
wallet: Wallet,
) -> Self {
pub async fn start(oracle_pk: schnorrsig::PublicKey) -> Self {
let db = in_memory_db().await;
let mocks = mocks::Mocks::default();
let (oracle, monitor, wallet) = mocks::create_actors(&mocks);
// Sync method need to be mocked before the actors start
mocks.oracle.lock().await.expect_sync().return_const(());
mocks.monitor.lock().await.expect_sync().return_const(());
let wallet_addr = wallet.create(None).spawn_global();
let settlement_time_interval_hours = time::Duration::hours(24);
@ -106,6 +95,7 @@ impl Maker {
cfd_feed: maker.cfd_feed_receiver,
inc_conn_actor_addr: maker.inc_conn_addr,
listen_addr: address,
mocks,
}
}
@ -131,17 +121,12 @@ impl Maker {
pub struct Taker {
pub order_feed: watch::Receiver<Option<Order>>,
pub cfd_feed: watch::Receiver<Vec<Cfd>>,
pub cfd_actor_addr: xtra::Address<taker_cfd::Actor<Oracle, Monitor, Wallet>>,
pub cfd_actor_addr: xtra::Address<taker_cfd::Actor<OracleActor, MonitorActor, WalletActor>>,
pub mocks: mocks::Mocks,
}
impl Taker {
pub async fn start(
oracle_pk: schnorrsig::PublicKey,
maker_address: SocketAddr,
oracle: Oracle,
monitor: Monitor,
wallet: Wallet,
) -> Self {
pub async fn start(oracle_pk: schnorrsig::PublicKey, maker_address: SocketAddr) -> Self {
let connection::Actor {
send_to_maker,
read_from_maker,
@ -149,6 +134,13 @@ impl Taker {
let db = in_memory_db().await;
let mocks = mocks::Mocks::default();
let (oracle, monitor, wallet) = mocks::create_actors(&mocks);
// Sync method need to be mocked before the actors start
mocks.oracle.lock().await.expect_sync().return_const(());
mocks.monitor.lock().await.expect_sync().return_const(());
let wallet_addr = wallet.create(None).spawn_global();
let taker = daemon::TakerActorSystem::new(
@ -167,6 +159,7 @@ impl Taker {
order_feed: taker.order_feed_receiver,
cfd_feed: taker.cfd_feed_receiver,
cfd_actor_addr: taker.cfd_actor_addr,
mocks,
}
}

Loading…
Cancel
Save