From 3c67bb90d711bbe88a68f4c5bf5f9713757448bd Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Tue, 4 May 2021 01:40:57 -0300 Subject: [PATCH] don't fail when a single one go on maintenance and set completion event regardless of failures --- lbry/extras/daemon/exchange_rate_manager.py | 3 +- .../other/test_exchange_rate_manager.py | 29 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lbry/extras/daemon/exchange_rate_manager.py b/lbry/extras/daemon/exchange_rate_manager.py index 283f6979b..bb6228796 100644 --- a/lbry/extras/daemon/exchange_rate_manager.py +++ b/lbry/extras/daemon/exchange_rate_manager.py @@ -79,7 +79,6 @@ class MarketFeed: log.debug("Saving rate update %f for %s from %s", rate, self.market, self.name) self.rate = ExchangeRate(self.market, rate, int(time.time())) self.last_check = time.time() - self.event.set() return self.rate except asyncio.CancelledError: raise @@ -95,6 +94,8 @@ class MarketFeed: log.warning("Error trying to connect to exchange rate %s: %s", self.name, str(e)) except Exception as e: log.exception("Exchange rate error (%s from %s):", self.market, self.name) + finally: + self.event.set() async def keep_updated(self): while True: diff --git a/tests/integration/other/test_exchange_rate_manager.py b/tests/integration/other/test_exchange_rate_manager.py index c8346f8ee..6f584bfc7 100644 --- a/tests/integration/other/test_exchange_rate_manager.py +++ b/tests/integration/other/test_exchange_rate_manager.py @@ -1,6 +1,8 @@ +import asyncio +import logging from decimal import Decimal from lbry.testcase import AsyncioTestCase -from lbry.extras.daemon.exchange_rate_manager import ExchangeRate, ExchangeRateManager, FEEDS +from lbry.extras.daemon.exchange_rate_manager import ExchangeRate, ExchangeRateManager, FEEDS, MarketFeed class TestExchangeRateManager(AsyncioTestCase): @@ -12,13 +14,32 @@ class TestExchangeRateManager(AsyncioTestCase): self.assertFalse(feed.is_online) self.assertIsNone(feed.rate) await manager.wait() + failures = set() for feed in manager.market_feeds: - self.assertTrue(feed.is_online) - self.assertIsInstance(feed.rate, ExchangeRate) - # print(f'{feed.name} - {feed.market} - {feed.rate.spot}') + if feed.is_online: + self.assertIsInstance(feed.rate, ExchangeRate) + else: + failures.add(feed.name) + self.assertFalse(feed.has_rate) + self.assertLessEqual(len(failures), 1, f"feed failures: {failures}. Please check exchange rate feeds!") lbc = manager.convert_currency('USD', 'LBC', Decimal('1.0')) self.assertGreaterEqual(lbc, 2.0) self.assertLessEqual(lbc, 10.0) lbc = manager.convert_currency('BTC', 'LBC', Decimal('0.01')) self.assertGreaterEqual(lbc, 1_000) self.assertLessEqual(lbc, 4_000) + + async def test_it_handles_feed_being_offline(self): + class FakeFeed(MarketFeed): + name = "fake" + url = "http://impossi.bru" + manager = ExchangeRateManager((FakeFeed,)) + manager.start() + self.addCleanup(manager.stop) + for feed in manager.market_feeds: + self.assertFalse(feed.is_online) + self.assertIsNone(feed.rate) + await asyncio.wait_for(manager.wait(), 2) + for feed in manager.market_feeds: + self.assertFalse(feed.is_online) + self.assertFalse(feed.has_rate)