diff --git a/bigchaindb/db/utils.py b/bigchaindb/db/utils.py index f3f4f5c7..d5551833 100644 --- a/bigchaindb/db/utils.py +++ b/bigchaindb/db/utils.py @@ -10,6 +10,7 @@ from bigchaindb import exceptions logger = logging.getLogger(__name__) + def get_conn(): '''Get the connection to the database.''' @@ -26,11 +27,7 @@ def init(): logger.info('Create:') logger.info(' - database `%s`', dbname) - try: - r.db_create(dbname).run(conn) - except r.ReqlOpFailedError as e: - logger.info(e.message) - return + r.db_create(dbname).run(conn) logger.info(' - tables') # create the tables @@ -81,7 +78,7 @@ def drop(assume_yes=False): logger.info('Drop database `%s`', dbname) r.db_drop(dbname).run(conn) logger.info('Done.') - except r.ReqlOpFailedError as e: - logger.info(e.message) + except r.ReqlOpFailedError: + raise exceptions.DatabaseDoesNotExist('Database `{}` does not exist'.format(dbname)) else: logger.info('Drop aborted') diff --git a/bigchaindb/exceptions.py b/bigchaindb/exceptions.py index 964daefe..684ae58c 100644 --- a/bigchaindb/exceptions.py +++ b/bigchaindb/exceptions.py @@ -22,3 +22,6 @@ class InvalidSignature(Exception): 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""" + diff --git a/tests/db/conftest.py b/tests/db/conftest.py index e0c92e70..438f30e5 100644 --- a/tests/db/conftest.py +++ b/tests/db/conftest.py @@ -25,8 +25,6 @@ def setup_database(request): r.db_create('bigchain_test').run() except r.ReqlOpFailedError as e: if e.message == 'Database `bigchain_test` already exists.': - print(e.message) - print('Deleting `bigchain_test` database.') r.db_drop('bigchain_test').run() r.db_create('bigchain_test').run() else: @@ -52,7 +50,12 @@ def setup_database(request): def fin(): print('Deleting `bigchain_test` database') get_conn().repl() - r.db_drop('bigchain_test').run() + try: + r.db_drop('bigchain_test').run() + except r.ReqlOpFailedError as e: + if e.message != 'Database `bigchain_test` does not exist.': + raise + print('Finished deleting `bigchain_test`') request.addfinalizer(fin) @@ -62,8 +65,12 @@ def setup_database(request): def cleanup_tables(request): def fin(): get_conn().repl() - r.db('bigchain_test').table('bigchain').delete().run() - r.db('bigchain_test').table('backlog').delete().run() + try: + r.db('bigchain_test').table('bigchain').delete().run() + r.db('bigchain_test').table('backlog').delete().run() + except r.ReqlOpFailedError as e: + if e.message != 'Database `bigchain_test` does not exist.': + raise request.addfinalizer(fin) diff --git a/tests/db/test_utils.py b/tests/db/test_utils.py new file mode 100644 index 00000000..20f2942c --- /dev/null +++ b/tests/db/test_utils.py @@ -0,0 +1,98 @@ +import builtins + +import pytest +import rethinkdb as r + +import bigchaindb +from bigchaindb.db import utils +from .conftest import setup_database as _setup_database + + +# Since we are testing database initialization and database drop, +# we need to use the `setup_database` fixture on a function level +@pytest.fixture(scope='function', autouse=True) +def setup_database(request): + _setup_database(request) + + +def test_init_creates_db_tables_and_indexes(): + conn = utils.get_conn() + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures so we need to remove it + r.db_drop(dbname).run(conn) + + utils.init() + + assert r.db_list().contains(dbname).run(conn) == True + + assert r.db(dbname).table_list().contains('backlog', 'bigchain').run(conn) == True + + assert r.db(dbname).table('bigchain').index_list().contains( + 'block_timestamp', + 'block_number').run(conn) == True + + assert r.db(dbname).table('backlog').index_list().contains( + 'transaction_timestamp', + 'assignee__transaction_timestamp').run(conn) == True + + +def test_init_fails_if_db_exists(): + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures + assert r.db_list().contains(dbname) == True + + with pytest.raises(bigchaindb.exceptions.DatabaseAlreadyExists): + utils.init() + + +def test_drop_interactively_drops_the_database_when_user_says_yes(monkeypatch): + conn = utils.get_conn() + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures + assert r.db_list().contains(dbname).run(conn) == True + + monkeypatch.setattr(builtins, 'input', lambda x: 'y') + utils.drop() + + assert r.db_list().contains(dbname).run(conn) == False + + +def test_drop_programmatically_drops_the_database_when_assume_yes_is_true(monkeypatch): + conn = utils.get_conn() + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures + assert r.db_list().contains(dbname).run(conn) == True + + utils.drop(assume_yes=True) + + assert r.db_list().contains(dbname).run(conn) == False + + +def test_drop_interactively_does_not_drop_the_database_when_user_says_no(monkeypatch): + conn = utils.get_conn() + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures + print(r.db_list().contains(dbname).run(conn)) + assert r.db_list().contains(dbname).run(conn) == True + + monkeypatch.setattr(builtins, 'input', lambda x: 'n') + utils.drop() + + assert r.db_list().contains(dbname).run(conn) == True + +def test_drop_non_existent_db_raises_an_error(): + conn = utils.get_conn() + dbname = bigchaindb.config['database']['name'] + + # The db is set up by fixtures + assert r.db_list().contains(dbname).run(conn) == True + utils.drop(assume_yes=True) + + with pytest.raises(bigchaindb.exceptions.DatabaseDoesNotExist): + utils.drop(assume_yes=True) +