bigchaindb/tests/commands/test_commands.py

348 lines
14 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
2016-02-14 17:18:41 +01:00
from argparse import Namespace
2016-02-18 16:27:24 +01:00
import copy
2016-02-14 17:18:41 +01:00
import pytest
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.bigchain 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']).command
assert parser.parse_args(['show-config']).command
assert parser.parse_args(['export-my-pubkey']).command
assert parser.parse_args(['init']).command
assert parser.parse_args(['drop']).command
assert parser.parse_args(['start']).command
assert parser.parse_args(['set-shards', '1']).command
assert parser.parse_args(['set-replicas', '1']).command
assert parser.parse_args(['load']).command
2016-09-21 14:10:04 +02:00
def test_start_raises_if_command_not_implemented():
from bigchaindb.commands.bigchain import utils
from bigchaindb.commands.bigchain import create_parser
parser = create_parser()
with pytest.raises(NotImplementedError):
# Will raise because `scope`, the third parameter,
# doesn't contain the function `run_configure`
utils.start(parser, ['configure'], {})
2016-09-21 15:00:13 +02:00
def test_start_raises_if_no_arguments_given():
from bigchaindb.commands.bigchain import utils
from bigchaindb.commands.bigchain import create_parser
parser = create_parser()
with pytest.raises(SystemExit):
utils.start(parser, [], {})
2016-09-21 14:10:04 +02:00
@patch('multiprocessing.cpu_count', return_value=42)
def test_start_sets_multiprocess_var_based_on_cli_args(mock_cpu_count):
from bigchaindb.commands.bigchain import utils
from bigchaindb.commands.bigchain import create_parser
2016-09-21 15:01:42 +02:00
def run_load(args):
return args
2016-09-21 14:10:04 +02:00
parser = create_parser()
assert utils.start(parser, ['load'], {'run_load': run_load}).multiprocess == 1
assert utils.start(parser, ['load', '--multiprocess'], {'run_load': run_load}).multiprocess == 42
2016-09-21 00:46:48 +02:00
@patch('bigchaindb.commands.utils.start')
def test_main_entrypoint(mock_start):
from bigchaindb.commands.bigchain import main
main()
assert mock_start.called
def test_bigchain_run_start(mock_run_configure, mock_processes_start, mock_db_init_with_existing_db):
2016-02-14 17:18:41 +01:00
from bigchaindb.commands.bigchain import run_start
args = Namespace(start_rethinkdb=False, allow_temp_keypair=False, config=None, yes=True)
2016-04-26 00:37:35 +02:00
run_start(args)
2016-03-24 01:41:00 +01:00
@pytest.mark.skipif(reason="BigchainDB doesn't support the automatic creation of a config file anymore")
2016-02-18 16:27:24 +01:00
def test_bigchain_run_start_assume_yes_create_default_config(monkeypatch, mock_processes_start,
mock_generate_key_pair, mock_db_init_with_existing_db):
import bigchaindb
from bigchaindb.commands.bigchain import run_start
from bigchaindb import config_utils
value = {}
expected_config = copy.deepcopy(bigchaindb._config)
expected_config['keypair']['public'] = 'pubkey'
expected_config['keypair']['private'] = 'privkey'
def mock_write_config(newconfig, filename=None):
value['return'] = newconfig
monkeypatch.setattr(config_utils, 'write_config', mock_write_config)
2016-04-14 10:55:07 +02:00
monkeypatch.setattr(config_utils, 'file_config', lambda x: config_utils.set_config(expected_config))
2016-02-18 16:27:24 +01:00
monkeypatch.setattr('os.path.exists', lambda path: False)
args = Namespace(config=None, yes=True)
run_start(args)
assert value['return'] == expected_config
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.usefixtures('ignore_local_config_file')
def test_bigchain_show_config(capsys):
2016-02-14 19:46:30 +01:00
from bigchaindb import config
from bigchaindb.commands.bigchain 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])
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
def test_bigchain_export_my_pubkey_when_pubkey_set(capsys, monkeypatch):
from bigchaindb import config
from bigchaindb.commands.bigchain import run_export_my_pubkey
args = Namespace(config='dummy')
# so in run_export_my_pubkey(args) below,
# filename=args.config='dummy' is passed to autoconfigure().
# We just assume autoconfigure() works and sets
# config['keypair']['public'] correctly (tested elsewhere).
# We force-set config['keypair']['public'] using monkeypatch.
monkeypatch.setitem(config['keypair'], 'public', 'Charlie_Bucket')
_, _ = capsys.readouterr() # has the effect of clearing capsys
run_export_my_pubkey(args)
out, err = capsys.readouterr()
assert out == config['keypair']['public'] + '\n'
assert out == 'Charlie_Bucket\n'
def test_bigchain_export_my_pubkey_when_pubkey_not_set(monkeypatch):
from bigchaindb import config
from bigchaindb.commands.bigchain import run_export_my_pubkey
args = Namespace(config='dummy')
monkeypatch.setitem(config['keypair'], 'public', None)
# assert that run_export_my_pubkey(args) raises SystemExit:
with pytest.raises(SystemExit) as exc_info:
run_export_my_pubkey(args)
# exc_info is an object of class ExceptionInfo
# https://pytest.org/latest/builtin.html#_pytest._code.ExceptionInfo
assert exc_info.type == SystemExit
# exc_info.value is an object of class SystemExit
# https://docs.python.org/3/library/exceptions.html#SystemExit
assert exc_info.value.code == \
"This node's public key wasn't set anywhere so it can't be exported"
def test_bigchain_run_init_when_db_exists(mock_db_init_with_existing_db):
2016-02-14 20:05:16 +01:00
from bigchaindb.commands.bigchain import run_init
args = Namespace(config=None)
run_init(args)
2016-02-14 20:30:50 +01:00
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
2016-12-05 20:10:35 +01:00
def test_drop_db_when_assumed_yes(mock_db_drop):
2016-02-14 20:30:50 +01:00
from bigchaindb.commands.bigchain import run_drop
args = Namespace(config=None, yes=True)
2016-12-05 20:10:35 +01:00
run_drop(args)
assert mock_db_drop.called
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
2016-12-05 20:10:35 +01:00
def test_drop_db_when_interactive_yes(mock_db_drop, monkeypatch):
from bigchaindb.commands.bigchain import run_drop
args = Namespace(config=None, yes=False)
monkeypatch.setattr('bigchaindb.commands.bigchain.input_on_stderr', lambda x: 'y')
2016-12-05 20:10:35 +01:00
run_drop(args)
assert mock_db_drop.called
2016-12-06 14:22:13 +01:00
@patch('bigchaindb.backend.schema.drop_database')
2016-12-05 20:10:35 +01:00
def test_drop_db_does_not_drop_when_interactive_no(mock_db_drop, monkeypatch):
from bigchaindb.commands.bigchain import run_drop
args = Namespace(config=None, yes=False)
monkeypatch.setattr('bigchaindb.commands.bigchain.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
def test_run_configure_when_config_exists_and_skipping(monkeypatch):
from bigchaindb.commands.bigchain import run_configure
monkeypatch.setattr('os.path.exists', lambda path: True)
args = Namespace(config='foo', yes=True)
return_value = run_configure(args, skip_if_exists=True)
assert return_value is None
# 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.
def test_run_configure_when_config_does_not_exist(monkeypatch,
mock_write_config,
mock_generate_key_pair,
mock_bigchaindb_backup_config):
from bigchaindb.commands.bigchain 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='foo', yes=True)
return_value = run_configure(args)
assert return_value is None
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.bigchain import run_configure
monkeypatch.setattr('os.path.exists', lambda path: True)
2016-04-26 03:24:56 +02:00
monkeypatch.setattr('builtins.input', lambda: '\n')
2016-02-29 14:28:02 +01:00
monkeypatch.setattr('bigchaindb.config_utils.write_config', mock_write_config)
args = Namespace(config='foo', yes=None)
run_configure(args)
assert value == {}
2016-04-26 00:37:35 +02:00
@patch('bigchaindb.common.crypto.generate_key_pair',
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
return_value=('private_key', 'public_key'))
@pytest.mark.usefixtures('ignore_local_config_file')
def test_allow_temp_keypair_generates_one_on_the_fly(mock_gen_keypair,
mock_processes_start,
mock_db_init_with_existing_db):
import bigchaindb
from bigchaindb.commands.bigchain import run_start
2016-12-22 11:57:13 +01:00
bigchaindb.config['keypair'] = {'private': None, 'public': None}
args = Namespace(allow_temp_keypair=True, start_rethinkdb=False, config=None, yes=True)
run_start(args)
assert bigchaindb.config['keypair']['private'] == 'private_key'
assert bigchaindb.config['keypair']['public'] == 'public_key'
@patch('bigchaindb.common.crypto.generate_key_pair',
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
return_value=('private_key', 'public_key'))
@pytest.mark.usefixtures('ignore_local_config_file')
def test_allow_temp_keypair_doesnt_override_if_keypair_found(mock_gen_keypair,
mock_processes_start,
mock_db_init_with_existing_db):
import bigchaindb
from bigchaindb.commands.bigchain import run_start
# Preconditions for the test
original_private_key = bigchaindb.config['keypair']['private']
original_public_key = bigchaindb.config['keypair']['public']
assert isinstance(original_public_key, str)
assert isinstance(original_private_key, str)
args = Namespace(allow_temp_keypair=True, start_rethinkdb=False, config=None, yes=True)
run_start(args)
assert bigchaindb.config['keypair']['private'] == original_private_key
assert bigchaindb.config['keypair']['public'] == original_public_key
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.bigchain import main
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
assert parser.add_argument.called is True
parser.add_argument.assert_any_call('--dev-start-rethinkdb',
dest='start_rethinkdb',
action='store_true',
help='Run RethinkDB on start')
parser.add_subparsers.assert_called_with(title='Commands',
dest='command')
subparsers.add_parser.assert_any_call('configure',
help='Prepare the config file '
'and create the node keypair')
subparsers.add_parser.assert_any_call('show-config',
help='Show the current '
'configuration')
subparsers.add_parserassert_any_call('export-my-pubkey',
help="Export this node's public "
'key')
subparsers.add_parser.assert_any_call('init', help='Init the database')
subparsers.add_parser.assert_any_call('drop', help='Drop the database')
subparsers.add_parser.assert_any_call('start', help='Start BigchainDB')
subparsers.add_parser.assert_any_call('set-shards',
help='Configure number of shards')
subsubparsers.add_argument.assert_any_call('num_shards',
metavar='num_shards',
type=int, default=1,
help='Number of shards')
subparsers.add_parser.assert_any_call('set-replicas',
help='Configure number of replicas')
subsubparsers.add_argument.assert_any_call('num_replicas',
metavar='num_replicas',
type=int, default=1,
help='Number of replicas (i.e. '
'the replication factor)')
subparsers.add_parser.assert_any_call('load',
help='Write transactions to the '
'backlog')
subsubparsers.add_argument.assert_any_call('-m', '--multiprocess',
nargs='?', type=int,
default=False,
help='Spawn multiple processes '
'to run the command, if no '
'value is provided, the number '
'of processes is equal to the '
'number of cores of the host '
'machine')
subsubparsers.add_argument.assert_any_call('-c', '--count',
default=0,
type=int,
help='Number of transactions '
'to push. If the parameter -m '
'is set, the count is '
'distributed equally to all '
'the processes')
assert start_mock.called is True