From e2aafb9cf9490e0fcbaa10d71476a69fbbed8493 Mon Sep 17 00:00:00 2001 From: codegeschrei Date: Thu, 23 Aug 2018 14:49:04 +0200 Subject: [PATCH 1/4] Problem: there is a new version of the python driver (#2477) Solution: update the Dockerfile for acceptance tests --- acceptance/python/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptance/python/Dockerfile b/acceptance/python/Dockerfile index b01105cb..a473a56a 100644 --- a/acceptance/python/Dockerfile +++ b/acceptance/python/Dockerfile @@ -5,5 +5,5 @@ RUN pip install --upgrade \ pycco \ websocket-client~=0.47.0 \ pytest~=3.0 \ - bigchaindb-driver==0.5.0 \ - blns \ No newline at end of file + bigchaindb-driver==0.5.1 \ + blns From a16d561f549054a49de5fae7cdd546d0e3b9eb98 Mon Sep 17 00:00:00 2001 From: Troy McConaghy Date: Thu, 23 Aug 2018 15:17:05 +0200 Subject: [PATCH 2/4] Add link to the Java driver in Contributing docs (#2478) --- docs/contributing/source/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/contributing/source/index.rst b/docs/contributing/source/index.rst index d64729a5..28c46e6c 100644 --- a/docs/contributing/source/index.rst +++ b/docs/contributing/source/index.rst @@ -12,6 +12,7 @@ It includes several sub-projects. - `BigchainDB Server `_ - `BigchainDB Python Driver `_ - `BigchainDB JavaScript Driver `_ +- `BigchainDB Java Driver `_ - `cryptoconditions `_ (a Python package by us) - `py-abci `_ (a Python package we use) - `BigchainDB Enhancement Proposals (BEPs) `_ From d31ab9fb4088d88edd8c846e7d58a4ddcf15531c Mon Sep 17 00:00:00 2001 From: codegeschrei Date: Fri, 24 Aug 2018 09:52:00 +0200 Subject: [PATCH 3/4] Problem: There is no way to vote for an election (#2458) * Problem: `run_upsert_validator_approve` was getting the voting power in a convoluted way Solution: Changed it to get the voting power from the election outputs * Problem: `run_upsert_validator_approve` casts votes for *all* voters, not just the user calling the command Solution: Filter vote txs by the users public key * Problem: Docs needed a more specific description of how to input the path to the private-key file Solution: Changed the wording a bit --- bigchaindb/commands/bigchaindb.py | 50 +++++++- .../upsert_validator/validator_election.py | 1 - .../source/server-reference/bigchaindb-cli.md | 14 +++ tests/commands/test_commands.py | 119 +++++++++++++++--- tests/conftest.py | 80 +++++++++++- tests/upsert_validator/conftest.py | 11 -- .../test_validator_election_vote.py | 7 +- tests/utils.py | 16 +++ 8 files changed, 265 insertions(+), 33 deletions(-) diff --git a/bigchaindb/commands/bigchaindb.py b/bigchaindb/commands/bigchaindb.py index 5e24e07c..184b82de 100644 --- a/bigchaindb/commands/bigchaindb.py +++ b/bigchaindb/commands/bigchaindb.py @@ -16,9 +16,10 @@ import sys from bigchaindb.utils import load_node_key from bigchaindb.common.exceptions import (DatabaseAlreadyExists, DatabaseDoesNotExist, - OperationError) + OperationError, KeypairMismatchException) import bigchaindb -from bigchaindb import backend, ValidatorElection, BigchainDB +from bigchaindb import (backend, ValidatorElection, + BigchainDB, ValidatorElectionVote) from bigchaindb.backend import schema from bigchaindb.backend import query from bigchaindb.backend.query import PRE_COMMIT_ID @@ -143,6 +144,43 @@ def run_upsert_validator_new(args, bigchain): raise OperationError('Failed to commit election') +def run_upsert_validator_approve(args, bigchain): + """Approve an election to add/update/remove a validator to an existing BigchainDB network + + :param args: dict + args = { + 'election_id': the election_id of the election (str) + 'sk': the path to the private key of the signer (str) + } + :param bigchain: an instance of BigchainDB + :return: a success message + :raises: OperationError if the write transaction fails for any reason + """ + + key = load_node_key(args.sk) + tx = bigchain.get_transaction(args.election_id) + voting_powers = [v.amount for v in tx.outputs if key.public_key in v.public_keys] + if len(voting_powers) > 0: + voting_power = voting_powers[0] + else: + raise KeypairMismatchException( + 'The key you provided does not match any of the eligible voters in this election.' + ) + + inputs = [i for i in tx.to_inputs() if key.public_key in i.owners_before] + approval = ValidatorElectionVote.generate(inputs, [ + ([key.public_key], voting_power)], tx.id).sign([key.private_key]) + approval.validate(bigchain) + + resp = bigchain.write_transaction(approval, 'broadcast_tx_commit') + + if resp == (202, ''): + print('Your vote has been submitted.') + return approval.id + else: + raise OperationError('Failed to vote for election') + + def _run_init(): bdb = bigchaindb.BigchainDB() @@ -264,6 +302,14 @@ def create_parser(): dest='sk', help='Path to the private key of the election initiator.') + approve_election_parser = validator_subparser.add_parser('approve', + help='Approve the election.') + approve_election_parser.add_argument('election_id', + help='The election_id of the election.') + approve_election_parser.add_argument('--private-key', + dest='sk', + help='Path to the private key of the election initiator.') + # parsers for showing/exporting config values subparsers.add_parser('show-config', help='Show the current configuration') diff --git a/bigchaindb/upsert_validator/validator_election.py b/bigchaindb/upsert_validator/validator_election.py index a2c68412..17ea298f 100644 --- a/bigchaindb/upsert_validator/validator_election.py +++ b/bigchaindb/upsert_validator/validator_election.py @@ -41,7 +41,6 @@ class ValidatorElection(Transaction): """Return a dictionary of validators with key as `public_key` and value as the `voting_power` """ - validators = {} for validator in bigchain.get_validators(height): # NOTE: we assume that Tendermint encodes public key in base64 diff --git a/docs/server/source/server-reference/bigchaindb-cli.md b/docs/server/source/server-reference/bigchaindb-cli.md index 4d837419..9f5c87d3 100644 --- a/docs/server/source/server-reference/bigchaindb-cli.md +++ b/docs/server/source/server-reference/bigchaindb-cli.md @@ -110,3 +110,17 @@ $ bigchaindb upsert-validator new B0E42D2589A455EAD339A035D6CE1C8C3E25863F268120 ``` If the command succeeds, it will create an election and return an `election_id`. Elections consist of one vote token per voting power, issued to the members of the validator set. Validators can cast their votes to approve the change to the validator set by spending their vote tokens. The status of the election can be monitored by providing the `election_id` to the `show` subcommand. + +#### upsert-validator approve + Approve an election by voting for it. + Below is the command line syntax and the return value, + ```bash +$ bigchaindb upsert-validator approve --private-key PATH_TO_YOUR_PRIVATE_KEY +``` + Here, `` is the transaction id of the election the approval should be given for. `--private-key` should be the path to Tendermint's private key which can be generally found at `/home/user/.tendermint/config/priv_validator.json`. + + Example usage, + ```bash +$ bigchaindb upsert-validator approve 04a067582cf03eba2b53b82e4adb5ece424474cbd4f7183780855a93ac5e3caa --private-key /home/user/.tendermint/config/priv_validator.json +``` + If the command succeeds, a message will be returned, that the vote was submitted successfully. diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index d834ae6b..8d7b0725 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -9,6 +9,10 @@ from argparse import Namespace import pytest +from bigchaindb import ValidatorElection +from bigchaindb.common.exceptions import KeypairMismatchException +from tests.conftest import node_keys + @pytest.mark.tendermint def test_make_sure_we_dont_remove_any_command(): @@ -24,6 +28,8 @@ def test_make_sure_we_dont_remove_any_command(): assert parser.parse_args(['start']).command assert parser.parse_args(['upsert-validator', 'new', 'TEMP_PUB_KEYPAIR', '10', 'TEMP_NODE_ID', '--private-key', 'TEMP_PATH_TO_PRIVATE_KEY']).command + assert parser.parse_args(['upsert-validator', 'approve', 'ELECTION_ID', '--private-key', + 'TEMP_PATH_TO_PRIVATE_KEY']).command @pytest.mark.tendermint @@ -358,13 +364,6 @@ def test_upsert_validator_new_with_tendermint(b, priv_validator_path, user_sk, m time.sleep(3) - def mock_get(): - return [ - {'pub_key': {'value': 'zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=', - 'type': 'tendermint/PubKeyEd25519'}, - 'voting_power': 10} - ] - # b.get_validators = mock_get # mock_get_validators = mock_get # monkeypatch.setattr('requests.get', mock_get) @@ -385,16 +384,9 @@ def test_upsert_validator_new_with_tendermint(b, priv_validator_path, user_sk, m @pytest.mark.tendermint @pytest.mark.bdb -def test_upsert_validator_new_without_tendermint(b, priv_validator_path, user_sk, monkeypatch): +def test_upsert_validator_new_without_tendermint(b, priv_validator_path, user_sk): from bigchaindb.commands.bigchaindb import run_upsert_validator_new - def mock_get(height): - return [ - {'pub_key': {'data': 'zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=', - 'type': 'tendermint/PubKeyEd25519'}, - 'voting_power': 10} - ] - def mock_write(tx, mode): b.store_bulk_transactions([tx]) return (202, '') @@ -411,3 +403,100 @@ def test_upsert_validator_new_without_tendermint(b, priv_validator_path, user_sk resp = run_upsert_validator_new(args, b) assert b.get_transaction(resp) + + +@pytest.mark.abci +def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_sk, validators): + from bigchaindb.commands.bigchaindb import run_upsert_validator_new, \ + run_upsert_validator_approve + + public_key = '8eJ8q9ZQpReWyQT5aFCiwtZ5wDZC4eDnCen88p3tQ6ie' + new_args = Namespace(action='new', + public_key=public_key, + power=1, + node_id='12345', + sk=priv_validator_path, + config={}) + + election_id = run_upsert_validator_new(new_args, b) + + args = Namespace(action='approve', + election_id=election_id, + sk=priv_validator_path, + config={}) + approve = run_upsert_validator_approve(args, b) + + assert b.get_transaction(approve) + + +@pytest.mark.bdb +@pytest.mark.tendermint +def test_upsert_validator_approve_without_tendermint(b, priv_validator_path, new_validator, node_key): + from bigchaindb.commands.bigchaindb import run_upsert_validator_approve + from argparse import Namespace + + b, election_id = call_election(b, new_validator, node_key) + + # call run_upsert_validator_approve with args that point to the election + args = Namespace(action='approve', + election_id=election_id, + sk=priv_validator_path, + config={}) + + approval_id = run_upsert_validator_approve(args, b) + + # assert returned id is in the db + assert b.get_transaction(approval_id) + + +@pytest.mark.bdb +@pytest.mark.tendermint +def test_upsert_validator_approve_called_with_bad_key(b, bad_validator_path, new_validator, node_key): + from bigchaindb.commands.bigchaindb import run_upsert_validator_approve + from argparse import Namespace + + b, election_id = call_election(b, new_validator, node_key) + + # call run_upsert_validator_approve with args that point to the election, but a bad signing key + args = Namespace(action='approve', + election_id=election_id, + sk=bad_validator_path, + config={}) + + with pytest.raises(KeypairMismatchException): + run_upsert_validator_approve(args, b) + + +def mock_get(height): + keys = node_keys() + pub_key = list(keys.keys())[0] + return [ + {'pub_key': {'data': pub_key, + 'type': 'tendermint/PubKeyEd25519'}, + 'voting_power': 10} + ] + + +def call_election(b, new_validator, node_key): + + def mock_write(tx, mode): + b.store_bulk_transactions([tx]) + return (202, '') + + # patch the validator set. We now have one validator with power 10 + b.get_validators = mock_get + b.write_transaction = mock_write + + # our voters is a list of length 1, populated from our mocked validator + voters = ValidatorElection.recipients(b) + # and our voter is the public key from the voter list + voter = node_key.public_key + valid_election = ValidatorElection.generate([voter], + voters, + new_validator, None).sign([node_key.private_key]) + + # patch in an election with a vote issued to the user + election_id = valid_election.id + b.store_bulk_transactions([valid_election]) + + return b, election_id diff --git a/tests/conftest.py b/tests/conftest.py index c5dabd2d..8c36f539 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -665,7 +665,7 @@ def ed25519_node_keys(node_keys): return node_keys_dict -@pytest.fixture(scope='session') +@pytest.fixture def node_keys(): return {'zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=': 'cM5oW4J0zmUSZ/+QRoRlincvgCwR0pEjFoY//ZnnjD3Mv8Nqy8q6VdnOFI0XDHhwtFcqRIz0Y8rtjSdngUTKUw==', @@ -677,7 +677,7 @@ def node_keys(): 'uz8bYgoL4rHErWT1gjjrnA+W7bgD/uDQWSRKDmC8otc95wnnxJo1GxYlmh0OaqOkJaobpu13BcUcvITjRFiVgw=='} -@pytest.fixture(scope='session') +@pytest.fixture def priv_validator_path(node_keys): (public_key, private_key) = list(node_keys.items())[0] priv_validator = { @@ -699,3 +699,79 @@ def priv_validator_path(node_keys): json.dump(priv_validator, socket) socket.close() return path + + +@pytest.fixture +def bad_validator_path(node_keys): + (public_key, private_key) = list(node_keys.items())[1] + priv_validator = { + 'address': '84F787D95E196DC5DE5F972666CFECCA36801426', + 'pub_key': { + 'type': 'AC26791624DE60', + 'value': public_key + }, + 'last_height': 0, + 'last_round': 0, + 'last_step': 0, + 'priv_key': { + 'type': '954568A3288910', + 'value': private_key + } + } + fd, path = tempfile.mkstemp() + socket = os.fdopen(fd, 'w') + json.dump(priv_validator, socket) + socket.close() + return path + + +@pytest.fixture +def validators(b, node_keys): + from bigchaindb.backend import query + + height = get_block_height(b) + + original_validators = b.get_validators() + + (public_key, private_key) = list(node_keys.items())[0] + + validator_set = [{'address': 'F5426F0980E36E03044F74DD414248D29ABCBDB2', + 'pub_key': { + 'data': public_key, + 'type': 'ed25519'}, + 'voting_power': 10}] + + validator_update = {'validators': validator_set, + 'height': height + 1} + + query.store_validator_set(b.connection, validator_update) + + yield + + height = get_block_height(b) + + validator_update = {'validators': original_validators, + 'height': height} + + query.store_validator_set(b.connection, validator_update) + + +def get_block_height(b): + + if b.get_latest_block(): + height = b.get_latest_block()['height'] + else: + height = 0 + + return height + + +@pytest.fixture +def new_validator(): + public_key = '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034' + power = 1 + node_id = 'fake_node_id' + + return {'public_key': public_key, + 'power': power, + 'node_id': node_id} diff --git a/tests/upsert_validator/conftest.py b/tests/upsert_validator/conftest.py index 64bf2279..49b41b0f 100644 --- a/tests/upsert_validator/conftest.py +++ b/tests/upsert_validator/conftest.py @@ -14,17 +14,6 @@ def b_mock(b, network_validators): return b -@pytest.fixture -def new_validator(): - public_key = '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034' - power = 1 - node_id = 'fake_node_id' - - return {'public_key': public_key, - 'power': power, - 'node_id': node_id} - - def mock_get_validators(network_validators): def validator_set(height): validators = [] diff --git a/tests/upsert_validator/test_validator_election_vote.py b/tests/upsert_validator/test_validator_election_vote.py index c0798224..d555b0d7 100644 --- a/tests/upsert_validator/test_validator_election_vote.py +++ b/tests/upsert_validator/test_validator_election_vote.py @@ -10,7 +10,7 @@ from bigchaindb.upsert_validator import ValidatorElection, ValidatorElectionVote from bigchaindb.common.exceptions import AmountError from bigchaindb.common.crypto import generate_key_pair from bigchaindb.common.exceptions import ValidationError - +from tests.utils import generate_block pytestmark = [pytest.mark.execute] @@ -219,10 +219,13 @@ def test_valid_election_conclude(b_mock, valid_election, ed25519_node_keys): @pytest.mark.abci -def test_upsert_validator(b, node_key, node_keys, new_validator, ed25519_node_keys): +def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys): import time import requests + if b.get_latest_block()['height'] == 0: + generate_block(b) + (node_pub, _) = list(node_keys.items())[0] validators = [{'pub_key': {'type': 'ed25519', diff --git a/tests/utils.py b/tests/utils.py index d9805f62..349f7e5a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,3 +21,19 @@ def flush_localmongo_db(connection, dbname): connection.conn[dbname].metadata.delete_many({}) connection.conn[dbname].utxos.delete_many({}) connection.conn[dbname].validators.delete_many({}) + + +def generate_block(bigchain): + from bigchaindb.common.crypto import generate_key_pair + from bigchaindb.models import Transaction + import time + + alice = generate_key_pair() + tx = Transaction.create([alice.public_key], + [([alice.public_key], 1)], + asset=None)\ + .sign([alice.private_key]) + + code, message = bigchain.write_transaction(tx, 'broadcast_tx_commit') + assert code == 202 + time.sleep(2) From 6fdcaf44a7439f157213087bc0fcc1611335ab9a Mon Sep 17 00:00:00 2001 From: codegeschrei Date: Mon, 27 Aug 2018 09:48:20 +0200 Subject: [PATCH 4/4] Problem: we have unused and outdated fixtures (#2476) * Problem: we have unused and outdated fixtures Solution: clean up fixtures and tests accordingly --- tests/backend/localmongodb/test_connection.py | 8 +- tests/backend/localmongodb/test_queries.py | 2 +- tests/commands/conftest.py | 4 +- tests/commands/test_commands.py | 11 +-- tests/conftest.py | 99 +------------------ tests/tendermint/conftest.py | 6 -- tests/tendermint/test_integration.py | 3 +- tests/tendermint/test_lib.py | 45 +++++---- tests/test_config_utils.py | 2 +- tests/test_core.py | 1 - tests/web/test_assets.py | 9 +- tests/web/test_block_tendermint.py | 6 +- tests/web/test_metadata.py | 8 +- tests/web/test_parameters.py | 2 + tests/web/test_server.py | 4 + tests/web/test_validators.py | 2 +- tests/web/test_websocket_server.py | 3 +- 17 files changed, 49 insertions(+), 166 deletions(-) diff --git a/tests/backend/localmongodb/test_connection.py b/tests/backend/localmongodb/test_connection.py index a76f5b85..77692abe 100644 --- a/tests/backend/localmongodb/test_connection.py +++ b/tests/backend/localmongodb/test_connection.py @@ -55,10 +55,8 @@ def test_get_connection_returns_the_correct_instance(db_host, db_port): assert conn.conn._topology_settings.replica_set_name == config['replicaset'] -@mock.patch('bigchaindb.backend.localmongodb.connection.initialize_replica_set') @mock.patch('pymongo.MongoClient.__init__') -@mock.patch('time.sleep') -def test_connection_error(mock_sleep, mock_client, mock_init_repl_set): +def test_connection_error(mock_client): from bigchaindb.backend import connect from bigchaindb.backend.exceptions import ConnectionError @@ -74,9 +72,7 @@ def test_connection_error(mock_sleep, mock_client, mock_init_repl_set): assert mock_client.call_count == 3 -@mock.patch('bigchaindb.backend.localmongodb.connection.initialize_replica_set') -@mock.patch('pymongo.MongoClient') -def test_connection_run_errors(mock_client, mock_init_repl_set): +def test_connection_run_errors(): from bigchaindb.backend import connect from bigchaindb.backend.exceptions import (DuplicateKeyError, OperationError, diff --git a/tests/backend/localmongodb/test_queries.py b/tests/backend/localmongodb/test_queries.py index 4d1d7bdf..363d02a1 100644 --- a/tests/backend/localmongodb/test_queries.py +++ b/tests/backend/localmongodb/test_queries.py @@ -7,7 +7,7 @@ from copy import deepcopy import pytest import pymongo -pytestmark = [pytest.mark.tendermint, pytest.mark.localmongodb, pytest.mark.bdb] +pytestmark = [pytest.mark.tendermint, pytest.mark.bdb] def test_get_txids_filtered(signed_create_tx, signed_transfer_tx): diff --git a/tests/commands/conftest.py b/tests/commands/conftest.py index 025d5708..ce09ff24 100644 --- a/tests/commands/conftest.py +++ b/tests/commands/conftest.py @@ -27,8 +27,8 @@ def mock_db_init_with_existing_db(monkeypatch): @pytest.fixture def mock_processes_start(monkeypatch): - from bigchaindb import processes - monkeypatch.setattr(processes, 'start', lambda *args: None) + from bigchaindb.utils import Process + monkeypatch.setattr(Process, 'run', lambda *args: None) @pytest.fixture diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 8d7b0725..5e2bd31e 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -185,7 +185,7 @@ def test_run_configure_when_config_does_exist(monkeypatch, mock_bigchaindb_backup_config): value = {} - def mock_write_config(newconfig, filename=None): + def mock_write_config(newconfig): value['return'] = newconfig from bigchaindb.commands.bigchaindb import run_configure @@ -250,11 +250,8 @@ def test_run_start_when_db_already_exists(mocker, @pytest.mark.tendermint -@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): +def test_calling_main(start_mock, monkeypatch): from bigchaindb.commands.bigchaindb import main argparser_mock = Mock() @@ -283,11 +280,9 @@ def test_calling_main(start_mock, base_parser_mock, parse_args_mock, assert start_mock.called is True -@patch('bigchaindb.config_utils.autoconfigure') @patch('bigchaindb.commands.bigchaindb.run_recover') @patch('bigchaindb.start.start') -def test_recover_db_on_start(mock_autoconfigure, - mock_run_recover, +def test_recover_db_on_start(mock_run_recover, mock_start, mocked_setup_logging): from bigchaindb.commands.bigchaindb import run_start diff --git a/tests/conftest.py b/tests/conftest.py index 8c36f539..0fd4d671 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,13 +37,6 @@ USER_PRIVATE_KEY = '8eJ8q9ZQpReWyQT5aFCiwtZ5wDZC4eDnCen88p3tQ6ie' USER_PUBLIC_KEY = 'JEAkEJqLbbgDRAtMm8YAjGp759Aq2qTn9eaEHUj2XePE' -def pytest_runtest_setup(item): - if isinstance(item, item.Function): - backend = item.session.config.getoption('--database-backend') - if (item.get_marker('localmongodb') and backend != 'localmongodb'): - pytest.skip('Skip tendermint specific tests if not using localmongodb') - - def pytest_addoption(parser): from bigchaindb.backend.connection import BACKENDS @@ -56,19 +49,6 @@ def pytest_addoption(parser): ) -def pytest_ignore_collect(path, config): - from bigchaindb.backend.connection import BACKENDS - path = str(path) - - supported_backends = BACKENDS.keys() - - if os.path.isdir(path): - dirname = os.path.split(path)[1] - if dirname in supported_backends and dirname != config.getoption('--database-backend'): - print('Ignoring unrequested backend test dir: ', path) - return True - - def pytest_configure(config): config.addinivalue_line( 'markers', @@ -266,28 +246,12 @@ def merlin(): return generate_key_pair() -@pytest.fixture -def merlin_privkey(merlin): - return merlin.private_key - - -@pytest.fixture -def merlin_pubkey(merlin): - return merlin.public_key - - @pytest.fixture def b(): from bigchaindb import BigchainDB return BigchainDB() -@pytest.fixture -def tb(): - from bigchaindb import BigchainDB - return BigchainDB() - - @pytest.fixture def create_tx(alice, user_pk): from bigchaindb.models import Transaction @@ -349,24 +313,6 @@ def inputs(user_pk, b, alice): b.store_bulk_transactions(transactions) -@pytest.fixture -def inputs_shared(user_pk, user2_pk, alice): - from bigchaindb.models import Transaction - - # create blocks with transactions for `USER` to spend - for block in range(4): - transactions = [ - Transaction.create( - [alice.public_key], - [user_pk, user2_pk], - metadata={'msg': random.random()}, - ).sign([alice.private_key]).to_dict() - for _ in range(10) - ] - block = Block(app_hash='', height=_get_height(b), transaction=transactions) - b.store_block(block._asdict()) - - @pytest.fixture def dummy_db(request): from bigchaindb.backend import connect, schema @@ -389,26 +335,6 @@ def dummy_db(request): pass -@pytest.fixture -def not_yet_created_db(request): - from bigchaindb.backend import connect, schema - from bigchaindb.common.exceptions import DatabaseDoesNotExist - conn = connect() - dbname = request.fixturename - xdist_suffix = getattr(request.config, 'slaveinput', {}).get('slaveid') - if xdist_suffix: - dbname = '{}_{}'.format(dbname, xdist_suffix) - try: - schema.drop_database(conn, dbname) - except DatabaseDoesNotExist: - pass - yield dbname - try: - schema.drop_database(conn, dbname) - except DatabaseDoesNotExist: - pass - - @pytest.fixture def db_config(): from bigchaindb import config @@ -464,29 +390,6 @@ def tendermint_ws_url(tendermint_host, tendermint_port): return 'ws://{}:{}/websocket'.format(tendermint_host, tendermint_port) -@pytest.fixture -def tendermint_context(tendermint_host, tendermint_port, tendermint_ws_url): - TendermintContext = namedtuple( - 'TendermintContext', ('host', 'port', 'ws_url')) - return TendermintContext( - host=tendermint_host, - port=tendermint_port, - ws_url=tendermint_ws_url, - ) - - -@pytest.fixture -def mocked_setup_pub_logger(mocker): - return mocker.patch( - 'bigchaindb.log.setup.setup_pub_logger', autospec=True, spec_set=True) - - -@pytest.fixture -def mocked_setup_sub_logger(mocker): - return mocker.patch( - 'bigchaindb.log.setup.setup_sub_logger', autospec=True, spec_set=True) - - @pytest.fixture(autouse=True) def _abci_http(request): if request.keywords.get('abci', None): @@ -513,7 +416,7 @@ def abci_http(_setup_database, _configure_bigchaindb, abci_server, @pytest.yield_fixture(scope='session') -def event_loop(request): +def event_loop(): import asyncio loop = asyncio.get_event_loop_policy().new_event_loop() diff --git a/tests/tendermint/conftest.py b/tests/tendermint/conftest.py index 22dec41c..8efa8e76 100644 --- a/tests/tendermint/conftest.py +++ b/tests/tendermint/conftest.py @@ -8,12 +8,6 @@ import codecs import abci.types_pb2 as types -@pytest.fixture -def b(): - from bigchaindb import BigchainDB - return BigchainDB() - - @pytest.fixture def validator_pub_key(): return 'B0E42D2589A455EAD339A035D6CE1C8C3E25863F268120AA0162AD7D003A4014' diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index 1a8250bd..683404bc 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -16,13 +16,12 @@ from io import BytesIO @pytest.mark.tendermint @pytest.mark.bdb -def test_app(tb, init_chain_request): +def test_app(b, init_chain_request): from bigchaindb import App from bigchaindb.tendermint_utils import calculate_hash from bigchaindb.common.crypto import generate_key_pair from bigchaindb.models import Transaction - b = tb app = App(b) p = ProtocolHandler(app) diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py index cc511b3a..d8223a25 100644 --- a/tests/tendermint/test_lib.py +++ b/tests/tendermint/test_lib.py @@ -57,10 +57,9 @@ def test_asset_is_separated_from_transaciton(b): @pytest.mark.bdb -def test_get_latest_block(tb): +def test_get_latest_block(b): from bigchaindb.lib import Block - b = tb for i in range(10): app_hash = os.urandom(16).hex() txn_id = os.urandom(16).hex() @@ -75,8 +74,8 @@ def test_get_latest_block(tb): @pytest.mark.bdb @patch('bigchaindb.backend.query.get_block', return_value=None) @patch('bigchaindb.BigchainDB.get_latest_block', return_value={'height': 10}) -def test_get_empty_block(_0, _1, tb): - assert tb.get_block(5) == {'height': 5, 'transactions': []} +def test_get_empty_block(_0, _1, b): + assert b.get_block(5) == {'height': 5, 'transactions': []} def test_validation_error(b): @@ -172,15 +171,15 @@ def test_validator_updates(b, validator_pub_key): @pytest.mark.bdb -def test_update_utxoset(tb, signed_create_tx, signed_transfer_tx, db_context): +def test_update_utxoset(b, signed_create_tx, signed_transfer_tx, db_context): mongo_client = MongoClient(host=db_context.host, port=db_context.port) - tb.update_utxoset(signed_create_tx) + b.update_utxoset(signed_create_tx) utxoset = mongo_client[db_context.name]['utxos'] assert utxoset.count() == 1 utxo = utxoset.find_one() assert utxo['transaction_id'] == signed_create_tx.id assert utxo['output_index'] == 0 - tb.update_utxoset(signed_transfer_tx) + b.update_utxoset(signed_transfer_tx) assert utxoset.count() == 1 utxo = utxoset.find_one() assert utxo['transaction_id'] == signed_transfer_tx.id @@ -188,14 +187,14 @@ def test_update_utxoset(tb, signed_create_tx, signed_transfer_tx, db_context): @pytest.mark.bdb -def test_store_transaction(mocker, tb, signed_create_tx, +def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): mocked_store_asset = mocker.patch('bigchaindb.backend.query.store_assets') mocked_store_metadata = mocker.patch( 'bigchaindb.backend.query.store_metadatas') mocked_store_transaction = mocker.patch( 'bigchaindb.backend.query.store_transactions') - tb.store_bulk_transactions([signed_create_tx]) + b.store_bulk_transactions([signed_create_tx]) # mongo_client = MongoClient(host=db_context.host, port=db_context.port) # utxoset = mongo_client[db_context.name]['utxos'] # assert utxoset.count() == 1 @@ -204,40 +203,40 @@ def test_store_transaction(mocker, tb, signed_create_tx, # assert utxo['output_index'] == 0 mocked_store_asset.assert_called_once_with( - tb.connection, + b.connection, [{'id': signed_create_tx.id, 'data': signed_create_tx.asset['data']}], ) mocked_store_metadata.assert_called_once_with( - tb.connection, + b.connection, [{'id': signed_create_tx.id, 'metadata': signed_create_tx.metadata}], ) mocked_store_transaction.assert_called_once_with( - tb.connection, + b.connection, [{k: v for k, v in signed_create_tx.to_dict().items() if k not in ('asset', 'metadata')}], ) mocked_store_asset.reset_mock() mocked_store_metadata.reset_mock() mocked_store_transaction.reset_mock() - tb.store_bulk_transactions([signed_transfer_tx]) + b.store_bulk_transactions([signed_transfer_tx]) # assert utxoset.count() == 1 # utxo = utxoset.find_one() # assert utxo['transaction_id'] == signed_transfer_tx.id # assert utxo['output_index'] == 0 assert not mocked_store_asset.called mocked_store_metadata.asser_called_once_with( - tb.connection, + b.connection, [{'id': signed_transfer_tx.id, 'metadata': signed_transfer_tx.metadata}], ) mocked_store_transaction.assert_called_once_with( - tb.connection, + b.connection, [{k: v for k, v in signed_transfer_tx.to_dict().items() if k != 'metadata'}], ) @pytest.mark.bdb -def test_store_bulk_transaction(mocker, tb, signed_create_tx, +def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): mocked_store_assets = mocker.patch( 'bigchaindb.backend.query.store_assets') @@ -245,7 +244,7 @@ def test_store_bulk_transaction(mocker, tb, signed_create_tx, 'bigchaindb.backend.query.store_metadatas') mocked_store_transactions = mocker.patch( 'bigchaindb.backend.query.store_transactions') - tb.store_bulk_transactions((signed_create_tx,)) + b.store_bulk_transactions((signed_create_tx,)) # mongo_client = MongoClient(host=db_context.host, port=db_context.port) # utxoset = mongo_client[db_context.name]['utxos'] # assert utxoset.count() == 1 @@ -253,34 +252,34 @@ def test_store_bulk_transaction(mocker, tb, signed_create_tx, # assert utxo['transaction_id'] == signed_create_tx.id # assert utxo['output_index'] == 0 mocked_store_assets.assert_called_once_with( - tb.connection, + b.connection, [{'id': signed_create_tx.id, 'data': signed_create_tx.asset['data']}], ) mocked_store_metadata.assert_called_once_with( - tb.connection, + b.connection, [{'id': signed_create_tx.id, 'metadata': signed_create_tx.metadata}], ) mocked_store_transactions.assert_called_once_with( - tb.connection, + b.connection, [{k: v for k, v in signed_create_tx.to_dict().items() if k not in ('asset', 'metadata')}], ) mocked_store_assets.reset_mock() mocked_store_metadata.reset_mock() mocked_store_transactions.reset_mock() - tb.store_bulk_transactions((signed_transfer_tx,)) + b.store_bulk_transactions((signed_transfer_tx,)) # assert utxoset.count() == 1 # utxo = utxoset.find_one() # assert utxo['transaction_id'] == signed_transfer_tx.id # assert utxo['output_index'] == 0 assert not mocked_store_assets.called mocked_store_metadata.asser_called_once_with( - tb.connection, + b.connection, [{'id': signed_transfer_tx.id, 'metadata': signed_transfer_tx.metadata}], ) mocked_store_transactions.assert_called_once_with( - tb.connection, + b.connection, [{k: v for k, v in signed_transfer_tx.to_dict().items() if k != 'metadata'}], ) diff --git a/tests/test_config_utils.py b/tests/test_config_utils.py index 05a5ad83..35f0e486 100644 --- a/tests/test_config_utils.py +++ b/tests/test_config_utils.py @@ -24,7 +24,7 @@ def clean_config(monkeypatch, request): monkeypatch.setattr('bigchaindb.config', original_config) -def test_bigchain_instance_is_initialized_when_conf_provided(request): +def test_bigchain_instance_is_initialized_when_conf_provided(): import bigchaindb from bigchaindb import config_utils assert 'CONFIGURED' not in bigchaindb.config diff --git a/tests/test_core.py b/tests/test_core.py index 0e3a2f12..03701267 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -66,7 +66,6 @@ def test_bigchain_class_initialization_with_parameters(): assert bigchain.consensus == BaseConsensusRules -@pytest.mark.genesis def test_get_spent_issue_1271(b, alice, bob, carol): from bigchaindb.models import Transaction diff --git a/tests/web/test_assets.py b/tests/web/test_assets.py index 800537ba..2c658cdc 100644 --- a/tests/web/test_assets.py +++ b/tests/web/test_assets.py @@ -23,8 +23,7 @@ def test_get_assets_with_missing_text_search(client): @pytest.mark.bdb @pytest.mark.tendermint -@pytest.mark.localmongodb -def test_get_assets_tendermint(client, tb, alice): +def test_get_assets_tendermint(client, b, alice): from bigchaindb.models import Transaction # test returns empty list when no assets are found @@ -37,7 +36,7 @@ def test_get_assets_tendermint(client, tb, alice): tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset).sign([alice.private_key]) - tb.store_bulk_transactions([tx]) + b.store_bulk_transactions([tx]) # test that asset is returned res = client.get(ASSETS_ENDPOINT + '?search=abc') @@ -51,11 +50,9 @@ def test_get_assets_tendermint(client, tb, alice): @pytest.mark.bdb @pytest.mark.tendermint -@pytest.mark.localmongodb -def test_get_assets_limit_tendermint(client, tb, alice): +def test_get_assets_limit_tendermint(client, b, alice): from bigchaindb.models import Transaction - b = tb # create two assets asset1 = {'msg': 'abc 1'} asset2 = {'msg': 'abc 2'} diff --git a/tests/web/test_block_tendermint.py b/tests/web/test_block_tendermint.py index a726a117..a92822c4 100644 --- a/tests/web/test_block_tendermint.py +++ b/tests/web/test_block_tendermint.py @@ -14,9 +14,8 @@ pytestmark = pytest.mark.tendermint @pytest.mark.bdb @pytest.mark.usefixtures('inputs') -def test_get_block_endpoint(tb, client, alice): +def test_get_block_endpoint(b, client, alice): import copy - b = tb tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}) tx = tx.sign([alice.private_key]) @@ -49,8 +48,7 @@ def test_get_block_returns_404_if_not_found(client): @pytest.mark.bdb -def test_get_block_containing_transaction(tb, client, alice): - b = tb +def test_get_block_containing_transaction(b, client, alice): tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}) tx = tx.sign([alice.private_key]) b.store_bulk_transactions([tx]) diff --git a/tests/web/test_metadata.py b/tests/web/test_metadata.py index aa0a2382..248ef946 100644 --- a/tests/web/test_metadata.py +++ b/tests/web/test_metadata.py @@ -23,11 +23,9 @@ def test_get_metadata_with_missing_text_search(client): @pytest.mark.bdb @pytest.mark.tendermint -def test_get_metadata_tendermint(client, tb, alice): +def test_get_metadata_tendermint(client, b, alice): from bigchaindb.models import Transaction - b = tb - # test returns empty list when no assets are found res = client.get(METADATA_ENDPOINT + '?search=abc') assert res.json == [] @@ -53,11 +51,9 @@ def test_get_metadata_tendermint(client, tb, alice): @pytest.mark.bdb @pytest.mark.tendermint -def test_get_metadata_limit_tendermint(client, tb, alice): +def test_get_metadata_limit_tendermint(client, b, alice): from bigchaindb.models import Transaction - b = tb - # create two assets asset1 = {'msg': 'abc 1'} meta1 = {'key': 'meta 1'} diff --git a/tests/web/test_parameters.py b/tests/web/test_parameters.py index ccf3119b..3eb8ab2a 100644 --- a/tests/web/test_parameters.py +++ b/tests/web/test_parameters.py @@ -4,6 +4,8 @@ import pytest +pytestmark = pytest.mark.tendermint + def test_valid_txid(): from bigchaindb.web.views.parameters import valid_txid diff --git a/tests/web/test_server.py b/tests/web/test_server.py index 215aa980..5fce3629 100644 --- a/tests/web/test_server.py +++ b/tests/web/test_server.py @@ -2,6 +2,10 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 +import pytest + +pytestmark = pytest.mark.tendermint + def test_settings(): import bigchaindb diff --git a/tests/web/test_validators.py b/tests/web/test_validators.py index d26d8cf1..714ceee4 100644 --- a/tests/web/test_validators.py +++ b/tests/web/test_validators.py @@ -9,7 +9,7 @@ pytestmark = pytest.mark.tendermint VALIDATORS_ENDPOINT = '/api/v1/validators/' -def test_get_validators_endpoint(b, client, monkeypatch): +def test_get_validators_endpoint(b, client): validator_set = [{'address': 'F5426F0980E36E03044F74DD414248D29ABCBDB2', 'pub_key': {'data': '4E2685D9016126864733225BE00F005515200727FBAB1312FC78C8B76831255A', 'type': 'ed25519'}, diff --git a/tests/web/test_websocket_server.py b/tests/web/test_websocket_server.py index 64309137..1a2b55af 100644 --- a/tests/web/test_websocket_server.py +++ b/tests/web/test_websocket_server.py @@ -136,7 +136,6 @@ def test_websocket_block_event(b, test_client, loop): @pytest.mark.skip('Processes are not stopping properly, and the whole test suite would hang') -@pytest.mark.genesis def test_integration_from_webapi_to_websocket(monkeypatch, client, loop): # XXX: I think that the `pytest-aiohttp` plugin is sparkling too much # magic in the `asyncio` module: running this test without monkey-patching @@ -152,6 +151,8 @@ def test_integration_from_webapi_to_websocket(monkeypatch, client, loop): import aiohttp from bigchaindb.common import crypto + # TODO processes does not exist anymore, when reactivating this test it + # will fail because of this from bigchaindb import processes from bigchaindb.models import Transaction