From 132f28ad44be07194ee68cda69a488c75d1b7b8b Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 16 Aug 2019 15:52:59 +0200 Subject: [PATCH] Add tests to correctly load / override pair-lists --- freqtrade/configuration/configuration.py | 21 ++++-- freqtrade/tests/test_configuration.py | 88 ++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index f7c393b60..cb698544d 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -4,6 +4,7 @@ This module contains the configuration class import logging import warnings from argparse import Namespace +from pathlib import Path from typing import Any, Callable, Dict, List, Optional from freqtrade import OperationalException, constants @@ -12,7 +13,7 @@ from freqtrade.configuration.create_datadir import create_datadir from freqtrade.configuration.json_schema import validate_config_schema from freqtrade.configuration.load_config import load_config_file from freqtrade.loggers import setup_logging -from freqtrade.misc import deep_merge_dicts +from freqtrade.misc import deep_merge_dicts, json_load from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -363,22 +364,28 @@ class Configuration(object): * whitelist from config """ - if "pairs" in self.args and self.args.pairs: + if "pairs" in config: return if "pairs_file" in self.args and self.args.pairs_file: - pairs_file = self.args.pairs_file + pairs_file = Path(self.args.pairs_file) logger.info(f'Reading pairs file "{pairs_file}".') # Download pairs from the pairs file if no config is specified # or if pairs file is specified explicitely if not pairs_file.exists(): - OperationalException(f'No pairs file found with path "{pairs_file}".') + raise OperationalException(f'No pairs file found with path "{pairs_file}".') - # with pairs_file.open() as file: - # pairs = list(set(json.load(file))) + config['pairs'] = json_load(pairs_file) - # pairs.sort() + config['pairs'].sort() + return if "config" in self.args: logger.info("Using pairlist from configuration.") config['pairs'] = config.get('exchange', {}).get('pair_whitelist') + else: + # Fall back to /dl_path/pairs.json + pairs_file = Path(config['datadir']) / "pairs.json" + if pairs_file.exists(): + config['pairs'] = json_load(pairs_file) + diff --git a/freqtrade/tests/test_configuration.py b/freqtrade/tests/test_configuration.py index 8cbd02ece..c351b9b72 100644 --- a/freqtrade/tests/test_configuration.py +++ b/freqtrade/tests/test_configuration.py @@ -704,3 +704,91 @@ def test_load_config_default_subkeys(all_conf, keys) -> None: validate_config_schema(all_conf) assert subkey in all_conf[key] assert all_conf[key][subkey] == keys[2] + + +def test_pairlist_resolving(): + arglist = [ + 'download-data', + '--pairs', 'ETH/BTC', 'XRP/BTC', + '--exchange', 'binance' + ] + + args = Arguments(arglist, '').get_parsed_arg() + + configuration = Configuration(args) + config = configuration.get_config() + + assert config['pairs'] == ['ETH/BTC', 'XRP/BTC'] + assert config['exchange']['name'] == 'binance' + + +def test_pairlist_resolving_with_config(mocker, default_conf): + patched_configuration_load_config_file(mocker, default_conf) + arglist = [ + '--config', 'config.json', + 'download-data', + ] + + args = Arguments(arglist, '').get_parsed_arg() + + configuration = Configuration(args) + config = configuration.get_config() + + assert config['pairs'] == default_conf['exchange']['pair_whitelist'] + assert config['exchange']['name'] == default_conf['exchange']['name'] + + # Override pairs + arglist = [ + '--config', 'config.json', + 'download-data', + '--pairs', 'ETH/BTC', 'XRP/BTC', + ] + + args = Arguments(arglist, '').get_parsed_arg() + + configuration = Configuration(args) + config = configuration.get_config() + + assert config['pairs'] == ['ETH/BTC', 'XRP/BTC'] + assert config['exchange']['name'] == default_conf['exchange']['name'] + + +def test_pairlist_resolving_with_config_pl(mocker, default_conf): + patched_configuration_load_config_file(mocker, default_conf) + load_mock = mocker.patch("freqtrade.configuration.configuration.json_load", + MagicMock(return_value=['XRP/BTC', 'ETH/BTC'])) + mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + + arglist = [ + '--config', 'config.json', + 'download-data', + '--pairs-file', 'pairs.json', + ] + + args = Arguments(arglist, '').get_parsed_arg() + + configuration = Configuration(args) + config = configuration.get_config() + + assert load_mock.call_count == 1 + assert config['pairs'] == ['ETH/BTC', 'XRP/BTC'] + assert config['exchange']['name'] == default_conf['exchange']['name'] + + +def test_pairlist_resolving_with_config_pl_not_exists(mocker, default_conf): + patched_configuration_load_config_file(mocker, default_conf) + mocker.patch("freqtrade.configuration.configuration.json_load", + MagicMock(return_value=['XRP/BTC', 'ETH/BTC'])) + mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + + arglist = [ + '--config', 'config.json', + 'download-data', + '--pairs-file', 'pairs.json', + ] + + args = Arguments(arglist, '').get_parsed_arg() + + with pytest.raises(OperationalException, match=r"No pairs file found with path.*"): + configuration = Configuration(args) + configuration.get_config()