bigchaindb/tests/commands/test_commands.py

379 lines
13 KiB
Python
Raw Normal View History

2016-04-07 14:31:34 +02:00
import json
2016-04-26 00:37:35 +02:00
from unittest.mock import Mock, patch
from argparse import Namespace
2016-02-14 17:18:41 +01:00
import pytest
@pytest.mark.tendermint
2016-09-21 00:46:48 +02:00
def test_make_sure_we_dont_remove_any_command():
# thanks to: http://stackoverflow.com/a/18161115/597097
from bigchaindb.commands.bigchaindb import create_parser
2016-09-21 14:10:04 +02:00
2016-09-21 00:46:48 +02:00
parser = create_parser()
assert parser.parse_args(['configure', 'localmongodb']).command
2016-09-21 00:46:48 +02:00
assert parser.parse_args(['show-config']).command
assert parser.parse_args(['init']).command
assert parser.parse_args(['drop']).command
assert parser.parse_args(['start']).command
assert parser.parse_args(['upsert-validator', 'TEMP_PUB_KEYPAIR', '10']).command
2016-09-21 00:46:48 +02:00
@pytest.mark.tendermint
2016-09-21 00:46:48 +02:00
@patch('bigchaindb.commands.utils.start')
def test_main_entrypoint(mock_start):
from bigchaindb.commands.bigchaindb import main
2016-09-21 00:46:48 +02:00
main()
assert mock_start.called
2017-03-13 17:55:11 +01:00
def test_bigchain_run_start(mock_run_configure,
mock_processes_start,
mock_db_init_with_existing_db,
mocked_setup_logging):
from bigchaindb import config
from bigchaindb.commands.bigchaindb import run_start
args = Namespace(config=None, yes=True,
2017-11-07 11:11:55 +01:00
skip_initialize_database=False)
2016-04-26 00:37:35 +02:00
run_start(args)
mocked_setup_logging.assert_called_once_with(user_log_config=config['log'])
2016-04-26 00:37:35 +02:00
2016-02-14 19:46:30 +01:00
# TODO Please beware, that if debugging, the "-s" switch for pytest will
# interfere with capsys.
# See related issue: https://github.com/pytest-dev/pytest/issues/128
@pytest.mark.tendermint
@pytest.mark.usefixtures('ignore_local_config_file')
def test_bigchain_show_config(capsys):
from bigchaindb.commands.bigchaindb import run_show_config
2016-04-12 16:23:09 +02:00
2016-02-14 19:46:30 +01:00
args = Namespace(config=None)
_, _ = capsys.readouterr()
run_show_config(args)
2016-04-12 16:23:09 +02:00
output_config = json.loads(capsys.readouterr()[0])
# Note: This test passed previously because we were always
# using the default configuration parameters, but since we
# are running with docker-compose now and expose parameters like
# BIGCHAINDB_SERVER_BIND, BIGCHAINDB_WSSERVER_HOST, BIGCHAINDB_WSSERVER_ADVERTISED_HOST
# the default comparison fails i.e. when config is imported at the beginning the
# dict returned is different that what is expected after run_show_config
# and run_show_config updates the bigchaindb.config
from bigchaindb import config
del config['CONFIGURED']
2016-04-12 16:23:09 +02:00
config['keypair']['private'] = 'x' * 45
assert output_config == config
2016-02-14 20:05:16 +01:00
@pytest.mark.tendermint
def test_bigchain_run_init_when_db_exists(mocker, capsys):
from bigchaindb.commands.bigchaindb import run_init
from bigchaindb.common.exceptions import DatabaseAlreadyExists
init_db_mock = mocker.patch(
'bigchaindb.commands.bigchaindb.schema.init_database',
autospec=True,
spec_set=True,
)
init_db_mock.side_effect = DatabaseAlreadyExists
2016-02-14 20:05:16 +01:00
args = Namespace(config=None)
run_init(args)
output_message = capsys.readouterr()[1]
print(output_message)
assert output_message == (
'The database already exists.\n'
'If you wish to re-initialize it, first drop it.\n'
)
2016-02-14 20:30:50 +01:00
@pytest.mark.tendermint
2017-04-12 16:12:41 +02:00
def test__run_init(mocker):
from bigchaindb.commands.bigchaindb import _run_init
bigchain_mock = mocker.patch(
'bigchaindb.commands.bigchaindb.bigchaindb.Bigchain')
init_db_mock = mocker.patch(
'bigchaindb.commands.bigchaindb.schema.init_database',
autospec=True,
spec_set=True,
)
_run_init()
bigchain_mock.assert_called_once_with()
init_db_mock.assert_called_once_with(
connection=bigchain_mock.return_value.connection)
@pytest.mark.tendermint
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
def test_drop_db_when_assumed_yes(mock_db_drop):
from bigchaindb.commands.bigchaindb import run_drop
2016-02-14 20:30:50 +01:00
args = Namespace(config=None, yes=True)
2016-12-05 20:10:35 +01:00
run_drop(args)
assert mock_db_drop.called
@pytest.mark.tendermint
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
def test_drop_db_when_interactive_yes(mock_db_drop, monkeypatch):
from bigchaindb.commands.bigchaindb import run_drop
2016-12-05 20:10:35 +01:00
args = Namespace(config=None, yes=False)
monkeypatch.setattr(
'bigchaindb.commands.bigchaindb.input_on_stderr', lambda x: 'y')
2016-12-05 20:10:35 +01:00
run_drop(args)
assert mock_db_drop.called
@pytest.mark.tendermint
@patch('bigchaindb.backend.schema.drop_database')
def test_drop_db_when_db_does_not_exist(mock_db_drop, capsys):
from bigchaindb import config
2017-04-04 10:25:24 +02:00
from bigchaindb.commands.bigchaindb import run_drop
from bigchaindb.common.exceptions import DatabaseDoesNotExist
args = Namespace(config=None, yes=True)
mock_db_drop.side_effect = DatabaseDoesNotExist
run_drop(args)
output_message = capsys.readouterr()[1]
assert output_message == "Cannot drop '{name}'. The database does not exist.\n".format(
name=config['database']['name'])
@pytest.mark.tendermint
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
def test_drop_db_does_not_drop_when_interactive_no(mock_db_drop, monkeypatch):
from bigchaindb.commands.bigchaindb import run_drop
2016-12-05 20:10:35 +01:00
args = Namespace(config=None, yes=False)
monkeypatch.setattr(
'bigchaindb.commands.bigchaindb.input_on_stderr', lambda x: 'n')
2016-12-05 20:10:35 +01:00
2016-02-14 20:30:50 +01:00
run_drop(args)
2016-12-05 20:10:35 +01:00
assert not mock_db_drop.called
2016-02-14 20:48:30 +01:00
# TODO Beware if you are putting breakpoints in there, and using the '-s'
# switch with pytest. It will just hang. Seems related to the monkeypatching of
# input_on_stderr.
@pytest.mark.tendermint
def test_run_configure_when_config_does_not_exist(monkeypatch,
mock_write_config,
mock_generate_key_pair,
mock_bigchaindb_backup_config):
from bigchaindb.commands.bigchaindb import run_configure
monkeypatch.setattr('os.path.exists', lambda path: False)
2016-04-26 03:24:56 +02:00
monkeypatch.setattr('builtins.input', lambda: '\n')
args = Namespace(config=None, backend='localmongodb', yes=True)
return_value = run_configure(args)
assert return_value is None
2016-02-29 14:28:02 +01:00
@pytest.mark.tendermint
2016-02-29 14:28:02 +01:00
def test_run_configure_when_config_does_exist(monkeypatch,
mock_write_config,
mock_generate_key_pair,
mock_bigchaindb_backup_config):
value = {}
2016-12-22 11:57:13 +01:00
2016-02-29 14:28:02 +01:00
def mock_write_config(newconfig, filename=None):
value['return'] = newconfig
from bigchaindb.commands.bigchaindb import run_configure
2016-02-29 14:28:02 +01:00
monkeypatch.setattr('os.path.exists', lambda path: True)
2016-04-26 03:24:56 +02:00
monkeypatch.setattr('builtins.input', lambda: '\n')
monkeypatch.setattr(
'bigchaindb.config_utils.write_config', mock_write_config)
2016-02-29 14:28:02 +01:00
args = Namespace(config=None, yes=None)
2016-02-29 14:28:02 +01:00
run_configure(args)
assert value == {}
2016-04-26 00:37:35 +02:00
@pytest.mark.tendermint
@pytest.mark.parametrize('backend', (
'localmongodb',
))
def test_run_configure_with_backend(backend, monkeypatch, mock_write_config):
import bigchaindb
from bigchaindb.commands.bigchaindb import run_configure
value = {}
def mock_write_config(new_config, filename=None):
value['return'] = new_config
monkeypatch.setattr('os.path.exists', lambda path: False)
monkeypatch.setattr('builtins.input', lambda: '\n')
monkeypatch.setattr('bigchaindb.config_utils.write_config',
mock_write_config)
args = Namespace(config=None, backend=backend, yes=True)
expected_config = bigchaindb.config
run_configure(args)
# update the expected config with the correct backend and keypair
backend_conf = getattr(bigchaindb, '_database_' + backend)
expected_config.update({'database': backend_conf,
'keypair': value['return']['keypair']})
assert value['return'] == expected_config
2017-03-13 17:55:11 +01:00
def test_run_start_when_db_already_exists(mocker,
monkeypatch,
run_start_args,
mocked_setup_logging):
from bigchaindb import config
from bigchaindb.commands.bigchaindb import run_start
2017-02-28 17:30:44 +01:00
from bigchaindb.common.exceptions import DatabaseAlreadyExists
mocked_start = mocker.patch('bigchaindb.processes.start')
def mock_run_init():
raise DatabaseAlreadyExists()
monkeypatch.setattr('builtins.input', lambda: '\x03')
2017-02-28 17:30:44 +01:00
monkeypatch.setattr(
'bigchaindb.commands.bigchaindb._run_init', mock_run_init)
2017-02-28 17:30:44 +01:00
run_start(run_start_args)
mocked_setup_logging.assert_called_once_with(user_log_config=config['log'])
2017-02-28 17:30:44 +01:00
assert mocked_start.called
@pytest.mark.tendermint
Rebase/feat/586/integrate tx model (#641) * Adjust imports to bigchaindb_common * Adjust get_spent function signature * Adjust block serialization * Fix BigchainApi Test * Fix TestTransactionValidation tests * Fix TestBlockValidation tests * WIP: TestMultipleInputs * Adjust tests to tx-model interface changes - Fix old tests - Fix tests in TestMultipleInputs class * Remove fulfillment message tests * Fix TransactionMalleability tests * Remove Cryptoconditions tests * Remove create_transaction * Remove signing logic * Remove consensus plugin * Fix block_creation pipeline * Fix election pipeline * Replace some util functions with bdb_common ones - timestamp ==> gen_timestamp - serialize. * Implement Block model * Simplify function signatures for vote functions Change parameter interface for the following functions: - has_previous_vote - verify_vote_signature - block_election_status so that they take a block's id and voters instead of a fake block. * Integrate Block and Transaction model * Fix leftover tests and cleanup conftest * Add bigchaindb-common to install_requires * Delete transactions after block is written (#609) * delete transactions after block is written * cleanup transaction_exists * check for duplicate transactions * delete invalid tx from backlog * test duplicate transaction * Remove dead code * Test processes.py * Test invalid tx in on server * Fix tests for core.py * Fix models tests * Test commands main fn * Add final coverage to vote pipeline * Add more tests to voting pipeline * Remove consensus plugin docs and misc * Post rebase fixes * Fix rebase mess * Remove extra blank line * Improve docstring * Remove comment handled in bigchaindb/cryptoconditions#27; see https://github.com/bigchaindb/cryptoconditions/issues/27 * Fix block serialization in block creation * Add signed_ prefix to transfer_tx * Improve docs * Add library documentation page on pipelines * PR feedback for models.py * Impr. readability of get_last_voted_block * Use dict comprehension * Add docker-compose file to build and serve docs locally for development purposes * Change private_key for signing_key * Improve docstrings * Remove consensus docs * Document new consensus module * Create different transactions for the block * Cleanup variable names in block.py * Create different transactions for the block * Cleanup variable names in block.py
2016-09-29 10:29:41 +02:00
@patch('argparse.ArgumentParser.parse_args')
@patch('bigchaindb.commands.utils.base_parser')
@patch('bigchaindb.commands.utils.start')
def test_calling_main(start_mock, base_parser_mock, parse_args_mock,
monkeypatch):
from bigchaindb.commands.bigchaindb import main
Rebase/feat/586/integrate tx model (#641) * Adjust imports to bigchaindb_common * Adjust get_spent function signature * Adjust block serialization * Fix BigchainApi Test * Fix TestTransactionValidation tests * Fix TestBlockValidation tests * WIP: TestMultipleInputs * Adjust tests to tx-model interface changes - Fix old tests - Fix tests in TestMultipleInputs class * Remove fulfillment message tests * Fix TransactionMalleability tests * Remove Cryptoconditions tests * Remove create_transaction * Remove signing logic * Remove consensus plugin * Fix block_creation pipeline * Fix election pipeline * Replace some util functions with bdb_common ones - timestamp ==> gen_timestamp - serialize. * Implement Block model * Simplify function signatures for vote functions Change parameter interface for the following functions: - has_previous_vote - verify_vote_signature - block_election_status so that they take a block's id and voters instead of a fake block. * Integrate Block and Transaction model * Fix leftover tests and cleanup conftest * Add bigchaindb-common to install_requires * Delete transactions after block is written (#609) * delete transactions after block is written * cleanup transaction_exists * check for duplicate transactions * delete invalid tx from backlog * test duplicate transaction * Remove dead code * Test processes.py * Test invalid tx in on server * Fix tests for core.py * Fix models tests * Test commands main fn * Add final coverage to vote pipeline * Add more tests to voting pipeline * Remove consensus plugin docs and misc * Post rebase fixes * Fix rebase mess * Remove extra blank line * Improve docstring * Remove comment handled in bigchaindb/cryptoconditions#27; see https://github.com/bigchaindb/cryptoconditions/issues/27 * Fix block serialization in block creation * Add signed_ prefix to transfer_tx * Improve docs * Add library documentation page on pipelines * PR feedback for models.py * Impr. readability of get_last_voted_block * Use dict comprehension * Add docker-compose file to build and serve docs locally for development purposes * Change private_key for signing_key * Improve docstrings * Remove consensus docs * Document new consensus module * Create different transactions for the block * Cleanup variable names in block.py * Create different transactions for the block * Cleanup variable names in block.py
2016-09-29 10:29:41 +02:00
argparser_mock = Mock()
parser = Mock()
subparsers = Mock()
subsubparsers = Mock()
subparsers.add_parser.return_value = subsubparsers
parser.add_subparsers.return_value = subparsers
argparser_mock.return_value = parser
monkeypatch.setattr('argparse.ArgumentParser', argparser_mock)
main()
assert argparser_mock.called is True
parser.add_subparsers.assert_called_with(title='Commands',
dest='command')
subparsers.add_parser.assert_any_call('configure',
help='Prepare the config file.')
Rebase/feat/586/integrate tx model (#641) * Adjust imports to bigchaindb_common * Adjust get_spent function signature * Adjust block serialization * Fix BigchainApi Test * Fix TestTransactionValidation tests * Fix TestBlockValidation tests * WIP: TestMultipleInputs * Adjust tests to tx-model interface changes - Fix old tests - Fix tests in TestMultipleInputs class * Remove fulfillment message tests * Fix TransactionMalleability tests * Remove Cryptoconditions tests * Remove create_transaction * Remove signing logic * Remove consensus plugin * Fix block_creation pipeline * Fix election pipeline * Replace some util functions with bdb_common ones - timestamp ==> gen_timestamp - serialize. * Implement Block model * Simplify function signatures for vote functions Change parameter interface for the following functions: - has_previous_vote - verify_vote_signature - block_election_status so that they take a block's id and voters instead of a fake block. * Integrate Block and Transaction model * Fix leftover tests and cleanup conftest * Add bigchaindb-common to install_requires * Delete transactions after block is written (#609) * delete transactions after block is written * cleanup transaction_exists * check for duplicate transactions * delete invalid tx from backlog * test duplicate transaction * Remove dead code * Test processes.py * Test invalid tx in on server * Fix tests for core.py * Fix models tests * Test commands main fn * Add final coverage to vote pipeline * Add more tests to voting pipeline * Remove consensus plugin docs and misc * Post rebase fixes * Fix rebase mess * Remove extra blank line * Improve docstring * Remove comment handled in bigchaindb/cryptoconditions#27; see https://github.com/bigchaindb/cryptoconditions/issues/27 * Fix block serialization in block creation * Add signed_ prefix to transfer_tx * Improve docs * Add library documentation page on pipelines * PR feedback for models.py * Impr. readability of get_last_voted_block * Use dict comprehension * Add docker-compose file to build and serve docs locally for development purposes * Change private_key for signing_key * Improve docstrings * Remove consensus docs * Document new consensus module * Create different transactions for the block * Cleanup variable names in block.py * Create different transactions for the block * Cleanup variable names in block.py
2016-09-29 10:29:41 +02:00
subparsers.add_parser.assert_any_call('show-config',
help='Show the current '
'configuration')
subparsers.add_parser.assert_any_call('init', help='Init the database')
subparsers.add_parser.assert_any_call('drop', help='Drop the database')
Rebase/feat/586/integrate tx model (#641) * Adjust imports to bigchaindb_common * Adjust get_spent function signature * Adjust block serialization * Fix BigchainApi Test * Fix TestTransactionValidation tests * Fix TestBlockValidation tests * WIP: TestMultipleInputs * Adjust tests to tx-model interface changes - Fix old tests - Fix tests in TestMultipleInputs class * Remove fulfillment message tests * Fix TransactionMalleability tests * Remove Cryptoconditions tests * Remove create_transaction * Remove signing logic * Remove consensus plugin * Fix block_creation pipeline * Fix election pipeline * Replace some util functions with bdb_common ones - timestamp ==> gen_timestamp - serialize. * Implement Block model * Simplify function signatures for vote functions Change parameter interface for the following functions: - has_previous_vote - verify_vote_signature - block_election_status so that they take a block's id and voters instead of a fake block. * Integrate Block and Transaction model * Fix leftover tests and cleanup conftest * Add bigchaindb-common to install_requires * Delete transactions after block is written (#609) * delete transactions after block is written * cleanup transaction_exists * check for duplicate transactions * delete invalid tx from backlog * test duplicate transaction * Remove dead code * Test processes.py * Test invalid tx in on server * Fix tests for core.py * Fix models tests * Test commands main fn * Add final coverage to vote pipeline * Add more tests to voting pipeline * Remove consensus plugin docs and misc * Post rebase fixes * Fix rebase mess * Remove extra blank line * Improve docstring * Remove comment handled in bigchaindb/cryptoconditions#27; see https://github.com/bigchaindb/cryptoconditions/issues/27 * Fix block serialization in block creation * Add signed_ prefix to transfer_tx * Improve docs * Add library documentation page on pipelines * PR feedback for models.py * Impr. readability of get_last_voted_block * Use dict comprehension * Add docker-compose file to build and serve docs locally for development purposes * Change private_key for signing_key * Improve docstrings * Remove consensus docs * Document new consensus module * Create different transactions for the block * Cleanup variable names in block.py * Create different transactions for the block * Cleanup variable names in block.py
2016-09-29 10:29:41 +02:00
subparsers.add_parser.assert_any_call('start', help='Start BigchainDB')
assert start_mock.called is True
2017-01-25 12:36:08 +01:00
@pytest.mark.tendermint
@pytest.mark.bdb
def test_recover_db_from_zombie_txn(b, monkeypatch):
from bigchaindb.commands.bigchaindb import run_recover
from bigchaindb.models import Transaction
from bigchaindb.common.crypto import generate_key_pair
from bigchaindb.tendermint.lib import Block
from bigchaindb import backend
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],
asset={'cycle': 'hero'},
metadata={'name': 'hohenheim'}) \
.sign([alice.private_key])
b.store_bulk_transactions([tx])
block = Block(app_hash='random_app_hash', height=10,
transactions=[])._asdict()
b.store_block(block)
def mock_get(uri):
return MockResponse(10)
monkeypatch.setattr('requests.get', mock_get)
run_recover(b)
assert list(backend.query.get_metadata(b.connection, [tx.id])) == []
assert not backend.query.get_asset(b.connection, tx.id)
assert not b.get_transaction(tx.id)
@pytest.mark.tendermint
@pytest.mark.bdb
def test_recover_db_from_zombie_block(b, monkeypatch):
from bigchaindb.commands.bigchaindb import run_recover
from bigchaindb.models import Transaction
from bigchaindb.common.crypto import generate_key_pair
from bigchaindb.tendermint.lib import Block
from bigchaindb import backend
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],
asset={'cycle': 'hero'},
metadata={'name': 'hohenheim'}) \
.sign([alice.private_key])
b.store_bulk_transactions([tx])
block9 = Block(app_hash='random_app_hash', height=9,
transactions=[])._asdict()
b.store_block(block9)
block10 = Block(app_hash='random_app_hash', height=10,
transactions=[tx.id])._asdict()
b.store_block(block10)
def mock_get(uri):
return MockResponse(9)
monkeypatch.setattr('requests.get', mock_get)
run_recover(b)
assert list(backend.query.get_metadata(b.connection, [tx.id])) == []
assert not backend.query.get_asset(b.connection, tx.id)
assert not b.get_transaction(tx.id)
block = b.get_latest_block()
assert block['height'] == 9
@patch('bigchaindb.config_utils.autoconfigure')
@patch('bigchaindb.commands.bigchaindb.run_recover')
@patch('bigchaindb.tendermint.commands.start')
def test_recover_db_on_start(mock_autoconfigure,
mock_run_recover,
mock_start,
mocked_setup_logging):
from bigchaindb.commands.bigchaindb import run_start
args = Namespace(start_rethinkdb=False, allow_temp_keypair=False, config=None, yes=True,
skip_initialize_database=False)
run_start(args)
assert mock_run_recover.called
assert mock_start.called
# Helper
class MockResponse():
def __init__(self, height):
self.height = height
def json(self):
return {'result': {'latest_block_height': self.height}}
@patch('bigchaindb.config_utils.autoconfigure')
@patch('bigchaindb.backend.query.store_validator_update')
@pytest.mark.tendermint
def test_upsert_validator(mock_autoconfigure, mock_store_validator_update):
from bigchaindb.commands.bigchaindb import run_upsert_validator
args = Namespace(public_key='BOB_PUBLIC_KEY', power='10', config={})
run_upsert_validator(args)
assert mock_store_validator_update.called