X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=test.py;h=ea1fd9a72c17da48fd398d68504125e5b04bbed7;hb=337c8286cc31d81ffdad06a225996f86c46c46f0;hp=637a3054c4d8449b3fb0963e4180e62b0b837567;hpb=0c6eb1640c0d0c0e7b679d1702415a35319863f1;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/test.py b/test.py index 637a305..ea1fd9a 100644 --- a/test.py +++ b/test.py @@ -70,6 +70,18 @@ class poloniexETest(unittest.TestCase): self.wm.stop() super(poloniexETest, self).tearDown() + def test__init(self): + with mock.patch("market.ccxt.poloniexE.session") as session: + session.request.return_value = "response" + ccxt = market.ccxt.poloniexE() + ccxt._market = mock.Mock + ccxt._market.report = mock.Mock() + + ccxt.session.request("GET", "URL", data="data", + headers="headers") + ccxt._market.report.log_http_request.assert_called_with('GET', 'URL', 'data', + 'headers', 'response') + def test_nanoseconds(self): with mock.patch.object(market.ccxt.time, "time") as time: time.return_value = 123456.7890123456 @@ -80,6 +92,58 @@ class poloniexETest(unittest.TestCase): time.return_value = 123456.7890123456 self.assertEqual(123456789012345, self.s.nonce()) + def test_request(self): + with mock.patch.object(market.ccxt.poloniex, "request") as request,\ + mock.patch("market.ccxt.retry_call") as retry_call: + with self.subTest(wrapped=True): + with self.subTest(desc="public"): + self.s.request("foo") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["foo"], + fkwargs={'api': 'public', 'method': 'GET', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private GET"): + self.s.request("foo", api="private") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["foo"], + fkwargs={'api': 'private', 'method': 'GET', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private POST regexp"): + self.s.request("returnFoo", api="private", method="POST") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["returnFoo"], + fkwargs={'api': 'private', 'method': 'POST', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private POST non-regexp"): + self.s.request("getMarginPosition", api="private", method="POST") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["getMarginPosition"], + fkwargs={'api': 'private', 'method': 'POST', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + retry_call.reset_mock() + request.reset_mock() + with self.subTest(wrapped=False): + with self.subTest(desc="private POST non-matching regexp"): + self.s.request("marginBuy", api="private", method="POST") + request.assert_called_with("marginBuy", + api="private", method="POST", params={}, + headers=None, body=None) + retry_call.assert_not_called() + + with self.subTest(desc="private POST non-matching non-regexp"): + self.s.request("closeMarginPositionOther", api="private", method="POST") + request.assert_called_with("closeMarginPositionOther", + api="private", method="POST", params={}, + headers=None, body=None) + retry_call.assert_not_called() + def test_order_precision(self): self.assertEqual(8, self.s.order_precision("FOO")) @@ -1125,17 +1189,11 @@ class MarketTest(WebMockTestCase): def test_from_config(self, ccxt): with mock.patch("market.ReportStore"): ccxt.poloniexE.return_value = self.ccxt - self.ccxt.session.request.return_value = "response" m = market.Market.from_config({"key": "key", "secred": "secret"}, self.market_args()) self.assertEqual(self.ccxt, m.ccxt) - self.ccxt.session.request("GET", "URL", data="data", - headers="headers") - m.report.log_http_request.assert_called_with('GET', 'URL', 'data', - 'headers', 'response') - m = market.Market.from_config({"key": "key", "secred": "secret"}, self.market_args(debug=True)) self.assertEqual(True, m.debug) @@ -1386,6 +1444,139 @@ class MarketTest(WebMockTestCase): self.ccxt.transfer_balance.assert_any_call("USDT", 100, "exchange", "margin") self.ccxt.transfer_balance.assert_any_call("ETC", 5, "margin", "exchange") + m.report.reset_mock() + fetch_balances.reset_mock() + with self.subTest(retry=True): + with mock.patch("market.ReportStore"): + m = market.Market(self.ccxt, self.market_args()) + + value_from = portfolio.Amount("BTC", "0.0") + value_from.linked_to = portfolio.Amount("ETH", "0.0") + value_to = portfolio.Amount("BTC", "-3.0") + trade = portfolio.Trade(value_from, value_to, "ETH", m) + + m.trades.all = [trade] + balance = portfolio.Balance("BTC", { "margin_in_position": "0", "margin_available": "0" }) + m.balances.all = {"BTC": balance} + + m.ccxt.transfer_balance.side_effect = [ + market.ccxt.RequestTimeout, + True + ] + m.move_balances() + self.ccxt.transfer_balance.assert_has_calls([ + mock.call("BTC", 3, "exchange", "margin"), + mock.call("BTC", 3, "exchange", "margin") + ]) + self.assertEqual(2, fetch_balances.call_count) + m.report.log_error.assert_called_with(mock.ANY, message="Retrying", exception=mock.ANY) + self.assertEqual(2, m.report.log_move_balances.call_count) + + self.ccxt.transfer_balance.reset_mock() + m.report.reset_mock() + fetch_balances.reset_mock() + with self.subTest(retry=True, too_much=True): + with mock.patch("market.ReportStore"): + m = market.Market(self.ccxt, self.market_args()) + + value_from = portfolio.Amount("BTC", "0.0") + value_from.linked_to = portfolio.Amount("ETH", "0.0") + value_to = portfolio.Amount("BTC", "-3.0") + trade = portfolio.Trade(value_from, value_to, "ETH", m) + + m.trades.all = [trade] + balance = portfolio.Balance("BTC", { "margin_in_position": "0", "margin_available": "0" }) + m.balances.all = {"BTC": balance} + + m.ccxt.transfer_balance.side_effect = [ + market.ccxt.RequestTimeout, + market.ccxt.RequestTimeout, + market.ccxt.RequestTimeout, + market.ccxt.RequestTimeout, + market.ccxt.RequestTimeout, + ] + with self.assertRaises(market.ccxt.RequestTimeout): + m.move_balances() + + self.ccxt.transfer_balance.reset_mock() + m.report.reset_mock() + fetch_balances.reset_mock() + with self.subTest(retry=True, partial_result=True): + with mock.patch("market.ReportStore"): + m = market.Market(self.ccxt, self.market_args()) + + value_from = portfolio.Amount("BTC", "1.0") + value_from.linked_to = portfolio.Amount("ETH", "10.0") + value_to = portfolio.Amount("BTC", "10.0") + trade1 = portfolio.Trade(value_from, value_to, "ETH", m) + + value_from = portfolio.Amount("BTC", "0.0") + value_from.linked_to = portfolio.Amount("ETH", "0.0") + value_to = portfolio.Amount("BTC", "-3.0") + trade2 = portfolio.Trade(value_from, value_to, "ETH", m) + + value_from = portfolio.Amount("USDT", "0.0") + value_from.linked_to = portfolio.Amount("XVG", "0.0") + value_to = portfolio.Amount("USDT", "-50.0") + trade3 = portfolio.Trade(value_from, value_to, "XVG", m) + + m.trades.all = [trade1, trade2, trade3] + balance1 = portfolio.Balance("BTC", { "margin_in_position": "0", "margin_available": "0" }) + balance2 = portfolio.Balance("USDT", { "margin_in_position": "100", "margin_available": "50" }) + balance3 = portfolio.Balance("ETC", { "margin_in_position": "10", "margin_available": "15" }) + m.balances.all = {"BTC": balance1, "USDT": balance2, "ETC": balance3} + + call_counts = { "BTC": 0, "USDT": 0, "ETC": 0 } + def _transfer_balance(currency, amount, from_, to_): + call_counts[currency] += 1 + if currency == "BTC": + m.balances.all["BTC"] = portfolio.Balance("BTC", { "margin_in_position": "0", "margin_available": "3" }) + if currency == "USDT": + if call_counts["USDT"] == 1: + raise market.ccxt.RequestTimeout + else: + m.balances.all["USDT"] = portfolio.Balance("USDT", { "margin_in_position": "100", "margin_available": "150" }) + if currency == "ETC": + m.balances.all["ETC"] = portfolio.Balance("ETC", { "margin_in_position": "10", "margin_available": "10" }) + + + m.ccxt.transfer_balance.side_effect = _transfer_balance + + m.move_balances() + self.ccxt.transfer_balance.assert_has_calls([ + mock.call("BTC", 3, "exchange", "margin"), + mock.call('USDT', 100, 'exchange', 'margin'), + mock.call('USDT', 100, 'exchange', 'margin'), + mock.call("ETC", 5, "margin", "exchange") + ]) + self.assertEqual(2, fetch_balances.call_count) + m.report.log_error.assert_called_with(mock.ANY, message="Retrying", exception=mock.ANY) + self.assertEqual(2, m.report.log_move_balances.call_count) + m.report.log_move_balances.asser_has_calls([ + mock.call( + { + 'BTC': portfolio.Amount("BTC", "3"), + 'USDT': portfolio.Amount("USDT", "150"), + 'ETC': portfolio.Amount("ETC", "10"), + }, + { + 'BTC': portfolio.Amount("BTC", "3"), + 'USDT': portfolio.Amount("USDT", "100"), + }), + mock.call( + { + 'BTC': portfolio.Amount("BTC", "3"), + 'USDT': portfolio.Amount("USDT", "150"), + 'ETC': portfolio.Amount("ETC", "10"), + }, + { + 'BTC': portfolio.Amount("BTC", "0"), + 'USDT': portfolio.Amount("USDT", "100"), + 'ETC': portfolio.Amount("ETC", "-5"), + }), + ]) + + def test_store_file_report(self): file_open = mock.mock_open() m = market.Market(self.ccxt, self.market_args(), report_path="present", user_id=1)