From 6389e86ed68c42425c456fe3c8373436be78f71c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 13 Mar 2021 15:36:34 +0100 Subject: [PATCH] Add test for uvloop fix --- tests/conftest.py | 12 +++++++++-- tests/exchange/test_exchange.py | 10 +-------- tests/rpc/test_rpc_apiserver.py | 38 ++++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 498d65b0a..75632e4c7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,7 @@ from copy import deepcopy from datetime import datetime from functools import reduce from pathlib import Path -from unittest.mock import MagicMock, PropertyMock +from unittest.mock import MagicMock, Mock, PropertyMock import arrow import numpy as np @@ -64,6 +64,14 @@ def get_args(args): return Arguments(args).get_parsed_arg() +# Source: https://stackoverflow.com/questions/29881236/how-to-mock-asyncio-coroutines +def get_mock_coro(return_value): + async def mock_coro(*args, **kwargs): + return return_value + + return Mock(wraps=mock_coro) + + def patched_configuration_load_config_file(mocker, config) -> None: mocker.patch( 'freqtrade.configuration.configuration.load_config_file', @@ -1736,7 +1744,7 @@ def import_fails() -> None: realimport = builtins.__import__ def mockedimport(name, *args, **kwargs): - if name in ["filelock", 'systemd.journal']: + if name in ["filelock", 'systemd.journal', 'uvloop']: raise ImportError(f"No module named '{name}'") return realimport(name, *args, **kwargs) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 75db2de26..3fd566fa3 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -18,21 +18,13 @@ from freqtrade.exchange.exchange import (market_is_active, timeframe_to_minutes, timeframe_to_next_date, timeframe_to_prev_date, timeframe_to_seconds) from freqtrade.resolvers.exchange_resolver import ExchangeResolver -from tests.conftest import get_patched_exchange, log_has, log_has_re +from tests.conftest import get_mock_coro, get_patched_exchange, log_has, log_has_re # Make sure to always keep one exchange here which is NOT subclassed!! EXCHANGES = ['bittrex', 'binance', 'kraken', 'ftx'] -# Source: https://stackoverflow.com/questions/29881236/how-to-mock-asyncio-coroutines -def get_mock_coro(return_value): - async def mock_coro(*args, **kwargs): - return return_value - - return Mock(wraps=mock_coro) - - def ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, fun, mock_ccxt_fun, retries=API_RETRY_COUNT + 1, **kwargs): diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 8590e0d21..01492b4f2 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -23,8 +23,8 @@ from freqtrade.rpc.api_server import ApiServer from freqtrade.rpc.api_server.api_auth import create_token, get_user_from_token from freqtrade.rpc.api_server.uvicorn_threaded import UvicornServer from freqtrade.state import RunMode, State -from tests.conftest import (create_mock_trades, get_patched_freqtradebot, log_has, log_has_re, - patch_get_signal) +from tests.conftest import (create_mock_trades, get_mock_coro, get_patched_freqtradebot, log_has, + log_has_re, patch_get_signal) BASE_URI = "/api/v1" @@ -230,7 +230,7 @@ def test_api__init__(default_conf, mocker): assert apiserver._config == default_conf -def test_api_UvicornServer(default_conf, mocker): +def test_api_UvicornServer(mocker): thread_mock = mocker.patch('freqtrade.rpc.api_server.uvicorn_threaded.threading.Thread') s = UvicornServer(uvicorn.Config(MagicMock(), port=8080, host='127.0.0.1')) assert thread_mock.call_count == 0 @@ -248,6 +248,38 @@ def test_api_UvicornServer(default_conf, mocker): assert s.should_exit is True +def test_api_UvicornServer_run(mocker): + serve_mock = mocker.patch('freqtrade.rpc.api_server.uvicorn_threaded.UvicornServer.serve', + get_mock_coro(None)) + s = UvicornServer(uvicorn.Config(MagicMock(), port=8080, host='127.0.0.1')) + assert serve_mock.call_count == 0 + + s.install_signal_handlers() + # Original implementation starts a thread - make sure that's not the case + assert serve_mock.call_count == 0 + + # Fake started to avoid sleeping forever + s.started = True + s.run() + assert serve_mock.call_count == 1 + + +def test_api_UvicornServer_run_no_uvloop(mocker, import_fails): + serve_mock = mocker.patch('freqtrade.rpc.api_server.uvicorn_threaded.UvicornServer.serve', + get_mock_coro(None)) + s = UvicornServer(uvicorn.Config(MagicMock(), port=8080, host='127.0.0.1')) + assert serve_mock.call_count == 0 + + s.install_signal_handlers() + # Original implementation starts a thread - make sure that's not the case + assert serve_mock.call_count == 0 + + # Fake started to avoid sleeping forever + s.started = True + s.run() + assert serve_mock.call_count == 1 + + def test_api_run(default_conf, mocker, caplog): default_conf.update({"api_server": {"enabled": True, "listen_ip_address": "127.0.0.1",