integration tests no longer mock Blob, BlobManager and Session

This commit is contained in:
Lex Berezhny 2018-07-31 09:48:57 -04:00 committed by Jack Robison
parent bc24dbea29
commit f061ca2b15
No known key found for this signature in database
GPG key ID: DF25C68FE0239BB2
3 changed files with 91 additions and 124 deletions

View file

@ -130,7 +130,7 @@ class ComponentManager:
stages = self.sort_components() stages = self.sort_components()
for stage in stages: for stage in stages:
yield defer.DeferredList([_setup(component) for component in stage]) yield defer.DeferredList([_setup(component) for component in stage if not component.running])
@defer.inlineCallbacks @defer.inlineCallbacks
def stop(self): def stop(self):

View file

@ -221,7 +221,7 @@ class Daemon(AuthJSONRPCServer):
# TODO: delete these, get the components where needed # TODO: delete these, get the components where needed
self.storage = None self.storage = None
self.dht_node = None self.dht_node = None
self.wallet = None #self.wallet = None
self.sd_identifier = None self.sd_identifier = None
self.file_manager = None self.file_manager = None
self.exchange_rate_manager = None self.exchange_rate_manager = None
@ -237,6 +237,10 @@ class Daemon(AuthJSONRPCServer):
def ledger(self): def ledger(self):
return self.wallet.default_account.ledger return self.wallet.default_account.ledger
@property
def wallet(self):
return self.session.wallet
@defer.inlineCallbacks @defer.inlineCallbacks
def setup(self): def setup(self):
log.info("Starting lbrynet-daemon") log.info("Starting lbrynet-daemon")

View file

@ -1,27 +1,58 @@
import six
import tempfile import tempfile
import logging import logging
import asyncio
from types import SimpleNamespace from types import SimpleNamespace
from twisted.internet import defer from twisted.internet import defer
from orchstr8.testcase import IntegrationTestCase, d2f from orchstr8.testcase import IntegrationTestCase, d2f
from lbrynet.core.cryptoutils import get_lbry_hash_obj
import lbryschema import lbryschema
lbryschema.BLOCKCHAIN_NAME = 'lbrycrd_regtest' lbryschema.BLOCKCHAIN_NAME = 'lbrycrd_regtest'
from lbrynet import conf as lbry_conf from lbrynet import conf as lbry_conf
from lbrynet.dht.node import Node
from lbrynet.daemon.Daemon import Daemon from lbrynet.daemon.Daemon import Daemon
from lbrynet.wallet.manager import LbryWalletManager from lbrynet.wallet.manager import LbryWalletManager
from lbrynet.daemon.Components import WalletComponent, FileManagerComponent, SessionComponent, DatabaseComponent from lbrynet.daemon.Components import WalletComponent, DHTComponent, HashAnnouncerComponent, ExchangeRateManagerComponent
from lbrynet.daemon.Components import REFLECTOR_COMPONENT, HASH_ANNOUNCER_COMPONENT, EXCHANGE_RATE_MANAGER_COMPONENT
from lbrynet.daemon.Components import UPNP_COMPONENT
from lbrynet.daemon.ComponentManager import ComponentManager from lbrynet.daemon.ComponentManager import ComponentManager
from lbrynet.file_manager.EncryptedFileManager import EncryptedFileManager
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class FakeDHT(DHTComponent):
def start(self):
self.dht_node = Node()
class FakeExchangeRateComponent(ExchangeRateManagerComponent):
def start(self):
self.exchange_rate_manager = SimpleNamespace()
def stop(self):
pass
class FakeHashAnnouncerComponent(HashAnnouncerComponent):
def start(self):
self.hash_announcer = SimpleNamespace()
def stop(self):
pass
class FakeAnalytics: class FakeAnalytics:
@property
def is_started(self):
return True
def send_new_channel(self): def send_new_channel(self):
pass pass
@ -32,52 +63,6 @@ class FakeAnalytics:
pass pass
class FakeBlob:
def __init__(self):
self.data = []
self.blob_hash = 'abc'
self.length = 3
def write(self, data):
self.data.append(data)
def close(self):
if self.data:
h = get_lbry_hash_obj()
h.update(b'hi')
return defer.succeed(h.hexdigest())
return defer.succeed(None)
def get_is_verified(self):
return True
def open_for_reading(self):
return six.StringIO('foo')
class FakeBlobManager:
def get_blob_creator(self):
return FakeBlob()
def creator_finished(self, blob_info, should_announce):
pass
def get_blob(self, sd_hash):
return FakeBlob()
class FakeSession:
blob_manager = FakeBlobManager()
peer_finder = None
rate_limiter = None
@property
def payment_rate_manager(self):
obj = SimpleNamespace()
obj.min_blob_data_payment_rate = 1
return obj
class CommandTestCase(IntegrationTestCase): class CommandTestCase(IntegrationTestCase):
WALLET_MANAGER = LbryWalletManager WALLET_MANAGER = LbryWalletManager
@ -95,6 +80,7 @@ class CommandTestCase(IntegrationTestCase):
lbry_conf.settings['lbryum_wallet_dir'] = self.stack.wallet.data_path lbry_conf.settings['lbryum_wallet_dir'] = self.stack.wallet.data_path
lbry_conf.settings['download_directory'] = self.stack.wallet.data_path lbry_conf.settings['download_directory'] = self.stack.wallet.data_path
lbry_conf.settings['use_upnp'] = False lbry_conf.settings['use_upnp'] = False
lbry_conf.settings['reflect_uploads'] = False
lbry_conf.settings['blockchain_name'] = 'lbrycrd_regtest' lbry_conf.settings['blockchain_name'] = 'lbrycrd_regtest'
lbry_conf.settings['lbryum_servers'] = [('localhost', 50001)] lbry_conf.settings['lbryum_servers'] = [('localhost', 50001)]
lbry_conf.settings['known_dht_nodes'] = [] lbry_conf.settings['known_dht_nodes'] = []
@ -105,136 +91,113 @@ class CommandTestCase(IntegrationTestCase):
sendtxid = await self.blockchain.send_to_address(address, 10) sendtxid = await self.blockchain.send_to_address(address, 10)
await self.confirm_tx(sendtxid) await self.confirm_tx(sendtxid)
def wallet_maker(component_manager):
self.wallet_component = WalletComponent(component_manager)
self.wallet_component.wallet = self.manager
self.wallet_component._running = True
return self.wallet_component
analytics_manager = FakeAnalytics() analytics_manager = FakeAnalytics()
self.daemon = Daemon(analytics_manager, ComponentManager(analytics_manager, skip_components=[ self.daemon = Daemon(analytics_manager, ComponentManager(
'wallet', 'database', 'session', 'file_manager' analytics_manager,
])) skip_components=[
#UPNP_COMPONENT,
REFLECTOR_COMPONENT,
#HASH_ANNOUNCER_COMPONENT,
#EXCHANGE_RATE_MANAGER_COMPONENT
],
dht=FakeDHT, wallet=wallet_maker,
hash_announcer=FakeHashAnnouncerComponent,
exchange_rate_manager=FakeExchangeRateComponent
))
await d2f(self.daemon.setup())
self.manager.old_db = self.daemon.session.storage
wallet_component = WalletComponent(self.daemon.component_manager) async def tearDown(self):
wallet_component.wallet = self.manager await super().tearDown()
wallet_component._running = True self.wallet_component._running = False
self.daemon.wallet = self.manager await d2f(self.daemon._shutdown())
self.daemon.component_manager.components.add(wallet_component)
storage_component = DatabaseComponent(self.daemon.component_manager)
await d2f(storage_component.start())
self.daemon.storage = storage_component.storage
self.daemon.wallet.old_db = self.daemon.storage
self.daemon.component_manager.components.add(storage_component)
session_component = SessionComponent(self.daemon.component_manager)
session_component.session = FakeSession()
session_component._running = True
self.daemon.session = session_component.session
self.daemon.session.storage = self.daemon.storage
self.daemon.session.wallet = self.daemon.wallet
self.daemon.session.blob_manager.storage = self.daemon.storage
self.daemon.component_manager.components.add(session_component)
file_manager = FileManagerComponent(self.daemon.component_manager)
file_manager.file_manager = EncryptedFileManager(session_component.session, True)
file_manager._running = True
self.daemon.file_manager = file_manager.file_manager
self.daemon.component_manager.components.add(file_manager)
async def confirm_tx(self, txid): async def confirm_tx(self, txid):
""" Wait for tx to be in mempool, then generate a block, wait for tx to be in a block. """ """ Wait for tx to be in mempool, then generate a block, wait for tx to be in a block. """
log.debug(
'Waiting on %s to be in mempool. (current height: %s, expected height: %s)',
txid, self.ledger.headers.height, self.blockchain._block_expected
)
await self.on_transaction_id(txid) await self.on_transaction_id(txid)
log.debug(
'%s is in mempool. (current height: %s, expected height: %s)',
txid, self.ledger.headers.height, self.blockchain._block_expected
)
await self.generate(1) await self.generate(1)
log.debug(
'Waiting on %s to be in block. (current height: %s, expected height: %s)',
txid, self.ledger.headers.height, self.blockchain._block_expected
)
await self.on_transaction_id(txid) await self.on_transaction_id(txid)
log.debug(
'%s is in a block. (current height: %s, expected height: %s)', def d_confirm_tx(self, txid):
txid, self.ledger.headers.height, self.blockchain._block_expected return defer.Deferred.fromFuture(asyncio.ensure_future(self.confirm_tx(txid)))
)
async def generate(self, blocks): async def generate(self, blocks):
""" Ask lbrycrd to generate some blocks and wait until ledger has them. """ """ Ask lbrycrd to generate some blocks and wait until ledger has them. """
log.info(
'Generating %s blocks. (current height: %s)',
blocks, self.ledger.headers.height
)
await self.blockchain.generate(blocks) await self.blockchain.generate(blocks)
await self.ledger.on_header.where(self.blockchain.is_expected_block) await self.ledger.on_header.where(self.blockchain.is_expected_block)
log.info(
"Headers up to date. (current height: %s, expected height: %s)", def d_generate(self, blocks):
self.ledger.headers.height, self.blockchain._block_expected return defer.Deferred.fromFuture(asyncio.ensure_future(self.generate(blocks)))
)
class CommonWorkflowTests(CommandTestCase): class CommonWorkflowTests(CommandTestCase):
VERBOSE = False VERBOSE = False
async def test_user_creating_channel_and_publishing_file(self): @defer.inlineCallbacks
def test_user_creating_channel_and_publishing_file(self):
# User checks their balance. # User checks their balance.
result = await d2f(self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)) result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
self.assertEqual(result, 10) self.assertEqual(result, 10)
# Decides to get a cool new channel. # Decides to get a cool new channel.
channel = await d2f(self.daemon.jsonrpc_channel_new('@spam', 1)) channel = yield self.daemon.jsonrpc_channel_new('@spam', 1)
self.assertTrue(channel['success']) self.assertTrue(channel['success'])
await self.confirm_tx(channel['txid']) yield self.d_confirm_tx(channel['txid'])
# Check balance, include utxos with less than 6 confirmations (unconfirmed). # Check balance, include utxos with less than 6 confirmations (unconfirmed).
result = await d2f(self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)) result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
self.assertEqual(result, 8.99) self.assertEqual(result, 8.99)
# Check confirmed balance, only includes utxos with 6+ confirmations. # Check confirmed balance, only includes utxos with 6+ confirmations.
result = await d2f(self.daemon.jsonrpc_wallet_balance()) result = yield self.daemon.jsonrpc_wallet_balance()
self.assertEqual(result, 0) self.assertEqual(result, 0)
# Add some confirmations (there is already 1 confirmation, so we add 5 to equal 6 total). # Add some confirmations (there is already 1 confirmation, so we add 5 to equal 6 total).
await self.generate(5) yield self.d_generate(5)
# Check balance again after some confirmations, should be correct again. # Check balance again after some confirmations, should be correct again.
result = await d2f(self.daemon.jsonrpc_wallet_balance()) result = yield self.daemon.jsonrpc_wallet_balance()
self.assertEqual(result, 8.99) self.assertEqual(result, 8.99)
# Now lets publish a hello world file to the channel. # Now lets publish a hello world file to the channel.
with tempfile.NamedTemporaryFile() as file: with tempfile.NamedTemporaryFile() as file:
file.write(b'hello world!') file.write(b'hello world!')
file.flush() file.flush()
claim = await d2f(self.daemon.jsonrpc_publish( claim = yield self.daemon.jsonrpc_publish(
'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id'] 'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id']
)) )
self.assertTrue(claim['success']) self.assertTrue(claim['success'])
await self.confirm_tx(claim['txid']) yield self.d_confirm_tx(claim['txid'])
# Check unconfirmed balance. # Check unconfirmed balance.
result = await d2f(self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)) result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
self.assertEqual(round(result, 2), 7.97) self.assertEqual(round(result, 2), 7.97)
# Resolve our claim. # Resolve our claim.
response = await d2f(self.ledger.resolve(0, 10, 'lbry://@spam/hovercraft')) response = yield self.ledger.resolve(0, 10, 'lbry://@spam/hovercraft')
self.assertIn('lbry://@spam/hovercraft', response) self.assertIn('lbry://@spam/hovercraft', response)
# A few confirmations before trying to spend again. # A few confirmations before trying to spend again.
await self.generate(5) yield self.d_generate(5)
# Verify confirmed balance. # Verify confirmed balance.
result = await d2f(self.daemon.jsonrpc_wallet_balance()) result = yield self.daemon.jsonrpc_wallet_balance()
self.assertEqual(round(result, 2), 7.97) self.assertEqual(round(result, 2), 7.97)
# Now lets update an existing claim. # Now lets update an existing claim.
return
with tempfile.NamedTemporaryFile() as file: with tempfile.NamedTemporaryFile() as file:
file.write(b'hello world x2!') file.write(b'hello world x2!')
file.flush() file.flush()
claim = await d2f(self.daemon.jsonrpc_publish( claim = yield self.daemon.jsonrpc_publish(
'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id'] 'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id']
)) )
self.assertTrue(claim['success']) self.assertTrue(claim['success'])
await self.confirm_tx(claim['txid']) yield self.d_confirm_tx(claim['txid'])