diff --git a/lbrynet/tests/mocks.py b/lbrynet/tests/mocks.py index c8e131362..49114610d 100644 --- a/lbrynet/tests/mocks.py +++ b/lbrynet/tests/mocks.py @@ -1,5 +1,6 @@ import base64 import io +import mock from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa @@ -10,6 +11,7 @@ from twisted.python.failure import Failure from lbrynet.core.client.ClientRequest import ClientRequest from lbrynet.core.Error import RequestCanceledError from lbrynet.core import BlobAvailability +from lbrynet.file_manager.EncryptedFileManager import EncryptedFileManager from lbrynet.dht.node import Node as RealNode from lbrynet.daemon import ExchangeRateManager as ERM from lbrynet import conf @@ -63,6 +65,7 @@ class BTCLBCFeed(ERM.MarketFeed): 0.0 ) + class USDBTCFeed(ERM.MarketFeed): def __init__(self): ERM.MarketFeed.__init__( @@ -74,6 +77,7 @@ class USDBTCFeed(ERM.MarketFeed): 0.0 ) + class ExchangeRateManager(ERM.ExchangeRateManager): def __init__(self, market_feeds, rates): self.market_feeds = market_feeds @@ -360,6 +364,96 @@ class BlobAvailabilityTracker(BlobAvailability.BlobAvailabilityTracker): pass +# The components below viz. FakeWallet, FakeSession, FakeFileManager are just for testing Component Manager's +# startup and stop +class FakeComponent(object): + depends_on = [] + component_name = None + + def __init__(self, component_manager): + self.component_manager = component_manager + self._running = False + + @property + def running(self): + return self._running + + def start(self): + raise NotImplementedError # Override + + def stop(self): + return defer.succeed(None) + + @property + def component(self): + return self + + @defer.inlineCallbacks + def _setup(self): + result = yield defer.maybeDeferred(self.start) + self._running = True + defer.returnValue(result) + + @defer.inlineCallbacks + def _stop(self): + result = yield defer.maybeDeferred(self.stop) + self._running = False + defer.returnValue(result) + + +class FakeDelayedWallet(FakeComponent): + component_name = "wallet" + depends_on = [] + + def start(self): + return defer.succeed(True) + + def stop(self): + d = defer.Deferred() + self.component_manager.reactor.callLater(1, d.callback, True) + return d + + +class FakeDelayedSession(FakeComponent): + component_name = "session" + depends_on = [FakeDelayedWallet.component_name] + + def start(self): + d = defer.Deferred() + self.component_manager.reactor.callLater(1, d.callback, True) + return d + + def stop(self): + d = defer.Deferred() + self.component_manager.reactor.callLater(1, d.callback, True) + return d + + +class FakeDelayedFileManager(FakeComponent): + component_name = "file_manager" + depends_on = [FakeDelayedSession.component_name] + + def start(self): + d = defer.Deferred() + self.component_manager.reactor.callLater(1, d.callback, True) + return d + + def stop(self): + return defer.succeed(True) + +class FakeFileManager(FakeComponent): + component_name = "file_manager" + depends_on = [] + + @property + def component(self): + return mock.Mock(spec=EncryptedFileManager) + + def start(self): + return defer.succeed(True) + + def stop(self): + pass create_stream_sd_file = { 'stream_name': '746573745f66696c65', diff --git a/lbrynet/tests/unit/components/__init__.py b/lbrynet/tests/unit/components/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/lbrynet/tests/unit/components/test_Component_Manager.py b/lbrynet/tests/unit/components/test_Component_Manager.py new file mode 100644 index 000000000..504b12ac8 --- /dev/null +++ b/lbrynet/tests/unit/components/test_Component_Manager.py @@ -0,0 +1,133 @@ +from twisted.internet.task import Clock +from twisted.trial import unittest + +from lbrynet.daemon.ComponentManager import ComponentManager +from lbrynet.daemon.Components import DATABASE_COMPONENT, DHT_COMPONENT, STREAM_IDENTIFIER_COMPONENT +from lbrynet.daemon.Components import HASH_ANNOUNCER_COMPONENT, REFLECTOR_COMPONENT, UPNP_COMPONENT +from lbrynet.daemon.Components import PEER_PROTOCOL_SERVER_COMPONENT, EXCHANGE_RATE_MANAGER_COMPONENT +from lbrynet.daemon import Components +from lbrynet.tests import mocks + + +class TestComponentManager(unittest.TestCase): + def setUp(self): + mocks.mock_conf_settings(self) + self.default_components_sort = [ + [Components.DatabaseComponent, + Components.ExchangeRateManagerComponent, + Components.UPnPComponent], + [Components.DHTComponent, + Components.WalletComponent], + [Components.HashAnnouncerComponent], + [Components.SessionComponent], + [Components.PeerProtocolServerComponent, + Components.StreamIdentifierComponent], + [Components.FileManagerComponent], + [Components.ReflectorComponent] + ] + self.component_manager = ComponentManager() + + def tearDown(self): + pass + + def test_sort_components(self): + stages = self.component_manager.sort_components() + + for stage_list, sorted_stage_list in zip(stages, self.default_components_sort): + self.assertEqual([type(stage) for stage in stage_list], sorted_stage_list) + + def test_sort_components_reverse(self): + rev_stages = self.component_manager.sort_components(reverse=True) + reverse_default_components_sort = reversed(self.default_components_sort) + + for stage_list, sorted_stage_list in zip(rev_stages, reverse_default_components_sort): + self.assertEqual([type(stage) for stage in stage_list], sorted_stage_list) + + def test_get_component_not_exists(self): + + with self.assertRaises(NameError): + self.component_manager.get_component("random_component") + + +class TestComponentManagerOverrides(unittest.TestCase): + def setUp(self): + mocks.mock_conf_settings(self) + + def test_init_with_overrides(self): + class FakeWallet(object): + component_name = "wallet" + depends_on = [] + + def __init__(self, component_manager): + self.component_manager = component_manager + + @property + def component(self): + return self + + new_component_manager = ComponentManager(wallet=FakeWallet) + fake_wallet = new_component_manager.get_component("wallet") + # wallet should be an instance of FakeWallet and not WalletComponent from Components.py + self.assertIsInstance(fake_wallet, FakeWallet) + self.assertNotIsInstance(fake_wallet, Components.WalletComponent) + + def test_init_with_wrong_overrides(self): + class FakeRandomComponent(object): + component_name = "someComponent" + depends_on = [] + + with self.assertRaises(SyntaxError): + ComponentManager(randomComponent=FakeRandomComponent) + + +class TestComponentManagerProperStart(unittest.TestCase): + def setUp(self): + self.reactor = Clock() + mocks.mock_conf_settings(self) + self.component_manager = ComponentManager( + skip_components=[DATABASE_COMPONENT, DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, STREAM_IDENTIFIER_COMPONENT, + PEER_PROTOCOL_SERVER_COMPONENT, REFLECTOR_COMPONENT, UPNP_COMPONENT, + EXCHANGE_RATE_MANAGER_COMPONENT], + reactor=self.reactor, + wallet=mocks.FakeDelayedWallet, + session=mocks.FakeDelayedSession, + file_manager=mocks.FakeDelayedFileManager + ) + + def tearDown(self): + pass + + def test_proper_starting_of_components(self): + self.component_manager.setup() + self.assertTrue(self.component_manager.get_component('wallet').running) + self.assertFalse(self.component_manager.get_component('session').running) + self.assertFalse(self.component_manager.get_component('file_manager').running) + + self.reactor.advance(1) + self.assertTrue(self.component_manager.get_component('wallet').running) + self.assertTrue(self.component_manager.get_component('session').running) + self.assertFalse(self.component_manager.get_component('file_manager').running) + + self.reactor.advance(1) + self.assertTrue(self.component_manager.get_component('wallet').running) + self.assertTrue(self.component_manager.get_component('session').running) + self.assertTrue(self.component_manager.get_component('file_manager').running) + + def test_proper_stopping_of_components(self): + self.component_manager.setup() + self.reactor.advance(1) + self.reactor.advance(1) + self.component_manager.stop() + self.assertFalse(self.component_manager.get_component('file_manager').running) + self.assertTrue(self.component_manager.get_component('session').running) + self.assertTrue(self.component_manager.get_component('wallet').running) + + self.reactor.advance(1) + self.assertFalse(self.component_manager.get_component('file_manager').running) + self.assertFalse(self.component_manager.get_component('session').running) + self.assertTrue(self.component_manager.get_component('wallet').running) + + self.reactor.advance(1) + self.assertFalse(self.component_manager.get_component('file_manager').running) + self.assertFalse(self.component_manager.get_component('session').running) + self.assertFalse(self.component_manager.get_component('wallet').running)