Skip to content

Commit

Permalink
implement unit & integration tests
Browse files Browse the repository at this point in the history
Signed-off-by: ozkanonur <work@onurozkan.dev>
  • Loading branch information
onur-ozkan committed May 3, 2023
1 parent a4440d4 commit 57be79e
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Some enhancements were done for `enable_bch_with_tokens`,`enable_eth_with_tokens`,`enable_tendermint_with_assets` RPCs in [#1762](https://github.com/KomodoPlatform/atomicDEX-API/pull/1762)
- A new parameter `get_balances` was added to the above methods requests, when this parameter is set to `false`, balances will not be returned in the response. The default value for this parameter is `true` to ensure backward compatibility.
- Token balances requests are now performed concurrently for the above methods.
- Add passive parent coin state for keeping tokens active when platform is disabled [#1763](https://github.com/KomodoPlatform/atomicDEX-API/pull/1763)


## v1.0.3-beta - 2023-04-28
Expand Down
54 changes: 53 additions & 1 deletion mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2249,7 +2249,7 @@ pub trait MmCoin:
/// Useful for executing `disable_coin` on parent coins
/// that have child tokens enabled.
///
/// Noneffective for child tokens.
/// Ineffective for child tokens.
fn update_is_available(&self, to: bool);
}

Expand Down Expand Up @@ -3874,3 +3874,55 @@ fn coins_conf_check(ctx: &MmArc, coins_en: &Json, ticker: &str, req: Option<&Jso
}
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

use mm2_test_helpers::for_tests::RICK;

#[test]
fn test_lp_coinfind() {
let ctx = mm2_core::mm_ctx::MmCtxBuilder::default().into_mm_arc();
let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap();
let coin = MmCoinEnum::Test(TestCoin::new(RICK));

// Add test coin to coins context
common::block_on(coins_ctx.add_token(coin.clone())).unwrap();

// Try to find RICK from coins context that was added above
let _found = common::block_on(lp_coinfind(&ctx, RICK)).unwrap();

assert!(matches!(Some(coin.clone()), _found));

coin.update_is_available(false);

// Try to find RICK from coins context after making it passive
let found = common::block_on(lp_coinfind(&ctx, RICK)).unwrap();

assert!(found.is_none());
}

#[test]
#[ignore]
fn test_lp_coinfind_any() {
let ctx = mm2_core::mm_ctx::MmCtxBuilder::default().into_mm_arc();
let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap();
let coin = MmCoinEnum::Test(TestCoin::new(RICK));

// Add test coin to coins context
common::block_on(coins_ctx.add_token(coin.clone())).unwrap();

// Try to find RICK from coins context that was added above
let _found = common::block_on(lp_coinfind_any(&ctx, RICK)).unwrap();

assert!(matches!(Some(coin.clone()), _found));

coin.update_is_available(false);

// Try to find RICK from coins context after making it passive
let _found = common::block_on(lp_coinfind_any(&ctx, RICK)).unwrap();

assert!(matches!(Some(coin), _found));
}
}
39 changes: 30 additions & 9 deletions mm2src/coins/test_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPay
VerificationResult, WatcherOps, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput,
WatcherValidateTakerFeeInput, WithdrawFut, WithdrawRequest};
use async_trait::async_trait;
use common::{executor::AbortedError, log::warn};
use common::executor::AbortedError;
use futures01::Future;
use keys::KeyPair;
use mm2_core::mm_ctx::MmArc;
Expand All @@ -21,20 +21,43 @@ use mm2_number::{BigDecimal, MmNumber};
use mocktopus::macros::*;
use rpc::v1::types::Bytes as BytesJson;
use serde_json::Value as Json;
use std::ops::Deref;
use std::sync::{atomic::{AtomicBool, Ordering},
Arc};

/// Dummy coin struct used in tests which functions are unimplemented but then mocked
/// in specific test to emulate the required behaviour
#[derive(Clone, Debug)]
pub struct TestCoin {
pub struct TestCoin(Arc<TestCoinImpl>);

impl Deref for TestCoin {
type Target = TestCoinImpl;

fn deref(&self) -> &Self::Target { &self.0 }
}

#[derive(Debug)]
pub struct TestCoinImpl {
ticker: String,
is_available: AtomicBool,
}

impl Default for TestCoin {
fn default() -> Self { TestCoin { ticker: "test".into() } }
fn default() -> Self {
TestCoin(Arc::new(TestCoinImpl {
ticker: "test".into(),
is_available: AtomicBool::new(true),
}))
}
}

impl TestCoin {
pub fn new(ticker: &str) -> TestCoin { TestCoin { ticker: ticker.into() } }
pub fn new(ticker: &str) -> TestCoin {
TestCoin(Arc::new(TestCoinImpl {
ticker: ticker.into(),
is_available: AtomicBool::new(true),
}))
}
}

#[mockable]
Expand All @@ -57,7 +80,7 @@ impl MarketCoinOps for TestCoin {

fn base_coin_balance(&self) -> BalanceFut<BigDecimal> { unimplemented!() }

fn platform_ticker(&self) -> &str { unimplemented!() }
fn platform_ticker(&self) -> &str { &self.ticker }

/// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format
fn send_raw_tx(&self, tx: &str) -> Box<dyn Future<Item = String, Error = String> + Send> { unimplemented!() }
Expand Down Expand Up @@ -358,9 +381,7 @@ impl MmCoin for TestCoin {

fn on_token_deactivated(&self, _ticker: &str) { () }

fn is_available(&self) -> bool { true }
fn is_available(&self) -> bool { self.is_available.load(Ordering::SeqCst) }

fn update_is_available(&self, _to: bool) {
warn!("`update_is_available` is ineffective for test coin");
}
fn update_is_available(&self, to: bool) { self.is_available.store(to, Ordering::SeqCst); }
}
7 changes: 4 additions & 3 deletions mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ pub async fn disable_coin(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, St
);
}

let response = |ticker: &str, cancelled_orders: Vec<Uuid>| {
let response = |ticker: &str, cancelled_orders: Vec<Uuid>, passivized: bool| {
let res = json!({
"result": {
"coin": ticker,
"cancelled_orders": cancelled_orders,
"passivized": passivized,
}
});

Expand All @@ -114,7 +115,7 @@ pub async fn disable_coin(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, St
if !coins_ctx.get_dependent_tokens(&ticker).await.is_empty() && !force_disable {
coin.update_is_available(false);

return response(&ticker, Vec::default());
return response(&ticker, Vec::default(), true);
}

// Proceed with diabling the coin/tokens.
Expand All @@ -135,7 +136,7 @@ pub async fn disable_coin(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, St

coins_ctx.remove_coin(coin).await;

response(&ticker, cancelled_orders)
response(&ticker, cancelled_orders, false)
}

#[derive(Serialize)]
Expand Down
9 changes: 6 additions & 3 deletions mm2src/mm2_main/tests/docker_tests/slp_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,15 @@ fn test_disable_platform_coin_with_tokens() {
false,
));
// Try to disable ADEXSLP token.
block_on(disable_coin(&mm, "ADEXSLP", false));
let res = block_on(disable_coin(&mm, "ADEXSLP", false));
assert!(!res.passivized);
// Check if platform_coin FORSLP is still enabled.
block_on(my_balance(&mm, "FORSLP"));
// Check if ADEXSLP token still enabled.
block_on(assert_coin_not_found_on_balance(&mm, "ADEXSLP"));
// Try to disable patform_coin.
block_on(disable_coin(&mm, "FORSLP", false));
let res = block_on(disable_coin(&mm, "FORSLP", false));
assert!(!res.passivized);

// Enable enable_bch_with_tokens again to restart the process
let _ = block_on(enable_bch_with_tokens(
Expand All @@ -256,5 +258,6 @@ fn test_disable_platform_coin_with_tokens() {
));

// Try to force disable platform coin, FORSLP.
block_on(disable_coin(&mm, "FORSLP", true));
let res = block_on(disable_coin(&mm, "FORSLP", true));
assert!(!res.passivized);
}
12 changes: 8 additions & 4 deletions mm2src/mm2_main/tests/docker_tests/solana_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,17 @@ fn test_disable_solana_platform_coin_with_tokens() {
block_on(enable_spl(&mm, "ADEX-SOL-DEVNET"));

// Try to passive platform coin, SOL-DEVNET.
block_on(disable_coin(&mm, "SOL-DEVNET", false));
let res = block_on(disable_coin(&mm, "SOL-DEVNET", false));
assert!(res.passivized);

// Try to disable ADEX-SOL-DEVNET and USDC-SOL-DEVNET
// This should work, because platform coin is still in the memory.
block_on(disable_coin(&mm, "ADEX-SOL-DEVNET", false));
block_on(disable_coin(&mm, "USDC-SOL-DEVNET", false));
let res = block_on(disable_coin(&mm, "ADEX-SOL-DEVNET", false));
assert!(!res.passivized);
let res = block_on(disable_coin(&mm, "USDC-SOL-DEVNET", false));
assert!(!res.passivized);

// Then try to force disable SOL-DEVNET platform coin.
block_on(disable_coin(&mm, "SOL-DEVNET", true));
let res = block_on(disable_coin(&mm, "SOL-DEVNET", true));
assert!(!res.passivized);
}
2 changes: 1 addition & 1 deletion mm2src/mm2_main/tests/mm2_tests/bch_and_slp_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn test_withdraw_cashaddresses() {
// Wait 5 seconds to avoid double spending
thread::sleep(Duration::from_secs(5));

//Disable BCH to enable in Legacy Mode
// Disable BCH to enable in Legacy Mode
block_on(disable_coin(&mm, "BCH", false));

let electrum = block_on(mm.rpc(&json! ({
Expand Down
7 changes: 5 additions & 2 deletions mm2src/mm2_main/tests/mm2_tests/eth_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,21 @@ fn test_disable_eth_coin_with_token() {
let order_uuid = order_uuid.get("result").unwrap().get("uuid").unwrap().as_str().unwrap();

// Passive ETH while having tokens enabled
block_on(disable_coin(&mm, "ETH", false));
let res = block_on(disable_coin(&mm, "ETH", false));
assert!(res.passivized);

// Try to disable JST token.
// This should work, because platform coin is still in the memory.
let res = block_on(disable_coin(&mm, "JST", false));
// We expected make_test_order to be cancelled
assert!(!res.passivized);
assert!(res.cancelled_orders.contains(order_uuid));

// Because it's currently passive, default `disable_coin` should fail.
block_on(disable_coin_err(&mm, "ETH", false));
// And forced `disable_coin` should not fail
block_on(disable_coin(&mm, "ETH", true));
let res = block_on(disable_coin(&mm, "ETH", true));
assert!(!res.passivized);
}

#[test]
Expand Down
10 changes: 7 additions & 3 deletions mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,16 @@ fn test_enable_lightning() {
);

// Try to passive tBTC-TEST-segwit platform coin.
block_on(disable_coin(&mm, "tBTC-TEST-segwit", false));
let res = block_on(disable_coin(&mm, "tBTC-TEST-segwit", false));
assert!(res.passivized);

// Try to disable tBTC-TEST-lightning token
// This should work, because platform coin is still in the memory.
block_on(disable_coin(&mm, "tBTC-TEST-lightning", false));
let res = block_on(disable_coin(&mm, "tBTC-TEST-lightning", false));
assert!(!res.passivized);
// Try to force disable tBTC-TEST-segwit platform coin.
block_on(disable_coin(&mm, "tBTC-TEST-segwit", true));
let res = block_on(disable_coin(&mm, "tBTC-TEST-segwit", true));
assert!(!res.passivized);

// Stop mm2
block_on(mm.stop()).unwrap();
Expand Down
62 changes: 55 additions & 7 deletions mm2src/mm2_main/tests/mm2_tests/tendermint_tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use common::block_on;
use mm2_number::BigDecimal;
use mm2_test_helpers::for_tests::{atom_testnet_conf, disable_coin, enable_tendermint, enable_tendermint_token,
enable_tendermint_without_balance, get_tendermint_my_tx_history, ibc_withdraw,
iris_nimda_testnet_conf, iris_testnet_conf, my_balance, send_raw_transaction,
withdraw_v1, MarketMakerIt, Mm2TestConf};
use mm2_test_helpers::for_tests::{atom_testnet_conf, disable_coin, disable_coin_err, enable_tendermint,
enable_tendermint_token, enable_tendermint_without_balance,
get_tendermint_my_tx_history, ibc_withdraw, iris_nimda_testnet_conf,
iris_testnet_conf, my_balance, send_raw_transaction, withdraw_v1, MarketMakerIt,
Mm2TestConf};
use mm2_test_helpers::structs::{RpcV2Response, TendermintActivationResult, TransactionDetails};
use serde_json::{self as json, json};

Expand Down Expand Up @@ -352,12 +353,59 @@ fn test_disable_tendermint_platform_coin_with_token() {
assert!(&activation_res.get("result").unwrap().get("balances").is_some());

// Try to passive platform coin, IRIS-TEST.
block_on(disable_coin(&mm, "IRIS-TEST", false));
let res = block_on(disable_coin(&mm, "IRIS-TEST", false));
assert!(res.passivized);

// Try to disable IRIS-NIMDA token when platform coin is passived.
// This should work, because platform coin is still in the memory.
block_on(disable_coin(&mm, "IRIS-NIMDA", false));
let res = block_on(disable_coin(&mm, "IRIS-NIMDA", false));
assert!(!res.passivized);

// Then try to force disable IRIS-TEST platform coin.
block_on(disable_coin(&mm, "IRIS-TEST", true));
let res = block_on(disable_coin(&mm, "IRIS-TEST", true));
assert!(!res.passivized);
}

#[test]
fn test_passive_coin_and_force_disable() {
const TEST_SEED: &str = "iris test seed";
let coins = json!([iris_testnet_conf(), iris_nimda_testnet_conf()]);
let platform_coin = coins[0]["coin"].as_str().unwrap();
let token = coins[1]["coin"].as_str().unwrap();

let conf = Mm2TestConf::seednode(TEST_SEED, &coins);
let mm = MarketMakerIt::start(conf.conf, conf.rpc_password, None).unwrap();

// Enable platform coin IRIS-TEST
let activation_res = block_on(enable_tendermint(&mm, platform_coin, &[], IRIS_TESTNET_RPC_URLS, false));
assert!(&activation_res.get("result").unwrap().get("address").is_some());

// Enable platform coin token IRIS-NIMDA
let activation_res = block_on(enable_tendermint_token(&mm, token));
assert!(&activation_res.get("result").unwrap().get("balances").is_some());

// Try to passive platform coin, IRIS-TEST.
let res = block_on(disable_coin(&mm, "IRIS-TEST", false));
assert!(res.passivized);

// Try to disable IRIS-NIMDA token when platform coin is passived.
// This should work, because platform coin is still in the memory.
let res = block_on(disable_coin(&mm, "IRIS-NIMDA", false));
assert!(!res.passivized);

// Re-activate passive coin
let activation_res = block_on(enable_tendermint(&mm, platform_coin, &[], IRIS_TESTNET_RPC_URLS, false));
assert!(&activation_res.get("result").unwrap().get("address").is_some());

// Enable platform coin token IRIS-NIMDA
let activation_res = block_on(enable_tendermint_token(&mm, token));
assert!(&activation_res.get("result").unwrap().get("balances").is_some());

// Try to force disable platform coin, IRIS-TEST.
let res = block_on(disable_coin(&mm, "IRIS-TEST", true));
assert!(!res.passivized);

// Try to disable IRIS-NIMDA token when platform coin force disabled.
// This should failed, because platform coin was purged with it's tokens.
block_on(disable_coin_err(&mm, "IRIS-NIMDA", false));
}
1 change: 1 addition & 0 deletions mm2src/mm2_test_helpers/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,7 @@ pub struct WatcherConf {
pub struct DisableResult {
pub coin: String,
pub cancelled_orders: HashSet<String>,
pub passivized: bool,
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down

0 comments on commit 57be79e

Please sign in to comment.