#! /usr/bin/env python '''support functions for jmclient tests.''' import pytest from jmclient import (select, select_gradual, select_greedy, select_greediest, choose_orders, choose_sweep_orders, weighted_order_choose) from jmclient.support import (calc_cj_fee, rand_exp_array, rand_norm_array, rand_weighted_choice, cheapest_order_choose, fidelity_bond_weighted_order_choose) from taker_test_data import t_orderbook import copy def test_utxo_selection(): """Check that all the utxo selection algorithms work with a random variety of wallet contents. """ unspent = [{'utxo':'a', 'value': 10000000}, {'utxo':'b', 'value': 20000000}, {'utxo':'c', 'value': 50000000}, {'utxo':'d', 'value': 50000000}] for selector in [select, select_gradual, select_greedy, select_greediest]: for amt in [9999999, 10000000, 110000000, 19999999, 20000000, 49999999, 50000000, 99999999, 100000000]: selector(unspent, amt) for amt in [1300000010, 2000000000]: with pytest.raises(Exception) as e_info: x = selector(unspent, amt) print(x) assert e_info.match("Not enough funds") def test_random_funcs(): x1 = rand_norm_array(5, 2, 10) assert len(x1) == 10 for x in x1: assert x > -7 #6 sigma! x2 = rand_exp_array(100, 10) assert len(x2) == 10 for x in x2: assert x > 0 x4 = rand_weighted_choice(5, [0.2, 0.1, 0.3, 0.15, 0.25]) assert x4 in range(5) #test weighted choice fails with invalid inputs with pytest.raises(ValueError) as e_info: x = rand_weighted_choice(5, [0.2, 0.1, 0.3, 0.15, 0.26]) assert e_info.match("Sum of probabilities") with pytest.raises(ValueError) as e_info: x = rand_weighted_choice(5, [0.25, 0.25, 0.25, 0.25]) assert e_info.match("Need: 5 probabilities.") def test_calc_cjfee(): assert calc_cj_fee("swabsoffer", 3000, 200000000) == 3000 assert calc_cj_fee("swreloffer", "0.01", 100000000) == 1000000 assert calc_cj_fee("sw0absoffer", 3000, 200000000) == 3000 assert calc_cj_fee("sw0reloffer", "0.01", 100000000) == 1000000 with pytest.raises(RuntimeError) as e_info: calc_cj_fee("dummyoffer", 2, 3) def test_choose_orders(): orderbook = copy.deepcopy(t_orderbook) #test not enough liquidity orders_fees = choose_orders(orderbook, 10000000, 7, weighted_order_choose) assert orders_fees == (None, 0) orders_fees = choose_orders(orderbook, 10000000, 3, weighted_order_choose) #need variable fee sizes for i, o in enumerate(orderbook): o['cjfee'] = str(float(o['cjfee']) + 0.0001*i) #test phi not zero orders_fees = choose_orders(orderbook, 10000000, 3, weighted_order_choose) assert len(orders_fees[0]) == 3 #test M < orderbook size for weighted orders_fees = choose_orders(orderbook, 10000000, 1, weighted_order_choose) assert len(orders_fees[0]) == 1 #test the hated 'cheapest' orders_fees = choose_orders(orderbook, 100000000, 3, cheapest_order_choose) assert len(orders_fees[0]) == 3 #test the fidelity bond one for i, o in enumerate(orderbook): o["fidelity_bond_value"] = i+1 orders_fees = choose_orders(orderbook, 100000000, 3, fidelity_bond_weighted_order_choose) assert len(orders_fees[0]) == 3 #test sweep result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, 30000, 3, weighted_order_choose, None) assert cjamount >= 49800000 assert cjamount <= 50000000 assert total_fee >= 30000 assert total_fee <= 100000 assert len(result) == 3 #test not enough liquidity result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, 30000, 7, weighted_order_choose, None) assert result == None assert cjamount == 0 assert total_fee == 0 #here we doctor the orderbook; (a) include an absfee #(b) add an unrecognized ordertype (does not raise, ignores) #(c) put an order with wrong minsize orderbook.append({u'counterparty': u'fake', u'ordertype': u'sw0absoffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': 9000}) result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, 30000, 7, cheapest_order_choose, None) assert total_fee > 0 #(b) orderbook.append({u'counterparty': u'fake2', u'ordertype': u'dummyoffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': 9000}) result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, 30000, 8, weighted_order_choose, None) #(c) #remove bad offer orderbook = orderbook[:-1] for i in range(7): orderbook[i]['minsize'] = 49999999 result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, 30000, 4, weighted_order_choose, None) assert result == None assert cjamount == 0 assert total_fee == 0