From d3a0b9515ccea8d0030605c60d9452671e117e77 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 17:18:41 +0100 Subject: [PATCH 1/9] Fix exception name --- bigchaindb/commands/bigchain.py | 3 ++- tests/test_commands.py | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/test_commands.py diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 77746b18..159668f4 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -8,6 +8,7 @@ import argparse import bigchaindb import bigchaindb.config_utils from bigchaindb import db +from bigchaindb.exceptions import DatabaseAlreadyExists from bigchaindb.commands.utils import base_parser, start from bigchaindb.processes import Processes from bigchaindb.crypto import generate_key_pair @@ -75,7 +76,7 @@ def run_start(args): bigchaindb.config_utils.file_config(args.config) try: db.init() - except db.DatabaseAlreadyExistsException: + except DatabaseAlreadyExists: pass p = Processes() logger.info('Start bigchaindb main process') diff --git a/tests/test_commands.py b/tests/test_commands.py new file mode 100644 index 00000000..4cfc0db8 --- /dev/null +++ b/tests/test_commands.py @@ -0,0 +1,39 @@ +from argparse import Namespace + +import pytest + + +@pytest.fixture +def mock_run_configure(monkeypatch): + from bigchaindb.commands import bigchain + monkeypatch.setattr(bigchain, 'run_configure', lambda *args, **kwargs: None) + + +@pytest.fixture +def mock_file_config(monkeypatch): + from bigchaindb import config_utils + monkeypatch.setattr(config_utils, 'file_config', lambda *args: None) + + +@pytest.fixture +def mock_db_init_with_existing_db(monkeypatch): + from bigchaindb import db + from bigchaindb.exceptions import DatabaseAlreadyExists + + def mockreturn(): + raise DatabaseAlreadyExists + + monkeypatch.setattr(db, 'init', mockreturn) + + +@pytest.fixture +def mock_processes_start(monkeypatch): + from bigchaindb.processes import Processes + monkeypatch.setattr(Processes, 'start', lambda *args: None) + + +def test_bigchain_run_start(mock_run_configure, mock_file_config, + mock_processes_start, mock_db_init_with_existing_db): + from bigchaindb.commands.bigchain import run_start + args = Namespace(config=None, yes=True) + run_start(args) From e1f4b6c731b415631335382735088bd4cd379432 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 17:19:13 +0100 Subject: [PATCH 2/9] Use explicit name Besides the fact that explicit names are generally considered a better practice, one should also keep in mind that when debugging, a variable like "p" clashes with the debugger command. --- bigchaindb/commands/bigchain.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 159668f4..2c59e0e5 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -78,9 +78,9 @@ def run_start(args): db.init() except DatabaseAlreadyExists: pass - p = Processes() + processes = Processes() logger.info('Start bigchaindb main process') - p.start() + processes.start() def main(): From 88d910f701ece7aaecf38f42b8b84e1464ca4dbf Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 19:46:12 +0100 Subject: [PATCH 3/9] Add todo note --- bigchaindb/commands/bigchain.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 2c59e0e5..3d7a0825 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -22,6 +22,9 @@ def run_show_config(args): """Show the current configuration""" from pprint import pprint + # TODO Proposal: remove the "hidden" configuration. Only show config. If + # the system needs to be configured, then display information on how to + # configure the system. bigchaindb.config_utils.file_config(args.config) pprint(bigchaindb.config) From 61c92682947b849a040a216911325a50e18db8fe Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 19:46:30 +0100 Subject: [PATCH 4/9] Add test for show_config option --- tests/test_commands.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_commands.py b/tests/test_commands.py index 4cfc0db8..6cc542d4 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -1,4 +1,5 @@ from argparse import Namespace +from pprint import pprint import pytest @@ -37,3 +38,18 @@ def test_bigchain_run_start(mock_run_configure, mock_file_config, from bigchaindb.commands.bigchain import run_start args = Namespace(config=None, yes=True) run_start(args) + + +# TODO Please beware, that if debugging, the "-s" switch for pytest will +# interfere with capsys. +# See related issue: https://github.com/pytest-dev/pytest/issues/128 +def test_bigchain_show_config(capsys, mock_file_config): + from bigchaindb import config + from bigchaindb.commands.bigchain import run_show_config + args = Namespace(config=None) + _, _ = capsys.readouterr() + run_show_config(args) + output_config, _ = capsys.readouterr() + pprint(config) + expected_outout_config, _ = capsys.readouterr() + assert output_config == expected_outout_config From 35344d87fafe85446ce090bc08b55bd261f15ec2 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 20:05:16 +0100 Subject: [PATCH 5/9] Handle case when db already exists --- bigchaindb/commands/bigchain.py | 9 ++++++++- tests/test_commands.py | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 3d7a0825..52c2c7f7 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -64,7 +64,14 @@ def run_configure(args, skip_if_exists=False): def run_init(args): """Initialize the database""" bigchaindb.config_utils.file_config(args.config) - db.init() + # TODO Provide mechanism to: + # 1. prompt the user to inquire whether they wish to drop the db + # 2. force the init, (e.g., via -f flag) + try: + db.init() + except DatabaseAlreadyExists: + print('The database already exists.') + print('If you wish to re-initialize it, first drop it.') def run_drop(args): diff --git a/tests/test_commands.py b/tests/test_commands.py index 6cc542d4..fc5db73e 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -53,3 +53,9 @@ def test_bigchain_show_config(capsys, mock_file_config): pprint(config) expected_outout_config, _ = capsys.readouterr() assert output_config == expected_outout_config + + +def test_bigchain_run_init_when_db_exists(mock_file_config, mock_db_init_with_existing_db): + from bigchaindb.commands.bigchain import run_init + args = Namespace(config=None) + run_init(args) From 2b483767ea64daee562c555ab50b3e21d8fd39af Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 20:30:50 +0100 Subject: [PATCH 6/9] Add test for run_drop --- tests/test_commands.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_commands.py b/tests/test_commands.py index fc5db73e..7b8f469a 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -33,6 +33,16 @@ def mock_processes_start(monkeypatch): monkeypatch.setattr(Processes, 'start', lambda *args: None) +@pytest.fixture +def mock_rethink_db_drop(monkeypatch): + def mockreturn(dbname): + class MockDropped(object): + def run(self, conn): + return + return MockDropped() + monkeypatch.setattr('rethinkdb.db_drop', mockreturn) + + def test_bigchain_run_start(mock_run_configure, mock_file_config, mock_processes_start, mock_db_init_with_existing_db): from bigchaindb.commands.bigchain import run_start @@ -59,3 +69,9 @@ def test_bigchain_run_init_when_db_exists(mock_file_config, mock_db_init_with_ex from bigchaindb.commands.bigchain import run_init args = Namespace(config=None) run_init(args) + + +def test_drop_existing_db(mock_file_config, mock_rethink_db_drop): + from bigchaindb.commands.bigchain import run_drop + args = Namespace(config=None, yes=True) + run_drop(args) From a766fc60b76aec0e70b56d903fd5cdfb0efe278f Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 20:48:30 +0100 Subject: [PATCH 7/9] Add test for run_configure --- tests/test_commands.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_commands.py b/tests/test_commands.py index 7b8f469a..1a8e453c 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -75,3 +75,11 @@ def test_drop_existing_db(mock_file_config, mock_rethink_db_drop): from bigchaindb.commands.bigchain import run_drop args = Namespace(config=None, yes=True) run_drop(args) + + +def test_run_configure_when_config_exists_and_skipping(monkeypatch): + from bigchaindb.commands.bigchain import run_configure + monkeypatch.setattr('os.path.exists', lambda path: True) + args = Namespace(config='foo', yes=True) + return_value = run_configure(args, skip_if_exists=True) + assert return_value is None From ab2a0f3a82195c8e619af684b91641ce1349eff5 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 20:51:06 +0100 Subject: [PATCH 8/9] Simplify, and avoid assignment that may not be used --- bigchaindb/commands/bigchain.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 52c2c7f7..7ea95851 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -36,13 +36,12 @@ def run_configure(args, skip_if_exists=False): skip_if_exists (bool): skip the function if a conf file already exists """ config_path = args.config or bigchaindb.config_utils.CONFIG_DEFAULT_PATH - proceed = args.yes config_file_exists = os.path.exists(config_path) if config_file_exists and skip_if_exists: return - if config_file_exists and not proceed: + if config_file_exists and not args.yes: want = input('Config file `{}` exists, do you want to override it? ' '(cannot be undone) [y/n]: '.format(config_path)) if not want: From 9919e275c217b7b5204d85928ce0dcf813598d47 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Sun, 14 Feb 2016 21:51:40 +0100 Subject: [PATCH 9/9] Add test for run_configure to write config --- tests/test_commands.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/test_commands.py b/tests/test_commands.py index 1a8e453c..3897129e 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -16,6 +16,12 @@ def mock_file_config(monkeypatch): monkeypatch.setattr(config_utils, 'file_config', lambda *args: None) +@pytest.fixture +def mock_write_config(monkeypatch): + from bigchaindb import config_utils + monkeypatch.setattr(config_utils, 'write_config', lambda *args: None) + + @pytest.fixture def mock_db_init_with_existing_db(monkeypatch): from bigchaindb import db @@ -43,6 +49,21 @@ def mock_rethink_db_drop(monkeypatch): monkeypatch.setattr('rethinkdb.db_drop', mockreturn) +@pytest.fixture +def mock_generate_key_pair(monkeypatch): + from bigchaindb import crypto + monkeypatch.setattr(crypto, 'generate_key_pair', lambda: ('privkey', 'pubkey')) + + +@pytest.fixture +def mock_bigchaindb_backup_config(monkeypatch): + config = { + 'keypair': {}, + 'database': {'host': 'host', 'port': 12345, 'name': 'adbname'}, + } + monkeypatch.setattr('bigchaindb._config', config) + + def test_bigchain_run_start(mock_run_configure, mock_file_config, mock_processes_start, mock_db_init_with_existing_db): from bigchaindb.commands.bigchain import run_start @@ -83,3 +104,18 @@ def test_run_configure_when_config_exists_and_skipping(monkeypatch): args = Namespace(config='foo', yes=True) return_value = run_configure(args, skip_if_exists=True) assert return_value is None + + +# TODO Beware if you are putting breakpoints in there, and using the '-s' +# switch with pytest. It will just hang. Seems related to the monkeypatching of +# input. +def test_run_configure_when_config_does_not_exist(monkeypatch, + mock_write_config, + mock_generate_key_pair, + mock_bigchaindb_backup_config): + from bigchaindb.commands.bigchain import run_configure + monkeypatch.setattr('os.path.exists', lambda path: False) + monkeypatch.setattr('builtins.input', lambda question: '\n') + args = Namespace(config='foo', yes=True) + return_value = run_configure(args) + assert return_value is None