exchange-data-manager/tests/test_config.py

172 lines
6.0 KiB
Python

"""Tests for configuration and wiring."""
import pytest
import tempfile
import os
from exchange_data_manager.config import Config, CacheConfig, DatabaseConfig
from exchange_data_manager.cache.manager import CacheManager
from exchange_data_manager.exchanges import CONNECTOR_REGISTRY, BinanceConnector
class TestCacheConfig:
"""Tests for CacheConfig dataclass."""
def test_default_values(self):
"""Test default configuration values."""
config = CacheConfig()
assert config.memory_max_candles == 100000
assert config.memory_ttl_seconds == 432000 # 5 days
assert config.time_tolerance_seconds == 5
assert config.count_tolerance == 1
assert config.fill_gaps is True
assert config.forward_fill_volume is True
def test_custom_values(self):
"""Test custom configuration values."""
config = CacheConfig(
memory_max_candles=50000,
memory_ttl_seconds=3600,
time_tolerance_seconds=10,
count_tolerance=2,
fill_gaps=False,
forward_fill_volume=False,
)
assert config.memory_max_candles == 50000
assert config.memory_ttl_seconds == 3600
assert config.time_tolerance_seconds == 10
assert config.count_tolerance == 2
assert config.fill_gaps is False
assert config.forward_fill_volume is False
class TestCacheManagerWiring:
"""Tests for CacheManager configuration wiring."""
def test_default_initialization(self):
"""Test CacheManager with default config (sync mode for testing)."""
manager = CacheManager(use_async_db=False)
assert manager.memory.max_candles == 100000
assert manager.memory.ttl_seconds == 432000
def test_config_wiring(self):
"""Test CacheManager uses provided config values."""
cache_config = CacheConfig(
memory_max_candles=50000,
memory_ttl_seconds=7200,
)
with tempfile.TemporaryDirectory() as tmpdir:
db_config = DatabaseConfig(path=os.path.join(tmpdir, "test.db"))
manager = CacheManager(
cache_config=cache_config,
database_config=db_config,
use_async_db=False,
)
assert manager.memory.max_candles == 50000
assert manager.memory.ttl_seconds == 7200
assert manager.database.db_path == os.path.join(tmpdir, "test.db")
def test_config_stored(self):
"""Test that config is stored for later use."""
cache_config = CacheConfig(
time_tolerance_seconds=10,
count_tolerance=5,
fill_gaps=False,
)
manager = CacheManager(cache_config=cache_config, use_async_db=False)
assert manager._cache_config.time_tolerance_seconds == 10
assert manager._cache_config.count_tolerance == 5
assert manager._cache_config.fill_gaps is False
class TestConfigLoad:
"""Tests for Config.load() method."""
def test_loads_config_file(self):
"""Test that Config.load() loads the config file."""
config = Config.load()
# Should load exchanges from config.yaml
assert "binance" in config.exchanges
# Binance should be enabled per config.yaml
assert config.exchanges["binance"].enabled is True
def test_default_fallback_without_file(self):
"""Test default config when no config file exists."""
# Load with explicit non-existent path to test defaults
config = Config.load("/nonexistent/path/config.yaml")
# Should fall back to default exchanges
assert "binance" in config.exchanges
assert "kucoin" in config.exchanges
assert "kraken" in config.exchanges
# Only implemented exchanges are enabled by default
assert config.exchanges["binance"].enabled is True
assert config.exchanges["kucoin"].enabled is False
assert config.exchanges["kraken"].enabled is False
def test_get_enabled_exchanges(self):
"""Test get_enabled_exchanges method."""
config = Config.load()
enabled = config.get_enabled_exchanges()
assert isinstance(enabled, list)
# Binance should be enabled per config.yaml
assert "binance" in enabled
# kucoin/kraken disabled in config.yaml
assert "kucoin" not in enabled
assert "kraken" not in enabled
class TestConnectorRegistry:
"""Tests for CONNECTOR_REGISTRY."""
def test_binance_registered(self):
"""Test that Binance connector is registered."""
assert "binance" in CONNECTOR_REGISTRY
assert CONNECTOR_REGISTRY["binance"] is BinanceConnector
def test_can_instantiate_connectors(self):
"""Test that registered connectors can be instantiated."""
for name, connector_class in CONNECTOR_REGISTRY.items():
connector = connector_class()
assert connector is not None
assert hasattr(connector, "fetch_candles")
class TestExchangeConfigWiring:
"""Tests for exchange config wiring to connectors."""
def test_connector_receives_config(self):
"""Test that connector receives ExchangeConfig."""
from exchange_data_manager.config import ExchangeConfig
ex_config = ExchangeConfig(enabled=True, rate_limit_ms=200)
connector = BinanceConnector(config=ex_config)
assert connector.config is ex_config
assert connector.rate_limit_ms == 200
def test_connector_default_rate_limit(self):
"""Test connector default rate limit when no config."""
connector = BinanceConnector()
assert connector.rate_limit_ms == 100 # Default
def test_ccxt_uses_rate_limit(self):
"""Test that ccxt client is configured with rate limit."""
from exchange_data_manager.config import ExchangeConfig
ex_config = ExchangeConfig(enabled=True, rate_limit_ms=250)
connector = BinanceConnector(config=ex_config)
# ccxt stores rateLimit in milliseconds
assert connector.client.rateLimit == 250