use jsonschema regex pattern for whitelist format and enhance validation error messages (closes #120)
This commit is contained in:
parent
d88cc084e6
commit
cd5afd6ff4
@ -6,7 +6,8 @@ import os
|
||||
import time
|
||||
from typing import Any, Callable, List, Dict
|
||||
|
||||
from jsonschema import validate
|
||||
from jsonschema import validate, Draft4Validator
|
||||
from jsonschema.exceptions import best_match, ValidationError
|
||||
from wrapt import synchronized
|
||||
|
||||
from freqtrade import __version__
|
||||
@ -58,8 +59,14 @@ def load_config(path: str) -> Dict:
|
||||
if 'internals' not in conf:
|
||||
conf['internals'] = {}
|
||||
logger.info('Validating configuration ...')
|
||||
validate(conf, CONF_SCHEMA)
|
||||
return conf
|
||||
try:
|
||||
validate(conf, CONF_SCHEMA)
|
||||
return conf
|
||||
except ValidationError:
|
||||
logger.fatal('Configuration is not valid! See config.json.example')
|
||||
raise ValidationError(
|
||||
best_match(Draft4Validator(CONF_SCHEMA).iter_errors(conf)).message
|
||||
)
|
||||
|
||||
|
||||
def throttle(func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any:
|
||||
@ -218,7 +225,10 @@ CONF_SCHEMA = {
|
||||
'secret': {'type': 'string'},
|
||||
'pair_whitelist': {
|
||||
'type': 'array',
|
||||
'items': {'type': 'string'},
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9A-Z]+_[0-9A-Z]+$'
|
||||
},
|
||||
'uniqueItems': True
|
||||
}
|
||||
},
|
||||
|
@ -1,12 +1,15 @@
|
||||
# pragma pylint: disable=missing-docstring,C0103
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from argparse import Namespace
|
||||
from copy import deepcopy
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from jsonschema import ValidationError
|
||||
|
||||
from freqtrade.misc import throttle, parse_args, start_backtesting
|
||||
from freqtrade.misc import throttle, parse_args, start_backtesting, load_config
|
||||
|
||||
|
||||
def test_throttle():
|
||||
@ -119,3 +122,28 @@ def test_start_backtesting(mocker):
|
||||
main_call_args = pytest_mock.call_args[0][0]
|
||||
assert main_call_args[0] == '-s'
|
||||
assert main_call_args[1].endswith(os.path.join('freqtrade', 'tests', 'test_backtesting.py'))
|
||||
|
||||
|
||||
def test_load_config(default_conf, mocker):
|
||||
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
|
||||
read_data=json.dumps(default_conf)
|
||||
))
|
||||
validated_conf = load_config('somefile')
|
||||
assert file_mock.call_count == 1
|
||||
assert validated_conf.items() >= default_conf.items()
|
||||
|
||||
|
||||
def test_load_config_invalid_pair(default_conf, mocker):
|
||||
conf = deepcopy(default_conf)
|
||||
conf['exchange']['pair_whitelist'].append('BTC-ETH')
|
||||
mocker.patch('freqtrade.misc.open', mocker.mock_open(read_data=json.dumps(conf)))
|
||||
with pytest.raises(ValidationError, match=r'.*does not match.*'):
|
||||
load_config('somefile')
|
||||
|
||||
|
||||
def test_load_config_missing_attributes(default_conf, mocker):
|
||||
conf = deepcopy(default_conf)
|
||||
conf.pop('exchange')
|
||||
mocker.patch('freqtrade.misc.open', mocker.mock_open(read_data=json.dumps(conf)))
|
||||
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
|
||||
load_config('somefile')
|
||||
|
Loading…
Reference in New Issue
Block a user