Feat/960/test mongodb queries (#1030)

* Created tests to mongodb queries

Small fix to queries

* cleanup pytest markers
This commit is contained in:
Rodolphe Marques 2017-01-10 16:49:30 +01:00 committed by GitHub
parent b4602b6283
commit c91eff70e5
2 changed files with 388 additions and 14 deletions

View File

@ -47,19 +47,25 @@ def get_stale_transactions(conn, reassign_delay):
@register_query(MongoDBConnection)
def get_transaction_from_block(conn, transaction_id, block_id):
return conn.db['bigchain'].aggregate([
{'$match': {'id': block_id}},
{'$project': {
'block.transactions': {
'$filter': {
'input': '$block.transactions',
'as': 'transaction',
'cond': {
'$eq': ['$$transaction.id', transaction_id]
try:
return conn.db['bigchain'].aggregate([
{'$match': {'id': block_id}},
{'$project': {
'block.transactions': {
'$filter': {
'input': '$block.transactions',
'as': 'transaction',
'cond': {
'$eq': ['$$transaction.id', transaction_id]
}
}
}
}
}}]).next()['block']['transactions'][0]
}}]).next()['block']['transactions'].pop()
except (StopIteration, IndexError):
# StopIteration is raised if the block was not found
# IndexError is returned if the block is found but no transactions
# match
return
@register_query(MongoDBConnection)
@ -207,9 +213,10 @@ def write_vote(conn, vote):
@register_query(MongoDBConnection)
def get_genesis_block(conn):
return conn.db['bigchain'].find_one({
'block.transactions.0.operation': 'GENESIS'
})
return conn.db['bigchain'].find_one(
{'block.transactions.0.operation': 'GENESIS'},
{'_id': False}
)
@register_query(MongoDBConnection)

View File

@ -0,0 +1,367 @@
import pytest
pytestmark = pytest.mark.bdb
def test_write_transaction(signed_create_tx):
from bigchaindb.backend import connect, query
conn = connect()
# write the transaction
query.write_transaction(conn, signed_create_tx.to_dict())
# get the transaction
tx_db = conn.db.backlog.find_one({'id': signed_create_tx.id},
{'_id': False})
assert tx_db == signed_create_tx.to_dict()
def test_update_transaction(signed_create_tx):
from bigchaindb.backend import connect, query
conn = connect()
# update_transaction can update any field we want, but lets update the
# same fields that are updated by bigchaindb core.
signed_create_tx = signed_create_tx.to_dict()
signed_create_tx.update({'assignee': 'aaa', 'assignment_timestamp': 10})
conn.db.backlog.insert_one(signed_create_tx)
query.update_transaction(conn, signed_create_tx['id'],
{'assignee': 'bbb', 'assignment_timestamp': 20})
tx_db = conn.db.backlog.find_one({'id': signed_create_tx['id']},
{'_id': False})
assert tx_db['assignee'] == 'bbb'
assert tx_db['assignment_timestamp'] == 20
def test_delete_transaction(signed_create_tx):
from bigchaindb.backend import connect, query
conn = connect()
# write_the transaction
result = conn.db.backlog.insert_one(signed_create_tx.to_dict())
# delete transaction
query.delete_transaction(conn, signed_create_tx.id)
tx_db = conn.db.backlog.find_one({'_id': result.inserted_id})
assert tx_db is None
def test_get_stale_transactions(signed_create_tx):
import time
from bigchaindb.backend import connect, query
conn = connect()
# create two transaction, one of them stale
tx1 = signed_create_tx.to_dict()
tx1.update({'id': 'notstale', 'assignment_timestamp': time.time()})
tx2 = signed_create_tx.to_dict()
tx2.update({'id': 'stale', 'assignment_timestamp': time.time() - 60})
# write the transactions
conn.db.backlog.insert_one(tx1)
conn.db.backlog.insert_one(tx2)
# get stale transactions
stale_txs = list(query.get_stale_transactions(conn, 30))
assert len(stale_txs) == 1
assert stale_txs[0]['id'] == 'stale'
def test_get_transaction_from_block(user_pk):
from bigchaindb.backend import connect, query
from bigchaindb.models import Transaction, Block
conn = connect()
# create a block with 2 transactions
txs = [
Transaction.create([user_pk], [([user_pk], 1)]),
Transaction.create([user_pk], [([user_pk], 1)]),
]
block = Block(transactions=txs)
conn.db.bigchain.insert_one(block.to_dict())
tx_db = query.get_transaction_from_block(conn, txs[0].id, block.id)
assert tx_db == txs[0].to_dict()
assert query.get_transaction_from_block(conn, txs[0].id, 'aaa') is None
assert query.get_transaction_from_block(conn, 'aaa', block.id) is None
def test_get_transaction_from_backlog(create_tx):
from bigchaindb.backend import connect, query
conn = connect()
# insert transaction
conn.db.backlog.insert_one(create_tx.to_dict())
# query the backlog
tx_db = query.get_transaction_from_backlog(conn, create_tx.id)
assert tx_db == create_tx.to_dict()
def test_get_block_status_from_transaction(create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create a block
block = Block(transactions=[create_tx], voters=['aaa', 'bbb', 'ccc'])
# insert block
conn.db.bigchain.insert_one(block.to_dict())
block_db = list(query.get_blocks_status_from_transaction(conn,
create_tx.id))
assert len(block_db) == 1
block_db = block_db.pop()
assert block_db['id'] == block.id
assert block_db['block']['voters'] == block.voters
def test_get_txids_by_asset_id(signed_create_tx, signed_transfer_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert two blocks, one for the create and one for the
# transfer transaction
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
block = Block(transactions=[signed_transfer_tx])
conn.db.bigchain.insert_one(block.to_dict())
txids = list(query.get_txids_by_asset_id(conn, signed_create_tx.id))
assert len(txids) == 2
assert txids == [signed_create_tx.id, signed_transfer_tx.id]
def test_get_asset_by_id(create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create asset and block
create_tx.asset = {'msg': 'aaa'}
block = Block(transactions=[create_tx])
conn.db.bigchain.insert_one(block.to_dict())
asset = list(query.get_asset_by_id(conn, create_tx.id))
assert len(asset) == 1
assert asset[0]['asset'] == create_tx.asset
def test_get_spent(signed_create_tx, signed_transfer_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert two blocks, one for the create and one for the
# transfer transaction
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
block = Block(transactions=[signed_transfer_tx])
conn.db.bigchain.insert_one(block.to_dict())
spents = list(query.get_spent(conn, signed_create_tx.id, 0))
assert len(spents) == 1
assert spents[0] == signed_transfer_tx.to_dict()
def test_get_owned_ids(signed_create_tx, user_pk):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert a block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
owned_ids = list(query.get_owned_ids(conn, user_pk))
assert len(owned_ids) == 1
assert owned_ids[0] == signed_create_tx.to_dict()
def test_get_votes_by_block_id(signed_create_tx, structurally_valid_vote):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert a block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
# create and insert some votes
structurally_valid_vote['vote']['voting_for_block'] = block.id
conn.db.votes.insert_one(structurally_valid_vote)
structurally_valid_vote['vote']['voting_for_block'] = block.id
structurally_valid_vote.pop('_id')
conn.db.votes.insert_one(structurally_valid_vote)
votes = list(query.get_votes_by_block_id(conn, block.id))
assert len(votes) == 2
assert votes[0]['vote']['voting_for_block'] == block.id
assert votes[1]['vote']['voting_for_block'] == block.id
def test_get_votes_by_block_id_and_voter(signed_create_tx,
structurally_valid_vote):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert a block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
# create and insert some votes
structurally_valid_vote['vote']['voting_for_block'] = block.id
structurally_valid_vote['node_pubkey'] = 'aaa'
conn.db.votes.insert_one(structurally_valid_vote)
structurally_valid_vote['vote']['voting_for_block'] = block.id
structurally_valid_vote['node_pubkey'] = 'bbb'
structurally_valid_vote.pop('_id')
conn.db.votes.insert_one(structurally_valid_vote)
votes = list(query.get_votes_by_block_id_and_voter(conn, block.id, 'aaa'))
assert len(votes) == 1
assert votes[0]['node_pubkey'] == 'aaa'
def test_write_block(signed_create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and write block
block = Block(transactions=[signed_create_tx])
query.write_block(conn, block)
block_db = conn.db.bigchain.find_one({'id': block.id}, {'_id': False})
assert block_db == block.to_dict()
def test_get_block(signed_create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
block_db = query.get_block(conn, block.id)
assert block_db == block.to_dict()
def test_has_transaction(signed_create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
assert query.has_transaction(conn, signed_create_tx.id)
assert query.has_transaction(conn, 'aaa') is False
def test_count_blocks(signed_create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert some blocks
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
conn.db.bigchain.insert_one(block.to_dict())
assert query.count_blocks(conn) == 2
def test_count_backlog(signed_create_tx):
from bigchaindb.backend import connect, query
conn = connect()
# create and insert some transations
conn.db.backlog.insert_one(signed_create_tx.to_dict())
signed_create_tx.metadata = {'msg': 'aaa'}
conn.db.backlog.insert_one(signed_create_tx.to_dict())
assert query.count_backlog(conn) == 2
def test_write_vote(structurally_valid_vote):
from bigchaindb.backend import connect, query
conn = connect()
# write a vote
query.write_vote(conn, structurally_valid_vote)
# retrieve the vote
vote_db = conn.db.votes.find_one(
{'node_pubkey': structurally_valid_vote['node_pubkey']}
)
assert vote_db == structurally_valid_vote
def test_get_genesis_block(genesis_block):
from bigchaindb.backend import connect, query
conn = connect()
assert query.get_genesis_block(conn) == genesis_block.to_dict()
def test_get_last_voted_block(genesis_block, signed_create_tx, b):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
from bigchaindb.common.exceptions import CyclicBlockchainError
conn = connect()
# check that the last voted block is the genesis block
assert query.get_last_voted_block(conn, b.me) == genesis_block.to_dict()
# create and insert a new vote and block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
vote = b.vote(block.id, genesis_block.id, True)
conn.db.votes.insert_one(vote)
assert query.get_last_voted_block(conn, b.me) == block.to_dict()
# force a bad chain
vote.pop('_id')
vote['vote']['voting_for_block'] = genesis_block.id
vote['vote']['previous_block'] = block.id
conn.db.votes.insert_one(vote)
with pytest.raises(CyclicBlockchainError):
query.get_last_voted_block(conn, b.me)
def test_get_unvoted_blocks(signed_create_tx):
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
# create and insert a block
block = Block(transactions=[signed_create_tx], node_pubkey='aaa')
conn.db.bigchain.insert_one(block.to_dict())
unvoted_blocks = list(query.get_unvoted_blocks(conn, 'aaa'))
assert len(unvoted_blocks) == 1
assert unvoted_blocks[0] == block.to_dict()