Explicitly close loop in async tests

This commit is contained in:
Matthias 2023-03-26 15:46:20 +02:00
parent 444d18aa39
commit fb1541bdf6
2 changed files with 15 additions and 8 deletions

View File

@ -205,6 +205,8 @@ class Exchange:
and self._api_async.session): and self._api_async.session):
logger.debug("Closing async ccxt session.") logger.debug("Closing async ccxt session.")
self.loop.run_until_complete(self._api_async.close()) self.loop.run_until_complete(self._api_async.close())
if self.loop and not self.loop.is_closed():
self.loop.close()
def validate_config(self, config): def validate_config(self, config):
# Check if timeframe is available # Check if timeframe is available

View File

@ -113,18 +113,21 @@ async def async_ccxt_exception(mocker, default_conf, api_mock, fun, mock_ccxt_fu
exchange = get_patched_exchange(mocker, default_conf, api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
await getattr(exchange, fun)(**kwargs) await getattr(exchange, fun)(**kwargs)
assert api_mock.__dict__[mock_ccxt_fun].call_count == retries assert api_mock.__dict__[mock_ccxt_fun].call_count == retries
exchange.close()
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.NetworkError("DeadBeef")) api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.NetworkError("DeadBeef"))
exchange = get_patched_exchange(mocker, default_conf, api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
await getattr(exchange, fun)(**kwargs) await getattr(exchange, fun)(**kwargs)
assert api_mock.__dict__[mock_ccxt_fun].call_count == retries assert api_mock.__dict__[mock_ccxt_fun].call_count == retries
exchange.close()
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.BaseError("DeadBeef")) api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.BaseError("DeadBeef"))
exchange = get_patched_exchange(mocker, default_conf, api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
await getattr(exchange, fun)(**kwargs) await getattr(exchange, fun)(**kwargs)
assert api_mock.__dict__[mock_ccxt_fun].call_count == 1 assert api_mock.__dict__[mock_ccxt_fun].call_count == 1
exchange.close()
def test_init(default_conf, mocker, caplog): def test_init(default_conf, mocker, caplog):
@ -2248,7 +2251,6 @@ def test_refresh_latest_ohlcv_cache(mocker, default_conf, candle_type, time_mach
assert res[pair2].at[0, 'open'] assert res[pair2].at[0, 'open']
@pytest.mark.asyncio
@pytest.mark.parametrize("exchange_name", EXCHANGES) @pytest.mark.parametrize("exchange_name", EXCHANGES)
async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_name): async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_name):
ohlcv = [ ohlcv = [
@ -2277,7 +2279,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
assert res[3] == ohlcv assert res[3] == ohlcv
assert exchange._api_async.fetch_ohlcv.call_count == 1 assert exchange._api_async.fetch_ohlcv.call_count == 1
assert not log_has(f"Using cached candle (OHLCV) data for {pair} ...", caplog) assert not log_has(f"Using cached candle (OHLCV) data for {pair} ...", caplog)
exchange.close()
# exchange = Exchange(default_conf) # exchange = Exchange(default_conf)
await async_ccxt_exception(mocker, default_conf, MagicMock(), await async_ccxt_exception(mocker, default_conf, MagicMock(),
"_async_get_candle_history", "fetch_ohlcv", "_async_get_candle_history", "fetch_ohlcv",
@ -2292,15 +2294,17 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
await exchange._async_get_candle_history(pair, "5m", CandleType.SPOT, await exchange._async_get_candle_history(pair, "5m", CandleType.SPOT,
(arrow.utcnow().int_timestamp - 2000) * 1000) (arrow.utcnow().int_timestamp - 2000) * 1000)
exchange.close()
with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching ' with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching '
r'historical candle \(OHLCV\) data\..*'): r'historical candle \(OHLCV\) data\..*'):
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NotSupported("Not supported")) api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NotSupported("Not supported"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
await exchange._async_get_candle_history(pair, "5m", CandleType.SPOT, await exchange._async_get_candle_history(pair, "5m", CandleType.SPOT,
(arrow.utcnow().int_timestamp - 2000) * 1000) (arrow.utcnow().int_timestamp - 2000) * 1000)
exchange.close()
@pytest.mark.asyncio
async def test__async_kucoin_get_candle_history(default_conf, mocker, caplog): async def test__async_kucoin_get_candle_history(default_conf, mocker, caplog):
from freqtrade.exchange.common import _reset_logging_mixin from freqtrade.exchange.common import _reset_logging_mixin
_reset_logging_mixin() _reset_logging_mixin()
@ -2341,9 +2345,9 @@ async def test__async_kucoin_get_candle_history(default_conf, mocker, caplog):
# Expect the "returned exception" message 12 times (4 retries * 3 (loop)) # Expect the "returned exception" message 12 times (4 retries * 3 (loop))
assert num_log_has_re(msg, caplog) == 12 assert num_log_has_re(msg, caplog) == 12
assert num_log_has_re(msg2, caplog) == 9 assert num_log_has_re(msg2, caplog) == 9
exchange.close()
@pytest.mark.asyncio
async def test__async_get_candle_history_empty(default_conf, mocker, caplog): async def test__async_get_candle_history_empty(default_conf, mocker, caplog):
""" Test empty exchange result """ """ Test empty exchange result """
ohlcv = [] ohlcv = []
@ -2363,6 +2367,7 @@ async def test__async_get_candle_history_empty(default_conf, mocker, caplog):
assert res[2] == CandleType.SPOT assert res[2] == CandleType.SPOT
assert res[3] == ohlcv assert res[3] == ohlcv
assert exchange._api_async.fetch_ohlcv.call_count == 1 assert exchange._api_async.fetch_ohlcv.call_count == 1
exchange.close()
def test_refresh_latest_ohlcv_inv_result(default_conf, mocker, caplog): def test_refresh_latest_ohlcv_inv_result(default_conf, mocker, caplog):
@ -2757,7 +2762,6 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na
assert res_ohlcv[9][5] == 2.31452783 assert res_ohlcv[9][5] == 2.31452783
@pytest.mark.asyncio
@pytest.mark.parametrize("exchange_name", EXCHANGES) @pytest.mark.parametrize("exchange_name", EXCHANGES)
async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name, async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name,
fetch_trades_result): fetch_trades_result):
@ -2785,8 +2789,8 @@ async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name,
assert exchange._api_async.fetch_trades.call_args[1]['limit'] == 1000 assert exchange._api_async.fetch_trades.call_args[1]['limit'] == 1000
assert exchange._api_async.fetch_trades.call_args[1]['params'] == {'from': '123'} assert exchange._api_async.fetch_trades.call_args[1]['params'] == {'from': '123'}
assert log_has_re(f"Fetching trades for pair {pair}, params: .*", caplog) assert log_has_re(f"Fetching trades for pair {pair}, params: .*", caplog)
exchange.close()
exchange = Exchange(default_conf)
await async_ccxt_exception(mocker, default_conf, MagicMock(), await async_ccxt_exception(mocker, default_conf, MagicMock(),
"_async_fetch_trades", "fetch_trades", "_async_fetch_trades", "fetch_trades",
pair='ABCD/BTC', since=None) pair='ABCD/BTC', since=None)
@ -2796,15 +2800,16 @@ async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name,
api_mock.fetch_trades = MagicMock(side_effect=ccxt.BaseError("Unknown error")) api_mock.fetch_trades = MagicMock(side_effect=ccxt.BaseError("Unknown error"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
await exchange._async_fetch_trades(pair, since=(arrow.utcnow().int_timestamp - 2000) * 1000) await exchange._async_fetch_trades(pair, since=(arrow.utcnow().int_timestamp - 2000) * 1000)
exchange.close()
with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching ' with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching '
r'historical trade data\..*'): r'historical trade data\..*'):
api_mock.fetch_trades = MagicMock(side_effect=ccxt.NotSupported("Not supported")) api_mock.fetch_trades = MagicMock(side_effect=ccxt.NotSupported("Not supported"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
await exchange._async_fetch_trades(pair, since=(arrow.utcnow().int_timestamp - 2000) * 1000) await exchange._async_fetch_trades(pair, since=(arrow.utcnow().int_timestamp - 2000) * 1000)
exchange.close()
@pytest.mark.asyncio
@pytest.mark.parametrize("exchange_name", EXCHANGES) @pytest.mark.parametrize("exchange_name", EXCHANGES)
async def test__async_fetch_trades_contract_size(default_conf, mocker, caplog, exchange_name, async def test__async_fetch_trades_contract_size(default_conf, mocker, caplog, exchange_name,
fetch_trades_result): fetch_trades_result):
@ -2839,6 +2844,7 @@ async def test__async_fetch_trades_contract_size(default_conf, mocker, caplog, e
pair = 'ETH/USDT:USDT' pair = 'ETH/USDT:USDT'
res = await exchange._async_fetch_trades(pair, since=None, params=None) res = await exchange._async_fetch_trades(pair, since=None, params=None)
assert res[0][5] == 300 assert res[0][5] == 300
exchange.close()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -4807,7 +4813,6 @@ def test_load_leverage_tiers(mocker, default_conf, leverage_tiers, exchange_name
) )
@pytest.mark.asyncio
@pytest.mark.parametrize('exchange_name', EXCHANGES) @pytest.mark.parametrize('exchange_name', EXCHANGES)
async def test_get_market_leverage_tiers(mocker, default_conf, exchange_name): async def test_get_market_leverage_tiers(mocker, default_conf, exchange_name):
default_conf['exchange']['name'] = exchange_name default_conf['exchange']['name'] = exchange_name