1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-26 11:16:44 +02:00

Resolved conflicts in fabfile.py

This commit is contained in:
troymc 2016-07-22 11:32:47 +02:00
commit c0648f7145
16 changed files with 303 additions and 99 deletions

View File

@ -526,22 +526,22 @@ class Bigchain(object):
return block
def vote(self, block, previous_block_id, decision, invalid_reason=None):
def vote(self, block_id, previous_block_id, decision, invalid_reason=None):
"""Cast your vote on the block given the previous_block_hash and the decision (valid/invalid)
return the block to the updated in the database.
Args:
block (dict): Block to vote.
block_id (str): The id of the block to vote.
previous_block_id (str): The id of the previous block.
decision (bool): Whether the block is valid or invalid.
invalid_reason (Optional[str]): Reason the block is invalid
"""
if block['id'] == previous_block_id:
if block_id == previous_block_id:
raise exceptions.CyclicBlockchainError()
vote = {
'voting_for_block': block['id'],
'voting_for_block': block_id,
'previous_block': previous_block_id,
'is_block_valid': decision,
'invalid_reason': invalid_reason,

View File

@ -18,55 +18,91 @@ def get_conn():
bigchaindb.config['database']['port'])
def get_database_name():
return bigchaindb.config['database']['name']
def create_database(conn, dbname):
if r.db_list().contains(dbname).run(conn):
raise exceptions.DatabaseAlreadyExists('Database `{}` already exists'.format(dbname))
logger.info('Create database `%s`.', dbname)
r.db_create(dbname).run(conn)
def create_table(conn, dbname, table_name):
logger.info('Create `%s` table.', table_name)
# create the table
r.db(dbname).table_create(table_name).run(conn)
def create_bigchain_secondary_index(conn, dbname):
logger.info('Create `bigchain` secondary index.')
# to order blocks by timestamp
r.db(dbname).table('bigchain')\
.index_create('block_timestamp', r.row['block']['timestamp'])\
.run(conn)
# to query the bigchain for a transaction id
r.db(dbname).table('bigchain')\
.index_create('transaction_id',
r.row['block']['transactions']['id'], multi=True)\
.run(conn)
# secondary index for payload data by UUID
r.db(dbname).table('bigchain')\
.index_create('payload_uuid',
r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\
.run(conn)
# wait for rethinkdb to finish creating secondary indexes
r.db(dbname).table('bigchain').index_wait().run(conn)
def create_backlog_secondary_index(conn, dbname):
logger.info('Create `backlog` secondary index.')
# to order transactions by timestamp
r.db(dbname).table('backlog')\
.index_create('transaction_timestamp',
r.row['transaction']['timestamp'])\
.run(conn)
# compound index to read transactions from the backlog per assignee
r.db(dbname).table('backlog')\
.index_create('assignee__transaction_timestamp',
[r.row['assignee'], r.row['transaction']['timestamp']])\
.run(conn)
# wait for rethinkdb to finish creating secondary indexes
r.db(dbname).table('backlog').index_wait().run(conn)
def create_votes_secondary_index(conn, dbname):
logger.info('Create `votes` secondary index.')
# compound index to order votes by block id and node
r.db(dbname).table('votes')\
.index_create('block_and_voter',
[r.row['vote']['voting_for_block'],
r.row['node_pubkey']])\
.run(conn)
# wait for rethinkdb to finish creating secondary indexes
r.db(dbname).table('votes').index_wait().run(conn)
def init():
# Try to access the keypair, throws an exception if it does not exist
b = bigchaindb.Bigchain()
conn = get_conn()
dbname = bigchaindb.config['database']['name']
dbname = get_database_name()
create_database(conn, dbname)
if r.db_list().contains(dbname).run(conn):
raise exceptions.DatabaseAlreadyExists('Database `{}` already exists'.format(dbname))
table_names = ['bigchain', 'backlog', 'votes']
for table_name in table_names:
create_table(conn, dbname, table_name)
create_bigchain_secondary_index(conn, dbname)
create_backlog_secondary_index(conn, dbname)
create_votes_secondary_index(conn, dbname)
logger.info('Create:')
logger.info(' - database `%s`', dbname)
r.db_create(dbname).run(conn)
logger.info(' - tables')
# create the tables
r.db(dbname).table_create('bigchain').run(conn)
r.db(dbname).table_create('backlog').run(conn)
r.db(dbname).table_create('votes').run(conn)
logger.info(' - indexes')
# create the secondary indexes
# to order blocks by timestamp
r.db(dbname).table('bigchain').index_create('block_timestamp', r.row['block']['timestamp']).run(conn)
# to order transactions by timestamp
r.db(dbname).table('backlog').index_create('transaction_timestamp', r.row['transaction']['timestamp']).run(conn)
# to query the bigchain for a transaction id
r.db(dbname).table('bigchain').index_create('transaction_id',
r.row['block']['transactions']['id'], multi=True).run(conn)
# compound index to read transactions from the backlog per assignee
r.db(dbname).table('backlog')\
.index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\
.run(conn)
# compound index to order votes by block id and node
r.db(dbname).table('votes').index_create('block_and_voter',
[r.row['vote']['voting_for_block'], r.row['node_pubkey']]).run(conn)
# secondary index for payload data by UUID
r.db(dbname).table('bigchain')\
.index_create('payload_uuid', r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\
.run(conn)
# wait for rethinkdb to finish creating secondary indexes
r.db(dbname).table('backlog').index_wait().run(conn)
r.db(dbname).table('bigchain').index_wait().run(conn)
r.db(dbname).table('votes').index_wait().run(conn)
logger.info(' - genesis block')
logger.info('Create genesis block.')
b.create_genesis_block()
logger.info('Done, have fun!')

View File

@ -136,7 +136,7 @@ class Voter(object):
return
validated_block, previous_block_id, decision = elem
vote = b.vote(validated_block, previous_block_id, decision)
vote = b.vote(validated_block['id'], previous_block_id, decision)
self.q_voted_block.put((validated_block, vote))
def update_block(self):
@ -156,7 +156,8 @@ class Voter(object):
return
block, vote = elem
logger.info('updating block %s and with vote %s', block, vote)
pretty_vote = 'valid' if vote['vote']['is_block_valid'] else 'invalid'
logger.info('voting %s for block %s', pretty_vote, block['id'])
b.write_vote(block, vote)
def bootstrap(self):

View File

@ -94,6 +94,8 @@ chmod +x add2known_hosts.sh
# Rollout base packages (dependencies) needed before
# storage backend (RethinkDB) and BigchainDB can be rolled out
fab install_base_software
fab get_pip3
fab upgrade_setuptools
if [ "$WHAT_TO_DEPLOY" == "servers" ]; then
# (Re)create the RethinkDB configuration file conf/rethinkdb.conf

View File

@ -52,24 +52,48 @@ def set_host(host_index):
@task
@parallel
def install_base_software():
# new from Troy April 5, 2016. Why? See http://tinyurl.com/lccfrsj
# sudo('rm -rf /var/lib/apt/lists/*')
# sudo('apt-get -y clean')
# from before:
# This deletes the dir where "apt-get update" stores the list of packages
sudo('rm -rf /var/lib/apt/lists/')
# Re-create that directory, and its subdirectory named "partial"
sudo('mkdir -p /var/lib/apt/lists/partial/')
# Repopulate the list of packages in /var/lib/apt/lists/
# See https://tinyurl.com/zjvj9g3
sudo('apt-get -y update')
# Configure all unpacked but unconfigured packages.
# See https://tinyurl.com/zf24hm5
sudo('dpkg --configure -a')
# Attempt to correct a system with broken dependencies in place.
# See https://tinyurl.com/zpktd7l
sudo('apt-get -y -f install')
# For some reason, repeating the last three things makes this
# installation process more reliable...
sudo('apt-get -y update')
sudo('dpkg --configure -a')
sudo('apt-get -y -f install')
sudo('apt-get -y install build-essential wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1 \
git gcc g++ python3-dev libboost-python-dev \
software-properties-common python-software-properties \
python3-setuptools ipython3 sysstat s3cmd')
sudo('easy_install3 pip')
# It seems that breaking apart
# sudo('pip3 install --upgrade pip wheel setuptools')
# into three separate statements is more reliable:
# Install the base dependencies not already installed.
sudo('apt-get -y install git g++ python3-dev')
sudo('apt-get -y -f install')
# Get an up-to-date Python 3 version of pip
@task
@parallel
def get_pip3():
# One way:
# sudo('apt-get -y install python3-setuptools')
# sudo('easy_install3 pip')
# Another way:
sudo('apt-get -y install python3-pip')
# Upgrade pip
sudo('pip3 install --upgrade pip')
sudo('pip3 install --upgrade wheel')
# Check the version of pip3
run('pip3 --version')
# Upgrade setuptools
@task
@parallel
def upgrade_setuptools():
sudo('pip3 install --upgrade setuptools')

View File

@ -1,7 +1,7 @@
The HTTP Client-Server API
==========================
Note: The HTTP client-server API is currently quite rudimentary. For example, there is no ability to do complex queries using the HTTP API. We plan to add querying capabilities in the future. If you want to build a full-featured proof-of-concept, we suggest you use :doc:`the Python Server API <../nodes/python-server-api-examples>` for now.
Note: The HTTP client-server API is currently quite rudimentary. For example, there is no ability to do complex queries using the HTTP API. We plan to add querying capabilities in the future. If you want to build a full-featured proof-of-concept, we suggest you use :doc:`the Python Server API <../drivers-clients/python-server-api-examples>` for now.
When you start Bigchaindb using `bigchaindb start`, an HTTP API is exposed at the address stored in the BigchainDB node configuration settings. The default is for that address to be:

View File

@ -7,6 +7,7 @@ BigchainDB Drivers & Clients
.. toctree::
:maxdepth: 1
python-server-api-examples
http-client-server-api
python-driver-api-examples
example-apps

View File

@ -1,10 +1,11 @@
# The Python Server API by Example
This section gives an example of using the Python Server API to interact _directly_ with a BigchainDB node running BigchainDB Server. That is, in this example, the Python code and BigchainDB Server run on the same machine.
**Currently, the HTTP Client-Server API is very rudimentary, so you may want to use the Python Server API to develop prototype clients and applications, for now. Keep in mind that in the future, clients will only be able to use the HTTP Client-Server API (and possibly other Client-Server APIs) to communicate with BigchainDB nodes.**
(One can also interact with a BigchainDB node via other APIs, including the HTTP Client-Server API.)
This section has examples of using the Python Server API to interact _directly_ with a BigchainDB node running BigchainDB Server. That is, in these examples, the Python code and BigchainDB Server run on the same machine.
One can also interact with a BigchainDB node via other APIs, including the HTTP Client-Server API.
We create a digital asset, sign it, write it to a BigchainDB Server instance, read it, transfer it to a different user, and then attempt to transfer it to another user, resulting in a double-spend error.
## Getting Started
@ -32,6 +33,7 @@ In a federation of BigchainDB nodes, each node has its own `Bigchain` instance.
The `Bigchain` class is the main API for all BigchainDB interactions, right now. It does things that BigchainDB nodes do, but it also does things that BigchainDB clients do. In the future, it will be refactored into different parts. The `Bigchain` class is documented [elsewhere (link)](../appendices/the-Bigchain-class.html).
## Create a Digital Asset
At a high level, a "digital asset" is something which can be represented digitally and can be assigned to a user. In BigchainDB, users are identified by their public key, and the data payload in a digital asset is represented using a generic [Python dict](https://docs.python.org/3.4/tutorial/datastructures.html#dictionaries).

View File

@ -13,4 +13,3 @@ BigchainDB Nodes
running-unit-tests
configuration
bigchaindb-cli
python-server-api-examples

View File

@ -35,4 +35,4 @@ bigchaindb start
That's it!
For now, you can get a good sense of how to work with BigchainDB by going through [the examples in the section on the Python Server API](nodes/python-server-api-examples.html).
For now, you can get a good sense of how to work with BigchainDB by going through [the examples in the section on the Python Server API](drivers-clients/python-server-api-examples.html).

View File

@ -1,3 +1,3 @@
# BigchainDB and Smart Contracts
BigchainDB isnt intended for running smart contracts. That said, it can do many of the things that smart contracts are used to do. For example, the owners of an asset can impose conditions that must be fulfilled by anyone wishing to transfer the asset to new owners; see the [section on conditions](models.html#conditions-and-fulfillments). BigchainDB also [supports a form of escrow](../nodes/python-server-api-examples.html#escrow).
BigchainDB isnt intended for running smart contracts. That said, it can do many of the things that smart contracts are used to do. For example, the owners of an asset can impose conditions that must be fulfilled by anyone wishing to transfer the asset to new owners; see the [section on conditions](models.html#conditions-and-fulfillments). BigchainDB also [supports a form of escrow](../drivers-clients/python-server-api-examples.html#escrow).

View File

@ -139,7 +139,7 @@ class TestBigchainApi(object):
b.write_block(block, durability='hard')
# vote the block invalid
vote = b.vote(block, b.get_last_voted_block()['id'], False)
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
b.write_vote(block, vote)
response = b.get_transaction(tx_signed["id"])
@ -280,13 +280,13 @@ class TestBigchainApi(object):
# make sure all the blocks are written at the same time
monkeypatch.setattr(util, 'timestamp', lambda: '1')
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_1['id']
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_2['id']
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_3['id']
@ -305,15 +305,15 @@ class TestBigchainApi(object):
# make sure all the blocks are written at different timestamps
monkeypatch.setattr(util, 'timestamp', lambda: '1')
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_1['id']
monkeypatch.setattr(util, 'timestamp', lambda: '2')
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_2['id']
monkeypatch.setattr(util, 'timestamp', lambda: '3')
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
assert b.get_last_voted_block()['id'] == block_3['id']
def test_no_vote_written_if_block_already_has_vote(self, b):
@ -323,11 +323,11 @@ class TestBigchainApi(object):
b.write_block(block_1, durability='hard')
b.write_vote(block_1, b.vote(block_1, genesis['id'], True))
b.write_vote(block_1, b.vote(block_1['id'], genesis['id'], True))
retrieved_block_1 = r.table('bigchain').get(block_1['id']).run(b.conn)
# try to vote again on the retrieved block, should do nothing
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1, genesis['id'], True))
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1['id'], genesis['id'], True))
retrieved_block_2 = r.table('bigchain').get(block_1['id']).run(b.conn)
assert retrieved_block_1 == retrieved_block_2
@ -337,8 +337,8 @@ class TestBigchainApi(object):
block_1 = dummy_block()
b.write_block(block_1, durability='hard')
# insert duplicate votes
vote_1 = b.vote(block_1, b.get_last_voted_block()['id'], True)
vote_2 = b.vote(block_1, b.get_last_voted_block()['id'], True)
vote_1 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
vote_2 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
vote_2['node_pubkey'] = 'aaaaaaa'
r.table('votes').insert(vote_1).run(b.conn)
r.table('votes').insert(vote_2).run(b.conn)
@ -355,7 +355,7 @@ class TestBigchainApi(object):
b.write_block(block_1, durability='hard')
# insert duplicate votes
for i in range(2):
r.table('votes').insert(b.vote(block_1, genesis['id'], True)).run(b.conn)
r.table('votes').insert(b.vote(block_1['id'], genesis['id'], True)).run(b.conn)
from bigchaindb.exceptions import MultipleVotesError
with pytest.raises(MultipleVotesError) as excinfo:
@ -372,7 +372,7 @@ class TestBigchainApi(object):
b.create_genesis_block()
block_1 = dummy_block()
b.write_block(block_1, durability='hard')
vote_1 = b.vote(block_1, b.get_last_voted_block()['id'], True)
vote_1 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
# mangle the signature
vote_1['signature'] = 'a' * 87
r.table('votes').insert(vote_1).run(b.conn)
@ -816,9 +816,9 @@ class TestBigchainBlock(object):
b.write_block(block_2, durability='hard')
b.write_block(block_3, durability='hard')
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
q_revert_delete = mp.Queue()
@ -1115,7 +1115,7 @@ class TestMultipleInputs(object):
b.write_block(block, durability='hard')
# vote the block VALID
vote = b.vote(block, genesis['id'], True)
vote = b.vote(block['id'], genesis['id'], True)
b.write_vote(block, vote)
# get input
@ -1131,7 +1131,7 @@ class TestMultipleInputs(object):
b.write_block(block, durability='hard')
# vote the block invalid
vote = b.vote(block, b.get_last_voted_block()['id'], False)
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
b.write_vote(block, vote)
owned_inputs_user1 = b.get_owned_ids(user_vk)
@ -1245,7 +1245,7 @@ class TestMultipleInputs(object):
b.write_block(block, durability='hard')
# vote the block VALID
vote = b.vote(block, genesis['id'], True)
vote = b.vote(block['id'], genesis['id'], True)
b.write_vote(block, vote)
# get input
@ -1262,7 +1262,7 @@ class TestMultipleInputs(object):
b.write_block(block, durability='hard')
# vote the block invalid
vote = b.vote(block, b.get_last_voted_block()['id'], False)
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
b.write_vote(block, vote)
response = b.get_transaction(tx_signed["id"])
spent_inputs_user1 = b.get_spent(owned_inputs_user1[0])

View File

@ -37,6 +37,113 @@ def test_init_creates_db_tables_and_indexes():
'assignee__transaction_timestamp').run(conn) is True
def test_create_database():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
assert r.db_list().contains(dbname).run(conn) is True
def test_create_bigchain_table():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'bigchain')
assert r.db(dbname).table_list().contains('bigchain').run(conn) is True
assert r.db(dbname).table_list().contains('backlog').run(conn) is False
assert r.db(dbname).table_list().contains('votes').run(conn) is False
def test_create_bigchain_secondary_index():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'bigchain')
utils.create_bigchain_secondary_index(conn, dbname)
assert r.db(dbname).table('bigchain').index_list().contains(
'block_timestamp').run(conn) is True
assert r.db(dbname).table('bigchain').index_list().contains(
'transaction_id').run(conn) is True
assert r.db(dbname).table('bigchain').index_list().contains(
'payload_uuid').run(conn) is True
def test_create_backlog_table():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'backlog')
assert r.db(dbname).table_list().contains('backlog').run(conn) is True
assert r.db(dbname).table_list().contains('bigchain').run(conn) is False
assert r.db(dbname).table_list().contains('votes').run(conn) is False
def test_create_backlog_secondary_index():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'backlog')
utils.create_backlog_secondary_index(conn, dbname)
assert r.db(dbname).table('backlog').index_list().contains(
'transaction_timestamp').run(conn) is True
assert r.db(dbname).table('backlog').index_list().contains(
'assignee__transaction_timestamp').run(conn) is True
def test_create_votes_table():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'votes')
assert r.db(dbname).table_list().contains('votes').run(conn) is True
assert r.db(dbname).table_list().contains('bigchain').run(conn) is False
assert r.db(dbname).table_list().contains('backlog').run(conn) is False
def test_create_votes_secondary_index():
conn = utils.get_conn()
dbname = utils.get_database_name()
# The db is set up by fixtures so we need to remove it
# and recreate it just with one table
r.db_drop(dbname).run(conn)
utils.create_database(conn, dbname)
utils.create_table(conn, dbname, 'votes')
utils.create_votes_secondary_index(conn, dbname)
assert r.db(dbname).table('votes').index_list().contains(
'block_and_voter').run(conn) is True
def test_init_fails_if_db_exists():
conn = utils.get_conn()
dbname = bigchaindb.config['database']['name']

View File

@ -237,7 +237,7 @@ class TestBigchainVoter(object):
# create valid block
block = dummy_block()
# retrieve vote
vote = b.vote(block, 'abc', True)
vote = b.vote(block['id'], 'abc', True)
# assert vote is correct
assert vote['vote']['voting_for_block'] == block['id']
@ -251,7 +251,7 @@ class TestBigchainVoter(object):
# create valid block
block = dummy_block()
# retrieve vote
vote = b.vote(block, 'abc', False)
vote = b.vote(block['id'], 'abc', False)
# assert vote is correct
assert vote['vote']['voting_for_block'] == block['id']
@ -372,15 +372,15 @@ class TestBlockElection(object):
test_block['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
# fake "yes" votes
valid_vote = [member.vote(test_block, 'abc', True)
valid_vote = [member.vote(test_block['id'], 'abc', True)
for member in test_federation]
# fake "no" votes
invalid_vote = [member.vote(test_block, 'abc', False)
invalid_vote = [member.vote(test_block['id'], 'abc', False)
for member in test_federation]
# fake "yes" votes with incorrect signatures
improperly_signed_valid_vote = [member.vote(test_block, 'abc', True) for
improperly_signed_valid_vote = [member.vote(test_block['id'], 'abc', True) for
member in test_federation]
[vote['vote'].update(this_should_ruin_things='lol')
for vote in improperly_signed_valid_vote]
@ -448,11 +448,11 @@ class TestBlockElection(object):
test_block['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
# fake "yes" votes
valid_vote = [member.vote(test_block, 'abc', True)
valid_vote = [member.vote(test_block['id'], 'abc', True)
for member in test_federation]
# fake "no" votes
invalid_vote = [member.vote(test_block, 'abc', False)
invalid_vote = [member.vote(test_block['id'], 'abc', False)
for member in test_federation]
r.table('votes').insert(valid_vote[:2], durability='hard').run(b.conn)
@ -490,12 +490,12 @@ class TestBlockElection(object):
test_block_2['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
# votes for block one
vote_1 = [member.vote(test_block_1, 'abc', True)
vote_1 = [member.vote(test_block_1['id'], 'abc', True)
for member in test_federation]
# votes for block two
vote_2 = [member.vote(test_block_2, 'abc', True) for member in test_federation[:2]] + \
[member.vote(test_block_2, 'abc', False) for member in test_federation[2:]]
vote_2 = [member.vote(test_block_2['id'], 'abc', True) for member in test_federation[:2]] + \
[member.vote(test_block_2['id'], 'abc', False) for member in test_federation[2:]]
# construct valid block
r.table('votes').insert(vote_1, durability='hard').run(b.conn)

View File

@ -1,4 +1,5 @@
import copy
from unittest.mock import mock_open, patch
import pytest
@ -9,6 +10,19 @@ from bigchaindb import exceptions
ORIGINAL_CONFIG = copy.deepcopy(bigchaindb._config)
@pytest.fixture
def ignore_local_config_file(monkeypatch):
"""
This fixture's purpose is to override the one under
:module:`tests/conftest.py` so that the original behaviour of
:func:`bigchaindb.config_utils.file_config` is restored, so that it can be
tested.
"""
from bigchaindb.config_utils import file_config
monkeypatch.setattr('bigchaindb.config_utils.file_config', file_config)
@pytest.fixture(scope='function', autouse=True)
def clean_config(monkeypatch):
monkeypatch.setattr('bigchaindb.config', copy.deepcopy(ORIGINAL_CONFIG))
@ -205,3 +219,21 @@ def test_update_config(monkeypatch):
assert bigchaindb.config['database']['host'] == 'test-host'
assert bigchaindb.config['database']['name'] == 'bigchaindb_other'
assert bigchaindb.config['database']['port'] == 28016
def test_file_config():
from bigchaindb.config_utils import file_config, CONFIG_DEFAULT_PATH
with patch('builtins.open', mock_open(read_data='{}')) as m:
config = file_config()
m.assert_called_once_with(CONFIG_DEFAULT_PATH)
assert config == {}
def test_write_config():
from bigchaindb.config_utils import write_config, CONFIG_DEFAULT_PATH
m = mock_open()
with patch('builtins.open', m):
write_config({})
m.assert_called_once_with(CONFIG_DEFAULT_PATH, 'w')
handle = m()
handle.write.assert_called_once_with('{}')