|
5 | 5 | from time import sleep |
6 | 6 | from unittest.mock import AsyncMock, MagicMock |
7 | 7 |
|
| 8 | +import pytest |
8 | 9 | from ccxt import NotSupported |
9 | 10 |
|
10 | 11 | from freqtrade.enums import CandleType |
| 12 | +from freqtrade.exceptions import TemporaryError |
11 | 13 | from freqtrade.exchange.exchange_ws import ExchangeWS |
12 | 14 | from ft_client.test_client.test_rest_client import log_has_re |
13 | 15 |
|
@@ -335,6 +337,68 @@ async def test_exchangews_get_ohlcv_missing_refresh_date(mocker, caplog): |
335 | 337 | exchange_ws.cleanup() |
336 | 338 |
|
337 | 339 |
|
| 340 | +def test_exchangews_ohlcvs_deepcopy_and_retry(mocker): |
| 341 | + config = MagicMock() |
| 342 | + ccxt_object = MagicMock() |
| 343 | + ccxt_object.ohlcvs = { |
| 344 | + "ETH/USDT": { |
| 345 | + "1m": [[1, 2, 3, 4, 5, 6]], |
| 346 | + } |
| 347 | + } |
| 348 | + mocker.patch("freqtrade.exchange.exchange_ws.ExchangeWS._start_forever", MagicMock()) |
| 349 | + |
| 350 | + exchange_ws = ExchangeWS(config, ccxt_object) |
| 351 | + |
| 352 | + call_count = {"count": 0} |
| 353 | + |
| 354 | + def deepcopy_side_effect(value): |
| 355 | + call_count["count"] += 1 |
| 356 | + if call_count["count"] < 3: |
| 357 | + raise RuntimeError("copy failed") |
| 358 | + return [candle.copy() for candle in value] |
| 359 | + |
| 360 | + mocker.patch("freqtrade.exchange.exchange_ws.deepcopy", deepcopy_side_effect) |
| 361 | + |
| 362 | + result = exchange_ws.ohlcvs("ETH/USDT", "1m") |
| 363 | + |
| 364 | + assert call_count["count"] == 3 |
| 365 | + assert result == [[1, 2, 3, 4, 5, 6]] |
| 366 | + assert result is not ccxt_object.ohlcvs["ETH/USDT"]["1m"] |
| 367 | + |
| 368 | + # Fail all the time |
| 369 | + mocker.patch("freqtrade.exchange.exchange_ws.deepcopy", side_effect=RuntimeError("copy failed")) |
| 370 | + with pytest.raises(TemporaryError, match=r"Error deepcopying: copy failed"): |
| 371 | + exchange_ws.ohlcvs("ETH/USDT", "1m") |
| 372 | + |
| 373 | + exchange_ws.cleanup() |
| 374 | + |
| 375 | + |
| 376 | +def test_exchangews_get_ohlcv_with_refresh(mocker): |
| 377 | + config = MagicMock() |
| 378 | + ccxt_object = MagicMock() |
| 379 | + mocker.patch("freqtrade.exchange.exchange_ws.ExchangeWS._start_forever", MagicMock()) |
| 380 | + |
| 381 | + exchange_ws = ExchangeWS(config, ccxt_object) |
| 382 | + ohlcvs_mock = mocker.patch.object( |
| 383 | + exchange_ws, "ohlcvs", return_value=[[10, 11, 12, 13, 14, 15]] |
| 384 | + ) |
| 385 | + |
| 386 | + paircomb = ("ETH/USDT", "1m", CandleType.SPOT) |
| 387 | + exchange_ws._klines_last_refresh[paircomb] = 123456789 |
| 388 | + |
| 389 | + candles, refresh = exchange_ws.get_ohlcv_with_refresh("ETH/USDT", "1m", CandleType.SPOT) |
| 390 | + |
| 391 | + ohlcvs_mock.assert_called_once_with("ETH/USDT", "1m") |
| 392 | + assert candles == [[10, 11, 12, 13, 14, 15]] |
| 393 | + assert refresh == 123456789 |
| 394 | + |
| 395 | + candles, refresh = exchange_ws.get_ohlcv_with_refresh("ETH/USDT", "5m", CandleType.SPOT) |
| 396 | + assert candles == [[10, 11, 12, 13, 14, 15]] |
| 397 | + assert refresh == 0 |
| 398 | + |
| 399 | + exchange_ws.cleanup() |
| 400 | + |
| 401 | + |
338 | 402 | def test_exchangews_continuous_stopped_task_exception(mocker, caplog): |
339 | 403 | config = MagicMock() |
340 | 404 | ccxt_object = MagicMock() |
|
0 commit comments