Test Bigchain.get_blocks_status_containing_tx() (#399)

* Test Bigchain.get_blocks_status_containing_tx()

exception case

* Test Bigchaindb.has_previous_vote()

* Add missing blank lines (pep 8)

* Group imports

* Move ImproperVoteError into .exceptions.py

* Simplify logic

* Simplify formatting

* Imrpove the docstrings a bit

* Move GenesisBlockAlreadyExistsError

into .exceptions.py

* Remove unused import

* Add missing blank line

* Remove extra blank line

* Group imports from same module together

* Add test for Bigchain.transaction_exists()
This commit is contained in:
Sylvain Bellemare 2016-06-28 14:19:22 +02:00 committed by GitHub
parent ac680cf5e9
commit 7bd6d485bc
5 changed files with 74 additions and 27 deletions

View File

@ -6,18 +6,7 @@ import rethinkdb as r
import rapidjson
import bigchaindb
from bigchaindb import util
from bigchaindb import config_utils
from bigchaindb import exceptions
from bigchaindb import crypto
class GenesisBlockAlreadyExistsError(Exception):
pass
class ImproperVoteError(Exception):
pass
from bigchaindb import config_utils, crypto, exceptions, util
class Bigchain(object):
@ -446,17 +435,22 @@ class Bigchain(object):
block (dict): block to check.
Returns:
True if this block already has a valid vote from this node, False otherwise. If
there is already a vote, but the vote is invalid, raises an ImproperVoteError
bool: :const:`True` if this block already has a
valid vote from this node, :const:`False` otherwise.
Raises:
ImproperVoteError: If there is already a vote,
but the vote is invalid.
"""
if block['votes']:
for vote in block['votes']:
if vote['node_pubkey'] == self.me:
if util.verify_vote_signature(block, vote):
return True
else:
raise ImproperVoteError('Block {block_id} already has an incorrectly signed vote '
'from public key {me}').format(block_id=block['id'], me=self.me)
if not util.verify_vote_signature(block, vote):
raise exceptions.ImproperVoteError(
'Block {} already has an incorrectly signed vote from public key {}'
).format(block['id'], self.me)
return True
return False
def is_valid_block(self, block):
@ -509,7 +503,7 @@ class Bigchain(object):
blocks_count = r.table('bigchain').count().run(self.conn)
if blocks_count:
raise GenesisBlockAlreadyExistsError('Cannot create the Genesis block')
raise exceptions.GenesisBlockAlreadyExistsError('Cannot create the Genesis block')
payload = {'message': 'Hello World from the BigchainDB'}
transaction = self.create_transaction([self.me], [self.me], None, 'GENESIS', payload=payload)

View File

@ -1,36 +1,54 @@
"""Custom exceptions used in the `bigchaindb` package.
"""
class OperationError(Exception):
"""Raised when an operation cannot go through"""
class TransactionDoesNotExist(Exception):
"""Raised if the transaction is not in the database"""
class TransactionOwnerError(Exception):
"""Raised if a user tries to transfer a transaction they don't own"""
class DoubleSpend(Exception):
"""Raised if a double spend is found"""
class InvalidHash(Exception):
"""Raised if there was an error checking the hash for a particular operation"""
class InvalidSignature(Exception):
"""Raised if there was an error checking the signature for a particular operation"""
class DatabaseAlreadyExists(Exception):
"""Raised when trying to create the database but the db is already there"""
class DatabaseDoesNotExist(Exception):
"""Raised when trying to delete the database but the db is not there"""
class KeypairNotFoundException(Exception):
"""Raised if operation cannot proceed because the keypair was not given"""
class KeypairMismatchException(Exception):
"""Raised if the private key(s) provided for signing don't match any of the curret owner(s)"""
class StartupError(Exception):
"""Raised when there is an error starting up the system"""
class ImproperVoteError(Exception):
"""Raised when an invalid vote is found"""
class GenesisBlockAlreadyExistsError(Exception):
"""Raised when trying to create the already existing genesis block"""

View File

@ -9,7 +9,6 @@ Tasks:
import pytest
import rethinkdb as r
import bigchaindb
from bigchaindb import Bigchain
from bigchaindb.db import get_conn
@ -73,6 +72,7 @@ def setup_database(request, node_config):
@pytest.fixture(scope='function', autouse=True)
def cleanup_tables(request, node_config):
db_name = node_config['database']['name']
def fin():
get_conn().repl()
try:
@ -87,11 +87,12 @@ def cleanup_tables(request, node_config):
@pytest.fixture
def inputs(user_vk, amount=1, b=None):
from bigchaindb.exceptions import GenesisBlockAlreadyExistsError
# 1. create the genesis block
b = b or Bigchain()
try:
b.create_genesis_block()
except bigchaindb.core.GenesisBlockAlreadyExistsError:
except GenesisBlockAlreadyExistsError:
pass
# 2. create block with transactions for `USER` to spend
@ -105,4 +106,3 @@ def inputs(user_vk, amount=1, b=None):
block = b.create_block(transactions)
b.write_block(block, durability='hard')
return block

View File

@ -8,9 +8,7 @@ import rethinkdb as r
import cryptoconditions as cc
import bigchaindb
from bigchaindb import util
from bigchaindb import exceptions
from bigchaindb import crypto
from bigchaindb import crypto, exceptions, util
from bigchaindb.voter import Voter
from bigchaindb.block import Block, BlockDeleteRevert
@ -178,7 +176,7 @@ class TestBigchainApi(object):
def test_create_genesis_block_fails_if_table_not_empty(self, b):
b.create_genesis_block()
with pytest.raises(bigchaindb.core.GenesisBlockAlreadyExistsError):
with pytest.raises(exceptions.GenesisBlockAlreadyExistsError):
b.create_genesis_block()
genesis_blocks = list(r.table('bigchain')

View File

@ -1,3 +1,7 @@
from collections import namedtuple
from rethinkdb.ast import RqlQuery
import pytest
@ -58,3 +62,36 @@ def test_bigchain_class_initialization_with_parameters(config):
assert bigchain.nodes_except_me == init_kwargs['keyring']
assert bigchain.consensus == BaseConsensusRules
assert bigchain._conn is None
def test_get_blocks_status_containing_tx(monkeypatch):
from bigchaindb.core import Bigchain
blocks = [
{'id': 1}, {'id': 2}
]
monkeypatch.setattr(
Bigchain, 'search_block_election_on_index', lambda x, y, z: blocks)
monkeypatch.setattr(
Bigchain, 'block_election_status', lambda x, y: Bigchain.BLOCK_VALID)
bigchain = Bigchain(public_key='pubkey', private_key='privkey')
with pytest.raises(Exception):
bigchain.get_blocks_status_containing_tx('txid')
def test_has_previous_vote(monkeypatch):
from bigchaindb.core import Bigchain
monkeypatch.setattr(
'bigchaindb.util.verify_vote_signature', lambda block, vote: False)
bigchain = Bigchain(public_key='pubkey', private_key='privkey')
block = {'votes': ({'node_pubkey': 'pubkey'},)}
with pytest.raises(Exception):
bigchain.has_previous_vote(block)
@pytest.mark.parametrize('items,exists', (((0,), True), ((), False)))
def test_transaction_exists(monkeypatch, items, exists):
from bigchaindb.core import Bigchain
monkeypatch.setattr(
RqlQuery, 'run', lambda x, y: namedtuple('response', 'items')(items))
bigchain = Bigchain(public_key='pubkey', private_key='privkey')
assert bigchain.transaction_exists('txid') is exists