mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Problem: Need tests to verify that the unified conclusion for ValidatorElection and MigrationElection works when both election types conclude in the same block
Solution: Wrote some integration tests
This commit is contained in:
parent
9942867e47
commit
cc0ce0e5e4
@ -20,15 +20,17 @@ from logging.config import dictConfig
|
||||
import pytest
|
||||
from pymongo import MongoClient
|
||||
|
||||
from bigchaindb import ValidatorElection
|
||||
from bigchaindb.common import crypto
|
||||
from bigchaindb.log import setup_logging
|
||||
from bigchaindb.migrations.migration_election import MigrationElection
|
||||
from bigchaindb.tendermint_utils import key_from_base64
|
||||
from bigchaindb.backend import schema
|
||||
from bigchaindb.backend import schema, query
|
||||
from bigchaindb.common.crypto import (key_pair_from_ed25519_key,
|
||||
public_key_from_ed25519_key)
|
||||
from bigchaindb.common.exceptions import DatabaseDoesNotExist
|
||||
from bigchaindb.lib import Block
|
||||
|
||||
from tests.utils import gen_vote
|
||||
|
||||
TEST_DB_NAME = 'bigchain_test'
|
||||
|
||||
@ -694,3 +696,117 @@ def new_validator():
|
||||
'type': 'ed25519-base16'},
|
||||
'power': power,
|
||||
'node_id': node_id}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_upsert_validator_election(b_mock, node_key, new_validator):
|
||||
voters = ValidatorElection.recipients(b_mock)
|
||||
return ValidatorElection.generate([node_key.public_key],
|
||||
voters,
|
||||
new_validator, None).sign([node_key.private_key])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_upsert_validator_election_2(b_mock, node_key, new_validator):
|
||||
voters = ValidatorElection.recipients(b_mock)
|
||||
return ValidatorElection.generate([node_key.public_key],
|
||||
voters,
|
||||
new_validator, None).sign([node_key.private_key])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_migration_election(b_mock, node_key):
|
||||
voters = MigrationElection.recipients(b_mock)
|
||||
return MigrationElection.generate([node_key.public_key],
|
||||
voters,
|
||||
{}, None).sign([node_key.private_key])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_migration_election_2(b_mock, node_key):
|
||||
voters = MigrationElection.recipients(b_mock)
|
||||
return MigrationElection.generate([node_key.public_key],
|
||||
voters,
|
||||
{}, None).sign([node_key.private_key])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ongoing_validator_election(b, valid_upsert_validator_election, ed25519_node_keys):
|
||||
validators = b.get_validators(height=1)
|
||||
genesis_validators = {'validators': validators,
|
||||
'height': 0,
|
||||
'election_id': None}
|
||||
query.store_validator_set(b.connection, genesis_validators)
|
||||
|
||||
b.store_bulk_transactions([valid_upsert_validator_election])
|
||||
block_1 = Block(app_hash='hash_1', height=1, transactions=[valid_upsert_validator_election.id])
|
||||
b.store_block(block_1._asdict())
|
||||
return valid_upsert_validator_election
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ongoing_validator_election_2(b, valid_upsert_validator_election_2, ed25519_node_keys):
|
||||
validators = b.get_validators(height=1)
|
||||
genesis_validators = {'validators': validators,
|
||||
'height': 0,
|
||||
'election_id': None}
|
||||
query.store_validator_set(b.connection, genesis_validators)
|
||||
|
||||
b.store_bulk_transactions([valid_upsert_validator_election_2])
|
||||
block_1 = Block(app_hash='hash_2', height=1, transactions=[valid_upsert_validator_election_2.id])
|
||||
b.store_block(block_1._asdict())
|
||||
return valid_upsert_validator_election_2
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ongoing_migration_election(b, valid_migration_election, ed25519_node_keys):
|
||||
|
||||
b.store_bulk_transactions([valid_migration_election])
|
||||
block_1 = Block(app_hash='hash_1', height=1, transactions=[valid_migration_election.id])
|
||||
b.store_block(block_1._asdict())
|
||||
return valid_migration_election
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ongoing_migration_election_2(b, valid_migration_election_2, ed25519_node_keys):
|
||||
|
||||
b.store_bulk_transactions([valid_migration_election_2])
|
||||
block_1 = Block(app_hash='hash_2', height=1, transactions=[valid_migration_election_2.id])
|
||||
b.store_block(block_1._asdict())
|
||||
return valid_migration_election_2
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def validator_election_votes(b_mock, ongoing_validator_election, ed25519_node_keys):
|
||||
voters = ValidatorElection.recipients(b_mock)
|
||||
votes = generate_votes(ongoing_validator_election, voters, ed25519_node_keys)
|
||||
return votes
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def validator_election_votes_2(b_mock, ongoing_validator_election_2, ed25519_node_keys):
|
||||
voters = ValidatorElection.recipients(b_mock)
|
||||
votes = generate_votes(ongoing_validator_election_2, voters, ed25519_node_keys)
|
||||
return votes
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def migration_election_votes(b_mock, ongoing_migration_election, ed25519_node_keys):
|
||||
voters = MigrationElection.recipients(b_mock)
|
||||
votes = generate_votes(ongoing_migration_election, voters, ed25519_node_keys)
|
||||
return votes
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def migration_election_votes_2(b_mock, ongoing_migration_election_2, ed25519_node_keys):
|
||||
voters = MigrationElection.recipients(b_mock)
|
||||
votes = generate_votes(ongoing_migration_election_2, voters, ed25519_node_keys)
|
||||
return votes
|
||||
|
||||
|
||||
def generate_votes(election, voters, keys):
|
||||
votes = []
|
||||
for voter in range(len(voters)):
|
||||
v = gen_vote(election, voter, keys)
|
||||
votes.append(v)
|
||||
return votes
|
||||
|
||||
0
tests/elections/__init__.py
Normal file
0
tests/elections/__init__.py
Normal file
60
tests/elections/test_election.py
Normal file
60
tests/elections/test_election.py
Normal file
@ -0,0 +1,60 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from bigchaindb.elections.election import Election
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_approved_elections_one_migration_one_upsert(b,
|
||||
ongoing_validator_election, validator_election_votes,
|
||||
ongoing_migration_election, migration_election_votes):
|
||||
txns = validator_election_votes + \
|
||||
migration_election_votes
|
||||
mock_chain_migration, mock_store_validator = run_approved_elections(b, txns)
|
||||
mock_chain_migration.assert_called_once()
|
||||
mock_store_validator.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_approved_elections_two_migrations_two_upsert(b,
|
||||
ongoing_validator_election, validator_election_votes,
|
||||
ongoing_validator_election_2, validator_election_votes_2,
|
||||
ongoing_migration_election, migration_election_votes,
|
||||
ongoing_migration_election_2, migration_election_votes_2):
|
||||
txns = validator_election_votes + \
|
||||
validator_election_votes_2 + \
|
||||
migration_election_votes + \
|
||||
migration_election_votes_2
|
||||
mock_chain_migration, mock_store_validator = run_approved_elections(b, txns)
|
||||
mock_chain_migration.assert_called_once()
|
||||
mock_store_validator.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_approved_elections_two_migrations_one_upsert(b,
|
||||
ongoing_validator_election, validator_election_votes,
|
||||
ongoing_migration_election, migration_election_votes,
|
||||
ongoing_migration_election_2, migration_election_votes_2):
|
||||
txns = validator_election_votes + \
|
||||
migration_election_votes + \
|
||||
migration_election_votes_2
|
||||
mock_chain_migration, mock_store_validator = run_approved_elections(b, txns)
|
||||
mock_chain_migration.assert_called_once()
|
||||
mock_store_validator.assert_called_once()
|
||||
|
||||
|
||||
def test_approved_elections_no_elections(b):
|
||||
txns = []
|
||||
mock_chain_migration, mock_store_validator = run_approved_elections(b, txns)
|
||||
mock_chain_migration.assert_not_called()
|
||||
mock_store_validator.assert_not_called()
|
||||
|
||||
|
||||
def run_approved_elections(bigchain, txns):
|
||||
mock_chain_migration = MagicMock()
|
||||
mock_store_validator = MagicMock()
|
||||
bigchain.migrate_abci_chain = mock_chain_migration
|
||||
bigchain.store_validator_set = mock_store_validator
|
||||
Election.approved_elections(bigchain, 1, txns)
|
||||
return mock_chain_migration, mock_store_validator
|
||||
@ -5,20 +5,10 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from bigchaindb import Vote
|
||||
from bigchaindb.backend.localmongodb import query
|
||||
from bigchaindb.lib import Block
|
||||
from bigchaindb.upsert_validator import ValidatorElection
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_upsert_validator_election(b_mock, node_key, new_validator):
|
||||
voters = ValidatorElection.recipients(b_mock)
|
||||
return ValidatorElection.generate([node_key.public_key],
|
||||
voters,
|
||||
new_validator, None).sign([node_key.private_key])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_upsert_validator_election_b(b, node_key, new_validator):
|
||||
voters = ValidatorElection.recipients(b)
|
||||
@ -37,30 +27,16 @@ def fixed_seed_election(b_mock, node_key, new_validator):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ongoing_election(b, valid_upsert_validator_election, ed25519_node_keys):
|
||||
validators = b.get_validators(height=1)
|
||||
genesis_validators = {'validators': validators,
|
||||
'height': 0,
|
||||
'election_id': None}
|
||||
query.store_validator_set(b.connection, genesis_validators)
|
||||
|
||||
b.store_bulk_transactions([valid_upsert_validator_election])
|
||||
block_1 = Block(app_hash='hash_1', height=1, transactions=[valid_upsert_validator_election.id])
|
||||
b.store_block(block_1._asdict())
|
||||
return valid_upsert_validator_election
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def concluded_election(b, ongoing_election, ed25519_node_keys):
|
||||
def concluded_election(b, ongoing_validator_election, ed25519_node_keys):
|
||||
election_result = {'height': 2,
|
||||
'election_id': ongoing_election.id}
|
||||
'election_id': ongoing_validator_election.id}
|
||||
|
||||
query.store_election_results(b.connection, election_result)
|
||||
return ongoing_election
|
||||
return ongoing_validator_election
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def inconclusive_election(b, ongoing_election, new_validator):
|
||||
def inconclusive_election(b, ongoing_validator_election, new_validator):
|
||||
validators = b.get_validators(height=1)
|
||||
validators[0]['voting_power'] = 15
|
||||
validator_update = {'validators': validators,
|
||||
@ -68,20 +44,4 @@ def inconclusive_election(b, ongoing_election, new_validator):
|
||||
'election_id': 'some_other_election'}
|
||||
|
||||
query.store_validator_set(b.connection, validator_update)
|
||||
return ongoing_election
|
||||
|
||||
|
||||
def vote(election, voter, keys, b):
|
||||
election_input = election.to_inputs()[voter]
|
||||
votes = election.outputs[voter].amount
|
||||
public_key = election_input.owners_before[0]
|
||||
key = keys[public_key]
|
||||
|
||||
election_pub_key = ValidatorElection.to_public_key(election.id)
|
||||
|
||||
v = Vote.generate([election_input],
|
||||
[([election_pub_key], votes)],
|
||||
election_id=election.id)\
|
||||
.sign([key.private_key])
|
||||
b.store_bulk_transactions([v])
|
||||
return v
|
||||
return ongoing_validator_election
|
||||
|
||||
@ -12,7 +12,7 @@ from bigchaindb.common.exceptions import AmountError
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
from bigchaindb.common.exceptions import ValidationError
|
||||
from bigchaindb.elections.vote import Vote
|
||||
from tests.utils import generate_block
|
||||
from tests.utils import generate_block, gen_vote
|
||||
|
||||
pytestmark = [pytest.mark.execute]
|
||||
|
||||
@ -341,22 +341,6 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys):
|
||||
# ============================================================================
|
||||
# Helper functions
|
||||
# ============================================================================
|
||||
def to_inputs(election, i, ed25519_node_keys):
|
||||
input0 = election.to_inputs()[i]
|
||||
votes = election.outputs[i].amount
|
||||
public_key0 = input0.owners_before[0]
|
||||
key0 = ed25519_node_keys[public_key0]
|
||||
return (input0, votes, key0)
|
||||
|
||||
|
||||
def gen_vote(election, i, ed25519_node_keys):
|
||||
(input_i, votes_i, key_i) = to_inputs(election, i, ed25519_node_keys)
|
||||
election_pub_key = ValidatorElection.to_public_key(election.id)
|
||||
return Vote.generate([input_i],
|
||||
[([election_pub_key], votes_i)],
|
||||
election_id=election.id)\
|
||||
.sign([key_i.private_key])
|
||||
|
||||
|
||||
def reset_validator_set(b, node_keys, height):
|
||||
validators = []
|
||||
|
||||
@ -111,9 +111,9 @@ def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixe
|
||||
tx_election.validate(b_mock)
|
||||
|
||||
|
||||
def test_get_status_ongoing(b, ongoing_election, new_validator):
|
||||
def test_get_status_ongoing(b, ongoing_validator_election, new_validator):
|
||||
status = ValidatorElection.ONGOING
|
||||
resp = ongoing_election.get_status(b)
|
||||
resp = ongoing_validator_election.get_status(b)
|
||||
assert resp == status
|
||||
|
||||
|
||||
@ -158,13 +158,13 @@ def test_get_status_inconclusive(b, inconclusive_election, new_validator):
|
||||
assert resp == status
|
||||
|
||||
|
||||
def test_upsert_validator_show(caplog, ongoing_election, b):
|
||||
def test_upsert_validator_show(caplog, ongoing_validator_election, b):
|
||||
from bigchaindb.commands.bigchaindb import run_election_show
|
||||
|
||||
election_id = ongoing_election.id
|
||||
public_key = public_key_to_base64(ongoing_election.asset['data']['public_key']['value'])
|
||||
power = ongoing_election.asset['data']['power']
|
||||
node_id = ongoing_election.asset['data']['node_id']
|
||||
election_id = ongoing_validator_election.id
|
||||
public_key = public_key_to_base64(ongoing_validator_election.asset['data']['public_key']['value'])
|
||||
power = ongoing_validator_election.asset['data']['power']
|
||||
node_id = ongoing_validator_election.asset['data']['node_id']
|
||||
status = ValidatorElection.ONGOING
|
||||
|
||||
show_args = Namespace(action='show',
|
||||
|
||||
@ -4,8 +4,10 @@
|
||||
|
||||
from functools import singledispatch
|
||||
|
||||
from bigchaindb import Vote
|
||||
from bigchaindb.backend.localmongodb.connection import LocalMongoDBConnection
|
||||
from bigchaindb.backend.schema import TABLES
|
||||
from bigchaindb.elections.election import Election
|
||||
|
||||
|
||||
@singledispatch
|
||||
@ -33,3 +35,20 @@ def generate_block(bigchain):
|
||||
code, message = bigchain.write_transaction(tx, 'broadcast_tx_commit')
|
||||
assert code == 202
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
def to_inputs(election, i, ed25519_node_keys):
|
||||
input0 = election.to_inputs()[i]
|
||||
votes = election.outputs[i].amount
|
||||
public_key0 = input0.owners_before[0]
|
||||
key0 = ed25519_node_keys[public_key0]
|
||||
return (input0, votes, key0)
|
||||
|
||||
|
||||
def gen_vote(election, i, ed25519_node_keys):
|
||||
(input_i, votes_i, key_i) = to_inputs(election, i, ed25519_node_keys)
|
||||
election_pub_key = Election.to_public_key(election.id)
|
||||
return Vote.generate([input_i],
|
||||
[([election_pub_key], votes_i)],
|
||||
election_id=election.id)\
|
||||
.sign([key_i.private_key])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user